query.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. <?php namespace Laravel\Database;
  2. use Closure;
  3. use Laravel\Database;
  4. use Laravel\Paginator;
  5. use Laravel\Database\Query\Grammars\Postgres;
  6. use Laravel\Database\Query\Grammars\SQLServer;
  7. class Query {
  8. /**
  9. * The database connection.
  10. *
  11. * @var Connection
  12. */
  13. public $connection;
  14. /**
  15. * The query grammar instance.
  16. *
  17. * @var Query\Grammars\Grammar
  18. */
  19. public $grammar;
  20. /**
  21. * The SELECT clause.
  22. *
  23. * @var array
  24. */
  25. public $selects;
  26. /**
  27. * The aggregating column and function.
  28. *
  29. * @var array
  30. */
  31. public $aggregate;
  32. /**
  33. * Indicates if the query should return distinct results.
  34. *
  35. * @var bool
  36. */
  37. public $distinct = false;
  38. /**
  39. * The table name.
  40. *
  41. * @var string
  42. */
  43. public $from;
  44. /**
  45. * The table joins.
  46. *
  47. * @var array
  48. */
  49. public $joins;
  50. /**
  51. * The WHERE clauses.
  52. *
  53. * @var array
  54. */
  55. public $wheres;
  56. /**
  57. * The GROUP BY clauses.
  58. *
  59. * @var array
  60. */
  61. public $groupings;
  62. /**
  63. * The HAVING clauses.
  64. *
  65. * @var array
  66. */
  67. public $havings;
  68. /**
  69. * The ORDER BY clauses.
  70. *
  71. * @var array
  72. */
  73. public $orderings;
  74. /**
  75. * The LIMIT value.
  76. *
  77. * @var int
  78. */
  79. public $limit;
  80. /**
  81. * The OFFSET value.
  82. *
  83. * @var int
  84. */
  85. public $offset;
  86. /**
  87. * The query value bindings.
  88. *
  89. * @var array
  90. */
  91. public $bindings = array();
  92. /**
  93. * Create a new query instance.
  94. *
  95. * @param Connection $connection
  96. * @param Grammar $grammar
  97. * @param string $table
  98. * @return void
  99. */
  100. public function __construct(Connection $connection, Query\Grammars\Grammar $grammar, $table)
  101. {
  102. $this->from = $table;
  103. $this->grammar = $grammar;
  104. $this->connection = $connection;
  105. }
  106. /**
  107. * Force the query to return distinct results.
  108. *
  109. * @return Query
  110. */
  111. public function distinct()
  112. {
  113. $this->distinct = true;
  114. return $this;
  115. }
  116. /**
  117. * Add an array of columns to the SELECT clause.
  118. *
  119. * @param array $columns
  120. * @return Query
  121. */
  122. public function select($columns = array('*'))
  123. {
  124. $this->selects = (array) $columns;
  125. return $this;
  126. }
  127. /**
  128. * Add a join clause to the query.
  129. *
  130. * @param string $table
  131. * @param string $column1
  132. * @param string $operator
  133. * @param string $column2
  134. * @param string $type
  135. * @return Query
  136. */
  137. public function join($table, $column1, $operator = null, $column2 = null, $type = 'INNER')
  138. {
  139. // If the "column" is really an instance of a Closure, the developer is
  140. // trying to create a join with a complex "ON" clause. So, we will add
  141. // the join, and then call the Closure with the join/
  142. if ($column1 instanceof Closure)
  143. {
  144. $this->joins[] = new Query\Join($type, $table);
  145. call_user_func($column1, end($this->joins));
  146. }
  147. // If the column is just a string, we can assume that the join just
  148. // has a simple on clause, and we'll create the join instance and
  149. // add the clause automatically for the develoepr.
  150. else
  151. {
  152. $join = new Query\Join($type, $table);
  153. $join->on($column1, $operator, $column2);
  154. $this->joins[] = $join;
  155. }
  156. return $this;
  157. }
  158. /**
  159. * Add a left join to the query.
  160. *
  161. * @param string $table
  162. * @param string $column1
  163. * @param string $operator
  164. * @param string $column2
  165. * @return Query
  166. */
  167. public function left_join($table, $column1, $operator = null, $column2 = null)
  168. {
  169. return $this->join($table, $column1, $operator, $column2, 'LEFT');
  170. }
  171. /**
  172. * Reset the where clause to its initial state.
  173. *
  174. * @return void
  175. */
  176. public function reset_where()
  177. {
  178. list($this->wheres, $this->bindings) = array(array(), array());
  179. }
  180. /**
  181. * Add a raw where condition to the query.
  182. *
  183. * @param string $where
  184. * @param array $bindings
  185. * @param string $connector
  186. * @return Query
  187. */
  188. public function raw_where($where, $bindings = array(), $connector = 'AND')
  189. {
  190. $this->wheres[] = array('type' => 'where_raw', 'connector' => $connector, 'sql' => $where);
  191. $this->bindings = array_merge($this->bindings, $bindings);
  192. return $this;
  193. }
  194. /**
  195. * Add a raw or where condition to the query.
  196. *
  197. * @param string $where
  198. * @param array $bindings
  199. * @return Query
  200. */
  201. public function raw_or_where($where, $bindings = array())
  202. {
  203. return $this->raw_where($where, $bindings, 'OR');
  204. }
  205. /**
  206. * Add a where condition to the query.
  207. *
  208. * @param string $column
  209. * @param string $operator
  210. * @param mixed $value
  211. * @param string $connector
  212. * @return Query
  213. */
  214. public function where($column, $operator = null, $value = null, $connector = 'AND')
  215. {
  216. // If a Closure is passed into the method, it means a nested where
  217. // clause is being initiated, so we will take a different course
  218. // of action than when the statement is just a simple where.
  219. if ($column instanceof Closure)
  220. {
  221. return $this->where_nested($column, $connector);
  222. }
  223. $type = 'where';
  224. $this->wheres[] = compact('type', 'column', 'operator', 'value', 'connector');
  225. $this->bindings[] = $value;
  226. return $this;
  227. }
  228. /**
  229. * Add an or where condition to the query.
  230. *
  231. * @param string $column
  232. * @param string $operator
  233. * @param mixed $value
  234. * @return Query
  235. */
  236. public function or_where($column, $operator = null, $value = null)
  237. {
  238. return $this->where($column, $operator, $value, 'OR');
  239. }
  240. /**
  241. * Add an or where condition for the primary key to the query.
  242. *
  243. * @param mixed $value
  244. * @return Query
  245. */
  246. public function or_where_id($value)
  247. {
  248. return $this->or_where('id', '=', $value);
  249. }
  250. /**
  251. * Add a where in condition to the query.
  252. *
  253. * @param string $column
  254. * @param array $values
  255. * @param string $connector
  256. * @param bool $not
  257. * @return Query
  258. */
  259. public function where_in($column, $values, $connector = 'AND', $not = false)
  260. {
  261. $type = ($not) ? 'where_not_in' : 'where_in';
  262. $this->wheres[] = compact('type', 'column', 'values', 'connector');
  263. $this->bindings = array_merge($this->bindings, $values);
  264. return $this;
  265. }
  266. /**
  267. * Add an or where in condition to the query.
  268. *
  269. * @param string $column
  270. * @param array $values
  271. * @return Query
  272. */
  273. public function or_where_in($column, $values)
  274. {
  275. return $this->where_in($column, $values, 'OR');
  276. }
  277. /**
  278. * Add a where not in condition to the query.
  279. *
  280. * @param string $column
  281. * @param array $values
  282. * @param string $connector
  283. * @return Query
  284. */
  285. public function where_not_in($column, $values, $connector = 'AND')
  286. {
  287. return $this->where_in($column, $values, $connector, true);
  288. }
  289. /**
  290. * Add an or where not in condition to the query.
  291. *
  292. * @param string $column
  293. * @param array $values
  294. * @return Query
  295. */
  296. public function or_where_not_in($column, $values)
  297. {
  298. return $this->where_not_in($column, $values, 'OR');
  299. }
  300. /**
  301. * Add a BETWEEN condition to the query
  302. *
  303. * @param string $column
  304. * @param mixed $min
  305. * @param mixed $max
  306. * @param string $connector
  307. * @param boolean $not
  308. * @return Query
  309. */
  310. public function where_between($column, $min, $max, $connector = 'AND', $not = false)
  311. {
  312. $type = ($not) ? 'where_not_between' : 'where_between';
  313. $this->wheres[] = compact('type', 'column', 'min', 'max', 'connector');
  314. $this->bindings[] = $min;
  315. $this->bindings[] = $max;
  316. return $this;
  317. }
  318. /**
  319. * Add a OR BETWEEN condition to the query
  320. *
  321. * @param string $column
  322. * @param mixed $min
  323. * @param mixed $max
  324. * @return Query
  325. */
  326. public function or_where_between($column, $min, $max)
  327. {
  328. return $this->where_between($column, $min, $max, 'OR');
  329. }
  330. /**
  331. * Add a NOT BETWEEN condition to the query
  332. *
  333. * @param string $column
  334. * @param mixed $min
  335. * @param mixed $max
  336. * @return Query
  337. */
  338. public function where_not_between($column, $min, $max, $connector = 'AND')
  339. {
  340. return $this->where_between($column, $min, $max, $connector, true);
  341. }
  342. /**
  343. * Add a OR NOT BETWEEN condition to the query
  344. *
  345. * @param string $column
  346. * @param mixed $min
  347. * @param mixed $max
  348. * @return Query
  349. */
  350. public function or_where_not_between($column, $min, $max)
  351. {
  352. return $this->where_not_between($column, $min, $max, 'OR');
  353. }
  354. /**
  355. * Add a where null condition to the query.
  356. *
  357. * @param string $column
  358. * @param string $connector
  359. * @param bool $not
  360. * @return Query
  361. */
  362. public function where_null($column, $connector = 'AND', $not = false)
  363. {
  364. $type = ($not) ? 'where_not_null' : 'where_null';
  365. $this->wheres[] = compact('type', 'column', 'connector');
  366. return $this;
  367. }
  368. /**
  369. * Add an or where null condition to the query.
  370. *
  371. * @param string $column
  372. * @return Query
  373. */
  374. public function or_where_null($column)
  375. {
  376. return $this->where_null($column, 'OR');
  377. }
  378. /**
  379. * Add a where not null condition to the query.
  380. *
  381. * @param string $column
  382. * @param string $connector
  383. * @return Query
  384. */
  385. public function where_not_null($column, $connector = 'AND')
  386. {
  387. return $this->where_null($column, $connector, true);
  388. }
  389. /**
  390. * Add an or where not null condition to the query.
  391. *
  392. * @param string $column
  393. * @return Query
  394. */
  395. public function or_where_not_null($column)
  396. {
  397. return $this->where_not_null($column, 'OR');
  398. }
  399. /**
  400. * Add a nested where condition to the query.
  401. *
  402. * @param Closure $callback
  403. * @param string $connector
  404. * @return Query
  405. */
  406. public function where_nested($callback, $connector = 'AND')
  407. {
  408. $type = 'where_nested';
  409. // To handle a nested where statement, we will actually instantiate a new
  410. // Query instance and run the callback over that instance, which will
  411. // allow the developer to have a fresh query instance
  412. $query = new Query($this->connection, $this->grammar, $this->from);
  413. call_user_func($callback, $query);
  414. // Once the callback has been run on the query, we will store the nested
  415. // query instance on the where clause array so that it's passed to the
  416. // query's query grammar instance when building.
  417. if ($query->wheres !== null)
  418. {
  419. $this->wheres[] = compact('type', 'query', 'connector');
  420. }
  421. $this->bindings = array_merge($this->bindings, $query->bindings);
  422. return $this;
  423. }
  424. /**
  425. * Add dynamic where conditions to the query.
  426. *
  427. * @param string $method
  428. * @param array $parameters
  429. * @return Query
  430. */
  431. private function dynamic_where($method, $parameters)
  432. {
  433. $finder = substr($method, 6);
  434. $flags = PREG_SPLIT_DELIM_CAPTURE;
  435. $segments = preg_split('/(_and_|_or_)/i', $finder, -1, $flags);
  436. // The connector variable will determine which connector will be used
  437. // for the condition. We'll change it as we come across new boolean
  438. // connectors in the dynamic method string.
  439. //
  440. // The index variable helps us get the correct parameter value for
  441. // the where condition. We increment it each time we add another
  442. // condition to the query's where clause.
  443. $connector = 'AND';
  444. $index = 0;
  445. foreach ($segments as $segment)
  446. {
  447. // If the segment is not a boolean connector, we can assume it it is
  448. // a column name, and we'll add it to the query as a new constraint
  449. // of the query's where clause and keep iterating the segments.
  450. if ($segment != '_and_' and $segment != '_or_')
  451. {
  452. $this->where($segment, '=', $parameters[$index], $connector);
  453. $index++;
  454. }
  455. // Otherwise, we will store the connector so we know how the next
  456. // where clause we find in the query should be connected to the
  457. // previous one and will add it when we find the next one.
  458. else
  459. {
  460. $connector = trim(strtoupper($segment), '_');
  461. }
  462. }
  463. return $this;
  464. }
  465. /**
  466. * Add a grouping to the query.
  467. *
  468. * @param string $column
  469. * @return Query
  470. */
  471. public function group_by($column)
  472. {
  473. $this->groupings[] = $column;
  474. return $this;
  475. }
  476. /**
  477. * Add a having to the query.
  478. *
  479. * @param string $column
  480. * @param string $operator
  481. * @param mixed $value
  482. */
  483. public function having($column, $operator, $value)
  484. {
  485. $this->havings[] = compact('column', 'operator', 'value');
  486. $this->bindings[] = $value;
  487. return $this;
  488. }
  489. /**
  490. * Add an ordering to the query.
  491. *
  492. * @param string $column
  493. * @param string $direction
  494. * @return Query
  495. */
  496. public function order_by($column, $direction = 'asc')
  497. {
  498. $this->orderings[] = compact('column', 'direction');
  499. return $this;
  500. }
  501. /**
  502. * Set the query offset.
  503. *
  504. * @param int $value
  505. * @return Query
  506. */
  507. public function skip($value)
  508. {
  509. $this->offset = $value;
  510. return $this;
  511. }
  512. /**
  513. * Set the query limit.
  514. *
  515. * @param int $value
  516. * @return Query
  517. */
  518. public function take($value)
  519. {
  520. $this->limit = $value;
  521. return $this;
  522. }
  523. /**
  524. * Set the query limit and offset for a given page.
  525. *
  526. * @param int $page
  527. * @param int $per_page
  528. * @return Query
  529. */
  530. public function for_page($page, $per_page)
  531. {
  532. return $this->skip(($page - 1) * $per_page)->take($per_page);
  533. }
  534. /**
  535. * Find a record by the primary key.
  536. *
  537. * @param int $id
  538. * @param array $columns
  539. * @return object
  540. */
  541. public function find($id, $columns = array('*'))
  542. {
  543. return $this->where('id', '=', $id)->first($columns);
  544. }
  545. /**
  546. * Execute the query as a SELECT statement and return a single column.
  547. *
  548. * @param string $column
  549. * @return mixed
  550. */
  551. public function only($column)
  552. {
  553. $sql = $this->grammar->select($this->select(array($column)));
  554. return $this->connection->only($sql, $this->bindings);
  555. }
  556. /**
  557. * Execute the query as a SELECT statement and return the first result.
  558. *
  559. * @param array $columns
  560. * @return mixed
  561. */
  562. public function first($columns = array('*'))
  563. {
  564. $columns = (array) $columns;
  565. // Since we only need the first result, we'll go ahead and set the
  566. // limit clause to 1, since this will be much faster than getting
  567. // all of the rows and then only returning the first.
  568. $results = $this->take(1)->get($columns);
  569. return (count($results) > 0) ? $results[0] : null;
  570. }
  571. /**
  572. * Get an array with the values of a given column.
  573. *
  574. * @param string $column
  575. * @param string $key
  576. * @return array
  577. */
  578. public function lists($column, $key = null)
  579. {
  580. $columns = (is_null($key)) ? array($column) : array($column, $key);
  581. $results = $this->get($columns);
  582. // First we will get the array of values for the requested column.
  583. // Of course, this array will simply have numeric keys. After we
  584. // have this array we will determine if we need to key the array
  585. // by another column from the result set.
  586. $values = array_map(function($row) use ($column)
  587. {
  588. return $row->$column;
  589. }, $results);
  590. // If a key was provided, we will extract an array of keys and
  591. // set the keys on the array of values using the array_combine
  592. // function provided by PHP, which should give us the proper
  593. // array form to return from the method.
  594. if ( ! is_null($key) && count($results))
  595. {
  596. return array_combine(array_map(function($row) use ($key)
  597. {
  598. return $row->$key;
  599. }, $results), $values);
  600. }
  601. return $values;
  602. }
  603. /**
  604. * Execute the query as a SELECT statement.
  605. *
  606. * @param array $columns
  607. * @return array
  608. */
  609. public function get($columns = array('*'))
  610. {
  611. if (is_null($this->selects)) $this->select($columns);
  612. $sql = $this->grammar->select($this);
  613. $results = $this->connection->query($sql, $this->bindings);
  614. // If the query has an offset and we are using the SQL Server grammar,
  615. // we need to spin through the results and remove the "rownum" from
  616. // each of the objects since there is no "offset".
  617. if ($this->offset > 0 and $this->grammar instanceof SQLServer)
  618. {
  619. array_walk($results, function($result)
  620. {
  621. unset($result->rownum);
  622. });
  623. }
  624. // Reset the SELECT clause so more queries can be performed using
  625. // the same instance. This is helpful for getting aggregates and
  626. // then getting actual results from the query.
  627. $this->selects = null;
  628. return $results;
  629. }
  630. /**
  631. * Get an aggregate value.
  632. *
  633. * @param string $aggregator
  634. * @param array $columns
  635. * @return mixed
  636. */
  637. public function aggregate($aggregator, $columns)
  638. {
  639. // We'll set the aggregate value so the grammar does not try to compile
  640. // a SELECT clause on the query. If an aggregator is present, it's own
  641. // grammar function will be used to build the SQL syntax.
  642. $this->aggregate = compact('aggregator', 'columns');
  643. $sql = $this->grammar->select($this);
  644. $result = $this->connection->only($sql, $this->bindings);
  645. // Reset the aggregate so more queries can be performed using the same
  646. // instance. This is helpful for getting aggregates and then getting
  647. // actual results from the query such as during paging.
  648. $this->aggregate = null;
  649. return $result;
  650. }
  651. /**
  652. * Get the paginated query results as a Paginator instance.
  653. *
  654. * @param int $per_page
  655. * @param array $columns
  656. * @return Paginator
  657. */
  658. public function paginate($per_page = 20, $columns = array('*'))
  659. {
  660. // Because some database engines may throw errors if we leave orderings
  661. // on the query when retrieving the total number of records, we'll drop
  662. // all of the ordreings and put them back on the query.
  663. list($orderings, $this->orderings) = array($this->orderings, null);
  664. $total = $this->count(reset($columns));
  665. $page = Paginator::page($total, $per_page);
  666. $this->orderings = $orderings;
  667. // Now we're ready to get the actual pagination results from the table
  668. // using the for_page and get methods. The "for_page" method provides
  669. // a convenient way to set the paging limit and offset.
  670. $results = $this->for_page($page, $per_page)->get($columns);
  671. return Paginator::make($results, $total, $per_page);
  672. }
  673. /**
  674. * Insert an array of values into the database table.
  675. *
  676. * @param array $values
  677. * @return bool
  678. */
  679. public function insert($values)
  680. {
  681. // Force every insert to be treated like a batch insert to make creating
  682. // the binding array simpler since we can just spin through the inserted
  683. // rows as if there/ was more than one every time.
  684. if ( ! is_array(reset($values))) $values = array($values);
  685. $bindings = array();
  686. // We need to merge the the insert values into the array of the query
  687. // bindings so that they will be bound to the PDO statement when it
  688. // is executed by the database connection.
  689. foreach ($values as $value)
  690. {
  691. $bindings = array_merge($bindings, array_values($value));
  692. }
  693. $sql = $this->grammar->insert($this, $values);
  694. return $this->connection->query($sql, $bindings);
  695. }
  696. /**
  697. * Insert an array of values into the database table and return the ID.
  698. *
  699. * @param array $values
  700. * @param string $column
  701. * @return int
  702. */
  703. public function insert_get_id($values, $column = 'id')
  704. {
  705. $sql = $this->grammar->insert_get_id($this, $values, $column);
  706. $result = $this->connection->query($sql, array_values($values));
  707. if ($this->grammar instanceof Postgres)
  708. {
  709. return (int) $result[0]->$column;
  710. }
  711. else
  712. {
  713. return (int) $this->connection->pdo->lastInsertId();
  714. }
  715. }
  716. /**
  717. * Increment the value of a column by a given amount.
  718. *
  719. * @param string $column
  720. * @param int $amount
  721. * @return int
  722. */
  723. public function increment($column, $amount = 1)
  724. {
  725. return $this->adjust($column, $amount, ' + ');
  726. }
  727. /**
  728. * Decrement the value of a column by a given amount.
  729. *
  730. * @param string $column
  731. * @param int $amount
  732. * @return int
  733. */
  734. public function decrement($column, $amount = 1)
  735. {
  736. return $this->adjust($column, $amount, ' - ');
  737. }
  738. /**
  739. * Adjust the value of a column up or down by a given amount.
  740. *
  741. * @param string $column
  742. * @param int $amount
  743. * @param string $operator
  744. * @return int
  745. */
  746. protected function adjust($column, $amount, $operator)
  747. {
  748. $wrapped = $this->grammar->wrap($column);
  749. // To make the adjustment to the column, we'll wrap the expression in an
  750. // Expression instance, which forces the adjustment to be injected into
  751. // the query as a string instead of bound.
  752. $value = Database::raw($wrapped.$operator.$amount);
  753. return $this->update(array($column => $value));
  754. }
  755. /**
  756. * Update an array of values in the database table.
  757. *
  758. * @param array $values
  759. * @return int
  760. */
  761. public function update($values)
  762. {
  763. // For update statements, we need to merge the bindings such that the update
  764. // values occur before the where bindings in the array since the sets will
  765. // precede any of the where clauses in the SQL syntax that is generated.
  766. $bindings = array_merge(array_values($values), $this->bindings);
  767. $sql = $this->grammar->update($this, $values);
  768. return $this->connection->query($sql, $bindings);
  769. }
  770. /**
  771. * Execute the query as a DELETE statement.
  772. *
  773. * Optionally, an ID may be passed to the method do delete a specific row.
  774. *
  775. * @param int $id
  776. * @return int
  777. */
  778. public function delete($id = null)
  779. {
  780. // If an ID is given to the method, we'll set the where clause to
  781. // match on the value of the ID. This allows the developer to
  782. // quickly delete a row by its primary key value.
  783. if ( ! is_null($id))
  784. {
  785. $this->where('id', '=', $id);
  786. }
  787. $sql = $this->grammar->delete($this);
  788. return $this->connection->query($sql, $this->bindings);
  789. }
  790. /**
  791. * Magic Method for handling dynamic functions.
  792. *
  793. * This method handles calls to aggregates as well as dynamic where clauses.
  794. */
  795. public function __call($method, $parameters)
  796. {
  797. if (strpos($method, 'where_') === 0)
  798. {
  799. return $this->dynamic_where($method, $parameters, $this);
  800. }
  801. // All of the aggregate methods are handled by a single method, so we'll
  802. // catch them all here and then pass them off to the agregate method
  803. // instead of creating methods for each one of them.
  804. if (in_array($method, array('count', 'min', 'max', 'avg', 'sum')))
  805. {
  806. if (count($parameters) == 0) $parameters[0] = '*';
  807. return $this->aggregate(strtoupper($method), (array) $parameters[0]);
  808. }
  809. throw new \Exception("Method [$method] is not defined on the Query class.");
  810. }
  811. }