diff options
author | Bharat Mediratta <bharat@menalto.com> | 2009-05-18 00:14:07 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2009-05-18 00:14:07 +0000 |
commit | fd0c0a608a5de2b26c29d3c44a7929e5a3b2c042 (patch) | |
tree | 387f2628cae3580b7f09682de6e908d002c5fbb0 /kohana/libraries/drivers/Database | |
parent | 5a6aef9c23930b1de609c9914297e0f97bc49a11 (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.php | 55 | ||||
-rw-r--r-- | kohana/libraries/drivers/Database/Mysql.php | 107 | ||||
-rw-r--r-- | kohana/libraries/drivers/Database/Mysqli.php | 39 | ||||
-rw-r--r-- | kohana/libraries/drivers/Database/Pdosqlite.php | 37 | ||||
-rw-r--r-- | kohana/libraries/drivers/Database/Pgsql.php | 99 |
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 +} |