PageRenderTime 63ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 1ms

/library/Doctrine/Doctrine/Expression/Driver.php

https://github.com/ostric/e-learning
PHP | 773 lines | 239 code | 49 blank | 485 comment | 10 complexity | 0d5933d290fe1cf099408f657afe87d5 MD5 | raw file
  1. <?php
  2. /*
  3. * $Id$
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information, see
  19. * <http://www.phpdoctrine.org>.
  20. */
  21. /**
  22. * Doctrine_Expression_Driver
  23. *
  24. * @package Doctrine
  25. * @subpackage Expression
  26. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  27. * @link www.phpdoctrine.org
  28. * @since 1.0
  29. * @version $Revision$
  30. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
  31. */
  32. class Doctrine_Expression_Driver extends Doctrine_Connection_Module
  33. {
  34. public function getIdentifier($column)
  35. {
  36. return $column;
  37. }
  38. public function getIdentifiers($columns)
  39. {
  40. return $columns;
  41. }
  42. /**
  43. * regexp
  44. * returns the regular expression operator
  45. *
  46. * @return string
  47. */
  48. public function regexp()
  49. {
  50. throw new Doctrine_Expression_Exception('Regular expression operator is not supported by this database driver.');
  51. }
  52. /**
  53. * Returns the average value of a column
  54. *
  55. * @param string $column the column to use
  56. * @return string generated sql including an AVG aggregate function
  57. */
  58. public function avg($column)
  59. {
  60. $column = $this->getIdentifier($column);
  61. return 'AVG(' . $column . ')';
  62. }
  63. /**
  64. * Returns the number of rows (without a NULL value) of a column
  65. *
  66. * If a '*' is used instead of a column the number of selected rows
  67. * is returned.
  68. *
  69. * @param string|integer $column the column to use
  70. * @return string generated sql including a COUNT aggregate function
  71. */
  72. public function count($column)
  73. {
  74. $column = $this->getIdentifier($column);
  75. return 'COUNT(' . $column . ')';
  76. }
  77. /**
  78. * Returns the highest value of a column
  79. *
  80. * @param string $column the column to use
  81. * @return string generated sql including a MAX aggregate function
  82. */
  83. public function max($column)
  84. {
  85. $column = $this->getIdentifier($column);
  86. return 'MAX(' . $column . ')';
  87. }
  88. /**
  89. * Returns the lowest value of a column
  90. *
  91. * @param string $column the column to use
  92. * @return string
  93. */
  94. public function min($column)
  95. {
  96. $column = $this->getIdentifier($column);
  97. return 'MIN(' . $column . ')';
  98. }
  99. /**
  100. * Returns the total sum of a column
  101. *
  102. * @param string $column the column to use
  103. * @return string
  104. */
  105. public function sum($column)
  106. {
  107. $column = $this->getIdentifier($column);
  108. return 'SUM(' . $column . ')';
  109. }
  110. // scalar functions
  111. /**
  112. * Returns the md5 sum of a field.
  113. *
  114. * Note: Not SQL92, but common functionality
  115. *
  116. * @return string
  117. */
  118. public function md5($column)
  119. {
  120. $column = $this->getIdentifier($column);
  121. return 'MD5(' . $column . ')';
  122. }
  123. /**
  124. * Returns the length of a text field.
  125. *
  126. * @param string $expression1
  127. * @param string $expression2
  128. * @return string
  129. */
  130. public function length($column)
  131. {
  132. $column = $this->getIdentifier($column);
  133. return 'LENGTH(' . $column . ')';
  134. }
  135. /**
  136. * Rounds a numeric field to the number of decimals specified.
  137. *
  138. * @param string $expression1
  139. * @param string $expression2
  140. * @return string
  141. */
  142. public function round($column, $decimals = 0)
  143. {
  144. $column = $this->getIdentifier($column);
  145. return 'ROUND(' . $column . ', ' . $decimals . ')';
  146. }
  147. /**
  148. * Returns the remainder of the division operation
  149. * $expression1 / $expression2.
  150. *
  151. * @param string $expression1
  152. * @param string $expression2
  153. * @return string
  154. */
  155. public function mod($expression1, $expression2)
  156. {
  157. $expression1 = $this->getIdentifier($expression1);
  158. $expression2 = $this->getIdentifier($expression2);
  159. return 'MOD(' . $expression1 . ', ' . $expression2 . ')';
  160. }
  161. /**
  162. * trim
  163. * returns the string $str with leading and proceeding space characters removed
  164. *
  165. * @param string $str literal string or column name
  166. * @return string
  167. */
  168. public function trim($str)
  169. {
  170. return 'TRIM(' . $str . ')';
  171. }
  172. /**
  173. * rtrim
  174. * returns the string $str with proceeding space characters removed
  175. *
  176. * @param string $str literal string or column name
  177. * @return string
  178. */
  179. public function rtrim($str)
  180. {
  181. return 'RTRIM(' . $str . ')';
  182. }
  183. /**
  184. * ltrim
  185. * returns the string $str with leading space characters removed
  186. *
  187. * @param string $str literal string or column name
  188. * @return string
  189. */
  190. public function ltrim($str)
  191. {
  192. return 'LTRIM(' . $str . ')';
  193. }
  194. /**
  195. * upper
  196. * Returns the string $str with all characters changed to
  197. * uppercase according to the current character set mapping.
  198. *
  199. * @param string $str literal string or column name
  200. * @return string
  201. */
  202. public function upper($str)
  203. {
  204. return 'UPPER(' . $str . ')';
  205. }
  206. /**
  207. * lower
  208. * Returns the string $str with all characters changed to
  209. * lowercase according to the current character set mapping.
  210. *
  211. * @param string $str literal string or column name
  212. * @return string
  213. */
  214. public function lower($str)
  215. {
  216. return 'LOWER(' . $str . ')';
  217. }
  218. /**
  219. * locate
  220. * returns the position of the first occurrence of substring $substr in string $str
  221. *
  222. * @param string $substr literal string to find
  223. * @param string $str literal string
  224. * @return integer
  225. */
  226. public function locate($str, $substr)
  227. {
  228. return 'LOCATE(' . $str . ', ' . $substr . ')';
  229. }
  230. /**
  231. * Returns the current system date.
  232. *
  233. * @return string
  234. */
  235. public function now()
  236. {
  237. return 'NOW()';
  238. }
  239. /**
  240. * soundex
  241. * Returns a string to call a function to compute the
  242. * soundex encoding of a string
  243. *
  244. * The string "?000" is returned if the argument is NULL.
  245. *
  246. * @param string $value
  247. * @return string SQL soundex function with given parameter
  248. */
  249. public function soundex($value)
  250. {
  251. throw new Doctrine_Expression_Exception('SQL soundex function not supported by this driver.');
  252. }
  253. /**
  254. * return string to call a function to get a substring inside an SQL statement
  255. *
  256. * Note: Not SQL92, but common functionality.
  257. *
  258. * SQLite only supports the 2 parameter variant of this function
  259. *
  260. * @param string $value an sql string literal or column name/alias
  261. * @param integer $position where to start the substring portion
  262. * @param integer $length the substring portion length
  263. * @return string SQL substring function with given parameters
  264. */
  265. public function substring($value, $from, $len = null)
  266. {
  267. $value = $this->getIdentifier($value);
  268. if ($len === null)
  269. return 'SUBSTRING(' . $value . ' FROM ' . $from . ')';
  270. else {
  271. $len = $this->getIdentifier($len);
  272. return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')';
  273. }
  274. }
  275. /**
  276. * Returns a series of strings concatinated
  277. *
  278. * concat() accepts an arbitrary number of parameters. Each parameter
  279. * must contain an expression or an array with expressions.
  280. *
  281. * @param string|array(string) strings that will be concatinated.
  282. */
  283. public function concat()
  284. {
  285. $args = func_get_args();
  286. return 'CONCAT(' . join(', ', (array) $args) . ')';
  287. }
  288. /**
  289. * Returns the SQL for a logical not.
  290. *
  291. * Example:
  292. * <code>
  293. * $q = new Doctrine_Query();
  294. * $e = $q->expr;
  295. * $q->select('*')->from('table')
  296. * ->where($e->eq('id', $e->not('null'));
  297. * </code>
  298. *
  299. * @return string a logical expression
  300. */
  301. public function not($expression)
  302. {
  303. $expression = $this->getIdentifier($expression);
  304. return 'NOT(' . $expression . ')';
  305. }
  306. /**
  307. * Returns the SQL to perform the same mathematical operation over an array
  308. * of values or expressions.
  309. *
  310. * basicMath() accepts an arbitrary number of parameters. Each parameter
  311. * must contain a value or an expression or an array with values or
  312. * expressions.
  313. *
  314. * @param string $type the type of operation, can be '+', '-', '*' or '/'.
  315. * @param string|array(string)
  316. * @return string an expression
  317. */
  318. private function basicMath($type, array $args)
  319. {
  320. $elements = $this->getIdentifiers($args);
  321. if (count($elements) < 1) {
  322. return '';
  323. }
  324. if (count($elements) == 1) {
  325. return $elements[0];
  326. } else {
  327. return '(' . implode(' ' . $type . ' ', $elements) . ')';
  328. }
  329. }
  330. /**
  331. * Returns the SQL to add values or expressions together.
  332. *
  333. * add() accepts an arbitrary number of parameters. Each parameter
  334. * must contain a value or an expression or an array with values or
  335. * expressions.
  336. *
  337. * Example:
  338. * <code>
  339. * $q = new Doctrine_Query();
  340. * $e = $q->expr;
  341. *
  342. * $q->select('u.*')
  343. * ->from('User u')
  344. * ->where($e->eq($e->add('id', 2), 12));
  345. * </code>
  346. *
  347. * @param string|array(string)
  348. * @return string an expression
  349. */
  350. public function add(array $args)
  351. {
  352. return $this->basicMath('+', $args);
  353. }
  354. /**
  355. * Returns the SQL to subtract values or expressions from eachother.
  356. *
  357. * subtract() accepts an arbitrary number of parameters. Each parameter
  358. * must contain a value or an expression or an array with values or
  359. * expressions.
  360. *
  361. * Example:
  362. * <code>
  363. * $q = new Doctrine_Query();
  364. * $e = $q->expr;
  365. *
  366. * $q->select('u.*')
  367. * ->from('User u')
  368. * ->where($e->eq($e->sub('id', 2), 12));
  369. * </code>
  370. *
  371. * @param string|array(string)
  372. * @return string an expression
  373. */
  374. public function sub(array $args)
  375. {
  376. return $this->basicMath('-', $args );
  377. }
  378. /**
  379. * Returns the SQL to multiply values or expressions by eachother.
  380. *
  381. * multiply() accepts an arbitrary number of parameters. Each parameter
  382. * must contain a value or an expression or an array with values or
  383. * expressions.
  384. *
  385. * Example:
  386. * <code>
  387. * $q = new Doctrine_Query();
  388. * $e = $q->expr;
  389. *
  390. * $q->select('u.*')
  391. * ->from('User u')
  392. * ->where($e->eq($e->mul('id', 2), 12));
  393. * </code>
  394. *
  395. * @param string|array(string)
  396. * @return string an expression
  397. */
  398. public function mul(array $args)
  399. {
  400. return $this->basicMath('*', $args);
  401. }
  402. /**
  403. * Returns the SQL to divide values or expressions by eachother.
  404. *
  405. * divide() accepts an arbitrary number of parameters. Each parameter
  406. * must contain a value or an expression or an array with values or
  407. * expressions.
  408. *
  409. * Example:
  410. * <code>
  411. * $q = new Doctrine_Query();
  412. * $e = $q->expr;
  413. *
  414. * $q->select('u.*')
  415. * ->from('User u')
  416. * ->where($e->eq($e->div('id', 2), 12));
  417. * </code>
  418. *
  419. * @param string|array(string)
  420. * @return string an expression
  421. */
  422. public function div(array $args)
  423. {
  424. return $this->basicMath('/', $args);
  425. }
  426. /**
  427. * Returns the SQL to check if two values are equal.
  428. *
  429. * Example:
  430. * <code>
  431. * $q = new Doctrine_Query();
  432. * $q->select('u.*')
  433. * ->from('User u')
  434. * ->where($q->expr->eq('id', 1));
  435. * </code>
  436. *
  437. * @param string $value1 logical expression to compare
  438. * @param string $value2 logical expression to compare with
  439. * @return string logical expression
  440. */
  441. public function eq($value1, $value2)
  442. {
  443. $value1 = $this->getIdentifier($value1);
  444. $value2 = $this->getIdentifier($value2);
  445. return $value1 . ' = ' . $value2;
  446. }
  447. /**
  448. * Returns the SQL to check if two values are unequal.
  449. *
  450. * Example:
  451. * <code>
  452. * $q = new Doctrine_Query();
  453. * $q->select('u.*')
  454. * ->from('User u')
  455. * ->where($q->expr->neq('id', 1));
  456. * </code>
  457. *
  458. * @param string $value1 logical expression to compare
  459. * @param string $value2 logical expression to compare with
  460. * @return string logical expression
  461. */
  462. public function neq($value1, $value2)
  463. {
  464. $value1 = $this->getIdentifier($value1);
  465. $value2 = $this->getIdentifier($value2);
  466. return $value1 . ' <> ' . $value2;
  467. }
  468. /**
  469. * Returns the SQL to check if one value is greater than another value.
  470. *
  471. * Example:
  472. * <code>
  473. * $q = new Doctrine_Query();
  474. * $q->select('u.*')
  475. * ->from('User u')
  476. * ->where($q->expr->gt('id', 1));
  477. * </code>
  478. *
  479. * @param string $value1 logical expression to compare
  480. * @param string $value2 logical expression to compare with
  481. * @return string logical expression
  482. */
  483. public function gt($value1, $value2)
  484. {
  485. $value1 = $this->getIdentifier($value1);
  486. $value2 = $this->getIdentifier($value2);
  487. return $value1 . ' > ' . $value2;
  488. }
  489. /**
  490. * Returns the SQL to check if one value is greater than or equal to
  491. * another value.
  492. *
  493. * Example:
  494. * <code>
  495. * $q = new Doctrine_Query();
  496. * $q->select('u.*')
  497. * ->from('User u')
  498. * ->where($q->expr->gte('id', 1));
  499. * </code>
  500. *
  501. * @param string $value1 logical expression to compare
  502. * @param string $value2 logical expression to compare with
  503. * @return string logical expression
  504. */
  505. public function gte($value1, $value2)
  506. {
  507. $value1 = $this->getIdentifier($value1);
  508. $value2 = $this->getIdentifier($value2);
  509. return $value1 . ' >= ' . $value2;
  510. }
  511. /**
  512. * Returns the SQL to check if one value is less than another value.
  513. *
  514. * Example:
  515. * <code>
  516. * $q = new Doctrine_Query();
  517. * $q->select('u.*')
  518. * ->from('User u')
  519. * ->where($q->expr->lt('id', 1));
  520. * </code>
  521. *
  522. * @param string $value1 logical expression to compare
  523. * @param string $value2 logical expression to compare with
  524. * @return string logical expression
  525. */
  526. public function lt($value1, $value2)
  527. {
  528. $value1 = $this->getIdentifier($value1);
  529. $value2 = $this->getIdentifier($value2);
  530. return $value1 . ' < ' . $value2;
  531. }
  532. /**
  533. * Returns the SQL to check if one value is less than or equal to
  534. * another value.
  535. *
  536. * Example:
  537. * <code>
  538. * $q = new Doctrine_Query();
  539. * $q->select('u.*')
  540. * ->from('User u')
  541. * ->where($q->expr->lte('id', 1));
  542. * </code>
  543. *
  544. * @param string $value1 logical expression to compare
  545. * @param string $value2 logical expression to compare with
  546. * @return string logical expression
  547. */
  548. public function lte($value1, $value2)
  549. {
  550. $value1 = $this->getIdentifier($value1);
  551. $value2 = $this->getIdentifier($value2);
  552. return $value1 . ' <= ' . $value2;
  553. }
  554. /**
  555. * Returns the SQL to check if a value is one in a set of
  556. * given values..
  557. *
  558. * in() accepts an arbitrary number of parameters. The first parameter
  559. * must always specify the value that should be matched against. Successive
  560. * must contain a logical expression or an array with logical expressions.
  561. * These expressions will be matched against the first parameter.
  562. *
  563. * Example:
  564. * <code>
  565. * $q = new Doctrine_Query();
  566. * $q->select('u.*')
  567. * ->from('User u')
  568. * ->where($q->expr->in( 'id', array(1,2,3)));
  569. * </code>
  570. *
  571. * @param string $column the value that should be matched against
  572. * @param string|array(string) values that will be matched against $column
  573. * @return string logical expression
  574. */
  575. public function in($column, $values)
  576. {
  577. if ( ! is_array($values)) {
  578. $values = array($values);
  579. }
  580. $values = $this->getIdentifiers($values);
  581. $column = $this->getIdentifier($column);
  582. if (count($values) == 0) {
  583. throw new Doctrine_Expression_Exception('Values array for IN operator should not be empty.');
  584. }
  585. return $column . ' IN (' . implode(', ', $values) . ')';
  586. }
  587. /**
  588. * Returns SQL that checks if a expression is null.
  589. *
  590. * Example:
  591. * <code>
  592. * $q = new Doctrine_Query();
  593. * $q->select('u.*')
  594. * ->from('User u')
  595. * ->where($q->expr->isNull('id'));
  596. * </code>
  597. *
  598. * @param string $expression the expression that should be compared to null
  599. * @return string logical expression
  600. */
  601. public function isNull($expression)
  602. {
  603. $expression = $this->getIdentifier($expression);
  604. return $expression . ' IS NULL';
  605. }
  606. /**
  607. * Returns SQL that checks if a expression is not null.
  608. *
  609. * Example:
  610. * <code>
  611. * $q = new Doctrine_Query();
  612. * $q->select('u.*')
  613. * ->from('User u')
  614. * ->where($q->expr->isNotNull('id'));
  615. * </code>
  616. *
  617. * @param string $expression the expression that should be compared to null
  618. * @return string logical expression
  619. */
  620. public function isNotNull($expression)
  621. {
  622. $expression = $this->getIdentifier($expression);
  623. return $expression . ' IS NOT NULL';
  624. }
  625. /**
  626. * Returns SQL that checks if an expression evaluates to a value between
  627. * two values.
  628. *
  629. * The parameter $expression is checked if it is between $value1 and $value2.
  630. *
  631. * Note: There is a slight difference in the way BETWEEN works on some databases.
  632. * http://www.w3schools.com/sql/sql_between.asp. If you want complete database
  633. * independence you should avoid using between().
  634. *
  635. * Example:
  636. * <code>
  637. * $q = new Doctrine_Query();
  638. * $q->select('u.*')
  639. * ->from('User u')
  640. * ->where($q->expr->between('id', 1, 5));
  641. * </code>
  642. *
  643. * @param string $expression the value to compare to
  644. * @param string $value1 the lower value to compare with
  645. * @param string $value2 the higher value to compare with
  646. * @return string logical expression
  647. */
  648. public function between($expression, $value1, $value2)
  649. {
  650. $expression = $this->getIdentifier($expression);
  651. $value1 = $this->getIdentifier($value1);
  652. $value2 = $this->getIdentifier($value2);
  653. return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2;
  654. }
  655. /**
  656. * Returns global unique identifier
  657. *
  658. * @return string to get global unique identifier
  659. */
  660. public function guid()
  661. {
  662. throw new Doctrine_Expression_Exception('method not implemented');
  663. }
  664. /**
  665. * returns arcus cosine SQL string
  666. *
  667. * @return string
  668. */
  669. public function acos($value)
  670. {
  671. return 'ACOS(' . $value . ')';
  672. }
  673. /**
  674. * sin
  675. *
  676. * @param string $value
  677. * @return void
  678. */
  679. public function sin($value)
  680. {
  681. return 'SIN(' . $value . ')';
  682. }
  683. /**
  684. * pi
  685. *
  686. * @return void
  687. */
  688. public function pi()
  689. {
  690. return 'PI()';
  691. }
  692. /**
  693. * cos
  694. *
  695. * @param string $value
  696. * @return void
  697. */
  698. public function cos($value)
  699. {
  700. return 'COS(' . $value . ')';
  701. }
  702. /**
  703. * coalesce
  704. *
  705. * @return string
  706. */
  707. public function coalesce()
  708. {
  709. $args = func_get_args();
  710. return 'COALESCE(' . join(', ', (array) $args) . ')';
  711. }
  712. /**
  713. * __call
  714. *
  715. * for all native RDBMS functions the function name itself is returned
  716. */
  717. public function __call($m, $a)
  718. {
  719. if ($this->conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_EXPR) {
  720. throw new Doctrine_Expression_Exception('Unknown expression ' . $m);
  721. }
  722. return $m . '(' . implode(', ', $a) . ')';
  723. }
  724. }