Upgrade to KH 3.3.0
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
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 = array();
|
||||
|
||||
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 === '!=')
|
||||
{
|
||||
// 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 ((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 = array();
|
||||
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 = array();
|
||||
|
||||
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 object $db Database instance
|
||||
* @param array $columns sorting columns
|
||||
* @return string
|
||||
*/
|
||||
protected function _compile_order_by(Database $db, array $columns)
|
||||
{
|
||||
$sort = array();
|
||||
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);
|
||||
}
|
||||
|
||||
$sort[] = $column.$direction;
|
||||
}
|
||||
|
||||
return 'ORDER BY '.implode(', ', $sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the current builder status.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
abstract public function reset();
|
||||
|
||||
} // End Database_Query_Builder
|
@@ -0,0 +1,99 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for DELETE statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_Query_Builder_Delete extends Database_Query_Builder_Where {
|
||||
|
||||
// DELETE FROM ...
|
||||
protected $_table;
|
||||
|
||||
/**
|
||||
* Set the table for a delete.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table = NULL)
|
||||
{
|
||||
if ($table)
|
||||
{
|
||||
// Set the inital table name
|
||||
$this->_table = $table;
|
||||
}
|
||||
|
||||
// Start the query with no SQL
|
||||
return parent::__construct(Database::DELETE, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table to delete from.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
$this->_table = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL query and return it.
|
||||
*
|
||||
* @param mixed $db Database instance or name of instance
|
||||
* @return string
|
||||
*/
|
||||
public function compile($db = NULL)
|
||||
{
|
||||
if ( ! is_object($db))
|
||||
{
|
||||
// Get the database instance
|
||||
$db = Database::instance($db);
|
||||
}
|
||||
|
||||
// Start a deletion query
|
||||
$query = 'DELETE FROM '.$db->quote_table($this->_table);
|
||||
|
||||
if ( ! empty($this->_where))
|
||||
{
|
||||
// Add deletion conditions
|
||||
$query .= ' WHERE '.$this->_compile_conditions($db, $this->_where);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_order_by))
|
||||
{
|
||||
// Add sorting
|
||||
$query .= ' '.$this->_compile_order_by($db, $this->_order_by);
|
||||
}
|
||||
|
||||
if ($this->_limit !== NULL)
|
||||
{
|
||||
// Add limiting
|
||||
$query .= ' LIMIT '.$this->_limit;
|
||||
}
|
||||
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_table = NULL;
|
||||
$this->_where = array();
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Database_Query_Builder_Delete
|
@@ -0,0 +1,181 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for INSERT statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
|
||||
// INSERT INTO ...
|
||||
protected $_table;
|
||||
|
||||
// (...)
|
||||
protected $_columns = array();
|
||||
|
||||
// VALUES (...)
|
||||
protected $_values = array();
|
||||
|
||||
/**
|
||||
* Set the table and columns for an insert.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @param array $columns column names
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table = NULL, array $columns = NULL)
|
||||
{
|
||||
if ($table)
|
||||
{
|
||||
// Set the inital table name
|
||||
$this->_table = $table;
|
||||
}
|
||||
|
||||
if ($columns)
|
||||
{
|
||||
// Set the column names
|
||||
$this->_columns = $columns;
|
||||
}
|
||||
|
||||
// Start the query with no SQL
|
||||
return parent::__construct(Database::INSERT, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table to insert into.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
$this->_table = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the columns that will be inserted.
|
||||
*
|
||||
* @param array $columns column names
|
||||
* @return $this
|
||||
*/
|
||||
public function columns(array $columns)
|
||||
{
|
||||
$this->_columns = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or overwrites values. Multiple value sets can be added.
|
||||
*
|
||||
* @param array $values values list
|
||||
* @param ...
|
||||
* @return $this
|
||||
*/
|
||||
public function values(array $values)
|
||||
{
|
||||
if ( ! is_array($this->_values))
|
||||
{
|
||||
throw new Kohana_Exception('INSERT INTO ... SELECT statements cannot be combined with INSERT INTO ... VALUES');
|
||||
}
|
||||
|
||||
// Get all of the passed values
|
||||
$values = func_get_args();
|
||||
|
||||
$this->_values = array_merge($this->_values, $values);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a sub-query to for the inserted values.
|
||||
*
|
||||
* @param object $query Database_Query of SELECT type
|
||||
* @return $this
|
||||
*/
|
||||
public function select(Database_Query $query)
|
||||
{
|
||||
if ($query->type() !== Database::SELECT)
|
||||
{
|
||||
throw new Kohana_Exception('Only SELECT queries can be combined with INSERT queries');
|
||||
}
|
||||
|
||||
$this->_values = $query;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL query and return it.
|
||||
*
|
||||
* @param mixed $db Database instance or name of instance
|
||||
* @return string
|
||||
*/
|
||||
public function compile($db = NULL)
|
||||
{
|
||||
if ( ! is_object($db))
|
||||
{
|
||||
// Get the database instance
|
||||
$db = Database::instance($db);
|
||||
}
|
||||
|
||||
// Start an insertion query
|
||||
$query = 'INSERT INTO '.$db->quote_table($this->_table);
|
||||
|
||||
// Add the column names
|
||||
$query .= ' ('.implode(', ', array_map(array($db, 'quote_column'), $this->_columns)).') ';
|
||||
|
||||
if (is_array($this->_values))
|
||||
{
|
||||
// Callback for quoting values
|
||||
$quote = array($db, 'quote');
|
||||
|
||||
$groups = array();
|
||||
foreach ($this->_values as $group)
|
||||
{
|
||||
foreach ($group as $offset => $value)
|
||||
{
|
||||
if ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
|
||||
{
|
||||
// Quote the value, it is not a parameter
|
||||
$group[$offset] = $db->quote($value);
|
||||
}
|
||||
}
|
||||
|
||||
$groups[] = '('.implode(', ', $group).')';
|
||||
}
|
||||
|
||||
// Add the values
|
||||
$query .= 'VALUES '.implode(', ', $groups);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the sub-query
|
||||
$query .= (string) $this->_values;
|
||||
}
|
||||
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_table = NULL;
|
||||
|
||||
$this->_columns =
|
||||
$this->_values = array();
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Database_Query_Builder_Insert
|
@@ -0,0 +1,149 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for JOIN statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_Query_Builder_Join extends Database_Query_Builder {
|
||||
|
||||
// Type of JOIN
|
||||
protected $_type;
|
||||
|
||||
// JOIN ...
|
||||
protected $_table;
|
||||
|
||||
// ON ...
|
||||
protected $_on = array();
|
||||
|
||||
// USING ...
|
||||
protected $_using = array();
|
||||
|
||||
/**
|
||||
* Creates a new JOIN statement for a table. Optionally, the type of JOIN
|
||||
* can be specified as the second parameter.
|
||||
*
|
||||
* @param mixed $table column name or array($column, $alias) or object
|
||||
* @param string $type type of JOIN: INNER, RIGHT, LEFT, etc
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table, $type = NULL)
|
||||
{
|
||||
// Set the table to JOIN on
|
||||
$this->_table = $table;
|
||||
|
||||
if ($type !== NULL)
|
||||
{
|
||||
// Set the JOIN type
|
||||
$this->_type = (string) $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new condition for joining.
|
||||
*
|
||||
* @param mixed $c1 column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $c2 column name or array($column, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function on($c1, $op, $c2)
|
||||
{
|
||||
if ( ! empty($this->_using))
|
||||
{
|
||||
throw new Kohana_Exception('JOIN ... ON ... cannot be combined with JOIN ... USING ...');
|
||||
}
|
||||
|
||||
$this->_on[] = array($c1, $op, $c2);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new condition for joining.
|
||||
*
|
||||
* @param string $columns column name
|
||||
* @return $this
|
||||
*/
|
||||
public function using($columns)
|
||||
{
|
||||
if ( ! empty($this->_on))
|
||||
{
|
||||
throw new Kohana_Exception('JOIN ... ON ... cannot be combined with JOIN ... USING ...');
|
||||
}
|
||||
|
||||
$columns = func_get_args();
|
||||
|
||||
$this->_using = array_merge($this->_using, $columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL partial for a JOIN statement and return it.
|
||||
*
|
||||
* @param mixed $db Database instance or name of instance
|
||||
* @return string
|
||||
*/
|
||||
public function compile($db = NULL)
|
||||
{
|
||||
if ( ! is_object($db))
|
||||
{
|
||||
// Get the database instance
|
||||
$db = Database::instance($db);
|
||||
}
|
||||
|
||||
if ($this->_type)
|
||||
{
|
||||
$sql = strtoupper($this->_type).' JOIN';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'JOIN';
|
||||
}
|
||||
|
||||
// Quote the table name that is being joined
|
||||
$sql .= ' '.$db->quote_table($this->_table);
|
||||
|
||||
if ( ! empty($this->_using))
|
||||
{
|
||||
// Quote and concat the columns
|
||||
$sql .= ' USING ('.implode(', ', array_map(array($db, 'quote_column'), $this->_using)).')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$conditions = array();
|
||||
foreach ($this->_on as $condition)
|
||||
{
|
||||
// Split the condition
|
||||
list($c1, $op, $c2) = $condition;
|
||||
|
||||
if ($op)
|
||||
{
|
||||
// Make the operator uppercase and spaced
|
||||
$op = ' '.strtoupper($op);
|
||||
}
|
||||
|
||||
// Quote each of the columns used for the condition
|
||||
$conditions[] = $db->quote_column($c1).$op.' '.$db->quote_column($c2);
|
||||
}
|
||||
|
||||
// Concat the conditions "... AND ..."
|
||||
$sql .= ' ON ('.implode(' AND ', $conditions).')';
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_type =
|
||||
$this->_table = NULL;
|
||||
|
||||
$this->_on = array();
|
||||
}
|
||||
|
||||
} // End Database_Query_Builder_Join
|
@@ -0,0 +1,446 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for SELECT statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where {
|
||||
|
||||
// SELECT ...
|
||||
protected $_select = array();
|
||||
|
||||
// DISTINCT
|
||||
protected $_distinct = FALSE;
|
||||
|
||||
// FROM ...
|
||||
protected $_from = array();
|
||||
|
||||
// JOIN ...
|
||||
protected $_join = array();
|
||||
|
||||
// GROUP BY ...
|
||||
protected $_group_by = array();
|
||||
|
||||
// HAVING ...
|
||||
protected $_having = array();
|
||||
|
||||
// OFFSET ...
|
||||
protected $_offset = NULL;
|
||||
|
||||
// UNION ...
|
||||
protected $_union = array();
|
||||
|
||||
// The last JOIN statement created
|
||||
protected $_last_join;
|
||||
|
||||
/**
|
||||
* Sets the initial columns to select from.
|
||||
*
|
||||
* @param array $columns column list
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $columns = NULL)
|
||||
{
|
||||
if ( ! empty($columns))
|
||||
{
|
||||
// Set the initial columns
|
||||
$this->_select = $columns;
|
||||
}
|
||||
|
||||
// Start the query with no actual SQL statement
|
||||
parent::__construct(Database::SELECT, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables selecting only unique columns using "SELECT DISTINCT"
|
||||
*
|
||||
* @param boolean $value enable or disable distinct columns
|
||||
* @return $this
|
||||
*/
|
||||
public function distinct($value)
|
||||
{
|
||||
$this->_distinct = (bool) $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the columns to select from.
|
||||
*
|
||||
* @param mixed $columns column name or array($column, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function select($columns = NULL)
|
||||
{
|
||||
$columns = func_get_args();
|
||||
|
||||
$this->_select = array_merge($this->_select, $columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the columns to select from, using an array.
|
||||
*
|
||||
* @param array $columns list of column names or aliases
|
||||
* @return $this
|
||||
*/
|
||||
public function select_array(array $columns)
|
||||
{
|
||||
$this->_select = array_merge($this->_select, $columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the tables to select "FROM ..."
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function from($tables)
|
||||
{
|
||||
$tables = func_get_args();
|
||||
|
||||
$this->_from = array_merge($this->_from, $tables);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds addition tables to "JOIN ...".
|
||||
*
|
||||
* @param mixed $table column name or array($column, $alias) or object
|
||||
* @param string $type join type (LEFT, RIGHT, INNER, etc)
|
||||
* @return $this
|
||||
*/
|
||||
public function join($table, $type = NULL)
|
||||
{
|
||||
$this->_join[] = $this->_last_join = new Database_Query_Builder_Join($table, $type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "ON ..." conditions for the last created JOIN statement.
|
||||
*
|
||||
* @param mixed $c1 column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $c2 column name or array($column, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function on($c1, $op, $c2)
|
||||
{
|
||||
$this->_last_join->on($c1, $op, $c2);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "USING ..." conditions for the last created JOIN statement.
|
||||
*
|
||||
* @param string $columns column name
|
||||
* @return $this
|
||||
*/
|
||||
public function using($columns)
|
||||
{
|
||||
$columns = func_get_args();
|
||||
|
||||
call_user_func_array(array($this->_last_join, 'using'), $columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a "GROUP BY ..." filter.
|
||||
*
|
||||
* @param mixed $columns column name or array($column, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function group_by($columns)
|
||||
{
|
||||
$columns = func_get_args();
|
||||
|
||||
$this->_group_by = array_merge($this->_group_by, $columns);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of and_having()
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function having($column, $op, $value = NULL)
|
||||
{
|
||||
return $this->and_having($column, $op, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new "AND HAVING" condition for the query.
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function and_having($column, $op, $value = NULL)
|
||||
{
|
||||
$this->_having[] = array('AND' => array($column, $op, $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new "OR HAVING" condition for the query.
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function or_having($column, $op, $value = NULL)
|
||||
{
|
||||
$this->_having[] = array('OR' => array($column, $op, $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of and_having_open()
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function having_open()
|
||||
{
|
||||
return $this->and_having_open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new "AND HAVING (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function and_having_open()
|
||||
{
|
||||
$this->_having[] = array('AND' => '(');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new "OR HAVING (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function or_having_open()
|
||||
{
|
||||
$this->_having[] = array('OR' => '(');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "AND HAVING (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function having_close()
|
||||
{
|
||||
return $this->and_having_close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "AND HAVING (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function and_having_close()
|
||||
{
|
||||
$this->_having[] = array('AND' => ')');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "OR HAVING (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function or_having_close()
|
||||
{
|
||||
$this->_having[] = array('OR' => ')');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an other UNION clause.
|
||||
*
|
||||
* @param mixed $select if string, it must be the name of a table. Else
|
||||
* must be an instance of Database_Query_Builder_Select
|
||||
* @param boolean $all decides if it's an UNION or UNION ALL clause
|
||||
* @return $this
|
||||
*/
|
||||
public function union($select, $all = TRUE)
|
||||
{
|
||||
if (is_string($select))
|
||||
{
|
||||
$select = DB::select()->from($select);
|
||||
}
|
||||
if ( ! $select instanceof Database_Query_Builder_Select)
|
||||
throw new Kohana_Exception('first parameter must be a string or an instance of Database_Query_Builder_Select');
|
||||
$this->_union []= array('select' => $select, 'all' => $all);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start returning results after "OFFSET ..."
|
||||
*
|
||||
* @param integer $number starting result number or NULL to reset
|
||||
* @return $this
|
||||
*/
|
||||
public function offset($number)
|
||||
{
|
||||
$this->_offset = $number;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL query and return it.
|
||||
*
|
||||
* @param mixed $db Database instance or name of instance
|
||||
* @return string
|
||||
*/
|
||||
public function compile($db = NULL)
|
||||
{
|
||||
if ( ! is_object($db))
|
||||
{
|
||||
// Get the database instance
|
||||
$db = Database::instance($db);
|
||||
}
|
||||
|
||||
// Callback to quote columns
|
||||
$quote_column = array($db, 'quote_column');
|
||||
|
||||
// Callback to quote tables
|
||||
$quote_table = array($db, 'quote_table');
|
||||
|
||||
// Start a selection query
|
||||
$query = 'SELECT ';
|
||||
|
||||
if ($this->_distinct === TRUE)
|
||||
{
|
||||
// Select only unique results
|
||||
$query .= 'DISTINCT ';
|
||||
}
|
||||
|
||||
if (empty($this->_select))
|
||||
{
|
||||
// Select all columns
|
||||
$query .= '*';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select all columns
|
||||
$query .= implode(', ', array_unique(array_map($quote_column, $this->_select)));
|
||||
}
|
||||
|
||||
if ( ! empty($this->_from))
|
||||
{
|
||||
// Set tables to select from
|
||||
$query .= ' FROM '.implode(', ', array_unique(array_map($quote_table, $this->_from)));
|
||||
}
|
||||
|
||||
if ( ! empty($this->_join))
|
||||
{
|
||||
// Add tables to join
|
||||
$query .= ' '.$this->_compile_join($db, $this->_join);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_where))
|
||||
{
|
||||
// Add selection conditions
|
||||
$query .= ' WHERE '.$this->_compile_conditions($db, $this->_where);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_group_by))
|
||||
{
|
||||
// Add grouping
|
||||
$query .= ' '.$this->_compile_group_by($db, $this->_group_by);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_having))
|
||||
{
|
||||
// Add filtering conditions
|
||||
$query .= ' HAVING '.$this->_compile_conditions($db, $this->_having);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_order_by))
|
||||
{
|
||||
// Add sorting
|
||||
$query .= ' '.$this->_compile_order_by($db, $this->_order_by);
|
||||
}
|
||||
|
||||
if ($this->_limit !== NULL)
|
||||
{
|
||||
// Add limiting
|
||||
$query .= ' LIMIT '.$this->_limit;
|
||||
}
|
||||
|
||||
if ($this->_offset !== NULL)
|
||||
{
|
||||
// Add offsets
|
||||
$query .= ' OFFSET '.$this->_offset;
|
||||
}
|
||||
|
||||
if ( ! empty($this->_union))
|
||||
{
|
||||
foreach ($this->_union as $u) {
|
||||
$query .= ' UNION ';
|
||||
if ($u['all'] === TRUE)
|
||||
{
|
||||
$query .= 'ALL ';
|
||||
}
|
||||
$query .= $u['select']->compile($db);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_select =
|
||||
$this->_from =
|
||||
$this->_join =
|
||||
$this->_where =
|
||||
$this->_group_by =
|
||||
$this->_having =
|
||||
$this->_order_by =
|
||||
$this->_union = array();
|
||||
|
||||
$this->_distinct = FALSE;
|
||||
|
||||
$this->_limit =
|
||||
$this->_offset =
|
||||
$this->_last_join = NULL;
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Database_Query_Select
|
@@ -0,0 +1,140 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for UPDATE statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_Query_Builder_Update extends Database_Query_Builder_Where {
|
||||
|
||||
// UPDATE ...
|
||||
protected $_table;
|
||||
|
||||
// SET ...
|
||||
protected $_set = array();
|
||||
|
||||
/**
|
||||
* Set the table for a update.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($table = NULL)
|
||||
{
|
||||
if ($table)
|
||||
{
|
||||
// Set the inital table name
|
||||
$this->_table = $table;
|
||||
}
|
||||
|
||||
// Start the query with no SQL
|
||||
return parent::__construct(Database::UPDATE, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table to update.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @return $this
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
$this->_table = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the values to update with an associative array.
|
||||
*
|
||||
* @param array $pairs associative (column => value) list
|
||||
* @return $this
|
||||
*/
|
||||
public function set(array $pairs)
|
||||
{
|
||||
foreach ($pairs as $column => $value)
|
||||
{
|
||||
$this->_set[] = array($column, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a single column.
|
||||
*
|
||||
* @param mixed $column table name or array($table, $alias) or object
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function value($column, $value)
|
||||
{
|
||||
$this->_set[] = array($column, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the SQL query and return it.
|
||||
*
|
||||
* @param mixed $db Database instance or name of instance
|
||||
* @return string
|
||||
*/
|
||||
public function compile($db = NULL)
|
||||
{
|
||||
if ( ! is_object($db))
|
||||
{
|
||||
// Get the database instance
|
||||
$db = Database::instance($db);
|
||||
}
|
||||
|
||||
// Start an update query
|
||||
$query = 'UPDATE '.$db->quote_table($this->_table);
|
||||
|
||||
// Add the columns to update
|
||||
$query .= ' SET '.$this->_compile_set($db, $this->_set);
|
||||
|
||||
if ( ! empty($this->_where))
|
||||
{
|
||||
// Add selection conditions
|
||||
$query .= ' WHERE '.$this->_compile_conditions($db, $this->_where);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_order_by))
|
||||
{
|
||||
// Add sorting
|
||||
$query .= ' '.$this->_compile_order_by($db, $this->_order_by);
|
||||
}
|
||||
|
||||
if ($this->_limit !== NULL)
|
||||
{
|
||||
// Add limiting
|
||||
$query .= ' LIMIT '.$this->_limit;
|
||||
}
|
||||
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_table = NULL;
|
||||
|
||||
$this->_set =
|
||||
$this->_where = array();
|
||||
|
||||
$this->_limit = NULL;
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
} // End Database_Query_Builder_Update
|
@@ -0,0 +1,180 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Database query builder for WHERE statements. See [Query Builder](/database/query/builder) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Kohana_Database_Query_Builder_Where extends Database_Query_Builder {
|
||||
|
||||
// WHERE ...
|
||||
protected $_where = array();
|
||||
|
||||
// ORDER BY ...
|
||||
protected $_order_by = array();
|
||||
|
||||
// LIMIT ...
|
||||
protected $_limit = NULL;
|
||||
|
||||
/**
|
||||
* Alias of and_where()
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function where($column, $op, $value)
|
||||
{
|
||||
return $this->and_where($column, $op, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new "AND WHERE" condition for the query.
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function and_where($column, $op, $value)
|
||||
{
|
||||
$this->_where[] = array('AND' => array($column, $op, $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new "OR WHERE" condition for the query.
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $op logic operator
|
||||
* @param mixed $value column value
|
||||
* @return $this
|
||||
*/
|
||||
public function or_where($column, $op, $value)
|
||||
{
|
||||
$this->_where[] = array('OR' => array($column, $op, $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of and_where_open()
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function where_open()
|
||||
{
|
||||
return $this->and_where_open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new "AND WHERE (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function and_where_open()
|
||||
{
|
||||
$this->_where[] = array('AND' => '(');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new "OR WHERE (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function or_where_open()
|
||||
{
|
||||
$this->_where[] = array('OR' => '(');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "WHERE (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function where_close()
|
||||
{
|
||||
return $this->and_where_close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "WHERE (...)" grouping or removes the grouping when it is
|
||||
* empty.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function where_close_empty()
|
||||
{
|
||||
$group = end($this->_where);
|
||||
|
||||
if ($group AND reset($group) === '(')
|
||||
{
|
||||
array_pop($this->_where);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->where_close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "WHERE (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function and_where_close()
|
||||
{
|
||||
$this->_where[] = array('AND' => ')');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an open "WHERE (...)" grouping.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function or_where_close()
|
||||
{
|
||||
$this->_where[] = array('OR' => ')');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies sorting with "ORDER BY ..."
|
||||
*
|
||||
* @param mixed $column column name or array($column, $alias) or object
|
||||
* @param string $direction direction of sorting
|
||||
* @return $this
|
||||
*/
|
||||
public function order_by($column, $direction = NULL)
|
||||
{
|
||||
$this->_order_by[] = array($column, $direction);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return up to "LIMIT ..." results
|
||||
*
|
||||
* @param integer $number maximum results to return or NULL to reset
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($number)
|
||||
{
|
||||
$this->_limit = $number;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Database_Query_Builder_Where
|
Reference in New Issue
Block a user