@param $source
@param $table
@param callable|Conditions $on

@return $this
185519
public function leftJoinOnTo($source, $table, $on)
    {
        $this->join('LEFT', $source, $table, $on);

        return $this;
    }
152920
public function outerJoinUsing($table, $where)
    {
        //argument test
        Argument::i()
            //Argument 1 must be a string
            ->test(1, 'string')
            //Argument 2 must be a string
            ->test(2, 'string');
        
        $where = func_get_args();
        $table = array_shift($where);
        
        $this->join[] = array(self::OUTER, $table, $where, true);
        
        return $this;
    }
1282936
public function left($table, ...$on) {
        $this->join($table, Condition::cleanField($on[0]) . '=' . Condition::cleanField($on[1]), self::LEFT);

        return $this;
    }
515210
public function from($table, $as = null)
	{
		$this->syntax->setFrom($table, $as);
		return $this;
	}
201443
public function rightJoin($table, $alias = null, $on = null)
    {
        return $this->join($table, $alias, $on, 'RIGHT JOIN');
    }
893868
public function Join(string $table, string $as, string $by, string $condition): QueryBuilder
    {
        $this->join[] = [
            'table' => $table,
            'as' => $as,
            'by' => $by,
            'cond' => $condition
        ];
        
        return $this;
    }
1070254
public function setTable(Table $table = null)
    {
        $this->table = $table;

        if ($table && !in_array($this, $table->getRows())) {
            $table->addRow($this);
        }

        return $this;
    }
1191915
public function join($table, $on, $type = 'full', $alias = '')
    {
        if (!isset($this->joins)) {
            $this->joins = [];
        }
        $join = [
            'table' => $this->trimName($table),
            'on' => $on,
            'type' => $type,
        ];
        if (!empty($alias)) {
            $join['alias'] = $this->trimName($alias);
        }
        $this->joins = array_merge($this->joins, [$join]);
        return $this;
    }
834167
public function leftJoin($table, array $fields = [], array $on = []) {
        return $this->_addJoin(Join::LEFT, $table, $fields, $on);
    }
826601
public function addJoin(string $tableKey, string $type, ?string $source, $table, ?string $alias, $on = null, array $params = [])
    {
        $this->join[$tableKey] = [
            'type'   => $type,
            'source' => $source,

            'table' => $table,
            'alias' => $alias,

            'on'     => $on,
            'params' => $params,
        ];

        return $this;
    }
287981
public function innerJoinTo($source, $table, string $on = null, string ...$params)
    {
        $this->join('INNER', $source, $table, $on, $params);

        return $this;
    }
1002123
public static function left(Table $table, string $alias, array $on) : Join
    {
        return new self(self::LEFT, $table, $alias, $on);
    }
1326741
public function leftJoinOn($table, $on)
    {
        $instance = $this->joinStrategyInstance();

        $instance->joinStrategy()->leftJoinOn($table, $on);

        return $instance;
    }
547189
public function table($table)
    {
        $tables = is_array($table) ? $table : func_get_args();
        $this->_parts['table'] = $tables;
        return $this;
    }
24798
public function after($source)
    {
        foreach ($this as $node) {
            if ($node instanceof Element) {
                $node->after($source);
            }
        }

        return $this;
    }
1269994
public function rightJoinOn($table, $on)
    {
        $instance = $this->joinStrategyInstance();

        $instance->joinStrategy()->rightJoinOn($table, $on);

        return $instance;
    }
1291203
final public function createTableIfNotExists(Table $table): Database
    {
        if (!$this->hasTable($table::getName())) {
            $this->createTable($table);
        }

        return $this;
    }