PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Illuminate/Database/Query/Builder.php

https://gitlab.com/barrel/framework
PHP | 1953 lines | 716 code | 275 blank | 962 comment | 35 complexity | 04bff39feecf9ba3402fa14940bfb567 MD5 | raw file
  1. <?php namespace Illuminate\Database\Query;
  2. use Closure;
  3. use Illuminate\Support\Collection;
  4. use Illuminate\Database\ConnectionInterface;
  5. use Illuminate\Database\Query\Grammars\Grammar;
  6. use Illuminate\Database\Query\Processors\Processor;
  7. class Builder {
  8. /**
  9. * The database connection instance.
  10. *
  11. * @var \Illuminate\Database\Connection
  12. */
  13. protected $connection;
  14. /**
  15. * The database query grammar instance.
  16. *
  17. * @var \Illuminate\Database\Query\Grammars\Grammar
  18. */
  19. protected $grammar;
  20. /**
  21. * The database query post processor instance.
  22. *
  23. * @var \Illuminate\Database\Query\Processors\Processor
  24. */
  25. protected $processor;
  26. /**
  27. * The current query value bindings.
  28. *
  29. * @var array
  30. */
  31. protected $bindings = array();
  32. /**
  33. * An aggregate function and column to be run.
  34. *
  35. * @var array
  36. */
  37. public $aggregate;
  38. /**
  39. * The columns that should be returned.
  40. *
  41. * @var array
  42. */
  43. public $columns;
  44. /**
  45. * Indicates if the query returns distinct results.
  46. *
  47. * @var bool
  48. */
  49. public $distinct = false;
  50. /**
  51. * The table which the query is targeting.
  52. *
  53. * @var string
  54. */
  55. public $from;
  56. /**
  57. * The table joins for the query.
  58. *
  59. * @var array
  60. */
  61. public $joins;
  62. /**
  63. * The where constraints for the query.
  64. *
  65. * @var array
  66. */
  67. public $wheres;
  68. /**
  69. * The groupings for the query.
  70. *
  71. * @var array
  72. */
  73. public $groups;
  74. /**
  75. * The having constraints for the query.
  76. *
  77. * @var array
  78. */
  79. public $havings;
  80. /**
  81. * The orderings for the query.
  82. *
  83. * @var array
  84. */
  85. public $orders;
  86. /**
  87. * The maximum number of records to return.
  88. *
  89. * @var int
  90. */
  91. public $limit;
  92. /**
  93. * The number of records to skip.
  94. *
  95. * @var int
  96. */
  97. public $offset;
  98. /**
  99. * The query union statements.
  100. *
  101. * @var array
  102. */
  103. public $unions;
  104. /**
  105. * Indicates whether row locking is being used.
  106. *
  107. * @var string|bool
  108. */
  109. public $lock;
  110. /**
  111. * The key that should be used when caching the query.
  112. *
  113. * @var string
  114. */
  115. protected $cacheKey;
  116. /**
  117. * The number of minutes to cache the query.
  118. *
  119. * @var int
  120. */
  121. protected $cacheMinutes;
  122. /**
  123. * The tags for the query cache.
  124. *
  125. * @var array
  126. */
  127. protected $cacheTags;
  128. /**
  129. * The cache driver to be used.
  130. *
  131. * @var string
  132. */
  133. protected $cacheDriver;
  134. /**
  135. * All of the available clause operators.
  136. *
  137. * @var array
  138. */
  139. protected $operators = array(
  140. '=', '<', '>', '<=', '>=', '<>', '!=',
  141. 'like', 'not like', 'between', 'ilike',
  142. '&', '|', '^', '<<', '>>',
  143. );
  144. /**
  145. * Create a new query builder instance.
  146. *
  147. * @param \Illuminate\Database\ConnectionInterface $connection
  148. * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
  149. * @param \Illuminate\Database\Query\Processors\Processor $processor
  150. * @return void
  151. */
  152. public function __construct(ConnectionInterface $connection,
  153. Grammar $grammar,
  154. Processor $processor)
  155. {
  156. $this->grammar = $grammar;
  157. $this->processor = $processor;
  158. $this->connection = $connection;
  159. }
  160. /**
  161. * Set the columns to be selected.
  162. *
  163. * @param array $columns
  164. * @return \Illuminate\Database\Query\Builder|static
  165. */
  166. public function select($columns = array('*'))
  167. {
  168. $this->columns = is_array($columns) ? $columns : func_get_args();
  169. return $this;
  170. }
  171. /**
  172. * Add a new "raw" select expression to the query.
  173. *
  174. * @param string $expression
  175. * @return \Illuminate\Database\Query\Builder|static
  176. */
  177. public function selectRaw($expression)
  178. {
  179. return $this->select(new Expression($expression));
  180. }
  181. /**
  182. * Add a new select column to the query.
  183. *
  184. * @param mixed $column
  185. * @return \Illuminate\Database\Query\Builder|static
  186. */
  187. public function addSelect($column)
  188. {
  189. $column = is_array($column) ? $column : func_get_args();
  190. $this->columns = array_merge((array) $this->columns, $column);
  191. return $this;
  192. }
  193. /**
  194. * Force the query to only return distinct results.
  195. *
  196. * @return \Illuminate\Database\Query\Builder|static
  197. */
  198. public function distinct()
  199. {
  200. $this->distinct = true;
  201. return $this;
  202. }
  203. /**
  204. * Set the table which the query is targeting.
  205. *
  206. * @param string $table
  207. * @return \Illuminate\Database\Query\Builder|static
  208. */
  209. public function from($table)
  210. {
  211. $this->from = $table;
  212. return $this;
  213. }
  214. /**
  215. * Add a join clause to the query.
  216. *
  217. * @param string $table
  218. * @param string $first
  219. * @param string $operator
  220. * @param string $two
  221. * @param string $type
  222. * @param bool $where
  223. * @return \Illuminate\Database\Query\Builder|static
  224. */
  225. public function join($table, $one, $operator = null, $two = null, $type = 'inner', $where = false)
  226. {
  227. // If the first "column" of the join is really a Closure instance the developer
  228. // is trying to build a join with a complex "on" clause containing more than
  229. // one condition, so we'll add the join and call a Closure with the query.
  230. if ($one instanceof Closure)
  231. {
  232. $this->joins[] = new JoinClause($this, $type, $table);
  233. call_user_func($one, end($this->joins));
  234. }
  235. // If the column is simply a string, we can assume the join simply has a basic
  236. // "on" clause with a single condition. So we will just build the join with
  237. // this simple join clauses attached to it. There is not a join callback.
  238. else
  239. {
  240. $join = new JoinClause($this, $type, $table);
  241. $this->joins[] = $join->on(
  242. $one, $operator, $two, 'and', $where
  243. );
  244. }
  245. return $this;
  246. }
  247. /**
  248. * Add a "join where" clause to the query.
  249. *
  250. * @param string $table
  251. * @param string $first
  252. * @param string $operator
  253. * @param string $two
  254. * @param string $type
  255. * @return \Illuminate\Database\Query\Builder|static
  256. */
  257. public function joinWhere($table, $one, $operator, $two, $type = 'inner')
  258. {
  259. return $this->join($table, $one, $operator, $two, $type, true);
  260. }
  261. /**
  262. * Add a left join to the query.
  263. *
  264. * @param string $table
  265. * @param string $first
  266. * @param string $operator
  267. * @param string $second
  268. * @return \Illuminate\Database\Query\Builder|static
  269. */
  270. public function leftJoin($table, $first, $operator = null, $second = null)
  271. {
  272. return $this->join($table, $first, $operator, $second, 'left');
  273. }
  274. /**
  275. * Add a "join where" clause to the query.
  276. *
  277. * @param string $table
  278. * @param string $first
  279. * @param string $operator
  280. * @param string $two
  281. * @return \Illuminate\Database\Query\Builder|static
  282. */
  283. public function leftJoinWhere($table, $one, $operator, $two)
  284. {
  285. return $this->joinWhere($table, $one, $operator, $two, 'left');
  286. }
  287. /**
  288. * Add a basic where clause to the query.
  289. *
  290. * @param string $column
  291. * @param string $operator
  292. * @param mixed $value
  293. * @param string $boolean
  294. * @return \Illuminate\Database\Query\Builder|static
  295. *
  296. * @throws \InvalidArgumentException
  297. */
  298. public function where($column, $operator = null, $value = null, $boolean = 'and')
  299. {
  300. if (func_num_args() == 2)
  301. {
  302. list($value, $operator) = array($operator, '=');
  303. }
  304. elseif ($this->invalidOperatorAndValue($operator, $value))
  305. {
  306. throw new \InvalidArgumentException("Value must be provided.");
  307. }
  308. // If the columns is actually a Closure instance, we will assume the developer
  309. // wants to begin a nested where statement which is wrapped in parenthesis.
  310. // We'll add that Closure to the query then return back out immediately.
  311. if ($column instanceof Closure)
  312. {
  313. return $this->whereNested($column, $boolean);
  314. }
  315. // If the given operator is not found in the list of valid operators we will
  316. // assume that the developer is just short-cutting the '=' operators and
  317. // we will set the operators to '=' and set the values appropriately.
  318. if ( ! in_array(strtolower($operator), $this->operators, true))
  319. {
  320. list($value, $operator) = array($operator, '=');
  321. }
  322. // If the value is a Closure, it means the developer is performing an entire
  323. // sub-select within the query and we will need to compile the sub-select
  324. // within the where clause to get the appropriate query record results.
  325. if ($value instanceof Closure)
  326. {
  327. return $this->whereSub($column, $operator, $value, $boolean);
  328. }
  329. // If the value is "null", we will just assume the developer wants to add a
  330. // where null clause to the query. So, we will allow a short-cut here to
  331. // that method for convenience so the developer doesn't have to check.
  332. if (is_null($value))
  333. {
  334. return $this->whereNull($column, $boolean, $operator != '=');
  335. }
  336. // Now that we are working with just a simple query we can put the elements
  337. // in our array and add the query binding to our array of bindings that
  338. // will be bound to each SQL statements when it is finally executed.
  339. $type = 'Basic';
  340. $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
  341. if ( ! $value instanceof Expression)
  342. {
  343. $this->bindings[] = $value;
  344. }
  345. return $this;
  346. }
  347. /**
  348. * Add an "or where" clause to the query.
  349. *
  350. * @param string $column
  351. * @param string $operator
  352. * @param mixed $value
  353. * @return \Illuminate\Database\Query\Builder|static
  354. */
  355. public function orWhere($column, $operator = null, $value = null)
  356. {
  357. return $this->where($column, $operator, $value, 'or');
  358. }
  359. /**
  360. * Determine if the given operator and value combination is legal.
  361. *
  362. * @param string $operator
  363. * @param mixed $value
  364. * @return bool
  365. */
  366. protected function invalidOperatorAndValue($operator, $value)
  367. {
  368. $isOperator = in_array($operator, $this->operators);
  369. return ($isOperator && $operator != '=' && is_null($value));
  370. }
  371. /**
  372. * Add a raw where clause to the query.
  373. *
  374. * @param string $sql
  375. * @param array $bindings
  376. * @param string $boolean
  377. * @return \Illuminate\Database\Query\Builder|static
  378. */
  379. public function whereRaw($sql, array $bindings = array(), $boolean = 'and')
  380. {
  381. $type = 'raw';
  382. $this->wheres[] = compact('type', 'sql', 'boolean');
  383. $this->bindings = array_merge($this->bindings, $bindings);
  384. return $this;
  385. }
  386. /**
  387. * Add a raw or where clause to the query.
  388. *
  389. * @param string $sql
  390. * @param array $bindings
  391. * @return \Illuminate\Database\Query\Builder|static
  392. */
  393. public function orWhereRaw($sql, array $bindings = array())
  394. {
  395. return $this->whereRaw($sql, $bindings, 'or');
  396. }
  397. /**
  398. * Add a where between statement to the query.
  399. *
  400. * @param string $column
  401. * @param array $values
  402. * @param string $boolean
  403. * @param bool $not
  404. * @return \Illuminate\Database\Query\Builder|static
  405. */
  406. public function whereBetween($column, array $values, $boolean = 'and', $not = false)
  407. {
  408. $type = 'between';
  409. $this->wheres[] = compact('column', 'type', 'boolean', 'not');
  410. $this->bindings = array_merge($this->bindings, $values);
  411. return $this;
  412. }
  413. /**
  414. * Add an or where between statement to the query.
  415. *
  416. * @param string $column
  417. * @param array $values
  418. * @param bool $not
  419. * @return \Illuminate\Database\Query\Builder|static
  420. */
  421. public function orWhereBetween($column, array $values, $not = false)
  422. {
  423. return $this->whereBetween($column, $values, 'or');
  424. }
  425. /**
  426. * Add a where not between statement to the query.
  427. *
  428. * @param string $column
  429. * @param array $values
  430. * @param string $boolean
  431. * @return \Illuminate\Database\Query\Builder|static
  432. */
  433. public function whereNotBetween($column, array $values, $boolean = 'and')
  434. {
  435. return $this->whereBetween($column, $values, $boolean, true);
  436. }
  437. /**
  438. * Add an or where not between statement to the query.
  439. *
  440. * @param string $column
  441. * @param array $values
  442. * @return \Illuminate\Database\Query\Builder|static
  443. */
  444. public function orWhereNotBetween($column, array $values)
  445. {
  446. return $this->whereNotBetween($column, $values, 'or');
  447. }
  448. /**
  449. * Add a nested where statement to the query.
  450. *
  451. * @param \Closure $callback
  452. * @param string $boolean
  453. * @return \Illuminate\Database\Query\Builder|static
  454. */
  455. public function whereNested(Closure $callback, $boolean = 'and')
  456. {
  457. // To handle nested queries we'll actually create a brand new query instance
  458. // and pass it off to the Closure that we have. The Closure can simply do
  459. // do whatever it wants to a query then we will store it for compiling.
  460. $query = $this->newQuery();
  461. $query->from($this->from);
  462. call_user_func($callback, $query);
  463. return $this->addNestedWhereQuery($query, $boolean);
  464. }
  465. /**
  466. * Add another query builder as a nested where to the query builder.
  467. *
  468. * @param \Illuminate\Database\Query\Builder|static $query
  469. * @param string $boolean
  470. * @return \Illuminate\Database\Query\Builder|static
  471. */
  472. public function addNestedWhereQuery($query, $boolean = 'and')
  473. {
  474. if (count($query->wheres))
  475. {
  476. $type = 'Nested';
  477. $this->wheres[] = compact('type', 'query', 'boolean');
  478. $this->mergeBindings($query);
  479. }
  480. return $this;
  481. }
  482. /**
  483. * Add a full sub-select to the query.
  484. *
  485. * @param string $column
  486. * @param string $operator
  487. * @param \Closure $callback
  488. * @param string $boolean
  489. * @return \Illuminate\Database\Query\Builder|static
  490. */
  491. protected function whereSub($column, $operator, Closure $callback, $boolean)
  492. {
  493. $type = 'Sub';
  494. $query = $this->newQuery();
  495. // Once we have the query instance we can simply execute it so it can add all
  496. // of the sub-select's conditions to itself, and then we can cache it off
  497. // in the array of where clauses for the "main" parent query instance.
  498. call_user_func($callback, $query);
  499. $this->wheres[] = compact('type', 'column', 'operator', 'query', 'boolean');
  500. $this->mergeBindings($query);
  501. return $this;
  502. }
  503. /**
  504. * Add an exists clause to the query.
  505. *
  506. * @param \Closure $callback
  507. * @param string $boolean
  508. * @param bool $not
  509. * @return \Illuminate\Database\Query\Builder|static
  510. */
  511. public function whereExists(Closure $callback, $boolean = 'and', $not = false)
  512. {
  513. $type = $not ? 'NotExists' : 'Exists';
  514. $query = $this->newQuery();
  515. // Similar to the sub-select clause, we will create a new query instance so
  516. // the developer may cleanly specify the entire exists query and we will
  517. // compile the whole thing in the grammar and insert it into the SQL.
  518. call_user_func($callback, $query);
  519. $this->wheres[] = compact('type', 'operator', 'query', 'boolean');
  520. $this->mergeBindings($query);
  521. return $this;
  522. }
  523. /**
  524. * Add an or exists clause to the query.
  525. *
  526. * @param \Closure $callback
  527. * @param bool $not
  528. * @return \Illuminate\Database\Query\Builder|static
  529. */
  530. public function orWhereExists(Closure $callback, $not = false)
  531. {
  532. return $this->whereExists($callback, 'or', $not);
  533. }
  534. /**
  535. * Add a where not exists clause to the query.
  536. *
  537. * @param \Closure $callback
  538. * @param string $boolean
  539. * @return \Illuminate\Database\Query\Builder|static
  540. */
  541. public function whereNotExists(Closure $callback, $boolean = 'and')
  542. {
  543. return $this->whereExists($callback, $boolean, true);
  544. }
  545. /**
  546. * Add a where not exists clause to the query.
  547. *
  548. * @param \Closure $callback
  549. * @return \Illuminate\Database\Query\Builder|static
  550. */
  551. public function orWhereNotExists(Closure $callback)
  552. {
  553. return $this->orWhereExists($callback, true);
  554. }
  555. /**
  556. * Add a "where in" clause to the query.
  557. *
  558. * @param string $column
  559. * @param mixed $values
  560. * @param string $boolean
  561. * @param bool $not
  562. * @return \Illuminate\Database\Query\Builder|static
  563. */
  564. public function whereIn($column, $values, $boolean = 'and', $not = false)
  565. {
  566. $type = $not ? 'NotIn' : 'In';
  567. // If the value of the where in clause is actually a Closure, we will assume that
  568. // the developer is using a full sub-select for this "in" statement, and will
  569. // execute those Closures, then we can re-construct the entire sub-selects.
  570. if ($values instanceof Closure)
  571. {
  572. return $this->whereInSub($column, $values, $boolean, $not);
  573. }
  574. $this->wheres[] = compact('type', 'column', 'values', 'boolean');
  575. $this->bindings = array_merge($this->bindings, $values);
  576. return $this;
  577. }
  578. /**
  579. * Add an "or where in" clause to the query.
  580. *
  581. * @param string $column
  582. * @param mixed $values
  583. * @return \Illuminate\Database\Query\Builder|static
  584. */
  585. public function orWhereIn($column, $values)
  586. {
  587. return $this->whereIn($column, $values, 'or');
  588. }
  589. /**
  590. * Add a "where not in" clause to the query.
  591. *
  592. * @param string $column
  593. * @param mixed $values
  594. * @param string $boolean
  595. * @return \Illuminate\Database\Query\Builder|static
  596. */
  597. public function whereNotIn($column, $values, $boolean = 'and')
  598. {
  599. return $this->whereIn($column, $values, $boolean, true);
  600. }
  601. /**
  602. * Add an "or where not in" clause to the query.
  603. *
  604. * @param string $column
  605. * @param mixed $values
  606. * @return \Illuminate\Database\Query\Builder|static
  607. */
  608. public function orWhereNotIn($column, $values)
  609. {
  610. return $this->whereNotIn($column, $values, 'or');
  611. }
  612. /**
  613. * Add a where in with a sub-select to the query.
  614. *
  615. * @param string $column
  616. * @param \Closure $callback
  617. * @param string $boolean
  618. * @param bool $not
  619. * @return \Illuminate\Database\Query\Builder|static
  620. */
  621. protected function whereInSub($column, Closure $callback, $boolean, $not)
  622. {
  623. $type = $not ? 'NotInSub' : 'InSub';
  624. // To create the exists sub-select, we will actually create a query and call the
  625. // provided callback with the query so the developer may set any of the query
  626. // conditions they want for the in clause, then we'll put it in this array.
  627. call_user_func($callback, $query = $this->newQuery());
  628. $this->wheres[] = compact('type', 'column', 'query', 'boolean');
  629. $this->mergeBindings($query);
  630. return $this;
  631. }
  632. /**
  633. * Add a "where null" clause to the query.
  634. *
  635. * @param string $column
  636. * @param string $boolean
  637. * @param bool $not
  638. * @return \Illuminate\Database\Query\Builder|static
  639. */
  640. public function whereNull($column, $boolean = 'and', $not = false)
  641. {
  642. $type = $not ? 'NotNull' : 'Null';
  643. $this->wheres[] = compact('type', 'column', 'boolean');
  644. return $this;
  645. }
  646. /**
  647. * Add an "or where null" clause to the query.
  648. *
  649. * @param string $column
  650. * @return \Illuminate\Database\Query\Builder|static
  651. */
  652. public function orWhereNull($column)
  653. {
  654. return $this->whereNull($column, 'or');
  655. }
  656. /**
  657. * Add a "where not null" clause to the query.
  658. *
  659. * @param string $column
  660. * @param string $boolean
  661. * @return \Illuminate\Database\Query\Builder|static
  662. */
  663. public function whereNotNull($column, $boolean = 'and')
  664. {
  665. return $this->whereNull($column, $boolean, true);
  666. }
  667. /**
  668. * Add an "or where not null" clause to the query.
  669. *
  670. * @param string $column
  671. * @return \Illuminate\Database\Query\Builder|static
  672. */
  673. public function orWhereNotNull($column)
  674. {
  675. return $this->whereNotNull($column, 'or');
  676. }
  677. /**
  678. * Add a "where day" statement to the query.
  679. *
  680. * @param string $column
  681. * @param string $operator
  682. * @param int $value
  683. * @param string $boolean
  684. * @return \Illuminate\Database\Query\Builder|static
  685. */
  686. public function whereDay($column, $operator, $value, $boolean = 'and')
  687. {
  688. return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean);
  689. }
  690. /**
  691. * Add a "where month" statement to the query.
  692. *
  693. * @param string $column
  694. * @param string $operator
  695. * @param int $value
  696. * @param string $boolean
  697. * @return \Illuminate\Database\Query\Builder|static
  698. */
  699. public function whereMonth($column, $operator, $value, $boolean = 'and')
  700. {
  701. return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean);
  702. }
  703. /**
  704. * Add a "where year" statement to the query.
  705. *
  706. * @param string $column
  707. * @param string $operator
  708. * @param int $value
  709. * @param string $boolean
  710. * @return \Illuminate\Database\Query\Builder|static
  711. */
  712. public function whereYear($column, $operator, $value, $boolean = 'and')
  713. {
  714. return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean);
  715. }
  716. /**
  717. * Add a date based (year, month, day) statement to the query.
  718. *
  719. * @param string $type
  720. * @param string $column
  721. * @param string $operator
  722. * @param int $value
  723. * @param string $boolean
  724. * @return \Illuminate\Database\Query\Builder|static
  725. */
  726. protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
  727. {
  728. $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
  729. $this->bindings[] = $value;
  730. return $this;
  731. }
  732. /**
  733. * Handles dynamic "where" clauses to the query.
  734. *
  735. * @param string $method
  736. * @param string $parameters
  737. * @return \Illuminate\Database\Query\Builder|static
  738. */
  739. public function dynamicWhere($method, $parameters)
  740. {
  741. $finder = substr($method, 5);
  742. $segments = preg_split('/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE);
  743. // The connector variable will determine which connector will be used for the
  744. // query condition. We will change it as we come across new boolean values
  745. // in the dynamic method strings, which could contain a number of these.
  746. $connector = 'and';
  747. $index = 0;
  748. foreach ($segments as $segment)
  749. {
  750. // If the segment is not a boolean connector, we can assume it is a column's name
  751. // and we will add it to the query as a new constraint as a where clause, then
  752. // we can keep iterating through the dynamic method string's segments again.
  753. if ($segment != 'And' && $segment != 'Or')
  754. {
  755. $this->addDynamic($segment, $connector, $parameters, $index);
  756. $index++;
  757. }
  758. // Otherwise, we will store the connector so we know how the next where clause we
  759. // find in the query should be connected to the previous ones, meaning we will
  760. // have the proper boolean connector to connect the next where clause found.
  761. else
  762. {
  763. $connector = $segment;
  764. }
  765. }
  766. return $this;
  767. }
  768. /**
  769. * Add a single dynamic where clause statement to the query.
  770. *
  771. * @param string $segment
  772. * @param string $connector
  773. * @param array $parameters
  774. * @param int $index
  775. * @return void
  776. */
  777. protected function addDynamic($segment, $connector, $parameters, $index)
  778. {
  779. // Once we have parsed out the columns and formatted the boolean operators we
  780. // are ready to add it to this query as a where clause just like any other
  781. // clause on the query. Then we'll increment the parameter index values.
  782. $bool = strtolower($connector);
  783. $this->where(snake_case($segment), '=', $parameters[$index], $bool);
  784. }
  785. /**
  786. * Add a "group by" clause to the query.
  787. *
  788. * @param dynamic $columns
  789. * @return \Illuminate\Database\Query\Builder|static
  790. */
  791. public function groupBy()
  792. {
  793. $this->groups = array_merge((array) $this->groups, func_get_args());
  794. return $this;
  795. }
  796. /**
  797. * Add a "having" clause to the query.
  798. *
  799. * @param string $column
  800. * @param string $operator
  801. * @param string $value
  802. * @return \Illuminate\Database\Query\Builder|static
  803. */
  804. public function having($column, $operator = null, $value = null)
  805. {
  806. $type = 'basic';
  807. $this->havings[] = compact('type', 'column', 'operator', 'value');
  808. $this->bindings[] = $value;
  809. return $this;
  810. }
  811. /**
  812. * Add a raw having clause to the query.
  813. *
  814. * @param string $sql
  815. * @param array $bindings
  816. * @param string $boolean
  817. * @return \Illuminate\Database\Query\Builder|static
  818. */
  819. public function havingRaw($sql, array $bindings = array(), $boolean = 'and')
  820. {
  821. $type = 'raw';
  822. $this->havings[] = compact('type', 'sql', 'boolean');
  823. $this->bindings = array_merge($this->bindings, $bindings);
  824. return $this;
  825. }
  826. /**
  827. * Add a raw or having clause to the query.
  828. *
  829. * @param string $sql
  830. * @param array $bindings
  831. * @return \Illuminate\Database\Query\Builder|static
  832. */
  833. public function orHavingRaw($sql, array $bindings = array())
  834. {
  835. return $this->havingRaw($sql, $bindings, 'or');
  836. }
  837. /**
  838. * Add an "order by" clause to the query.
  839. *
  840. * @param string $column
  841. * @param string $direction
  842. * @return \Illuminate\Database\Query\Builder|static
  843. */
  844. public function orderBy($column, $direction = 'asc')
  845. {
  846. $direction = strtolower($direction) == 'asc' ? 'asc' : 'desc';
  847. $this->orders[] = compact('column', 'direction');
  848. return $this;
  849. }
  850. /**
  851. * Add an "order by" clause for a timestamp to the query.
  852. *
  853. * @param string $column
  854. * @return \Illuminate\Database\Query\Builder|static
  855. */
  856. public function latest($column = 'created_at')
  857. {
  858. return $this->orderBy($column, 'desc');
  859. }
  860. /**
  861. * Add an "order by" clause for a timestamp to the query.
  862. *
  863. * @param string $column
  864. * @return \Illuminate\Database\Query\Builder|static
  865. */
  866. public function oldest($column = 'created_at')
  867. {
  868. return $this->orderBy($column, 'asc');
  869. }
  870. /**
  871. * Add a raw "order by" clause to the query.
  872. *
  873. * @param string $sql
  874. * @param array $bindings
  875. * @return \Illuminate\Database\Query\Builder|static
  876. */
  877. public function orderByRaw($sql, $bindings = array())
  878. {
  879. $type = 'raw';
  880. $this->orders[] = compact('type', 'sql');
  881. $this->bindings = array_merge($this->bindings, $bindings);
  882. return $this;
  883. }
  884. /**
  885. * Set the "offset" value of the query.
  886. *
  887. * @param int $value
  888. * @return \Illuminate\Database\Query\Builder|static
  889. */
  890. public function offset($value)
  891. {
  892. $this->offset = max(0, $value);
  893. return $this;
  894. }
  895. /**
  896. * Alias to set the "offset" value of the query.
  897. *
  898. * @param int $value
  899. * @return \Illuminate\Database\Query\Builder|static
  900. */
  901. public function skip($value)
  902. {
  903. return $this->offset($value);
  904. }
  905. /**
  906. * Set the "limit" value of the query.
  907. *
  908. * @param int $value
  909. * @return \Illuminate\Database\Query\Builder|static
  910. */
  911. public function limit($value)
  912. {
  913. if ($value > 0) $this->limit = $value;
  914. return $this;
  915. }
  916. /**
  917. * Alias to set the "limit" value of the query.
  918. *
  919. * @param int $value
  920. * @return \Illuminate\Database\Query\Builder|static
  921. */
  922. public function take($value)
  923. {
  924. return $this->limit($value);
  925. }
  926. /**
  927. * Set the limit and offset for a given page.
  928. *
  929. * @param int $page
  930. * @param int $perPage
  931. * @return \Illuminate\Database\Query\Builder|static
  932. */
  933. public function forPage($page, $perPage = 15)
  934. {
  935. return $this->skip(($page - 1) * $perPage)->take($perPage);
  936. }
  937. /**
  938. * Add a union statement to the query.
  939. *
  940. * @param \Illuminate\Database\Query\Builder|\Closure $query
  941. * @param bool $all
  942. * @return \Illuminate\Database\Query\Builder|static
  943. */
  944. public function union($query, $all = false)
  945. {
  946. if ($query instanceof Closure)
  947. {
  948. call_user_func($query, $query = $this->newQuery());
  949. }
  950. $this->unions[] = compact('query', 'all');
  951. return $this->mergeBindings($query);
  952. }
  953. /**
  954. * Add a union all statement to the query.
  955. *
  956. * @param \Illuminate\Database\Query\Builder|\Closure $query
  957. * @return \Illuminate\Database\Query\Builder|static
  958. */
  959. public function unionAll($query)
  960. {
  961. return $this->union($query, true);
  962. }
  963. /**
  964. * Lock the selected rows in the table.
  965. *
  966. * @param bool $update
  967. * @return \Illuminate\Database\Query\Builder
  968. */
  969. public function lock($value = true)
  970. {
  971. $this->lock = $value;
  972. return $this;
  973. }
  974. /**
  975. * Lock the selected rows in the table for updating.
  976. *
  977. * @return \Illuminate\Database\Query\Builder
  978. */
  979. public function lockForUpdate()
  980. {
  981. return $this->lock(true);
  982. }
  983. /**
  984. * Share lock the selected rows in the table.
  985. *
  986. * @return \Illuminate\Database\Query\Builder
  987. */
  988. public function sharedLock()
  989. {
  990. return $this->lock(false);
  991. }
  992. /**
  993. * Get the SQL representation of the query.
  994. *
  995. * @return string
  996. */
  997. public function toSql()
  998. {
  999. return $this->grammar->compileSelect($this);
  1000. }
  1001. /**
  1002. * Indicate that the query results should be cached.
  1003. *
  1004. * @param \DateTime|int $minutes
  1005. * @param string $key
  1006. * @return \Illuminate\Database\Query\Builder|static
  1007. */
  1008. public function remember($minutes, $key = null)
  1009. {
  1010. list($this->cacheMinutes, $this->cacheKey) = array($minutes, $key);
  1011. return $this;
  1012. }
  1013. /**
  1014. * Indicate that the query results should be cached forever.
  1015. *
  1016. * @param string $key
  1017. * @return \Illuminate\Database\Query\Builder|static
  1018. */
  1019. public function rememberForever($key = null)
  1020. {
  1021. return $this->remember(-1, $key);
  1022. }
  1023. /**
  1024. * Indicate that the results, if cached, should use the given cache tags.
  1025. *
  1026. * @param array|dynamic $cacheTags
  1027. * @return \Illuminate\Database\Query\Builder|static
  1028. */
  1029. public function cacheTags($cacheTags)
  1030. {
  1031. $this->cacheTags = $cacheTags;
  1032. return $this;
  1033. }
  1034. /**
  1035. * Indicate that the results, if cached, should use the given cache driver.
  1036. *
  1037. * @param string $cacheDriver
  1038. * @return \Illuminate\Database\Query\Builder|static
  1039. */
  1040. public function cacheDriver($cacheDriver)
  1041. {
  1042. $this->cacheDriver = $cacheDriver;
  1043. return $this;
  1044. }
  1045. /**
  1046. * Execute a query for a single record by ID.
  1047. *
  1048. * @param int $id
  1049. * @param array $columns
  1050. * @return mixed|static
  1051. */
  1052. public function find($id, $columns = array('*'))
  1053. {
  1054. return $this->where('id', '=', $id)->first($columns);
  1055. }
  1056. /**
  1057. * Pluck a single column's value from the first result of a query.
  1058. *
  1059. * @param string $column
  1060. * @return mixed
  1061. */
  1062. public function pluck($column)
  1063. {
  1064. $result = (array) $this->first(array($column));
  1065. return count($result) > 0 ? reset($result) : null;
  1066. }
  1067. /**
  1068. * Execute the query and get the first result.
  1069. *
  1070. * @param array $columns
  1071. * @return mixed|static
  1072. */
  1073. public function first($columns = array('*'))
  1074. {
  1075. $results = $this->take(1)->get($columns);
  1076. return count($results) > 0 ? reset($results) : null;
  1077. }
  1078. /**
  1079. * Execute the query as a "select" statement.
  1080. *
  1081. * @param array $columns
  1082. * @return array|static[]
  1083. */
  1084. public function get($columns = array('*'))
  1085. {
  1086. if ( ! is_null($this->cacheMinutes)) return $this->getCached($columns);
  1087. return $this->getFresh($columns);
  1088. }
  1089. /**
  1090. * Execute the query as a fresh "select" statement.
  1091. *
  1092. * @param array $columns
  1093. * @return array|static[]
  1094. */
  1095. public function getFresh($columns = array('*'))
  1096. {
  1097. if (is_null($this->columns)) $this->columns = $columns;
  1098. return $this->processor->processSelect($this, $this->runSelect());
  1099. }
  1100. /**
  1101. * Run the query as a "select" statement against the connection.
  1102. *
  1103. * @return array
  1104. */
  1105. protected function runSelect()
  1106. {
  1107. return $this->connection->select($this->toSql(), $this->bindings);
  1108. }
  1109. /**
  1110. * Execute the query as a cached "select" statement.
  1111. *
  1112. * @param array $columns
  1113. * @return array
  1114. */
  1115. public function getCached($columns = array('*'))
  1116. {
  1117. if (is_null($this->columns)) $this->columns = $columns;
  1118. // If the query is requested to be cached, we will cache it using a unique key
  1119. // for this database connection and query statement, including the bindings
  1120. // that are used on this query, providing great convenience when caching.
  1121. list($key, $minutes) = $this->getCacheInfo();
  1122. $cache = $this->getCache();
  1123. $callback = $this->getCacheCallback($columns);
  1124. // If the "minutes" value is less than zero, we will use that as the indicator
  1125. // that the value should be remembered values should be stored indefinitely
  1126. // and if we have minutes we will use the typical remember function here.
  1127. if ($minutes < 0)
  1128. {
  1129. return $cache->rememberForever($key, $callback);
  1130. }
  1131. else
  1132. {
  1133. return $cache->remember($key, $minutes, $callback);
  1134. }
  1135. }
  1136. /**
  1137. * Get the cache object with tags assigned, if applicable.
  1138. *
  1139. * @return \Illuminate\Cache\CacheManager
  1140. */
  1141. protected function getCache()
  1142. {
  1143. $cache = $this->connection->getCacheManager()->driver($this->cacheDriver);
  1144. return $this->cacheTags ? $cache->tags($this->cacheTags) : $cache;
  1145. }
  1146. /**
  1147. * Get the cache key and cache minutes as an array.
  1148. *
  1149. * @return array
  1150. */
  1151. protected function getCacheInfo()
  1152. {
  1153. return array($this->getCacheKey(), $this->cacheMinutes);
  1154. }
  1155. /**
  1156. * Get a unique cache key for the complete query.
  1157. *
  1158. * @return string
  1159. */
  1160. public function getCacheKey()
  1161. {
  1162. return $this->cacheKey ?: $this->generateCacheKey();
  1163. }
  1164. /**
  1165. * Generate the unique cache key for the query.
  1166. *
  1167. * @return string
  1168. */
  1169. public function generateCacheKey()
  1170. {
  1171. $name = $this->connection->getName();
  1172. return md5($name.$this->toSql().serialize($this->bindings));
  1173. }
  1174. /**
  1175. * Get the Closure callback used when caching queries.
  1176. *
  1177. * @param array $columns
  1178. * @return \Closure
  1179. */
  1180. protected function getCacheCallback($columns)
  1181. {
  1182. return function() use ($columns) { return $this->getFresh($columns); };
  1183. }
  1184. /**
  1185. * Chunk the results of the query.
  1186. *
  1187. * @param int $count
  1188. * @param callable $callback
  1189. * @return void
  1190. */
  1191. public function chunk($count, $callback)
  1192. {
  1193. $results = $this->forPage($page = 1, $count)->get();
  1194. while (count($results) > 0)
  1195. {
  1196. // On each chunk result set, we will pass them to the callback and then let the
  1197. // developer take care of everything within the callback, which allows us to
  1198. // keep the memory low for spinning through large result sets for working.
  1199. call_user_func($callback, $results);
  1200. $page++;
  1201. $results = $this->forPage($page, $count)->get();
  1202. }
  1203. }
  1204. /**
  1205. * Get an array with the values of a given column.
  1206. *
  1207. * @param string $column
  1208. * @param string $key
  1209. * @return array
  1210. */
  1211. public function lists($column, $key = null)
  1212. {
  1213. $columns = $this->getListSelect($column, $key);
  1214. // First we will just get all of the column values for the record result set
  1215. // then we can associate those values with the column if it was specified
  1216. // otherwise we can just give these values back without a specific key.
  1217. $results = new Collection($this->get($columns));
  1218. $values = $results->fetch($columns[0])->all();
  1219. // If a key was specified and we have results, we will go ahead and combine
  1220. // the values with the keys of all of the records so that the values can
  1221. // be accessed by the key of the rows instead of simply being numeric.
  1222. if ( ! is_null($key) && count($results) > 0)
  1223. {
  1224. $keys = $results->fetch($key)->all();
  1225. return array_combine($keys, $values);
  1226. }
  1227. return $values;
  1228. }
  1229. /**
  1230. * Get the columns that should be used in a list array.
  1231. *
  1232. * @param string $column
  1233. * @param string $key
  1234. * @return array
  1235. */
  1236. protected function getListSelect($column, $key)
  1237. {
  1238. $select = is_null($key) ? array($column) : array($column, $key);
  1239. // If the selected column contains a "dot", we will remove it so that the list
  1240. // operation can run normally. Specifying the table is not needed, since we
  1241. // really want the names of the columns as it is in this resulting array.
  1242. if (($dot = strpos($select[0], '.')) !== false)
  1243. {
  1244. $select[0] = substr($select[0], $dot + 1);
  1245. }
  1246. return $select;
  1247. }
  1248. /**
  1249. * Concatenate values of a given column as a string.
  1250. *
  1251. * @param string $column
  1252. * @param string $glue
  1253. * @return string
  1254. */
  1255. public function implode($column, $glue = null)
  1256. {
  1257. if (is_null($glue)) return implode($this->lists($column));
  1258. return implode($glue, $this->lists($column));
  1259. }
  1260. /**
  1261. * Get a paginator for the "select" statement.
  1262. *
  1263. * @param int $perPage
  1264. * @param array $columns
  1265. * @return \Illuminate\Pagination\Paginator
  1266. */
  1267. public function paginate($perPage = 15, $columns = array('*'))
  1268. {
  1269. $paginator = $this->connection->getPaginator();
  1270. if (isset($this->groups))
  1271. {
  1272. return $this->groupedPaginate($paginator, $perPage, $columns);
  1273. }
  1274. else
  1275. {
  1276. return $this->ungroupedPaginate($paginator, $perPage, $columns);
  1277. }
  1278. }
  1279. /**
  1280. * Create a paginator for a grouped pagination statement.
  1281. *
  1282. * @param \Illuminate\Pagination\Factory $paginator
  1283. * @param int $perPage
  1284. * @param array $columns
  1285. * @return \Illuminate\Pagination\Paginator
  1286. */
  1287. protected function groupedPaginate($paginator, $perPage, $columns)
  1288. {
  1289. $results = $this->get($columns);
  1290. return $this->buildRawPaginator($paginator, $results, $perPage);
  1291. }
  1292. /**
  1293. * Build a paginator instance from a raw result array.
  1294. *
  1295. * @param \Illuminate\Pagination\Factory $paginator
  1296. * @param array $results
  1297. * @param int $perPage
  1298. * @return \Illuminate\Pagination\Paginator
  1299. */
  1300. public function buildRawPaginator($paginator, $results, $perPage)
  1301. {
  1302. // For queries which have a group by, we will actually retrieve the entire set
  1303. // of rows from the table and "slice" them via PHP. This is inefficient and
  1304. // the developer must be aware of this behavior; however, it's an option.
  1305. $start = ($paginator->getCurrentPage() - 1) * $perPage;
  1306. $sliced = array_slice($results, $start, $perPage);
  1307. return $paginator->make($sliced, count($results), $perPage);
  1308. }
  1309. /**
  1310. * Create a paginator for an un-grouped pagination statement.
  1311. *
  1312. * @param \Illuminate\Pagination\Factory $paginator
  1313. * @param int $perPage
  1314. * @param array $columns
  1315. * @return \Illuminate\Pagination\Paginator
  1316. */
  1317. protected function ungroupedPaginate($paginator, $perPage, $columns)
  1318. {
  1319. $total = $this->getPaginationCount();
  1320. // Once we have the total number of records to be paginated, we can grab the
  1321. // current page and the result array. Then we are ready to create a brand
  1322. // new Paginator instances for the results which will create the links.
  1323. $page = $paginator->getCurrentPage($total);
  1324. $results = $this->forPage($page, $perPage)->get($columns);
  1325. return $paginator->make($results, $total, $perPage);
  1326. }
  1327. /**
  1328. * Get the count of the total records for pagination.
  1329. *
  1330. * @return int
  1331. */
  1332. public function getPaginationCount()
  1333. {
  1334. list($orders, $this->orders) = array($this->orders, null);
  1335. $columns = $this->columns;
  1336. // Because some database engines may throw errors if we leave the ordering
  1337. // statements on the query, we will "back them up" and remove them from
  1338. // the query. Once we have the count we will put them back onto this.
  1339. $total = $this->count();
  1340. $this->orders = $orders;
  1341. // Once the query is run we need to put the old select columns back on the
  1342. // instance so that the select query will run properly. Otherwise, they
  1343. // will be cleared, then the query will fire with all of the columns.
  1344. $this->columns = $columns;
  1345. return $total;
  1346. }
  1347. /**
  1348. * Determine if any rows exist for the current query.
  1349. *
  1350. * @return bool
  1351. */
  1352. public function exists()
  1353. {
  1354. return $this->count() > 0;
  1355. }
  1356. /**
  1357. * Retrieve the "count" result of the query.
  1358. *
  1359. * @param string $column
  1360. * @return int
  1361. */
  1362. public function count($column = '*')
  1363. {
  1364. return $this->aggregate(__FUNCTION__, array($column));
  1365. }
  1366. /**
  1367. * Retrieve the minimum value of a given column.
  1368. *
  1369. * @param string $column
  1370. * @return mixed
  1371. */
  1372. public function min($column)
  1373. {
  1374. return $this->aggregate(__FUNCTION__, array($column));
  1375. }
  1376. /**
  1377. * Retrieve the maximum value of a given column.
  1378. *
  1379. * @param string $column
  1380. * @return mixed
  1381. */
  1382. public function max($column)
  1383. {
  1384. return $this->aggregate(__FUNCTION__, array($column));
  1385. }
  1386. /**
  1387. * Retrieve the sum of the values of a given column.
  1388. *
  1389. * @param string $column
  1390. * @return mixed
  1391. */
  1392. public function sum($column)
  1393. {
  1394. return $this->aggregate(__FUNCTION__, array($column));
  1395. }
  1396. /**
  1397. * Retrieve the average of the values of a given column.
  1398. *
  1399. * @param string $column
  1400. * @return mixed
  1401. */
  1402. public function avg($column)
  1403. {
  1404. return $this->aggregate(__FUNCTION__, array($column));
  1405. }
  1406. /**
  1407. * Execute an aggregate function on the database.
  1408. *
  1409. * @param string $function
  1410. * @param array $columns
  1411. * @return mixed
  1412. */
  1413. public function aggregate($function, $columns = array('*'))
  1414. {
  1415. $this->aggregate = compact('function', 'columns');
  1416. $results = $this->get($columns);
  1417. // Once we have executed the query, we will reset the aggregate property so
  1418. // that more select queries can be executed against the database without
  1419. // the aggregate value getting in the way when the grammar builds it.
  1420. $this->columns = null; $this->aggregate = null;
  1421. if (isset($results[0]))
  1422. {
  1423. $result = (array) $results[0];
  1424. return $result['aggregate'];
  1425. }
  1426. }
  1427. /**
  1428. * Insert a new record into the database.
  1429. *
  1430. * @param array $values
  1431. * @return bool
  1432. */
  1433. public function insert(array $values)
  1434. {
  1435. // Since every insert gets treated like a batch insert, we will make sure the
  1436. // bindings are structured in a way that is convenient for building these
  1437. // inserts statements by verifying the elements are actually an array.
  1438. if ( ! is_array(reset($values)))
  1439. {
  1440. $values = array($values);
  1441. }
  1442. // Since every insert gets treated like a batch insert, we will make sure the
  1443. // bindings are structured in a way that is convenient for building these
  1444. // inserts statements by verifying the elements are actually an array.
  1445. else
  1446. {
  1447. foreach ($values as $key => $value)
  1448. {
  1449. ksort($value); $values[$key] = $value;
  1450. }
  1451. }
  1452. // We'll treat every insert like a batch insert so we can easily insert each
  1453. // of the records into the database consistently. This will make it much
  1454. // easier on the grammars to just handle one type of record insertion.
  1455. $bindings = array();
  1456. foreach ($values as $record)
  1457. {
  1458. $bindings = array_merge($bindings, array_values($record));
  1459. }
  1460. $sql = $this->grammar->compileInsert($this, $values);
  1461. // Once we have compiled the insert statement's SQL we can execute it on the
  1462. // connection and return a result as a boolean success indicator as that
  1463. // is the same type of result returned by the raw connection instance.
  1464. $bindings = $this->cleanBindings($bindings);
  1465. return $this->connection->insert($sql, $bindings);
  1466. }
  1467. /**
  1468. * Insert a new record and get the value of the primary key.
  1469. *
  1470. * @param array $values
  1471. * @param string $sequence
  1472. * @return int
  1473. */
  1474. public function insertGetId(array $values, $sequence = null)
  1475. {
  1476. $sql = $this->grammar->compileInsertGetId($this, $values, $sequence);
  1477. $values = $this->cleanBindings($values);
  1478. return $this->processor->processInsertGetId($this, $sql, $values, $sequence);
  1479. }
  1480. /**
  1481. * Update a record in the database.
  1482. *
  1483. * @param array $values
  1484. * @return int
  1485. */
  1486. public function update(array $values)
  1487. {
  1488. $bindings = array_values(array_merge($values, $this->bindings));
  1489. $sql = $this->grammar->compileUpdate($this, $values);
  1490. return $this->connection->update($sql, $this->cleanBindings($bindings));
  1491. }
  1492. /**
  1493. * Increment a column's value by a given amount.
  1494. *
  1495. * @param string $column
  1496. * @param int $amount
  1497. * @param array $extra
  1498. * @return int
  1499. */
  1500. public function increment($column, $amount = 1, array $extra = array())
  1501. {
  1502. $wrapped = $this->grammar->wrap($column);
  1503. $columns = array_merge(array($column => $this->raw("$wrapped + $amount")), $extra);
  1504. return $this->update($columns);
  1505. }
  1506. /**
  1507. * Decrement a column's value by a given amount.
  1508. *
  1509. * @param string $column
  1510. * @param int $amount
  1511. * @param array $extra
  1512. * @return int
  1513. */
  1514. public function decrement($column, $amount = 1, array $extra = array())
  1515. {
  1516. $wrapped = $this->grammar->wrap($column);
  1517. $columns = array_merge(array($column => $this->raw("$wrapped - $amount")), $extra);
  1518. return $this->update($columns);
  1519. }
  1520. /**
  1521. * Delete a record from the database.
  1522. *
  1523. * @param mixed $id
  1524. * @return int
  1525. */
  1526. public function delete($id = null)
  1527. {
  1528. // If an ID is passed to the method, we will set the where clause to check
  1529. // the ID to allow developers to simply and quickly remove a single row
  1530. // from their database without manually specifying the where clauses.
  1531. if ( ! is_null($id)) $this->where('id', '=', $id);
  1532. $sql = $this->grammar->compileDelete($this);
  1533. return $this->connection->delete($sql, $this->bindings);
  1534. }
  1535. /**
  1536. * Run a truncate statement on the table.
  1537. *
  1538. * @return void
  1539. */
  1540. public function truncate()
  1541. {
  1542. foreach ($this->grammar->compileTruncate($this) as $sql => $bindings)
  1543. {
  1544. $this->connection->statement($sql, $bindings);
  1545. }
  1546. }
  1547. /**
  1548. * Get a new instance of the query builder.
  1549. *
  1550. * @return \Illuminate\Database\Query\Builder
  1551. */
  1552. public function newQuery()
  1553. {
  1554. return new Builder($this->connection, $this->grammar, $this->processor);
  1555. }
  1556. /**
  1557. * Merge an array of where clauses and bindings.
  1558. *
  1559. * @param array $wheres
  1560. * @param array $bindings
  1561. * @return void
  1562. */
  1563. public function mergeWheres($wheres, $bindings)
  1564. {
  1565. $this->wheres = array_merge((array) $this->wheres, (array) $wheres);
  1566. $this->bindings = array_values(array_merge($this->bindings, (array) $bindings));
  1567. }
  1568. /**
  1569. * Remove all of the expressions from a list of bindings.
  1570. *
  1571. * @param array $bindings
  1572. * @return array
  1573. */
  1574. protected function cleanBindings(array $bindings)
  1575. {
  1576. return array_values(array_filter($bindings, function($binding)
  1577. {
  1578. return ! $binding instanceof Expression;
  1579. }));
  1580. }
  1581. /**
  1582. * Create a raw database expression.
  1583. *
  1584. * @param mixed $value
  1585. * @return \Illuminate\Database\Query\Expression
  1586. */
  1587. public function raw($value)
  1588. {
  1589. return $this->connection->raw($value);
  1590. }
  1591. /**
  1592. * Get the current query value bindings.
  1593. *
  1594. * @return array
  1595. */
  1596. public function getBindings()
  1597. {
  1598. return $this->bindings;
  1599. }
  1600. /**
  1601. * Set the bindings on the query builder.
  1602. *
  1603. * @param array $bindings
  1604. * @return \Illuminate\Database\Query\Builder
  1605. */
  1606. public function setBindings(array $bindings)
  1607. {
  1608. $this->bindings = $bindings;
  1609. return $this;
  1610. }
  1611. /**
  1612. * Add a binding to the query.
  1613. *
  1614. * @param mixed $value
  1615. * @return \Illuminate\Database\Query\Builder
  1616. */
  1617. public function addBinding($value)
  1618. {
  1619. $this->bindings[] = $value;
  1620. return $this;
  1621. }
  1622. /**
  1623. * Merge an array of bindings into our bindings.
  1624. *
  1625. * @param \Illuminate\Database\Query\Builder $query
  1626. * @return \Illuminate\Database\Query\Builder
  1627. */
  1628. public function mergeBindings(Builder $query)
  1629. {
  1630. $this->bindings = array_values(array_merge($this->bindings, $query->bindings));
  1631. return $this;
  1632. }
  1633. /**
  1634. * Get the database connection instance.
  1635. *
  1636. * @return \Illuminate\Database\ConnectionInterface
  1637. */
  1638. public function getConnection()
  1639. {
  1640. return $this->connection;
  1641. }
  1642. /**
  1643. * Get the database query processor instance.
  1644. *
  1645. * @return \Illuminate\Database\Query\Processors\Processor
  1646. */
  1647. public function getProcessor()
  1648. {
  1649. return $this->processor;
  1650. }
  1651. /**
  1652. * Get the query grammar instance.
  1653. *
  1654. * @return \Illuminate\Database\Grammar
  1655. */
  1656. public function getGrammar()
  1657. {
  1658. return $this->grammar;
  1659. }
  1660. /**
  1661. * Handle dynamic method calls into the method.
  1662. *
  1663. * @param string $method
  1664. * @param array $parameters
  1665. * @return mixed
  1666. *
  1667. * @throws \BadMethodCallException
  1668. */
  1669. public function __call($method, $parameters)
  1670. {
  1671. if (starts_with($method, 'where'))
  1672. {
  1673. return $this->dynamicWhere($method, $parameters);
  1674. }
  1675. $className = get_class($this);
  1676. throw new \BadMethodCallException("Call to undefined method {$className}::{$method}()");
  1677. }
  1678. }