123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- <?php
- /**
- * Database query builder. See [Query Builder](/database/query/builder) for usage and examples.
- *
- * @package Kohana/Database
- * @category Query
- * @author Kohana Team
- * @copyright (c) Kohana Team
- * @license https://koseven.ga/LICENSE.md
- */
- abstract class Kohana_Database_Query_Builder extends Database_Query {
- /**
- * Compiles an array of JOIN statements into an SQL partial.
- *
- * @param object $db Database instance
- * @param array $joins join statements
- * @return string
- */
- protected function _compile_join(Database $db, array $joins)
- {
- $statements = [];
- foreach ($joins as $join)
- {
- // Compile each of the join statements
- $statements[] = $join->compile($db);
- }
- return implode(' ', $statements);
- }
- /**
- * Compiles an array of conditions into an SQL partial. Used for WHERE
- * and HAVING.
- *
- * @param object $db Database instance
- * @param array $conditions condition statements
- * @return string
- */
- protected function _compile_conditions(Database $db, array $conditions)
- {
- $last_condition = NULL;
- $sql = '';
- foreach ($conditions as $group)
- {
- // Process groups of conditions
- foreach ($group as $logic => $condition)
- {
- if ($condition === '(')
- {
- if ( ! empty($sql) AND $last_condition !== '(')
- {
- // Include logic operator
- $sql .= ' '.$logic.' ';
- }
- $sql .= '(';
- }
- elseif ($condition === ')')
- {
- $sql .= ')';
- }
- else
- {
- if ( ! empty($sql) AND $last_condition !== '(')
- {
- // Add the logic operator
- $sql .= ' '.$logic.' ';
- }
- // Split the condition
- list($column, $op, $value) = $condition;
- if ($value === NULL)
- {
- if ($op === '=')
- {
- // Convert "val = NULL" to "val IS NULL"
- $op = 'IS';
- }
- elseif ($op === '!=' OR $op === '<>')
- {
- // Convert "val != NULL" to "valu IS NOT NULL"
- $op = 'IS NOT';
- }
- }
- // Database operators are always uppercase
- $op = strtoupper($op);
- if ($op === 'BETWEEN' AND is_array($value))
- {
- // BETWEEN always has exactly two arguments
- list($min, $max) = $value;
- if ((is_string($min) AND array_key_exists($min, $this->_parameters)) === FALSE)
- {
- // Quote the value, it is not a parameter
- $min = $db->quote($min);
- }
- if ((is_string($max) AND array_key_exists($max, $this->_parameters)) === FALSE)
- {
- // Quote the value, it is not a parameter
- $max = $db->quote($max);
- }
- // Quote the min and max value
- $value = $min.' AND '.$max;
- }
- elseif ($op === 'IN' AND is_array($value) AND count($value) === 0)
- {
- $value = '(NULL)';
- }
- elseif ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
- {
- // Quote the value, it is not a parameter
- $value = $db->quote($value);
- }
- if ($column)
- {
- if (is_array($column))
- {
- // Use the column name
- $column = $db->quote_identifier(reset($column));
- }
- else
- {
- // Apply proper quoting to the column
- $column = $db->quote_column($column);
- }
- }
- // Append the statement to the query
- $sql .= trim($column.' '.$op.' '.$value);
- }
- $last_condition = $condition;
- }
- }
- return $sql;
- }
- /**
- * Compiles an array of set values into an SQL partial. Used for UPDATE.
- *
- * @param object $db Database instance
- * @param array $values updated values
- * @return string
- */
- protected function _compile_set(Database $db, array $values)
- {
- $set = [];
- foreach ($values as $group)
- {
- // Split the set
- list ($column, $value) = $group;
- // Quote the column name
- $column = $db->quote_column($column);
- if ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
- {
- // Quote the value, it is not a parameter
- $value = $db->quote($value);
- }
- $set[$column] = $column.' = '.$value;
- }
- return implode(', ', $set);
- }
- /**
- * Compiles an array of GROUP BY columns into an SQL partial.
- *
- * @param object $db Database instance
- * @param array $columns
- * @return string
- */
- protected function _compile_group_by(Database $db, array $columns)
- {
- $group = [];
- foreach ($columns as $column)
- {
- if (is_array($column))
- {
- // Use the column alias
- $column = $db->quote_identifier(end($column));
- }
- else
- {
- // Apply proper quoting to the column
- $column = $db->quote_column($column);
- }
- $group[] = $column;
- }
- return 'GROUP BY '.implode(', ', $group);
- }
- /**
- * Compiles an array of ORDER BY statements into an SQL partial.
- *
- * @param Database $db Database instance
- * @param array $columns sorting columns
- *
- * @return string
- * @throws Database_Exception
- */
- protected function _compile_order_by(Database $db, array $columns)
- {
- $sort = [];
- foreach ($columns as $group)
- {
- list ($column, $direction) = $group;
- if (is_array($column))
- {
- // Use the column alias
- $column = $db->quote_identifier(end($column));
- }
- else
- {
- // Apply proper quoting to the column
- $column = $db->quote_column($column);
- }
- if ($direction)
- {
- // Make the direction uppercase
- $direction = ' '.strtoupper($direction);
- // Make sure direction is either ASC or DESC to prevent injections
- if ( ! in_array($direction, [' ASC', ' DESC'])) {
- throw new Database_Exception('Invalid sorting direction: ' . $direction);
- }
- }
- $sort[] = $column.$direction;
- }
- return 'ORDER BY '.implode(', ', $sort);
- }
- /**
- * Reset the current builder status.
- *
- * @return $this
- */
- abstract public function reset();
- } // End Database_Query_Builder
|