经过一天左右的努力,终于把laravel的源代码整合到了yaf框架上面,下面说一下laravel的db层的一些处理吧,我使用的是laravel5.1.4,下面是database所在的位置:laravel5.1.4/vendor/laravel/framework/src/Illuminate/Database ,这个路径就是它的文件地址目录。
我们来到Database文件夹后,会看到一些目录,这里简单介绍下它们的作用:
Connectors----用于连接 、 Console-----用于命令行 、 Eloquent-----用于ORM
Migrantions----用于迁移、 Query-------用于查询、 Schema--------用于操作数据库结构
该目录下还有一些其他的文件,都是一些比较通用的文件和接口性质的东西,当然也有一些和MySQL以及Postgresql息息相关的东西,这里就不一一介绍啦。
然后我们进入Query目录,发现它有两个目录和三个文件,其中Builder.php是具体的命令,比如我们常用的transaction、get、lists都是在这个文件中定义的,而Expression.php则是具体的表达式,而JoinClause.php则是和连接相关的操作,主要处理连接里面具体的每个小环节的操作。一般来说,这里面最大的就是Builder.php,它有52KB,它是负责接收用户传递过来的数据的,我们的命令也就写在这个接口里面。
而Grammars文件夹则是根据用户的输入来进行编译,也就是它里面的函数多是以compile开头,而且多数是compileInsert这种形式,因为在它的源代码中我们经常会发现它的构造中是compile加上action的ucfirst操作之后的字符串拼接得到。而在Grammars里面又会有Grammar.php和MySqlGrammar.php等和具体的数据库相关的文件。
而在Connection.php中引用它们的时候,它是不知道我们使用了哪个数据库的,因此laravel给我们提供的解决办法是,我不管你使用的是哪个具体的Grammar,我只知道,你给我用的时候,必须是QueryGrammar。由于我们的业务中都是使用的MySQL,因此我们可以写一个QueryGrammar来继承自MySQLGrammar,当然,不这样做也是可以的。
其中绝大多数都是在Builder和Grammar中跳转,还有少数是需要Processor的,一般都是这样,很多具体的细节就不废话了。下面把Builder.php的代码贴上来把:
<?php
namespace Illuminate\Database\Query;
use Closure;
use BadMethodCallException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Illuminate\Support\Collection;
use Illuminate\Pagination\Paginator;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Database\Query\Processors\Processor;
class Builder
{
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $connection;
/**
* The database query grammar instance.
*
* @var \Illuminate\Database\Query\Grammars\Grammar
*/
protected $grammar;
/**
* The database query post processor instance.
*
* @var \Illuminate\Database\Query\Processors\Processor
*/
protected $processor;
/**
* The current query value bindings.
*
* @var array
*/
protected $bindings = [
'select' => [],
'join' => [],
'where' => [],
'having' => [],
'order' => [],
];
/**
* An aggregate function and column to be run.
*
* @var array
*/
public $aggregate;
/**
* The columns that should be returned.
*
* @var array
*/
public $columns;
/**
* Indicates if the query returns distinct results.
*
* @var bool
*/
public $distinct = false;
/**
* The table which the query is targeting.
*
* @var string
*/
public $from;
/**
* The table joins for the query.
*
* @var array
*/
public $joins;
/**
* The where constraints for the query.
*
* @var array
*/
public $wheres;
/**
* The groupings for the query.
*
* @var array
*/
public $groups;
/**
* The having constraints for the query.
*
* @var array
*/
public $havings;
/**
* The orderings for the query.
*
* @var array
*/
public $orders;
/**
* The maximum number of records to return.
*
* @var int
*/
public $limit;
/**
* The number of records to skip.
*
* @var int
*/
public $offset;
/**
* The query union statements.
*
* @var array
*/
public $unions;
/**
* The maximum number of union records to return.
*
* @var int
*/
public $unionLimit;
/**
* The number of union records to skip.
*
* @var int
*/
public $unionOffset;
/**
* The orderings for the union query.
*
* @var array
*/
public $unionOrders;
/**
* Indicates whether row locking is being used.
*
* @var string|bool
*/
public $lock;
/**
* The field backups currently in use.
*
* @var array
*/
protected $backups = [];
/**
* All of the available clause operators.
*
* @var array
*/
protected $operators = [
'=', '<', '>', '<=', '>=', '<>', '!=',
'like', 'like binary', 'not like', 'between', 'ilike',
'&', '|', '^', '<<', '>>',
'rlike', 'regexp', 'not regexp',
'~', '~*', '!~', '!~*', 'similar to',
'not similar to',
];
/**
* Whether use write pdo for select.
*
* @var bool
*/
protected $useWritePdo = false;
/**
* Create a new query builder instance.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @param \Illuminate\Database\Query\Grammars\Grammar $grammar
* @param \Illuminate\Database\Query\Processors\Processor $processor
* @return void
*/
public function __construct(ConnectionInterface $connection,
Grammar $grammar,
Processor $processor)
{
$this->grammar = $grammar;
$this->processor = $processor;
$this->connection = $connection;
}
/**
* Set the columns to be selected.
*
* @param array $columns
* @return $this
*/
public function select($columns = ['*'])
{
$this->columns = is_array($columns) ? $columns : func_get_args();
return $this;
}
/**
* Add a new "raw" select expression to the query.
*
* @param string $expression
* @param array $bindings
* @return \Illuminate\Database\Query\Builder|static
*/
public function selectRaw($expression, array $bindings = [])
{
$this->addSelect(new Expression($expression));
if ($bindings) {
$this->addBinding($bindings, 'select');
}
return $this;
}
/**
* Add a subselect expression to the query.
*
* @param \Closure|\Illuminate\Database\Query\Builder|string $query
* @param string $as
* @return \Illuminate\Database\Query\Builder|static
*/
public function selectSub($query, $as)
{
if ($query instanceof Closure) {
$callback = $query;
$callback($query = $this->newQuery());
}
if ($query instanceof self) {
$bindings = $query->getBindings();
$query = $query->toSql();
} elseif (is_string($query)) {
$bindings = [];
} else {
throw new InvalidArgumentException;
}
return $this->selectRaw('('.$query.') as '.$this->grammar->wrap($as), $bindings);
}
/**
* Add a new select column to the query.
*
* @param mixed $column
* @return $this
*/
public function addSelect($column)
{
$column = is_array($column) ? $column : func_get_args();
$this->columns = array_merge((array) $this->columns, $column);
return $this;
}
/**
* Force the query to only return distinct results.
*
* @return $this
*/
public function distinct()
{
$this->distinct = true;
return $this;
}
/**
* Set the table which the query is targeting.
*
* @param string $table
* @return $this
*/
public function from($table)
{
$this->from = $table;
return $this;
}
/**
* Add a join clause to the query.
*
* @param string $table
* @param string $one
* @param string $operator
* @param string $two
* @param string $type
* @param bool $where
* @return $this
*/
public function join($table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
{
// If the first "column" of the join is really a Closure instance the developer
// is trying to build a join with a complex "on" clause containing more than
// one condition, so we'll add the join and call a Closure with the query.
if ($one instanceof Closure) {
$this->joins[] = new JoinClause($type, $table);
call_user_func($one, end($this->joins));
}
// If the column is simply a string, we can assume the join simply has a basic
// "on" clause with a single condition. So we will just build the join with
// this simple join clauses attached to it. There is not a join callback.
else {
$join = new JoinClause($type, $table);
$this->joins[] = $join->on(
$one, $operator, $two, 'and', $where
);
}
return $this;
}
/**
* Add a "join where" clause to the query.
*
* @param string $table
* @param string $one
* @param string $operator
* @param string $two
* @param string $type
* @return \Illuminate\Database\Query\Builder|static
*/
public function joinWhere($table, $one, $operator, $two, $type = 'inner')
{
return $this->join($table, $one, $operator, $two, $type, true);
}
/**
* Add a left join to the query.
*
* @param string $table
* @param string $first
* @param string $operator
* @param string $second
* @return \Illuminate\Database\Query\Builder|static
*/
public function leftJoin($table, $first, $operator = null, $second = null)
{
return $this->join($table, $first, $operator, $second, 'left');
}
/**
* Add a "join where" clause to the query.
*
* @param string $table
* @param string $one
* @param string $operator
* @param string $two
* @return \Illuminate\Database\Query\Builder|static
*/
public function leftJoinWhere($table, $one, $operator, $two)
{
return $this->joinWhere($table, $one, $operator, $two, 'left');
}
/**
* Add a right join to the query.
*
* @param string $table
* @param string $first
* @param string $operator
* @param string $second
* @return \Illuminate\Database\Query\Builder|static
*/
public function rightJoin($table, $first, $operator = null, $second = null)
{
return $this->join