diff --git a/classes/db_pdo.php b/classes/db_pdo.php index 51a26e1..58111dd 100644 --- a/classes/db_pdo.php +++ b/classes/db_pdo.php @@ -23,40 +23,23 @@ */ abstract class DB_PDO extends PDO { - /** - * Reference to the last executed query - * - * @var mixed - */ + // Reference to the last executed query protected $statement; - /** - * Character to escape identifiers - * - * @var string - */ + // Character to escape identifiers protected $escape_char = '"'; - /** - * Reference to sql sub class - * - * @var Object - */ + // Reference to sql sub class public $sql; - /** - * Reference to util sub class - * - * @var Object - */ + // Reference to util sub class public $util; - /** - * Last query executed - * - * @var string - */ + // Last query executed public $last_query; + + // Prefix to apply to table namesa + public $table_prefix = ''; /** * PDO constructor wrapper @@ -203,6 +186,68 @@ abstract class DB_PDO extends PDO { echo "Error:
{$i1}:{$i2}\n{$i3}
"; } + // -------------------------------------------------------------------------- + + /** + * Quote database table name, and set prefix + * + * @param mixed $table + * @return string + */ + public function quote_table($table) + { + // An array is only passed if it's a table with alias + if (is_array($table)) + { + $table =& $table[0]; + } + + // If there isn't a prefix set, just quote the table name + if (empty($this->table_prefix)) + { + return $this->quote_ident($table); + } + + // Split indentifier by period, will split into: + // database.schema.table OR + // schema.table OR + // database.table OR + // table + $idents = (array) explode('.', $table); + $segments = count($idents); + + // Reference the last item in the split string + $last =& $idents[$segments - 1]; + + // Quote the last item + $last = $this->_prefix($last); + + // Rejoin + $table = implode('.', $idents); + + // Finally, quote the table + return $this->quote_ident($table); + } + + // -------------------------------------------------------------------------- + + /** + * Sets the table prefix on the passed string + * + * @param string $str + * @return string + */ + protected function _prefix($str) + { + // Don't prefix an already prefixed table + if (strpos($str, $this->table_prefix) !== FALSE) + { + return $str; + } + + return $this->table_prefix.$str; + } + // -------------------------------------------------------------------------- /** @@ -215,7 +260,7 @@ abstract class DB_PDO extends PDO { { if (is_array($ident)) { - return array_map(array($this, 'quote_ident'), $ident); + return array_map(array($this, __METHOD__), $ident); } // Handle comma-separated identifiers @@ -223,7 +268,7 @@ abstract class DB_PDO extends PDO { { $parts = explode(',', $ident); $parts = array_map('mb_trim', $parts); - $parts = array_map(array($this, 'quote_ident'), $parts); + $parts = array_map(array($this, __METHOD__), $parts); $ident = implode(',', $parts); } @@ -471,7 +516,6 @@ abstract class DB_PDO extends PDO { * Empty the passed table * * @param string $table - * * @return void */ abstract public function truncate($table); diff --git a/classes/db_util.php b/classes/db_util.php index fd3cc4c..7102d5b 100644 --- a/classes/db_util.php +++ b/classes/db_util.php @@ -33,7 +33,7 @@ abstract class DB_Util { */ public function __construct(&$conn) { - $this->conn =& $conn; + $this->conn = $conn; } // -------------------------------------------------------------------------- diff --git a/classes/query_builder.php b/classes/query_builder.php index 6e060e1..8653bfc 100644 --- a/classes/query_builder.php +++ b/classes/query_builder.php @@ -130,6 +130,13 @@ class Query_Builder { { throw new BadConnectionException('Connection failed, invalid arguments', 2); } + + // Set the table prefix, if it exists + if (isset($params->prefix)) + { + $this->table_prefix = $params->prefix; + $this->db->table_prefix = $params->prefix; + } // Set the connection name property, if applicable if (isset($params->name)) @@ -170,12 +177,6 @@ class Query_Builder { throw new BadDBDriverException('Database driver does not exist, or is not supported'); } - // Set the table prefix, if it exists - if (isset($params->prefix)) - { - $this->table_prefix = $params->prefix; - } - // Create the dsn for the database to connect to switch($dbtype) { @@ -220,7 +221,7 @@ class Query_Builder { { // Split fields by comma $fields_array = explode(",", $fields); - $fields_array = array_map('trim', $fields_array); + $fields_array = array_map('mb_trim', $fields_array); // Split on 'As' foreach ($fields_array as $key => $field) @@ -228,7 +229,7 @@ class Query_Builder { if (stripos($field, 'as') !== FALSE) { $fields_array[$key] = preg_split('` as `i', $field); - $fields_array[$key] = array_map('trim', $fields_array[$key]); + $fields_array[$key] = array_map('mb_trim', $fields_array[$key]); } } @@ -357,17 +358,18 @@ class Query_Builder { /** * Specify the database table to select from * - * @param string $dbname + * @param string $tblname * @return $this */ - public function from($dbname) + public function from($tblname) { // Split identifiers on spaces - $ident_array = explode(' ', trim($dbname)); - $ident_array = array_map('trim', $ident_array); + $ident_array = explode(' ', trim($tblname)); + $ident_array = array_map('mb_trim', $ident_array); // Quote the identifiers - $ident_array = array_map(array($this->db, 'quote_ident'), $ident_array); + $ident_array[0] = $this->db->quote_table($ident_array[0]); + $ident_array = $this->db->quote_ident($ident_array); // Paste it back together $this->from_string = implode(' ', $ident_array); @@ -788,7 +790,11 @@ class Query_Builder { */ public function join($table, $condition, $type='') { - $table = implode(' ', array_map(array($this->db, 'quote_ident'), explode(' ', trim($table)))); + // Prefix and quote table name + $table = explode(' ', mb_trim($table)); + $table[0] = $this->db->quote_table($table[0]); + $table = $this->db->quote_ident($table); + $table = implode(' ', $table); // Parse out the join condition $parts = $this->parser->parse_join($condition); @@ -1038,7 +1044,7 @@ class Query_Builder { */ public function count_all($table) { - $sql = 'SELECT * FROM '.$this->quote_ident($table); + $sql = 'SELECT * FROM '.$this->quote_table($table); $res = $this->query($sql); return (int) count($res->fetchAll()); } @@ -1210,7 +1216,7 @@ class Query_Builder { * @param bool * @resturn string */ - protected function _get_compile($type, $table, $reset) + private function _get_compile($type, $table, $reset) { $sql = $this->_compile($type, $table); @@ -1312,7 +1318,7 @@ class Query_Builder { { $sql = ''; - $table = $this->quote_ident($table); + $table = $this->quote_table($table); switch($type) { @@ -1345,7 +1351,7 @@ class Query_Builder { break; } - // Set the where string + // Set the where clause if ( ! empty($this->query_map)) { foreach($this->query_map as $q) @@ -1354,25 +1360,19 @@ class Query_Builder { } } - // Set the group_by string + // Set the group_by clause if ( ! empty($this->group_string)) { $sql .= $this->group_string; } - // Set the order_by string + // Set the order_by clause if ( ! empty($this->order_string)) { $sql .= $this->order_string; } - // Set the limit via the class variables - if (isset($this->limit) && is_numeric($this->limit)) - { - $sql = $this->sql->limit($sql, $this->limit, $this->offset); - } - - // Set the having string + // Set the having clause if ( ! empty($this->having_map)) { foreach($this->having_map as $h) @@ -1380,6 +1380,12 @@ class Query_Builder { $sql .= $h['conjunction'] . $h['string']; } } + + // Set the limit via the class variables + if (isset($this->limit) && is_numeric($this->limit)) + { + $sql = $this->sql->limit($sql, $this->limit, $this->offset); + } // Add the query to the list of executed queries $this->queries[] = $sql; @@ -1387,7 +1393,7 @@ class Query_Builder { // Set the last query to get rowcounts properly $this->db->last_query = $sql; - //echo $sql . '
'; + // echo $sql . '
'; return $sql; } diff --git a/drivers/firebird/firebird_driver.php b/drivers/firebird/firebird_driver.php index 5a7c359..33a8701 100644 --- a/drivers/firebird/firebird_driver.php +++ b/drivers/firebird/firebird_driver.php @@ -106,7 +106,7 @@ class Firebird extends DB_PDO { */ public function truncate($table) { - // Firebird lacka a truncate command + // Firebird lacks a truncate command $sql = 'DELETE FROM "'.$table.'"'; $this->statement = $this->query($sql); } diff --git a/tests/core/db_qb_test.php b/tests/core/db_qb_test.php index f0c5479..015f398 100644 --- a/tests/core/db_qb_test.php +++ b/tests/core/db_qb_test.php @@ -31,6 +31,17 @@ abstract class QBTest extends UnitTestCase { $this->assertIsA($query, 'PDOStatement'); } + // -------------------------------------------------------------------------- + + public function TestPrefixGet() + { + if (empty($this->db)) return; + + $query = $this->db->from('test')->get(); + + $this->assertIsA($query, 'PDOStatement'); + } + // -------------------------------------------------------------------------- public function TestGetWNumRows() @@ -153,7 +164,7 @@ abstract class QBTest extends UnitTestCase { if (empty($this->db)) return; $query = $this->db->select_max('id', 'di') - ->get('create_test'); + ->get('test'); $this->assertIsA($query, 'PDOStatement'); } @@ -367,8 +378,8 @@ abstract class QBTest extends UnitTestCase { { if (empty($this->db)) return; - $query = $this->db->from('create_test') - ->join('create_join cj', 'cj.id = create_test.id') + $query = $this->db->from('create_test ct') + ->join('join cj', 'cj.id = ct.id') ->get(); $this->assertIsA($query, 'PDOStatement'); @@ -385,7 +396,7 @@ abstract class QBTest extends UnitTestCase { $query = $this->db->set('id', 4) ->set('key', 4) ->set('val', 5) - ->insert('create_test'); + ->insert('test'); $this->assertIsA($query, 'PDOStatement'); } @@ -434,7 +445,7 @@ abstract class QBTest extends UnitTestCase { ->set('id', 4) ->set('key', 'gogle') ->set('val', 'non-word') - ->update('create_test'); + ->update('test'); $this->assertIsA($query, 'PDOStatement'); } @@ -457,7 +468,7 @@ abstract class QBTest extends UnitTestCase { public function TestCountAll() { if (empty($this->db)) return; - $query = $this->db->count_all('create_test'); + $query = $this->db->count_all('test'); $this->assertTrue(is_numeric($query)); } @@ -467,7 +478,7 @@ abstract class QBTest extends UnitTestCase { public function TestCountAllResults() { if (empty($this->db)) return; - $query = $this->db->count_all_results('create_test'); + $query = $this->db->count_all_results('test'); $this->assertTrue(is_numeric($query)); } @@ -479,7 +490,7 @@ abstract class QBTest extends UnitTestCase { if (empty($this->db)) return; $query = $this->db->select('id, key as k, val') - ->from('create_test') + ->from('test') ->where(' id ', 1) ->or_where('key >', 0) ->limit(2, 1) diff --git a/tests/databases/firebird/firebird-qb.php b/tests/databases/firebird/firebird-qb.php index a202ab0..4f5f6ab 100644 --- a/tests/databases/firebird/firebird-qb.php +++ b/tests/databases/firebird/firebird-qb.php @@ -31,6 +31,7 @@ class FirebirdQBTest extends QBTest { $params->host = 'localhost'; $params->user = 'sysdba'; $params->pass = 'masterkey'; + $params->prefix = 'create_'; $this->db = new Query_Builder($params); // echo '
Firebird Queries
'; diff --git a/tests/databases/mysql/mysql-qb.php b/tests/databases/mysql/mysql-qb.php index f9c7c2b..815fd9d 100644 --- a/tests/databases/mysql/mysql-qb.php +++ b/tests/databases/mysql/mysql-qb.php @@ -25,6 +25,7 @@ class MySQLQBTest extends QBTest { $params = json_decode(file_get_contents(QBASE_DIR . "test_config.json")); $params = $params->mysql; $params->type = "MySQL"; + $params->prefix = "create_"; $this->db = new Query_Builder($params); @@ -38,7 +39,8 @@ class MySQLQBTest extends QBTest { 'database' => 'test', 'user' => 'root', 'pass' => NULL, - 'type' => 'mysql' + 'type' => 'mysql', + 'prefix' => 'create_' ); $this->db = new Query_Builder($params); diff --git a/tests/databases/pgsql/pgsql-qb.php b/tests/databases/pgsql/pgsql-qb.php index 4619898..78367c4 100644 --- a/tests/databases/pgsql/pgsql-qb.php +++ b/tests/databases/pgsql/pgsql-qb.php @@ -24,6 +24,7 @@ class PgSQLQBTest extends QBTest { $params = json_decode(file_get_contents(QBASE_DIR . "test_config.json")); $params = $params->pgsql; $params->type = "pgsql"; + $params->prefix = 'create_'; $this->db = new Query_Builder($params); @@ -38,7 +39,8 @@ class PgSQLQBTest extends QBTest { 'database' => 'test', 'user' => 'postgres', 'pass' => '', - 'type' => 'pgsql' + 'type' => 'pgsql', + 'prefix' => 'create' ); $this->db = new Query_Builder($params); diff --git a/tests/databases/sqlite/sqlite-qb.php b/tests/databases/sqlite/sqlite-qb.php index 81b853f..0dac9b7 100644 --- a/tests/databases/sqlite/sqlite-qb.php +++ b/tests/databases/sqlite/sqlite-qb.php @@ -26,6 +26,7 @@ $params->type = 'sqlite'; $params->file = $path; $params->host = 'localhost'; + $params->prefix = 'create_'; $this->db = new Query_Builder($params); // echo '
SQLite Queries
'; diff --git a/tests/db_files/FB_TEST_DB.FDB b/tests/db_files/FB_TEST_DB.FDB index c3affdf..7c38340 100644 Binary files a/tests/db_files/FB_TEST_DB.FDB and b/tests/db_files/FB_TEST_DB.FDB differ