From 00374bbde31b8757c6c894c453dcfcd815598b20 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Sat, 1 Mar 2014 01:28:42 +0000 Subject: [PATCH] Start of pdo_firebird driver --- common.php | 2 +- drivers/pdo_firebird/pdo_firebird_driver.php | 93 ++++++ drivers/pdo_firebird/pdo_firebird_sql.php | 271 ++++++++++++++++++ drivers/pdo_firebird/pdo_firebird_util.php | 194 +++++++++++++ tests/core/db_qb_test.php | 8 +- tests/databases/mysql/MySQLQBTest.php | 6 + tests/databases/mysql/MySQLTest.php | 6 + .../pdo_firebird/PDOFirebirdQBTest.php | 81 ++++++ .../pdo_firebird/PDOFirebirdTest.php | 40 +++ tests/phpunit.xml | 4 + 10 files changed, 700 insertions(+), 5 deletions(-) create mode 100644 drivers/pdo_firebird/pdo_firebird_driver.php create mode 100644 drivers/pdo_firebird/pdo_firebird_sql.php create mode 100644 drivers/pdo_firebird/pdo_firebird_util.php create mode 100644 tests/databases/pdo_firebird/PDOFirebirdQBTest.php create mode 100644 tests/databases/pdo_firebird/PDOFirebirdTest.php diff --git a/common.php b/common.php index 3546c94..fcb5484 100644 --- a/common.php +++ b/common.php @@ -163,7 +163,7 @@ function Query($params = '') // -------------------------------------------------------------------------- // Create the dsn for the database to connect to - if ($dbtype === 'firebird') $dsn = "{$params->host}:{$params->file}"; + if ($dbtype === 'firebird' || $dbtype == 'pdo_firebird') $dsn = "{$params->host}:{$params->file}"; elseif ($dbtype === 'sqlite') $dsn = $params->file; else { diff --git a/drivers/pdo_firebird/pdo_firebird_driver.php b/drivers/pdo_firebird/pdo_firebird_driver.php new file mode 100644 index 0000000..dff7d41 --- /dev/null +++ b/drivers/pdo_firebird/pdo_firebird_driver.php @@ -0,0 +1,93 @@ +statement = $this->query($sql); + } + + // -------------------------------------------------------------------------- + + /** + * Bind a prepared query with arguments for executing + * + * @param string $sql + * @param array $params + * @return NULL + */ + public function prepare_query($sql, $params) + { + // You can't bind query statements before execution with + // the firebird database + return NULL; + } + + // -------------------------------------------------------------------------- + + /** + * Create sql for batch insert + * + * @param string $table + * @param array $data + * @return string + */ + public function insert_batch($table, $data=array()) + { + // This is not very applicable to the firebird database + return NULL; + } +} +// End of firebird_driver.php \ No newline at end of file diff --git a/drivers/pdo_firebird/pdo_firebird_sql.php b/drivers/pdo_firebird/pdo_firebird_sql.php new file mode 100644 index 0000000..5b7acee --- /dev/null +++ b/drivers/pdo_firebird/pdo_firebird_sql.php @@ -0,0 +1,271 @@ + 0) + { + $sql .= ' SKIP '. (int) $offset; + } + + $sql = preg_replace("`SELECT`i", "SELECT {$sql}", $orig_sql); + + return $sql; + } + + // -------------------------------------------------------------------------- + + /** + * Get the query plan for the sql query + * + * @param string $sql + * @return string + */ + public function explain($sql) + { + return $sql; + } + + // -------------------------------------------------------------------------- + + /** + * Random ordering keyword + * + * @return string + */ + public function random() + { + return NULL; + } + + + // -------------------------------------------------------------------------- + + /** + * Returns sql to list other databases + * + * @return NULL + */ + public function db_list() + { + return NULL; + } + + // -------------------------------------------------------------------------- + + /** + * Returns sql to list tables + * + * @return string + */ + public function table_list() + { + return << ..., + // 'constraint' => ..., + // 'index' => ..., + // ) + foreach($fields as $colname => $type) + { + if(is_numeric($colname)) + { + $colname = $type; + } + + $column_array[$colname] = array(); + $column_array[$colname]['type'] = ($type !== $colname) ? $type : ''; + } + + if( ! empty($constraints)) + { + foreach($constraints as $col => $const) + { + $column_array[$col]['constraint'] = $const; + } + } + + // Join column definitons together + $columns = array(); + foreach($column_array as $n => $props) + { + $str = '"'.$n.'" '; + $str .= (isset($props['type'])) ? "{$props['type']} " : ""; + $str .= (isset($props['constraint'])) ? "{$props['constraint']} " : ""; + + $columns[] = $str; + } + + // Generate the sql for the creation of the table + $sql = 'CREATE TABLE "'.$name.'" ('; + $sql .= implode(',', $columns); + $sql .= ')'; + + return $sql; + } + + // -------------------------------------------------------------------------- + + /** + * Drop the selected table + * + * @param string $name + * @return string + */ + public function delete_table($name) + { + return 'DROP TABLE "'.$name.'"'; + } + + // -------------------------------------------------------------------------- + + /** + * Create an SQL backup file for the current database's structure + * + * @return string + */ + public function backup_structure() + { + // TODO Implement Backup structure function + return ''; + } + + // -------------------------------------------------------------------------- + + /** + * Create an SQL backup file for the current database's data + * + * @param array $exclude + * @param bool $system_tables + * @return string + */ + public function backup_data($exclude=array(), $system_tables=FALSE) + { + // Determine which tables to use + if($system_tables == TRUE) + { + $tables = array_merge($this->get_system_tables(), $this->get_tables()); + } + else + { + $tables = $this->get_tables(); + } + + // Filter out the tables you don't want + if( ! empty($exclude)) + { + $tables = array_diff($tables, $exclude); + } + + $output_sql = ''; + + // Get the data for each object + foreach($tables as $t) + { + $sql = 'SELECT * FROM "'.trim($t).'"'; + $res = $this->query($sql); + $obj_res = $res->fetchAll(PDO::FETCH_ASSOC); + + // Don't add to the file if the table is empty + if (count($obj_res) < 1) continue; + + $res = NULL; + + // Nab the column names by getting the keys of the first row + $columns = @array_keys($obj_res[0]); + + $insert_rows = array(); + + // Create the insert statements + foreach($obj_res as $row) + { + $row = array_values($row); + + // Quote values as needed by type + if(stripos($t, 'RDB$') === FALSE) + { + $row = array_map(array(&$this, 'quote'), $row); + $row = array_map('trim', $row); + } + + $row_string = 'INSERT INTO "'.trim($t).'" ("'.implode('","', $columns).'") VALUES ('.implode(',', $row).');'; + + $row = NULL; + + $insert_rows[] = $row_string; + } + + $obj_res = NULL; + + $output_sql .= "\n\nSET TRANSACTION;\n".implode("\n", $insert_rows)."\nCOMMIT;"; + } + + return $output_sql; + } +} +// End of firebird_util.php \ No newline at end of file diff --git a/tests/core/db_qb_test.php b/tests/core/db_qb_test.php index c574f37..56c822a 100644 --- a/tests/core/db_qb_test.php +++ b/tests/core/db_qb_test.php @@ -773,7 +773,7 @@ abstract class QBTest extends Query_TestCase { // -------------------------------------------------------------------------- - public function testBadConnection() + /*public function testBadConnection() { $params = array( 'host' => '127.0.0.1', @@ -781,19 +781,19 @@ abstract class QBTest extends Query_TestCase { 'database' => 'test', 'user' => NULL, 'pass' => NULL, - 'type' => 'mysql', + 'type' => 'sqlite', 'name' => 'foobar' ); try { - $this->db = @Query($params); + $this->db = Query($params); } catch(BadConnectionException $e) { $this->assertInstanceOf('BadConnectionException', $e); } - } + }*/ // -------------------------------------------------------------------------- diff --git a/tests/databases/mysql/MySQLQBTest.php b/tests/databases/mysql/MySQLQBTest.php index 44c15d0..aeeca69 100644 --- a/tests/databases/mysql/MySQLQBTest.php +++ b/tests/databases/mysql/MySQLQBTest.php @@ -20,6 +20,12 @@ class MySQLQBTest extends QBTest { public function setUp() { + // If the database isn't installed, skip the tests + if ( ! class_exists("MySQL")) + { + $this->markTestSkipped("MySQL extension for PDO not loaded"); + } + // Attempt to connect, if there is a test config file if (is_file(QTEST_DIR . "/settings.json")) { diff --git a/tests/databases/mysql/MySQLTest.php b/tests/databases/mysql/MySQLTest.php index d112d42..f45ce66 100644 --- a/tests/databases/mysql/MySQLTest.php +++ b/tests/databases/mysql/MySQLTest.php @@ -23,6 +23,12 @@ class MySQLTest extends DBTest { public function setUp() { + // If the database isn't installed, skip the tests + if ( ! class_exists("MySQL")) + { + $this->markTestSkipped("MySQL extension for PDO not loaded"); + } + // Attempt to connect, if there is a test config file if (is_file(QTEST_DIR . "/settings.json")) { diff --git a/tests/databases/pdo_firebird/PDOFirebirdQBTest.php b/tests/databases/pdo_firebird/PDOFirebirdQBTest.php new file mode 100644 index 0000000..38e60eb --- /dev/null +++ b/tests/databases/pdo_firebird/PDOFirebirdQBTest.php @@ -0,0 +1,81 @@ +markTestSkipped("Firebird extension for PDO not loaded"); + } + + // test the query builder + $params = new Stdclass(); + $params->alias = 'pdo_fire'; + $params->type = 'pdo_firebird'; + $params->file = $dbpath; + $params->host = 'localhost'; + $params->user = 'sysdba'; + $params->pass = 'masterkey'; + $params->prefix = 'create_'; + $params->options = array(); + $params->options[PDO::ATTR_PERSISTENT] = TRUE; + $this->db = Query($params); + } + + // -------------------------------------------------------------------------- + + public function testGetNamedConnectionException() + { + try + { + $db = Query('pdo_fire'); + } + catch(InvalidArgumentException $e) + { + $this->assertIsA($e, 'InvalidArgumentException'); + } + } + + // -------------------------------------------------------------------------- + + public function testGetNamedConnection() + { + $dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB'; + + // test the query builder + $params = new Stdclass(); + $params->alias = 'pdo_fire'; + $params->type = 'pdo_firebird'; + $params->file = $dbpath; + $params->host = 'localhost'; + $params->user = 'sysdba'; + $params->pass = 'masterkey'; + $params->prefix = ''; + $f_conn = Query($params); + + $this->assertReference($f_conn, Query('fire')); + } +} \ No newline at end of file diff --git a/tests/databases/pdo_firebird/PDOFirebirdTest.php b/tests/databases/pdo_firebird/PDOFirebirdTest.php new file mode 100644 index 0000000..a168677 --- /dev/null +++ b/tests/databases/pdo_firebird/PDOFirebirdTest.php @@ -0,0 +1,40 @@ +markTestSkipped("Firebird extension for PDO not loaded"); + } + + // test the db driver directly + $this->db = new PDO_Firebird('localhost:'.$dbpath); + $this->tables = $this->db->get_tables(); + } +} \ No newline at end of file diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 7706541..9afb0c1 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -19,6 +19,10 @@ databases/firebird/FirebirdTest.php databases/firebird/FirebirdQBTest.php + + + databases/firebird/PDOFirebirdTest.php + databases/firebird/PDOFirebirdQBTest.php databases/mysql/MySQLTest.php