Update Kohana to 3.1.3.1
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Config_Database extends Kohana_Config_Database {}
|
@@ -15,7 +15,7 @@
|
||||
* @copyright (c) 2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Config_Database extends Kohana_Config_Reader {
|
||||
class Kohana_Config_Database extends Config_Reader {
|
||||
|
||||
protected $_database_instance = 'default';
|
||||
|
||||
|
@@ -158,12 +158,18 @@ abstract class Kohana_Database {
|
||||
|
||||
/**
|
||||
* Disconnect from the database. This is called automatically by [Database::__destruct].
|
||||
* Clears the database instance from [Database::$instances].
|
||||
*
|
||||
* $db->disconnect();
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function disconnect();
|
||||
public function disconnect()
|
||||
{
|
||||
unset(Database::$instances[$this->_instance]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection character set. This is called automatically by [Database::connect].
|
||||
@@ -196,51 +202,47 @@ abstract class Kohana_Database {
|
||||
abstract public function query($type, $sql, $as_object = FALSE, array $params = NULL);
|
||||
|
||||
/**
|
||||
* Count the number of records in the last query, without LIMIT or OFFSET applied.
|
||||
* Start a SQL transaction
|
||||
*
|
||||
* // Get the total number of records that match the last query
|
||||
* $count = $db->count_last_query();
|
||||
* // Start the transactions
|
||||
* $db->begin();
|
||||
*
|
||||
* @deprecated since v3.0.9
|
||||
* @return integer
|
||||
* try {
|
||||
* DB::insert('users')->values($user1)...
|
||||
* DB::insert('users')->values($user2)...
|
||||
* // Insert successful commit the changes
|
||||
* $db->commit();
|
||||
* }
|
||||
* catch (Database_Exception $e)
|
||||
* {
|
||||
* // Insert failed. Rolling back changes...
|
||||
* $db->rollback();
|
||||
* }
|
||||
*
|
||||
* @param string transaction mode
|
||||
* @return boolean
|
||||
*/
|
||||
public function count_last_query()
|
||||
{
|
||||
if ($sql = $this->last_query)
|
||||
{
|
||||
$sql = trim($sql);
|
||||
if (stripos($sql, 'SELECT') !== 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
abstract public function begin($mode = NULL);
|
||||
|
||||
if (stripos($sql, 'LIMIT') !== FALSE)
|
||||
{
|
||||
// Remove LIMIT from the SQL
|
||||
$sql = preg_replace('/\sLIMIT\s+[^a-z]+/i', ' ', $sql);
|
||||
}
|
||||
/**
|
||||
* Commit the current transaction
|
||||
*
|
||||
* // Commit the database changes
|
||||
* $db->commit();
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function commit();
|
||||
|
||||
if (stripos($sql, 'OFFSET') !== FALSE)
|
||||
{
|
||||
// Remove OFFSET from the SQL
|
||||
$sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql);
|
||||
}
|
||||
|
||||
// Get the total rows from the last query executed
|
||||
$result = $this->query
|
||||
(
|
||||
Database::SELECT,
|
||||
'SELECT COUNT(*) AS '.$this->quote_identifier('total_rows').' '
|
||||
.'FROM ('.$sql.') AS '.$this->quote_table('counted_results'),
|
||||
TRUE
|
||||
);
|
||||
|
||||
// Return the total number of rows from the query
|
||||
return (int) $result->current()->total_rows;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
/**
|
||||
* Abort the current transaction
|
||||
*
|
||||
* // Undo the changes
|
||||
* $db->rollback();
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function rollback();
|
||||
|
||||
/**
|
||||
* Count the number of records in a table.
|
||||
@@ -254,7 +256,7 @@ abstract class Kohana_Database {
|
||||
public function count_records($table)
|
||||
{
|
||||
// Quote the table name
|
||||
$table = $this->quote_identifier($table);
|
||||
$table = $this->quote_table($table);
|
||||
|
||||
return $this->query(Database::SELECT, 'SELECT COUNT(*) AS total_row_count FROM '.$table, FALSE)
|
||||
->get('total_row_count');
|
||||
@@ -471,6 +473,90 @@ abstract class Kohana_Database {
|
||||
return $this->escape($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a database column name and add the table prefix if needed.
|
||||
*
|
||||
* $column = $db->quote_column($column);
|
||||
*
|
||||
* You can also use SQL methods within identifiers.
|
||||
*
|
||||
* // The value of "column" will be quoted
|
||||
* $column = $db->quote_column('COUNT("column")');
|
||||
*
|
||||
* @param mixed column name or array(column, alias)
|
||||
* @return string
|
||||
* @uses Database::quote_identifier
|
||||
* @uses Database::table_prefix
|
||||
*/
|
||||
public function quote_column($column)
|
||||
{
|
||||
if (is_array($column))
|
||||
{
|
||||
list($column, $alias) = $column;
|
||||
}
|
||||
|
||||
if ($column instanceof Database_Query)
|
||||
{
|
||||
// Create a sub-query
|
||||
$column = '('.$column->compile($this).')';
|
||||
}
|
||||
elseif ($column instanceof Database_Expression)
|
||||
{
|
||||
// Use a raw expression
|
||||
$column = $column->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert to a string
|
||||
$column = (string) $column;
|
||||
|
||||
if ($column === '*')
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
elseif (strpos($column, '"') !== FALSE)
|
||||
{
|
||||
// Quote the column in FUNC("column") identifiers
|
||||
$column = preg_replace('/"(.+?)"/e', '$this->quote_column("$1")', $column);
|
||||
}
|
||||
elseif (strpos($column, '.') !== FALSE)
|
||||
{
|
||||
$parts = explode('.', $column);
|
||||
|
||||
if ($prefix = $this->table_prefix())
|
||||
{
|
||||
// Get the offset of the table name, 2nd-to-last part
|
||||
$offset = count($parts) - 2;
|
||||
|
||||
// Add the table prefix to the table name
|
||||
$parts[$offset] = $prefix.$parts[$offset];
|
||||
}
|
||||
|
||||
foreach ($parts as & $part)
|
||||
{
|
||||
if ($part !== '*')
|
||||
{
|
||||
// Quote each of the parts
|
||||
$part = $this->_identifier.$part.$this->_identifier;
|
||||
}
|
||||
}
|
||||
|
||||
$column = implode('.', $parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
$column = $this->_identifier.$column.$this->_identifier;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($alias))
|
||||
{
|
||||
$column .= ' AS '.$this->_identifier.$alias.$this->_identifier;
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a database table name and adds the table prefix if needed.
|
||||
*
|
||||
@@ -481,40 +567,67 @@ abstract class Kohana_Database {
|
||||
* @uses Database::quote_identifier
|
||||
* @uses Database::table_prefix
|
||||
*/
|
||||
public function quote_table($value)
|
||||
public function quote_table($table)
|
||||
{
|
||||
// Assign the table by reference from the value
|
||||
if (is_array($value))
|
||||
if (is_array($table))
|
||||
{
|
||||
$table =& $value[0];
|
||||
list($table, $alias) = $table;
|
||||
}
|
||||
|
||||
// Attach table prefix to alias
|
||||
$value[1] = $this->table_prefix().$value[1];
|
||||
if ($table instanceof Database_Query)
|
||||
{
|
||||
// Create a sub-query
|
||||
$table = '('.$table->compile($this).')';
|
||||
}
|
||||
elseif ($table instanceof Database_Expression)
|
||||
{
|
||||
// Use a raw expression
|
||||
$table = $table->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
$table =& $value;
|
||||
// Convert to a string
|
||||
$table = (string) $table;
|
||||
|
||||
if (strpos($table, '.') !== FALSE)
|
||||
{
|
||||
$parts = explode('.', $table);
|
||||
|
||||
if ($prefix = $this->table_prefix())
|
||||
{
|
||||
// Get the offset of the table name, last part
|
||||
$offset = count($parts) - 1;
|
||||
|
||||
// Add the table prefix to the table name
|
||||
$parts[$offset] = $prefix.$parts[$offset];
|
||||
}
|
||||
|
||||
foreach ($parts as & $part)
|
||||
{
|
||||
// Quote each of the parts
|
||||
$part = $this->_identifier.$part.$this->_identifier;
|
||||
}
|
||||
|
||||
$table = implode('.', $parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the table prefix
|
||||
$table = $this->_identifier.$this->table_prefix().$table.$this->_identifier;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_string($table) AND strpos($table, '.') === FALSE)
|
||||
if (isset($alias))
|
||||
{
|
||||
// Add the table prefix for tables
|
||||
$table = $this->table_prefix().$table;
|
||||
// Attach table prefix to alias
|
||||
$table .= ' AS '.$this->_identifier.$this->table_prefix().$alias.$this->_identifier;
|
||||
}
|
||||
|
||||
return $this->quote_identifier($value);
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a database identifier, such as a column name. Adds the
|
||||
* table prefix to the identifier if a table name is present.
|
||||
*
|
||||
* $column = $db->quote_identifier($column);
|
||||
*
|
||||
* You can also use SQL methods within identifiers.
|
||||
*
|
||||
* // The value of "column" will be quoted
|
||||
* $column = $db->quote_identifier('COUNT("column")');
|
||||
* Quote a database identifier
|
||||
*
|
||||
* Objects passed to this function will be converted to strings.
|
||||
* [Database_Expression] objects will use the value of the expression.
|
||||
@@ -523,67 +636,53 @@ abstract class Kohana_Database {
|
||||
*
|
||||
* @param mixed any identifier
|
||||
* @return string
|
||||
* @uses Database::table_prefix
|
||||
*/
|
||||
public function quote_identifier($value)
|
||||
{
|
||||
if ($value === '*')
|
||||
if (is_array($value))
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
elseif (is_object($value))
|
||||
{
|
||||
if ($value instanceof Database_Query)
|
||||
{
|
||||
// Create a sub-query
|
||||
return '('.$value->compile($this).')';
|
||||
}
|
||||
elseif ($value instanceof Database_Expression)
|
||||
{
|
||||
// Use a raw expression
|
||||
return $value->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert the object to a string
|
||||
return $this->quote_identifier( (string) $value);
|
||||
}
|
||||
}
|
||||
elseif (is_array($value))
|
||||
{
|
||||
// Separate the column and alias
|
||||
list ($value, $alias) = $value;
|
||||
|
||||
return $this->quote_identifier($value).' AS '.$this->quote_identifier($alias);
|
||||
list($value, $alias) = $value;
|
||||
}
|
||||
|
||||
if (strpos($value, '"') !== FALSE)
|
||||
if ($value instanceof Database_Query)
|
||||
{
|
||||
// Quote the column in FUNC("ident") identifiers
|
||||
return preg_replace('/"(.+?)"/e', '$this->quote_identifier("$1")', $value);
|
||||
// Create a sub-query
|
||||
$value = '('.$value->compile($this).')';
|
||||
}
|
||||
elseif (strpos($value, '.') !== FALSE)
|
||||
elseif ($value instanceof Database_Expression)
|
||||
{
|
||||
// Split the identifier into the individual parts
|
||||
$parts = explode('.', $value);
|
||||
|
||||
if ($prefix = $this->table_prefix())
|
||||
{
|
||||
// Get the offset of the table name, 2nd-to-last part
|
||||
// This works for databases that can have 3 identifiers (Postgre)
|
||||
$offset = count($parts) - 2;
|
||||
|
||||
// Add the table prefix to the table name
|
||||
$parts[$offset] = $prefix.$parts[$offset];
|
||||
}
|
||||
|
||||
// Quote each of the parts
|
||||
return implode('.', array_map(array($this, __FUNCTION__), $parts));
|
||||
// Use a raw expression
|
||||
$value = $value->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_identifier.$value.$this->_identifier;
|
||||
// Convert to a string
|
||||
$value = (string) $value;
|
||||
|
||||
if (strpos($value, '.') !== FALSE)
|
||||
{
|
||||
$parts = explode('.', $value);
|
||||
|
||||
foreach ($parts as & $part)
|
||||
{
|
||||
// Quote each of the parts
|
||||
$part = $this->_identifier.$part.$this->_identifier;
|
||||
}
|
||||
|
||||
$value = implode('.', $parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $this->_identifier.$value.$this->_identifier;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($alias))
|
||||
{
|
||||
$value .= ' AS '.$this->_identifier.$alias.$this->_identifier;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -64,9 +64,8 @@ class Kohana_Database_MySQL extends Database {
|
||||
// No connection exists
|
||||
$this->_connection = NULL;
|
||||
|
||||
throw new Database_Exception(':error', array(
|
||||
':error' => mysql_error(),
|
||||
),
|
||||
throw new Database_Exception(':error',
|
||||
array(':error' => mysql_error()),
|
||||
mysql_errno());
|
||||
}
|
||||
|
||||
@@ -114,6 +113,9 @@ class Kohana_Database_MySQL extends Database {
|
||||
{
|
||||
// Clear the connection
|
||||
$this->_connection = NULL;
|
||||
|
||||
// Clear the instance
|
||||
parent::disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,6 +258,57 @@ class Kohana_Database_MySQL extends Database {
|
||||
return parent::datatype($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a SQL transaction
|
||||
*
|
||||
* @link http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
|
||||
*
|
||||
* @param string Isolation level
|
||||
* @return boolean
|
||||
*/
|
||||
public function begin($mode = NULL)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
if ($mode AND ! mysql_query("SET TRANSACTION ISOLATION LEVEL $mode", $this->_connection))
|
||||
{
|
||||
throw new Database_Exception(':error',
|
||||
array(':error' => mysql_error($this->_connection)),
|
||||
mysql_errno($this->_connection));
|
||||
}
|
||||
|
||||
return (bool) mysql_query('START TRANSACTION', $this->_connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a SQL transaction
|
||||
*
|
||||
* @param string Isolation level
|
||||
* @return boolean
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return (bool) mysql_query('COMMIT', $this->_connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback a SQL transaction
|
||||
*
|
||||
* @param string Isolation level
|
||||
* @return boolean
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return (bool) mysql_query('ROLLBACK', $this->_connection);
|
||||
}
|
||||
|
||||
public function list_tables($like = NULL)
|
||||
{
|
||||
if (is_string($like))
|
||||
@@ -368,8 +421,8 @@ class Kohana_Database_MySQL extends Database {
|
||||
if (($value = mysql_real_escape_string( (string) $value, $this->_connection)) === FALSE)
|
||||
{
|
||||
throw new Database_Exception(':error',
|
||||
array(':error' => mysql_errno($this->_connection)),
|
||||
mysql_error($this->_connection));
|
||||
array(':error' => mysql_error($this->_connection)),
|
||||
mysql_errno($this->_connection));
|
||||
}
|
||||
|
||||
// SQL standard is to use single-quotes for all values
|
||||
|
@@ -46,7 +46,7 @@ class Kohana_Database_MySQL_Result extends Database_Result {
|
||||
public function current()
|
||||
{
|
||||
if ($this->_current_row !== $this->_internal_row AND ! $this->seek($this->_current_row))
|
||||
return FALSE;
|
||||
return NULL;
|
||||
|
||||
// Increment internal row for optimization assuming rows are fetched in order
|
||||
$this->_internal_row++;
|
||||
|
@@ -56,11 +56,9 @@ class Kohana_Database_PDO extends Database {
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Database_Exception(':error', array(
|
||||
':error' => $e->getMessage(),
|
||||
),
|
||||
$e->getCode(),
|
||||
$e);
|
||||
throw new Database_Exception(':error',
|
||||
array(':error' => $e->getMessage()),
|
||||
$e->getCode());
|
||||
}
|
||||
|
||||
if ( ! empty($this->_config['charset']))
|
||||
@@ -75,7 +73,7 @@ class Kohana_Database_PDO extends Database {
|
||||
// Destroy the PDO object
|
||||
$this->_connection = NULL;
|
||||
|
||||
return TRUE;
|
||||
return parent::disconnect();
|
||||
}
|
||||
|
||||
public function set_charset($charset)
|
||||
@@ -111,12 +109,12 @@ class Kohana_Database_PDO extends Database {
|
||||
}
|
||||
|
||||
// Convert the exception in a database exception
|
||||
throw new Database_Exception(':error [ :query ]', array(
|
||||
throw new Database_Exception(':error [ :query ]',
|
||||
array(
|
||||
':error' => $e->getMessage(),
|
||||
':query' => $sql
|
||||
),
|
||||
$e->getCode(),
|
||||
$e);
|
||||
$e->getCode());
|
||||
}
|
||||
|
||||
if (isset($benchmark))
|
||||
@@ -163,6 +161,30 @@ class Kohana_Database_PDO extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public function begin($mode = NULL)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return $this->_connection->beginTransaction();
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return $this->_connection->commit();
|
||||
}
|
||||
|
||||
public function rollback()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return $this->_connection->rollBack();
|
||||
}
|
||||
|
||||
public function list_tables($like = NULL)
|
||||
{
|
||||
throw new Kohana_Exception('Database method :method is not supported by :class',
|
||||
|
@@ -14,7 +14,7 @@ class Kohana_Database_Query {
|
||||
protected $_type;
|
||||
|
||||
// Cache lifetime
|
||||
protected $_lifetime;
|
||||
protected $_lifetime = NULL;
|
||||
|
||||
// SQL statement
|
||||
protected $_sql;
|
||||
@@ -55,7 +55,7 @@ class Kohana_Database_Query {
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
return Kohana::exception_text($e);
|
||||
return Kohana_Exception::text($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class Kohana_Database_Query {
|
||||
/**
|
||||
* Enables the query to be cached for a specified amount of time.
|
||||
*
|
||||
* @param integer number of seconds to cache or null for default
|
||||
* @param integer number of seconds to cache
|
||||
* @return $this
|
||||
* @uses Kohana::$cache_life
|
||||
*/
|
||||
@@ -209,7 +209,7 @@ class Kohana_Database_Query {
|
||||
// Compile the SQL query
|
||||
$sql = $this->compile($db);
|
||||
|
||||
if ( ! empty($this->_lifetime) AND $this->_type === Database::SELECT)
|
||||
if ($this->_lifetime !== NULL AND $this->_type === Database::SELECT)
|
||||
{
|
||||
// Set the cache key based on the database instance name and SQL
|
||||
$cache_key = 'Database::query("'.$db.'", "'.$sql.'")';
|
||||
|
@@ -95,37 +95,31 @@ abstract class Kohana_Database_Query_Builder extends Database_Query {
|
||||
// BETWEEN always has exactly two arguments
|
||||
list($min, $max) = $value;
|
||||
|
||||
if (is_string($min) AND array_key_exists($min, $this->_parameters))
|
||||
if ((is_string($min) AND array_key_exists($min, $this->_parameters)) === FALSE)
|
||||
{
|
||||
// Set the parameter as the minimum
|
||||
$min = $this->_parameters[$min];
|
||||
// Quote the value, it is not a parameter
|
||||
$min = $db->quote($min);
|
||||
}
|
||||
|
||||
if (is_string($max) AND array_key_exists($max, $this->_parameters))
|
||||
if ((is_string($max) AND array_key_exists($max, $this->_parameters)) === FALSE)
|
||||
{
|
||||
// Set the parameter as the maximum
|
||||
$max = $this->_parameters[$max];
|
||||
// Quote the value, it is not a parameter
|
||||
$max = $db->quote($max);
|
||||
}
|
||||
|
||||
// Quote the min and max value
|
||||
$value = $db->quote($min).' AND '.$db->quote($max);
|
||||
$value = $min.' AND '.$max;
|
||||
}
|
||||
else
|
||||
elseif ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
|
||||
{
|
||||
if (is_string($value) AND array_key_exists($value, $this->_parameters))
|
||||
{
|
||||
// Set the parameter as the value
|
||||
$value = $this->_parameters[$value];
|
||||
}
|
||||
|
||||
// Quote the entire value normally
|
||||
// Quote the value, it is not a parameter
|
||||
$value = $db->quote($value);
|
||||
}
|
||||
|
||||
if ($column)
|
||||
{
|
||||
// Apply proper quoting to the column
|
||||
$column = $db->quote_identifier($column);
|
||||
$column = $db->quote_column($column);
|
||||
}
|
||||
|
||||
// Append the statement to the query
|
||||
@@ -155,15 +149,15 @@ abstract class Kohana_Database_Query_Builder extends Database_Query {
|
||||
list ($column, $value) = $group;
|
||||
|
||||
// Quote the column name
|
||||
$column = $db->quote_identifier($column);
|
||||
$column = $db->quote_column($column);
|
||||
|
||||
if (is_string($value) AND array_key_exists($value, $this->_parameters))
|
||||
if ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
|
||||
{
|
||||
// Use the parameter value
|
||||
$value = $this->_parameters[$value];
|
||||
// Quote the value, it is not a parameter
|
||||
$value = $db->quote($value);
|
||||
}
|
||||
|
||||
$set[$column] = $column.' = '.$db->quote($value);
|
||||
$set[$column] = $column.' = '.$value;
|
||||
}
|
||||
|
||||
return implode(', ', $set);
|
||||
@@ -192,7 +186,7 @@ abstract class Kohana_Database_Query_Builder extends Database_Query {
|
||||
if ($column)
|
||||
{
|
||||
// Quote the column, if it has a value
|
||||
$column = $db->quote_identifier($column);
|
||||
$column = $db->quote_column($column);
|
||||
}
|
||||
|
||||
$sort[] = trim($column.' '.$direction);
|
||||
|
@@ -73,7 +73,9 @@ class Kohana_Database_Query_Builder_Delete extends Database_Query_Builder_Where
|
||||
$query .= ' LIMIT '.$this->_limit;
|
||||
}
|
||||
|
||||
return $query;
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
@@ -83,6 +85,8 @@ class Kohana_Database_Query_Builder_Delete extends Database_Query_Builder_Where
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -122,7 +122,7 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
$query = 'INSERT INTO '.$db->quote_table($this->_table);
|
||||
|
||||
// Add the column names
|
||||
$query .= ' ('.implode(', ', array_map(array($db, 'quote_identifier'), $this->_columns)).') ';
|
||||
$query .= ' ('.implode(', ', array_map(array($db, 'quote_column'), $this->_columns)).') ';
|
||||
|
||||
if (is_array($this->_values))
|
||||
{
|
||||
@@ -132,16 +132,16 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
$groups = array();
|
||||
foreach ($this->_values as $group)
|
||||
{
|
||||
foreach ($group as $i => $value)
|
||||
foreach ($group as $offset => $value)
|
||||
{
|
||||
if (is_string($value) AND isset($this->_parameters[$value]))
|
||||
if ((is_string($value) AND array_key_exists($value, $this->_parameters)) === FALSE)
|
||||
{
|
||||
// Use the parameter value
|
||||
$group[$i] = $this->_parameters[$value];
|
||||
// Quote the value, it is not a parameter
|
||||
$group[$offset] = $db->quote($value);
|
||||
}
|
||||
}
|
||||
|
||||
$groups[] = '('.implode(', ', array_map($quote, $group)).')';
|
||||
$groups[] = '('.implode(', ', $group).')';
|
||||
}
|
||||
|
||||
// Add the values
|
||||
@@ -153,7 +153,9 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
$query .= (string) $this->_values;
|
||||
}
|
||||
|
||||
return $query;
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
@@ -165,6 +167,8 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,9 @@ class Kohana_Database_Query_Builder_Join extends Database_Query_Builder {
|
||||
// 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.
|
||||
@@ -49,11 +52,37 @@ class Kohana_Database_Query_Builder_Join extends Database_Query_Builder {
|
||||
*/
|
||||
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 column name
|
||||
* @param ...
|
||||
* @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.
|
||||
*
|
||||
@@ -72,27 +101,35 @@ class Kohana_Database_Query_Builder_Join extends Database_Query_Builder {
|
||||
}
|
||||
|
||||
// Quote the table name that is being joined
|
||||
$sql .= ' '.$db->quote_table($this->_table).' ON ';
|
||||
$sql .= ' '.$db->quote_table($this->_table);
|
||||
|
||||
$conditions = array();
|
||||
foreach ($this->_on as $condition)
|
||||
if ( ! empty($this->_using))
|
||||
{
|
||||
// Split the condition
|
||||
list($c1, $op, $c2) = $condition;
|
||||
|
||||
if ($op)
|
||||
// Quote and concat the columns
|
||||
$sql .= ' USING ('.implode(', ', array_map(array($db, 'quote_column'), $this->_using)).')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$conditions = array();
|
||||
foreach ($this->_on as $condition)
|
||||
{
|
||||
// Make the operator uppercase and spaced
|
||||
$op = ' '.strtoupper($op);
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Quote each of the identifiers used for the condition
|
||||
$conditions[] = $db->quote_identifier($c1).$op.' '.$db->quote_identifier($c2);
|
||||
// Concat the conditions "... AND ..."
|
||||
$sql .= ' ON ('.implode(' AND ', $conditions).')';
|
||||
}
|
||||
|
||||
// Concat the conditions "... AND ..."
|
||||
$sql .= '('.implode(' AND ', $conditions).')';
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,9 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
// OFFSET ...
|
||||
protected $_offset = NULL;
|
||||
|
||||
// UNION ...
|
||||
protected $_union = array();
|
||||
|
||||
// The last JOIN statement created
|
||||
protected $_last_join;
|
||||
|
||||
@@ -139,6 +142,22 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "USING ..." conditions for the last created JOIN statement.
|
||||
*
|
||||
* @param string column name
|
||||
* @param ...
|
||||
* @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.
|
||||
*
|
||||
@@ -266,6 +285,26 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
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 ..."
|
||||
*
|
||||
@@ -287,8 +326,8 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
*/
|
||||
public function compile(Database $db)
|
||||
{
|
||||
// Callback to quote identifiers
|
||||
$quote_ident = array($db, 'quote_identifier');
|
||||
// Callback to quote columns
|
||||
$quote_column = array($db, 'quote_column');
|
||||
|
||||
// Callback to quote tables
|
||||
$quote_table = array($db, 'quote_table');
|
||||
@@ -310,7 +349,7 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
else
|
||||
{
|
||||
// Select all columns
|
||||
$query .= implode(', ', array_unique(array_map($quote_ident, $this->_select)));
|
||||
$query .= implode(', ', array_unique(array_map($quote_column, $this->_select)));
|
||||
}
|
||||
|
||||
if ( ! empty($this->_from))
|
||||
@@ -334,7 +373,7 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
if ( ! empty($this->_group_by))
|
||||
{
|
||||
// Add sorting
|
||||
$query .= ' GROUP BY '.implode(', ', array_map($quote_ident, $this->_group_by));
|
||||
$query .= ' GROUP BY '.implode(', ', array_map($quote_column, $this->_group_by));
|
||||
}
|
||||
|
||||
if ( ! empty($this->_having))
|
||||
@@ -360,8 +399,22 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
@@ -372,7 +425,8 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
$this->_where =
|
||||
$this->_group_by =
|
||||
$this->_having =
|
||||
$this->_order_by = array();
|
||||
$this->_order_by =
|
||||
$this->_union = array();
|
||||
|
||||
$this->_distinct = FALSE;
|
||||
|
||||
@@ -382,7 +436,10 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Database_Query_Select
|
||||
|
||||
|
@@ -109,7 +109,9 @@ class Kohana_Database_Query_Builder_Update extends Database_Query_Builder_Where
|
||||
$query .= ' LIMIT '.$this->_limit;
|
||||
}
|
||||
|
||||
return $query;
|
||||
$this->_sql = $query;
|
||||
|
||||
return parent::compile($db);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
@@ -123,6 +125,8 @@ class Kohana_Database_Query_Builder_Update extends Database_Query_Builder_Where
|
||||
|
||||
$this->_parameters = array();
|
||||
|
||||
$this->_sql = NULL;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,7 @@ class Kohana_Database_Result_Cached extends Database_Result {
|
||||
public function current()
|
||||
{
|
||||
// Return an array of the row
|
||||
return $this->valid() ? $this->_result[$this->_current_row] : FALSE;
|
||||
return $this->valid() ? $this->_result[$this->_current_row] : NULL;
|
||||
}
|
||||
|
||||
} // End Database_Result_Cached
|
||||
|
@@ -0,0 +1,58 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Database Model base class.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Models
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Model_Database extends Model {
|
||||
|
||||
/**
|
||||
* Create a new model instance. A [Database] instance or configuration
|
||||
* group name can be passed to the model. If no database is defined, the
|
||||
* "default" database group will be used.
|
||||
*
|
||||
* $model = Model::factory($name);
|
||||
*
|
||||
* @param string model name
|
||||
* @param mixed Database instance object or string
|
||||
* @return Model
|
||||
*/
|
||||
public static function factory($name, $db = NULL)
|
||||
{
|
||||
// Add the model prefix
|
||||
$class = 'Model_'.$name;
|
||||
|
||||
return new $class($db);
|
||||
}
|
||||
|
||||
// Database instance
|
||||
protected $_db = 'default';
|
||||
|
||||
/**
|
||||
* Loads the database.
|
||||
*
|
||||
* $model = new Foo_Model($db);
|
||||
*
|
||||
* @param mixed Database instance object or string
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($db = NULL)
|
||||
{
|
||||
if ($db !== NULL)
|
||||
{
|
||||
// Set the database instance name
|
||||
$this->_db = $db;
|
||||
}
|
||||
|
||||
if (is_string($this->_db))
|
||||
{
|
||||
// Load the database
|
||||
$this->_db = Database::instance($this->_db);
|
||||
}
|
||||
}
|
||||
|
||||
} // End Model
|
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class Model_Database extends Kohana_Model_Database {}
|
Reference in New Issue
Block a user