Builder.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php defined('SYSPATH') OR die('No direct script access.');
  2. /**
  3. * Database query builder. See [Query Builder](/database/query/builder) for usage and examples.
  4. *
  5. * @package Kohana/Database
  6. * @category Query
  7. * @author Kohana Team
  8. * @copyright (c) 2008-2009 Kohana Team
  9. * @license http://kohanaphp.com/license
  10. */
  11. abstract class Kohana_Database_Query_Builder extends Database_Query {
  12. /**
  13. * Compiles an array of JOIN statements into an SQL partial.
  14. *
  15. * @param object $db Database instance
  16. * @param array $joins join statements
  17. * @return string
  18. */
  19. protected function _compile_join(Database $db, array $joins)
  20. {
  21. $statements = array();
  22. foreach ($joins as $join)
  23. {
  24. // Compile each of the join statements
  25. $statements[] = $join->compile($db);
  26. }
  27. return implode(' ', $statements);
  28. }
  29. /**
  30. * Compiles an array of conditions into an SQL partial. Used for WHERE
  31. * and HAVING.
  32. *
  33. * @param object $db Database instance
  34. * @param array $conditions condition statements
  35. * @return string
  36. */
  37. protected function _compile_conditions(Database $db, array $conditions)
  38. {
  39. $last_condition = NULL;
  40. $sql = '';
  41. foreach ($conditions as $group)
  42. {
  43. // Process groups of conditions
  44. foreach ($group as $logic => $condition)
  45. {
  46. if ($condition === '(')
  47. {
  48. if ( ! empty($sql) AND $last_condition !== '(')
  49. {
  50. // Include logic operator
  51. $sql .= ' '.$logic.' ';
  52. }
  53. $sql .= '(';
  54. }
  55. elseif ($condition === ')')
  56. {
  57. $sql .= ')';
  58. }
  59. else
  60. {
  61. if ( ! empty($sql) AND $last_condition !== '(')
  62. {
  63. // Add the logic operator
  64. $sql .= ' '.$logic.' ';
  65. }
  66. // Split the condition
  67. list($column, $op, $value) = $condition;
  68. if ($value === NULL)
  69. {
  70. if ($op === '=')
  71. {
  72. // Convert "val = NULL" to "val IS NULL"
  73. $op = 'IS';
  74. }
  75. elseif ($op === '!=')
  76. {
  77. // Convert "val != NULL" to "valu IS NOT NULL"
  78. $op = 'IS NOT';
  79. }
  80. }
  81. // Database operators are always uppercase
  82. $op = strtoupper($op);
  83. if ($op === 'BETWEEN' AND is_array($value))
  84. {
  85. // BETWEEN always has exactly two arguments
  86. list($min, $max) = $value;
  87. if ((is_string($min) AND array_key_exists($min, $this->_parameters)) === FALSE)
  88. {
  89. // Quote the value, it is not a parameter
  90. $min = $db->quote($min);
  91. }
  92. if ((is_string($max) AND array_key_exists($max, $this->_parameters)) === FALSE)
  93. {
  94. // Quote the value, it is not a parameter
  95. $max = $db->quote($max);
  96. }
  97. // Quote the min and max value
  98. $value = $min.' AND '.$max;
  99. }
  100. elseif ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
  101. {
  102. // Quote the value, it is not a parameter
  103. $value = $db->quote($value);
  104. }
  105. if ($column)
  106. {
  107. if (is_array($column))
  108. {
  109. // Use the column name
  110. $column = $db->quote_identifier(reset($column));
  111. }
  112. else
  113. {
  114. // Apply proper quoting to the column
  115. $column = $db->quote_column($column);
  116. }
  117. }
  118. // Append the statement to the query
  119. $sql .= trim($column.' '.$op.' '.$value);
  120. }
  121. $last_condition = $condition;
  122. }
  123. }
  124. return $sql;
  125. }
  126. /**
  127. * Compiles an array of set values into an SQL partial. Used for UPDATE.
  128. *
  129. * @param object $db Database instance
  130. * @param array $values updated values
  131. * @return string
  132. */
  133. protected function _compile_set(Database $db, array $values)
  134. {
  135. $set = array();
  136. foreach ($values as $group)
  137. {
  138. // Split the set
  139. list ($column, $value) = $group;
  140. // Quote the column name
  141. $column = $db->quote_column($column);
  142. if ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
  143. {
  144. // Quote the value, it is not a parameter
  145. $value = $db->quote($value);
  146. }
  147. $set[$column] = $column.' = '.$value;
  148. }
  149. return implode(', ', $set);
  150. }
  151. /**
  152. * Compiles an array of GROUP BY columns into an SQL partial.
  153. *
  154. * @param object $db Database instance
  155. * @param array $columns
  156. * @return string
  157. */
  158. protected function _compile_group_by(Database $db, array $columns)
  159. {
  160. $group = array();
  161. foreach ($columns as $column)
  162. {
  163. if (is_array($column))
  164. {
  165. // Use the column alias
  166. $column = $db->quote_identifier(end($column));
  167. }
  168. else
  169. {
  170. // Apply proper quoting to the column
  171. $column = $db->quote_column($column);
  172. }
  173. $group[] = $column;
  174. }
  175. return 'GROUP BY '.implode(', ', $group);
  176. }
  177. /**
  178. * Compiles an array of ORDER BY statements into an SQL partial.
  179. *
  180. * @param object $db Database instance
  181. * @param array $columns sorting columns
  182. * @return string
  183. */
  184. protected function _compile_order_by(Database $db, array $columns)
  185. {
  186. $sort = array();
  187. foreach ($columns as $group)
  188. {
  189. list ($column, $direction) = $group;
  190. if (is_array($column))
  191. {
  192. // Use the column alias
  193. $column = $db->quote_identifier(end($column));
  194. }
  195. else
  196. {
  197. // Apply proper quoting to the column
  198. $column = $db->quote_column($column);
  199. }
  200. if ($direction)
  201. {
  202. // Make the direction uppercase
  203. $direction = ' '.strtoupper($direction);
  204. }
  205. $sort[] = $column.$direction;
  206. }
  207. return 'ORDER BY '.implode(', ', $sort);
  208. }
  209. /**
  210. * Reset the current builder status.
  211. *
  212. * @return $this
  213. */
  214. abstract public function reset();
  215. } // End Database_Query_Builder