summaryrefslogtreecommitdiff
path: root/kohana/libraries/drivers/Database
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2009-05-18 00:14:07 +0000
committerBharat Mediratta <bharat@menalto.com>2009-05-18 00:14:07 +0000
commitfd0c0a608a5de2b26c29d3c44a7929e5a3b2c042 (patch)
tree387f2628cae3580b7f09682de6e908d002c5fbb0 /kohana/libraries/drivers/Database
parent5a6aef9c23930b1de609c9914297e0f97bc49a11 (diff)
Updated kohana and modules/unit_test to upstream r4356
Diffstat (limited to 'kohana/libraries/drivers/Database')
-rw-r--r--kohana/libraries/drivers/Database/Mssql.php55
-rw-r--r--kohana/libraries/drivers/Database/Mysql.php107
-rw-r--r--kohana/libraries/drivers/Database/Mysqli.php39
-rw-r--r--kohana/libraries/drivers/Database/Pdosqlite.php37
-rw-r--r--kohana/libraries/drivers/Database/Pgsql.php99
5 files changed, 163 insertions, 174 deletions
diff --git a/kohana/libraries/drivers/Database/Mssql.php b/kohana/libraries/drivers/Database/Mssql.php
index 3e89faba..6947679a 100644
--- a/kohana/libraries/drivers/Database/Mssql.php
+++ b/kohana/libraries/drivers/Database/Mssql.php
@@ -89,19 +89,19 @@ class Database_Mssql_Driver extends Database_Driver
{
$hash = $this->query_hash($sql);
- if ( ! isset(self::$query_cache[$hash]))
+ if ( ! isset($this->query_cache[$hash]))
{
// Set the cached object
- self::$query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
+ $this->query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
}
else
{
// Rewind cached result
- self::$query_cache[$hash]->rewind();
+ $this->query_cache[$hash]->rewind();
}
// Return the cached query
- return self::$query_cache[$hash];
+ return $this->query_cache[$hash];
}
return new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
@@ -128,9 +128,22 @@ class Database_Mssql_Driver extends Database_Driver
if (!$this->db_config['escape'])
return $column;
- if (strtolower($column) == 'count(*)' OR $column == '*')
+ if ($column == '*')
return $column;
+ // This matches any functions we support to SELECT.
+ if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches))
+ {
+ if ( count($matches) == 3)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).')';
+ }
+ else if ( count($matches) == 5)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]);
+ }
+ }
+
// This matches any modifiers we support to SELECT.
if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column))
{
@@ -251,7 +264,7 @@ class Database_Mssql_Driver extends Database_Driver
return preg_replace($characters, $replace, $str);
}
- public function list_tables(Database $db)
+ public function list_tables()
{
$sql = 'SHOW TABLES FROM ['.$this->db_config['connection']['database'].']';
$result = $this->query($sql)->result(FALSE, MSSQL_ASSOC);
@@ -272,36 +285,22 @@ class Database_Mssql_Driver extends Database_Driver
public function list_fields($table)
{
- static $tables;
+ $result = array();
- if (empty($tables[$table]))
+ foreach ($this->field_data($table) as $row)
{
- foreach ($this->field_data($table) as $row)
- {
- // Make an associative array
- $tables[$table][$row->Field] = $this->sql_type($row->Type);
- }
+ // Make an associative array
+ $result[$row->Field] = $this->sql_type($row->Type);
}
- return $tables[$table];
+ return $result;
}
public function field_data($table)
{
- $columns = array();
-
- if ($query = MSSQL_query('SHOW COLUMNS FROM '.$this->escape_table($table), $this->link))
- {
- if (MSSQL_num_rows($query) > 0)
- {
- while ($row = MSSQL_fetch_object($query))
- {
- $columns[] = $row;
- }
- }
- }
+ $query = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table), $this->link);
- return $columns;
+ return $query->result_array(TRUE);
}
}
@@ -460,4 +459,4 @@ class Mssql_Result extends Database_Result {
return mssql_data_seek($this->result, $offset);
}
-} // End mssql_Result Class \ No newline at end of file
+} // End mssql_Result Class
diff --git a/kohana/libraries/drivers/Database/Mysql.php b/kohana/libraries/drivers/Database/Mysql.php
index 9315ed1f..978de459 100644
--- a/kohana/libraries/drivers/Database/Mysql.php
+++ b/kohana/libraries/drivers/Database/Mysql.php
@@ -22,12 +22,6 @@ class Database_Mysql_Driver extends Database_Driver {
protected $db_config;
/**
- * Performance caches.
- */
- private $tables_cache;
- private $fields_cache;
-
- /**
* Sets the config for the class.
*
* @param array database configuration
@@ -35,8 +29,6 @@ class Database_Mysql_Driver extends Database_Driver {
public function __construct($config)
{
$this->db_config = $config;
- $this->tables_cache = array();
- $this->fields_cache = array();
Kohana::log('debug', 'MySQL Database Driver Initialized');
}
@@ -85,23 +77,23 @@ class Database_Mysql_Driver extends Database_Driver {
public function query($sql)
{
// Only cache if it's turned on, and only cache if it's not a write statement
- if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql))
+ if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql))
{
$hash = $this->query_hash($sql);
- if ( ! isset(self::$query_cache[$hash]))
+ if ( ! isset($this->query_cache[$hash]))
{
// Set the cached object
- self::$query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
+ $this->query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
}
else
{
// Rewind cached result
- self::$query_cache[$hash]->rewind();
+ $this->query_cache[$hash]->rewind();
}
// Return the cached query
- return self::$query_cache[$hash];
+ return $this->query_cache[$hash];
}
return new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
@@ -136,9 +128,22 @@ class Database_Mysql_Driver extends Database_Driver {
if (!$this->db_config['escape'])
return $column;
- if (strtolower($column) == 'count(*)' OR $column == '*')
+ if ($column == '*')
return $column;
+ // This matches any functions we support to SELECT.
+ if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches))
+ {
+ if ( count($matches) == 3)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).')';
+ }
+ else if ( count($matches) == 5)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]);
+ }
+ }
+
// This matches any modifiers we support to SELECT.
if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column))
{
@@ -217,8 +222,8 @@ class Database_Mysql_Driver extends Database_Driver {
{
$froms[] = $this->escape_column($from);
}
- $sql .= "\nFROM ";
- $sql .= implode(', ', $froms);
+ $sql .= "\nFROM (";
+ $sql .= implode(', ', $froms).")";
}
if (count($database['join']) > 0)
@@ -273,11 +278,11 @@ class Database_Mysql_Driver extends Database_Driver {
return mysql_real_escape_string($str, $this->link);
}
- public function list_tables(Database $db)
+ public function list_tables()
{
- $tables =& $this->tables_cache;
+ $tables = array();
- if (empty($tables) AND $query = $db->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database'])))
+ if ($query = $this->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database'])))
{
foreach ($query->result(FALSE) as $row)
{
@@ -295,63 +300,37 @@ class Database_Mysql_Driver extends Database_Driver {
public function list_fields($table)
{
- $tables =& $this->fields_cache;
+ $result = NULL;
- if (empty($tables[$table]))
+ foreach ($this->field_data($table) as $row)
{
- foreach ($this->field_data($table) as $row)
+ // Make an associative array
+ $result[$row->Field] = $this->sql_type($row->Type);
+
+ if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment')
+ {
+ // For sequenced (AUTO_INCREMENT) tables
+ $result[$row->Field]['sequenced'] = TRUE;
+ }
+
+ if ($row->Null === 'YES')
{
- // Make an associative array
- $tables[$table][$row->Field] = $this->sql_type($row->Type);
-
- if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment')
- {
- // For sequenced (AUTO_INCREMENT) tables
- $tables[$table][$row->Field]['sequenced'] = TRUE;
- }
-
- if ($row->Null === 'YES')
- {
- // Set NULL status
- $tables[$table][$row->Field]['null'] = TRUE;
- }
+ // Set NULL status
+ $result[$row->Field]['null'] = TRUE;
}
}
- if (!isset($tables[$table]))
+ if (!isset($result))
throw new Kohana_Database_Exception('database.table_not_found', $table);
- return $tables[$table];
+ return $result;
}
public function field_data($table)
{
- $columns = array();
-
- if ($query = mysql_query('SHOW COLUMNS FROM '.$this->escape_table($table), $this->link))
- {
- if (mysql_num_rows($query))
- {
- while ($row = mysql_fetch_object($query))
- {
- $columns[] = $row;
- }
- }
- }
+ $result = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table));
- return $columns;
- }
-
- /**
- * Clears the internal query cache.
- *
- * @param string SQL query
- */
- public function clear_cache($sql = NULL)
- {
- parent::clear_cache($sql);
- $this->tables_cache = array();
- $this->fields_cache = array();
+ return $result->result_array(TRUE);
}
} // End Database_Mysql_Driver Class
@@ -514,4 +493,4 @@ class Mysql_Result extends Database_Result {
}
}
-} // End Mysql_Result Class \ No newline at end of file
+} // End Mysql_Result Class
diff --git a/kohana/libraries/drivers/Database/Mysqli.php b/kohana/libraries/drivers/Database/Mysqli.php
index 13a81281..f15e4283 100644
--- a/kohana/libraries/drivers/Database/Mysqli.php
+++ b/kohana/libraries/drivers/Database/Mysqli.php
@@ -68,23 +68,23 @@ class Database_Mysqli_Driver extends Database_Mysql_Driver {
public function query($sql)
{
// Only cache if it's turned on, and only cache if it's not a write statement
- if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql))
+ if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql))
{
$hash = $this->query_hash($sql);
- if ( ! isset(self::$query_cache[$hash]))
+ if ( ! isset($this->query_cache[$hash]))
{
// Set the cached object
- self::$query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql);
+ $this->query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql);
}
else
{
// Rewind cached result
- self::$query_cache[$hash]->rewind();
+ $this->query_cache[$hash]->rewind();
}
// Return the cached query
- return self::$query_cache[$hash];
+ return $this->query_cache[$hash];
}
return new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql);
@@ -111,22 +111,6 @@ class Database_Mysqli_Driver extends Database_Mysql_Driver {
return $this->link->error;
}
- public function field_data($table)
- {
- $columns = array();
- $query = $this->link->query('SHOW COLUMNS FROM '.$this->escape_table($table));
-
- if (is_object($query))
- {
- while ($row = $query->fetch_object())
- {
- $columns[] = $row;
- }
- }
-
- return $columns;
- }
-
} // End Database_Mysqli_Driver Class
/**
@@ -299,12 +283,15 @@ class Kohana_Mysqli_Result extends Database_Result {
public function seek($offset)
{
- if ( ! $this->offsetExists($offset))
- return FALSE;
+ if ($this->offsetExists($offset) AND $this->result->data_seek($offset))
+ {
+ // Set the current row to the offset
+ $this->current_row = $offset;
- $this->result->data_seek($offset);
+ return TRUE;
+ }
- return TRUE;
+ return FALSE;
}
public function offsetGet($offset)
@@ -368,4 +355,4 @@ class Kohana_Mysqli_Statement {
$this->stmt->execute();
return $this->stmt;
}
-} \ No newline at end of file
+}
diff --git a/kohana/libraries/drivers/Database/Pdosqlite.php b/kohana/libraries/drivers/Database/Pdosqlite.php
index 5a512877..c2d1bb21 100644
--- a/kohana/libraries/drivers/Database/Pdosqlite.php
+++ b/kohana/libraries/drivers/Database/Pdosqlite.php
@@ -43,7 +43,7 @@ class Database_Pdosqlite_Driver extends Database_Driver {
array(PDO::ATTR_PERSISTENT => $this->db_config['persistent']));
$this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
- $this->link->query('PRAGMA count_changes=1;');
+ //$this->link->query('PRAGMA count_changes=1;');
if ($charset = $this->db_config['character_set'])
{
@@ -63,7 +63,7 @@ class Database_Pdosqlite_Driver extends Database_Driver {
public function query($sql)
{
- try
+ try
{
$sth = $this->link->prepare($sql);
}
@@ -92,9 +92,22 @@ class Database_Pdosqlite_Driver extends Database_Driver {
if ( ! $this->db_config['escape'])
return $column;
- if (strtolower($column) == 'count(*)' OR $column == '*')
+ if ($column == '*')
return $column;
+ // This matches any functions we support to SELECT.
+ if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches))
+ {
+ if ( count($matches) == 3)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).')';
+ }
+ else if ( count($matches) == 5)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]);
+ }
+ }
+
// This matches any modifiers we support to SELECT.
if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column))
{
@@ -205,12 +218,12 @@ class Database_Pdosqlite_Driver extends Database_Driver {
return $res;
}
- public function list_tables(Database $db)
+ public function list_tables()
{
$sql = "SELECT `name` FROM `sqlite_master` WHERE `type`='table' ORDER BY `name`;";
try
{
- $result = $db->query($sql)->result(FALSE, PDO::FETCH_ASSOC);
+ $result = $this->query($sql)->result(FALSE, PDO::FETCH_ASSOC);
$tables = array();
foreach ($result as $row)
{
@@ -298,14 +311,12 @@ class Pdosqlite_Result extends Database_Result {
{
if (is_object($result) OR $result = $link->prepare($sql))
{
- // run the query
- try
+ // run the query. Return true if success, false otherwise
+ if( ! $result->execute())
{
- $result->execute();
- }
- catch (PDOException $e)
- {
- throw new Kohana_Database_Exception('database.error', $e->getMessage());
+ // Throw Kohana Exception with error message. See PDOStatement errorInfo() method
+ $arr_infos = $result->errorInfo();
+ throw new Kohana_Database_Exception('database.error', $arr_infos[2]);
}
if (preg_match('/^SELECT|PRAGMA|EXPLAIN/i', $sql))
@@ -320,6 +331,8 @@ class Pdosqlite_Result extends Database_Result {
elseif (preg_match('/^DELETE|INSERT|UPDATE/i', $sql))
{
$this->insert_id = $link->lastInsertId();
+
+ $this->total_rows = $result->rowCount();
}
}
else
diff --git a/kohana/libraries/drivers/Database/Pgsql.php b/kohana/libraries/drivers/Database/Pgsql.php
index 62a33ad6..c8a7d819 100644
--- a/kohana/libraries/drivers/Database/Pgsql.php
+++ b/kohana/libraries/drivers/Database/Pgsql.php
@@ -68,18 +68,18 @@ class Database_Pgsql_Driver extends Database_Driver {
{
$hash = $this->query_hash($sql);
- if ( ! isset(self::$query_cache[$hash]))
+ if ( ! isset($this->query_cache[$hash]))
{
// Set the cached object
- self::$query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql);
+ $this->query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql);
}
else
{
// Rewind cached result
- self::$query_cache[$hash]->rewind();
+ $this->query_cache[$hash]->rewind();
}
- return self::$query_cache[$hash];
+ return $this->query_cache[$hash];
}
// Suppress warning triggered when a database error occurs (e.g., a constraint violation)
@@ -104,9 +104,22 @@ class Database_Pgsql_Driver extends Database_Driver {
if (!$this->db_config['escape'])
return $column;
- if (strtolower($column) == 'count(*)' OR $column == '*')
+ if ($column == '*')
return $column;
+ // This matches any functions we support to SELECT.
+ if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches))
+ {
+ if ( count($matches) == 3)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).')';
+ }
+ else if ( count($matches) == 5)
+ {
+ return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]);
+ }
+ }
+
// This matches any modifiers we support to SELECT.
if ( ! preg_match('/\b(?:all|distinct)\s/i', $column))
{
@@ -147,14 +160,14 @@ class Database_Pgsql_Driver extends Database_Driver {
{
$prefix = ($num_regexs == 0) ? '' : $type;
- return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\'';
+ return $prefix.' '.$this->escape_column($field).' ~* \''.$this->escape_str($match).'\'';
}
public function notregex($field, $match, $type, $num_regexs)
{
$prefix = $num_regexs == 0 ? '' : $type;
- return $prefix.' '.$this->escape_column($field).' NOT REGEXP \''.$this->escape_str($match) . '\'';
+ return $prefix.' '.$this->escape_column($field).' !~* \''.$this->escape_str($match) . '\'';
}
public function limit($limit, $offset = 0)
@@ -225,10 +238,10 @@ class Database_Pgsql_Driver extends Database_Driver {
return pg_escape_string($this->link, $str);
}
- public function list_tables(Database $db)
+ public function list_tables()
{
$sql = 'SELECT table_schema || \'.\' || table_name FROM information_schema.tables WHERE table_schema NOT IN (\'pg_catalog\', \'information_schema\')';
- $result = $db->query($sql)->result(FALSE, PGSQL_ASSOC);
+ $result = $this->query($sql)->result(FALSE, PGSQL_ASSOC);
$retval = array();
foreach ($result as $row)
@@ -246,39 +259,34 @@ class Database_Pgsql_Driver extends Database_Driver {
public function list_fields($table)
{
- static $tables;
+ $result = NULL;
- if (empty($tables[$table]))
+ foreach ($this->field_data($table) as $row)
{
- foreach ($this->field_data($table) as $row)
+ // Make an associative array
+ $result[$row->column_name] = $this->sql_type($row->data_type);
+
+ if (!strncmp($row->column_default, 'nextval(', 8))
+ {
+ $result[$row->column_name]['sequenced'] = TRUE;
+ }
+
+ if ($row->is_nullable === 'YES')
{
- // Make an associative array
- $tables[$table][$row->column_name] = $this->sql_type($row->data_type);
-
- if (!strncmp($row->column_default, 'nextval(', 8))
- {
- $tables[$table][$row->column_name]['sequenced'] = TRUE;
- }
-
- if ($row->is_nullable === 'YES')
- {
- $tables[$table][$row->column_name]['null'] = TRUE;
- }
+ $result[$row->column_name]['null'] = TRUE;
}
}
- if (!isset($tables[$table]))
+ if (!isset($result))
throw new Kohana_Database_Exception('database.table_not_found', $table);
- return $tables[$table];
+ return $result;
}
public function field_data($table)
{
- $columns = array();
-
// http://www.postgresql.org/docs/8.3/static/infoschema-columns.html
- $result = pg_query($this->link, '
+ $result = $this->query('
SELECT column_name, column_default, is_nullable, data_type, udt_name,
character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale
FROM information_schema.columns
@@ -286,15 +294,7 @@ class Database_Pgsql_Driver extends Database_Driver {
ORDER BY ordinal_position
');
- if ($result)
- {
- while ($row = pg_fetch_object($result))
- {
- $columns[] = $row;
- }
- }
-
- return $columns;
+ return $result->result_array(TRUE);
}
} // End Database_Pgsql_Driver Class
@@ -318,6 +318,7 @@ class Pgsql_Result extends Database_Result {
*/
public function __construct($result, $link, $object = TRUE, $sql)
{
+ $this->link = $link;
$this->result = $result;
// If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query
@@ -418,9 +419,14 @@ class Pgsql_Result extends Database_Result {
}
}
- while ($row = $fetch($this->result, NULL, $type))
+ if ($this->total_rows)
{
- $rows[] = $row;
+ pg_result_seek($this->result, 0);
+
+ while ($row = $fetch($this->result, NULL, $type))
+ {
+ $rows[] = $row;
+ }
}
return $rows;
@@ -450,10 +456,15 @@ class Pgsql_Result extends Database_Result {
public function seek($offset)
{
- if ( ! $this->offsetExists($offset))
- return FALSE;
+ if ($this->offsetExists($offset) AND pg_result_seek($this->result, $offset))
+ {
+ // Set the current row to the offset
+ $this->current_row = $offset;
- return pg_result_seek($this->result, $offset);
+ return TRUE;
+ }
+
+ return FALSE;
}
public function list_fields()
@@ -524,4 +535,4 @@ class Kohana_Pgsql_Statement {
{
return $this;
}
-} \ No newline at end of file
+}