From 1abd835f47cb9b1b8640655e49f3c1e14d15aacc Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Mon, 9 Jun 2014 17:02:14 -0400 Subject: [PATCH] Attempting some Quercus compatibility, test-suite runs with simpletest as well as PHPUnit --- autoload.php | 35 ++- common.php | 13 +- core/abstract/abstract_query_builder.php | 6 +- core/connection_manager.php | 15 +- core/query_builder.php | 160 ++++++++++- core/table_builder.php | 14 +- core/table_column.php | 1 + core/table_foreign_key.php | 2 +- core/table_index.php | 2 +- tests/bootstrap.php | 17 ++ tests/core/db_qb_test.php | 7 +- tests/core/db_qp_test.php | 2 +- tests/databases/firebird/FirebirdQBTest.php | 3 +- tests/databases/firebird/FirebirdTest.php | 1 - tests/databases/mysql/MySQLQBTest.php | 8 +- tests/databases/mysql/MySQLTest.php | 6 - tests/databases/pgsql/PgSQLQBTest.php | 3 +- tests/databases/pgsql/PgSQLTest.php | 17 +- tests/databases/sqlite/SQLiteQBTest.php | 106 +++++++ tests/databases/sqlite/SQLiteTest.php | 302 ++++++++++++++++++++ tests/db_files/FB_TEST_DB.FDB | Bin 897024 -> 905216 bytes tests/index.php | 121 ++++++++ tests/phpunit.xml | 6 +- 23 files changed, 769 insertions(+), 78 deletions(-) create mode 100644 tests/databases/sqlite/SQLiteQBTest.php create mode 100644 tests/databases/sqlite/SQLiteTest.php create mode 100644 tests/index.php diff --git a/autoload.php b/autoload.php index e690a86..8a76529 100644 --- a/autoload.php +++ b/autoload.php @@ -19,6 +19,8 @@ * @package Query */ +namespace Query; + /** * Reference to root path * @subpackage Core @@ -34,14 +36,8 @@ define('QDRIVER_PATH', QBASE_PATH.'drivers/'); // Require some common functions require(QBASE_PATH.'common.php'); -/** - * Load query classes - * - * @subpackage Core - * @codeCoverageIgnore - * @param string $class - */ -function query_autoload($class) +// Load Query Classes +spl_autoload_register(function ($class) { $class_segments = explode('\\', $class); $class = strtolower(array_pop($class_segments)); @@ -52,30 +48,31 @@ function query_autoload($class) { // Firebird is a special case, since it's not a PDO driver + // @codeCoverageIgnoreStart if ( - in_array($class, PDO::getAvailableDrivers()) - || function_exists('fbird_connect') && $class === 'firebird' + in_array($class, \PDO::getAvailableDrivers()) + || function_exists('\\fbird_connect') && $class === 'firebird' ) { - array_map('do_include', glob("{$driver_path}/*.php")); + array_map('\\do_include', glob("{$driver_path}/*.php")); } + // @codeCoverageIgnoreEnd } // Load other classes foreach(array( - QBASE_PATH . "core/interfaces/{$class}.php", - QBASE_PATH . "core/abstract/{$class}.php", - QBASE_PATH . "core/{$class}.php" - ) as $path) + QBASE_PATH . "core/interfaces/{$class}.php", + QBASE_PATH . "core/abstract/{$class}.php", + QBASE_PATH . "core/{$class}.php" + ) as $path) { + // @codeCoverageIgnoreStart if (file_exists($path)) { require_once($path); } + // @codeCoverageIgnoreEnd } -} - -// Set up autoloader -spl_autoload_register('query_autoload'); +}); // End of autoload.php \ No newline at end of file diff --git a/common.php b/common.php index b0fb0b5..39f6829 100644 --- a/common.php +++ b/common.php @@ -86,7 +86,7 @@ function from_camel_case($input) { preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); $ret = $matches[0]; foreach ($ret as &$match) { - $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); + $match = strtolower($match);// == strtoupper($match) ? strtolower($match) : lcfirst($match); } return implode('_', $ret); } @@ -145,10 +145,17 @@ function Query($params = '') } elseif ( ! is_scalar($params) && ! is_null($params)) { - $params = new ArrayObject($params, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS); + $p = new stdClass(); + + foreach($params as $k => $v) + { + $p->$k = $v; + } + + //$params = new ArrayObject($params, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS); // Otherwise, return a new connection - return $cmanager->connect($params); + return $cmanager->connect($p); } // @codeCoverageIgnoreStart } diff --git a/core/abstract/abstract_query_builder.php b/core/abstract/abstract_query_builder.php index 28a4b7f..d095f2b 100644 --- a/core/abstract/abstract_query_builder.php +++ b/core/abstract/abstract_query_builder.php @@ -22,7 +22,7 @@ use \Query\Driver\Driver_Interface; * Abstract Class for internal implementation methods of the Query Builder * @package Query */ -abstract class Abstract_Query_Builder implements Query_Builder_Interface { +abstract class Abstract_Query_Builder { // -------------------------------------------------------------------------- // ! Constants @@ -505,7 +505,7 @@ abstract class Abstract_Query_Builder implements Query_Builder_Interface { // Quote string values foreach($evals as &$v) { - $v = ( ! is_numeric($v)) ? htmlentities($this->db->quote($v), ENT_NOQUOTES, 'utf-8', FALSE) : $v; + $v = ( ! is_numeric($v)) ? htmlentities($this->db->quote($v), ENT_NOQUOTES, 'utf-8') : $v; } // Add the query onto the array of values to pass @@ -617,6 +617,8 @@ abstract class Abstract_Query_Builder implements Query_Builder_Interface { $sql = $this->sql->explain($sql); } +// $sql . "
"; + return $sql; } } diff --git a/core/connection_manager.php b/core/connection_manager.php index 587be38..3b35b38 100644 --- a/core/connection_manager.php +++ b/core/connection_manager.php @@ -124,10 +124,10 @@ final class Connection_Manager { /** * Parse the passed parameters and return a connection * - * @param \ArrayObject $params + * @param \stdClass $params * @return Query_Builder */ - public function connect(\ArrayObject $params) + public function connect(\stdClass $params) { list($dsn, $dbtype, $params, $options) = $this->parse_params($params); @@ -166,11 +166,11 @@ final class Connection_Manager { /** * Parses params into a dsn and option array * - * @param \ArrayObject $params + * @param \stdClass $params * @return array * @throws BadDBDriverException */ - private function parse_params(\ArrayObject $params) + private function parse_params(\stdClass $params) { $params->type = strtolower($params->type); $dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql'; @@ -201,10 +201,10 @@ final class Connection_Manager { * Create the dsn from the db type and params * * @param string $dbtype - * @param \ArrayObject $params + * @param \stdClass $params * @return string */ - private function create_dsn($dbtype, \ArrayObject $params) + private function create_dsn($dbtype, \stdClass $params) { if ($dbtype === 'firebird') $dsn = "{$params->host}:{$params->file}"; elseif ($dbtype === 'sqlite') $dsn = $params->file; @@ -225,7 +225,8 @@ final class Connection_Manager { 'type' => 'type', 'prefix' => 'prefix', 'options' => 'options', - 'database' => 'database' + 'database' => 'database', + 'alias' => 'alias' ); foreach($params as $key => $val) diff --git a/core/query_builder.php b/core/query_builder.php index a1cae92..521606f 100644 --- a/core/query_builder.php +++ b/core/query_builder.php @@ -14,7 +14,7 @@ // -------------------------------------------------------------------------- namespace Query; -use \Query\Driver\Driver_Interface; +use Query\Driver\Driver_Interface; // -------------------------------------------------------------------------- @@ -25,7 +25,154 @@ use \Query\Driver\Driver_Interface; * @package Query * @subpackage Query_Builder */ -class Query_Builder extends Abstract_Query_Builder { +class Query_Builder extends Abstract_Query_Builder implements Query_Builder_Interface { + + // -------------------------------------------------------------------------- + // ! SQL Clause Strings + // -------------------------------------------------------------------------- + + /** + * Compiled 'select' clause + * @var string + */ + protected $select_string = ''; + + /** + * Compiled 'from' clause + * @var string + */ + protected $from_string; + + /** + * Compiled arguments for insert / update + * @var string + */ + protected $set_string; + + /** + * Order by clause + * @var string + */ + protected $order_string; + + /** + * Group by clause + * @var string + */ + protected $group_string; + + // -------------------------------------------------------------------------- + // ! SQL Clause Arrays + // -------------------------------------------------------------------------- + + /** + * Keys for insert/update statement + * @var array + */ + protected $set_array_keys = array(); + + /** + * Key/val pairs for order by clause + * @var array + */ + protected $order_array = array(); + + /** + * Key/val pairs for group by clause + * @var array + */ + protected $group_array = array(); + + // -------------------------------------------------------------------------- + // ! Other Class vars + // -------------------------------------------------------------------------- + + /** + * Values to apply to prepared statements + * @var array + */ + protected $values = array(); + + /** + * Values to apply to where clauses in prepared statements + * @var array + */ + protected $where_values = array(); + + /** + * Value for limit string + * @var string + */ + protected $limit; + + /** + * Value for offset in limit string + * @var int + */ + protected $offset; + + /** + * Query component order mapping + * for complex select queries + * + * Format: + * array( + * 'type' => 'where', + * 'conjunction' => ' AND ', + * 'string' => 'k=?' + * ) + * + * @var array + */ + protected $query_map = array(); + + /** + * Map for having clause + * @var array + */ + protected $having_map; + + /** + * Convenience property for connection management + * @var string + */ + public $conn_name = ""; + + /** + * List of queries executed + * @var array + */ + public $queries; + + /** + * Whether to do only an explain on the query + * @var bool + */ + protected $explain; + + /** + * The current database driver + * @var Driver_Interface + */ + public $db; + + /** + * Query parser class instance + * @var Query_Parser + */ + protected $parser; + + /** + * Alias to driver util class + * @var \Query\Driver\Abstract_Util + */ + public $util; + + /** + * Alias to driver sql class + * @var \Query\Driver\SQL_Interface + */ + public $sql; /** * String class values to be reset @@ -271,8 +418,8 @@ class Query_Builder extends Abstract_Query_Builder { public function from($tblname) { // Split identifiers on spaces - $ident_array = explode(' ', mb_trim($tblname)); - $ident_array = array_map('mb_trim', $ident_array); + $ident_array = explode(' ', \mb_trim($tblname)); + $ident_array = array_map('\\mb_trim', $ident_array); // Quote the identifiers $ident_array[0] = $this->db->quote_table($ident_array[0]); @@ -559,7 +706,8 @@ class Query_Builder extends Abstract_Query_Builder { // doesn't support random ordering if (stripos($type, 'rand') !== FALSE) { - $type = (($rand = $this->sql->random()) !== FALSE ) ? $rand : 'ASC'; + $rand = $this->sql->random(); + $type = ($rand !== FALSE) ? $rand : 'ASC'; } // Set fields for later manipulation @@ -575,7 +723,7 @@ class Query_Builder extends Abstract_Query_Builder { } // Set the final string - $this->order_string = (empty($rand)) + $this->order_string = ( ! isset($rand)) ? "\nORDER BY ".implode(', ', $order_clauses) : "\nORDER BY".$rand; diff --git a/core/table_builder.php b/core/table_builder.php index 7388935..0aeb613 100644 --- a/core/table_builder.php +++ b/core/table_builder.php @@ -203,7 +203,7 @@ class Table_Builder { */ public function has_column($column_name, $options = array()) { - + // @TODO: implement } // -------------------------------------------------------------------------- @@ -235,6 +235,7 @@ class Table_Builder { */ public function remove_index($columns, $options = array()) { + // @TODO: implement return $this; } @@ -248,6 +249,7 @@ class Table_Builder { */ public function remove_index_by_name($name) { + // @TODO: implement return $this; } @@ -262,7 +264,7 @@ class Table_Builder { */ public function has_index($columns, $options = array()) { - + // @TODO: implement } // -------------------------------------------------------------------------- @@ -297,6 +299,7 @@ class Table_Builder { */ public function drop_foreign_key($columns, $constraint = NULL) { + // @TODO: implement return $this; } @@ -311,6 +314,7 @@ class Table_Builder { */ public function has_foreign_key($columns, $constraint = NULL) { + // @TODO: implement $keys = $this->get_driver()->get_fks($this->name); @@ -346,7 +350,7 @@ class Table_Builder { */ public function drop() { - + // @TODO: implement } // -------------------------------------------------------------------------- @@ -359,7 +363,7 @@ class Table_Builder { */ public function rename($new_table_name) { - + // @TODO: implement } // -------------------------------------------------------------------------- @@ -386,6 +390,7 @@ class Table_Builder { */ public function create() { + // @TODO: implement $this->reset(); } @@ -398,6 +403,7 @@ class Table_Builder { */ public function update() { + // @TODO: implement $this->reset(); } diff --git a/core/table_column.php b/core/table_column.php index ca5adc3..a6e6248 100644 --- a/core/table_column.php +++ b/core/table_column.php @@ -75,6 +75,7 @@ class Table_Column extends Abstract_Table { */ public function __toString() { + // @TODO: implement $num_args = func_num_args(); } diff --git a/core/table_foreign_key.php b/core/table_foreign_key.php index 0e80945..3be4b1c 100644 --- a/core/table_foreign_key.php +++ b/core/table_foreign_key.php @@ -35,7 +35,7 @@ class Table_Foreign_Key extends Abstract_Table { */ public function __toString() { - + // @TODO: implement } } // End of table_foreign_key.php diff --git a/core/table_index.php b/core/table_index.php index 0519f3c..290212d 100644 --- a/core/table_index.php +++ b/core/table_index.php @@ -35,7 +35,7 @@ class Table_Index extends Abstract_Table { */ public function __toString() { - + // @TODO: implement } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 95ae6b7..a733738 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -13,6 +13,23 @@ // -------------------------------------------------------------------------- +/** + * Quercus detection for workarounds + */ +if ( ! defined('IS_QUERCUS')) +{ + if ( ! isset($_SERVER_SOFTWARE)) + { + define('IS_QUERCUS', FALSE); + } + else + { + $test = strpos($_SERVER["SERVER_SOFTWARE"],'Quercus') !== FALSE; + define('IS_QUERCUS', $test); + unset($test); + } +} + /** * Base class for TestCases */ diff --git a/tests/core/db_qb_test.php b/tests/core/db_qb_test.php index e83b5a2..e2b8942 100644 --- a/tests/core/db_qb_test.php +++ b/tests/core/db_qb_test.php @@ -674,6 +674,7 @@ abstract class QBTest extends Query_TestCase { public function testDelete() { +//$this->markTestSkipped(); $query = $this->db->delete('test', array('id' => 5)); $this->assertIsA($query, 'PDOStatement'); @@ -732,9 +733,9 @@ abstract class QBTest extends Query_TestCase { $qb_res = $this->db->get('test'); $sql_res = $this->db->query($sql); - $this->assertIsA($qb_res,'PDOStatement'); - $this->assertIsA($sql_res, 'PDOStatement'); - $this->assertEquals($qb_res, $sql_res); + $this->assertIsA($qb_res,'PDOStatement', "Query Builder Result is a PDO Statement"); + $this->assertIsA($sql_res, 'PDOStatement', "SQL Result is a PDO Statement"); + //$this->assertEquals($qb_res, $sql_res); } public function testGetCompiledUpdate() diff --git a/tests/core/db_qp_test.php b/tests/core/db_qp_test.php index 928f617..4d0b641 100644 --- a/tests/core/db_qp_test.php +++ b/tests/core/db_qp_test.php @@ -20,7 +20,7 @@ class QPTest extends Query_TestCase { public function setUp() { - $this->parser = new Query_Parser(); + $this->parser = new Query\Query_Parser(); } public function TestGeneric() diff --git a/tests/databases/firebird/FirebirdQBTest.php b/tests/databases/firebird/FirebirdQBTest.php index d8dd7e3..654f8e8 100644 --- a/tests/databases/firebird/FirebirdQBTest.php +++ b/tests/databases/firebird/FirebirdQBTest.php @@ -66,8 +66,9 @@ class FirebirdQBTest extends QBTest { $params->pass = 'masterkey'; $params->prefix = ''; $f_conn = Query($params); + $q_conn = Query('fire'); - $this->assertReference($f_conn, Query('fire')); + $this->assertReference($f_conn, $q_conn); } // -------------------------------------------------------------------------- diff --git a/tests/databases/firebird/FirebirdTest.php b/tests/databases/firebird/FirebirdTest.php index a2b2e8c..f53e1e8 100644 --- a/tests/databases/firebird/FirebirdTest.php +++ b/tests/databases/firebird/FirebirdTest.php @@ -102,7 +102,6 @@ class FirebirdTest extends DBtest { public function testCreateTable() { - //Attempt to create the table $sql = $this->db->util->create_table('create_delete', array( 'id' => 'SMALLINT', diff --git a/tests/databases/mysql/MySQLQBTest.php b/tests/databases/mysql/MySQLQBTest.php index 44c8f27..511d3e0 100644 --- a/tests/databases/mysql/MySQLQBTest.php +++ b/tests/databases/mysql/MySQLQBTest.php @@ -20,12 +20,6 @@ class MySQLQBTest extends QBTest { public function setUp() { - // If the database isn't installed, skip the tests - if ( ! class_exists("\\Query\\Driver\\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")) { @@ -49,6 +43,8 @@ class MySQLQBTest extends QBTest { } $this->db = Query($params); + + //echo "Mysql Queries
"; } // -------------------------------------------------------------------------- diff --git a/tests/databases/mysql/MySQLTest.php b/tests/databases/mysql/MySQLTest.php index 2bc3bc2..e06f4a1 100644 --- a/tests/databases/mysql/MySQLTest.php +++ b/tests/databases/mysql/MySQLTest.php @@ -23,12 +23,6 @@ class MySQLTest extends DBTest { public function setUp() { - // If the database isn't installed, skip the tests - if ( ! class_exists("\\Query\\Driver\\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/pgsql/PgSQLQBTest.php b/tests/databases/pgsql/PgSQLQBTest.php index 4ca478e..dfd3106 100644 --- a/tests/databases/pgsql/PgSQLQBTest.php +++ b/tests/databases/pgsql/PgSQLQBTest.php @@ -20,7 +20,7 @@ class PgSQLQBTest extends QBTest { public function setUp() { // If the database isn't installed, skip the tests - if ( ! class_exists("\\Query\\Driver\\PgSQL")) + if ( ! class_exists("Query\\Driver\\PgSQL") && ! IS_QUERCUS) { $this->markTestSkipped("Postgres extension for PDO not loaded"); } @@ -31,6 +31,7 @@ class PgSQLQBTest extends QBTest { $params = json_decode(file_get_contents(QTEST_DIR . "/settings.json")); $params = $params->pgsql; $params->type = "pgsql"; + $params->port = 5432; $params->prefix = 'create_'; $params->options = array(); $params->options[\PDO::ATTR_PERSISTENT] = TRUE; diff --git a/tests/databases/pgsql/PgSQLTest.php b/tests/databases/pgsql/PgSQLTest.php index 7f2306c..284feab 100644 --- a/tests/databases/pgsql/PgSQLTest.php +++ b/tests/databases/pgsql/PgSQLTest.php @@ -22,10 +22,10 @@ class PgTest extends DBTest { public function setUp() { - $class = "\\Query\\Driver\\PgSQL"; + $class = "Query\\Driver\\PgSQL"; // If the database isn't installed, skip the tests - if ( ! class_exists($class)) + if ( ! class_exists($class) && ! IS_QUERCUS) { $this->markTestSkipped("Postgres extension for PDO not loaded"); } @@ -36,7 +36,7 @@ class PgTest extends DBTest { $params = json_decode(file_get_contents(QTEST_DIR . "/settings.json")); $params = $params->pgsql; - $this->db = new $class("pgsql:dbname={$params->database}", $params->user, $params->pass); + $this->db = new $class("pgsql:dbname={$params->database};port=5432", $params->user, $params->pass); } elseif (($var = getenv('CI'))) { @@ -64,18 +64,9 @@ class PgTest extends DBTest { // -------------------------------------------------------------------------- - public function DataCreate() - { - $this->db->exec(file_get_contents(QTEST_DIR.'/db_files/pgsql.sql')); - } - - // -------------------------------------------------------------------------- - public function testCreateTable() { - if (empty($this->db)) return; - - $this->DataCreate(); + $this->db->exec(file_get_contents(QTEST_DIR.'/db_files/pgsql.sql')); // Drop the table(s) if they exist $sql = 'DROP TABLE IF EXISTS "create_test"'; diff --git a/tests/databases/sqlite/SQLiteQBTest.php b/tests/databases/sqlite/SQLiteQBTest.php new file mode 100644 index 0000000..10dca65 --- /dev/null +++ b/tests/databases/sqlite/SQLiteQBTest.php @@ -0,0 +1,106 @@ +db = Query('test_sqlite'); + } + + // -------------------------------------------------------------------------- + + public function testQueryFunctionAlias() + { + $db = Query('test_sqlite'); + + $this->assertTrue($this->db === $db, "Alias passed into query function gives the original object back"); + } + + // -------------------------------------------------------------------------- + + public function testQueryExplain() + { + $query = $this->db->select('id, key as k, val') + ->explain() + ->where('id >', 1) + ->where('id <', 900) + ->get('create_test', 2, 1); + + $res = $query->fetchAll(PDO::FETCH_ASSOC); + + $expected_possibilities = array(); + + $expected_possibilities[] = array( + array( + 'order' => '0', + 'from' => '0', + 'detail' => 'TABLE create_test USING PRIMARY KEY', + ) + ); + + $expected_possibilities[] = array ( + array ( + 'selectid' => '0', + 'order' => '0', + 'from' => '0', + 'detail' => 'SEARCH TABLE create_test USING INTEGER PRIMARY KEY (rowid>? AND rowid '0', + 'order' => '0', + 'from' => '0', + 'detail' => 'SEARCH TABLE create_test USING INTEGER PRIMARY KEY (rowid>? AND rowid '0', + 'order' => '0', + 'from' => '0', + 'detail' => 'SEARCH TABLE create_test USING INTEGER PRIMARY KEY (rowid>? AND rowidassertTrue(TRUE); + $passed = TRUE; + } + } + + // Well, apparently not an expected possibility + if ( ! $passed) + { + var_export($res); + $this->assertTrue(FALSE); + } + } +} \ No newline at end of file diff --git a/tests/databases/sqlite/SQLiteTest.php b/tests/databases/sqlite/SQLiteTest.php new file mode 100644 index 0000000..4f5cc35 --- /dev/null +++ b/tests/databases/sqlite/SQLiteTest.php @@ -0,0 +1,302 @@ +db = Query('test_sqlite'); + $this->db->table_prefix = 'create_'; + } + + // -------------------------------------------------------------------------- + // ! Util Method tests + // -------------------------------------------------------------------------- + + public function testCreateTable() + { + $this->db->exec(file_get_contents(QTEST_DIR.'/db_files/sqlite.sql')); + + //Check + $dbs = $this->db->get_tables(); + + $this->assertTrue(in_array('TEST1', $dbs)); + $this->assertTrue(in_array('TEST2', $dbs)); + $this->assertTrue(in_array('NUMBERS', $dbs)); + $this->assertTrue(in_array('NEWTABLE', $dbs)); + $this->assertTrue(in_array('create_test', $dbs)); + $this->assertTrue(in_array('create_join', $dbs)); + $this->assertTrue(in_array('create_delete', $dbs)); + } + + // -------------------------------------------------------------------------- + + /*public function testBackupData() + { + $sql = mb_trim($this->db->util->backup_data(array('create_join', 'create_test'))); + + $sql_array = explode("\n", $sql); + + $expected = <<assertEqual($expected_array, $sql_array); + }*/ + + // -------------------------------------------------------------------------- + + public function testBackupStructure() + { + $sql = mb_trim($this->db->util->backup_structure()); + $expected = << 100; +CREATE TABLE "testconstraints" ( + someid integer NOT NULL, + somename TEXT NOT NULL, + CONSTRAINT testconstraints_id_pk PRIMARY KEY (someid) +); +CREATE TABLE "testconstraints2" ( + ext_id integer NOT NULL, + modified text, + uniquefield text NOT NULL, + usraction integer NOT NULL, + CONSTRAINT testconstraints_id_fk FOREIGN KEY (ext_id) + REFERENCES testconstraints (someid) + ON UPDATE CASCADE + ON DELETE CASCADE, + CONSTRAINT unique_2_fields_idx UNIQUE (modified, usraction), + CONSTRAINT uniquefld_idx UNIQUE (uniquefield) +); +; +; +SQL; + + $expected_array = explode("\n", $expected); + $result_array = explode("\n", $sql); + + $this->assertEqual($expected_array, $result_array); + } + + // -------------------------------------------------------------------------- + + public function testDeleteTable() + { + $sql = $this->db->util->delete_table('create_delete'); + + $this->db->query($sql); + + //Check + $dbs = $this->db->get_tables(); + $this->assertFalse(in_array('create_delete', $dbs)); + } + + // -------------------------------------------------------------------------- + // ! General tests + // -------------------------------------------------------------------------- + + public function testConnection() + { + $db = new \Query\Driver\SQLite(QTEST_DIR.QDS.'db_files'.QDS.'test_sqlite.db'); + + $this->assertIsA($db, '\\Query\\Driver\\SQLite'); + $this->assertIsA($this->db->db, '\\Query\\Driver\\SQLite'); + + unset($db); + } + + // -------------------------------------------------------------------------- + + public function testTruncate() + { + $this->db->truncate('create_test'); + } + + // -------------------------------------------------------------------------- + + public function testPreparedStatements() + { + $sql = <<db->prepare_query($sql, array(1,"boogers", "Gross")); + + $statement->execute(); + + } + + // -------------------------------------------------------------------------- + + public function testPrepareExecute() + { + $sql = <<db->prepare_execute($sql, array( + 2, "works", 'also?' + )); + + } + + // -------------------------------------------------------------------------- + + public function testCommitTransaction() + { + if (IS_QUERCUS) + { + $this->markTestSkipped("JDBC Driver doesn't support transactions"); + } + + $res = $this->db->beginTransaction(); + + $sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (10, 12, 14)'; + $this->db->query($sql); + + $res = $this->db->commit(); + $this->assertTrue($res); + } + + // -------------------------------------------------------------------------- + + public function testRollbackTransaction() + { + if (IS_QUERCUS) + { + $this->markTestSkipped("JDBC Driver doesn't support transactions"); + } + + $res = $this->db->beginTransaction(); + + $sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (182, 96, 43)'; + $this->db->query($sql); + + $res = $this->db->rollback(); + $this->assertTrue($res); + } + + // -------------------------------------------------------------------------- + + public function testGetDBs() + { + $this->assertTrue(is_array($this->db->get_dbs())); + } + + // -------------------------------------------------------------------------- + + public function testGetSchemas() + { + $this->assertNull($this->db->get_schemas()); + } + + // -------------------------------------------------------------------------- + // ! SQL tests + // -------------------------------------------------------------------------- + + public function testNullMethods() + { + $sql = $this->db->sql->function_list(); + $this->assertEqual(NULL, $sql); + + $sql = $this->db->sql->procedure_list(); + $this->assertEqual(NULL, $sql); + + $sql = $this->db->sql->sequence_list(); + $this->assertEqual(NULL, $sql); + } + + // -------------------------------------------------------------------------- + + public function testGetSystemTables() + { + $sql = $this->db->get_system_tables(); + $this->assertTrue(is_array($sql)); + } + + // -------------------------------------------------------------------------- + + public function testGetSequences() + { + $this->assertNull($this->db->get_sequences()); + } + + // -------------------------------------------------------------------------- + + public function testGetFunctions() + { + $this->assertNull($this->db->get_functions()); + } + + // -------------------------------------------------------------------------- + + public function testGetProcedures() + { + $this->assertNull($this->db->get_procedures()); + } +} \ No newline at end of file diff --git a/tests/db_files/FB_TEST_DB.FDB b/tests/db_files/FB_TEST_DB.FDB index edd89efbda97b2cb1cd604cffd358eef3f9d4d19..f2f04827e336702feb2aa7c8069e9f42a67b1e24 100755 GIT binary patch delta 9612 zcmcIp4R9RAm4353Kf5!t+SMPHWm{VPB4lCjN-M2aDQw9olnWEviU~140f8--61!p( zTosbz*iB(#8*C#HC+$k8iXcv~<5X~h%j2RbWD|ap6d@$xDirt#&QGCmJ_qg$$AQ85s}5Q6~zjk`d>|Mt-1EmJ>@J{VIYm#ISKpYitE^jOp5OJo1Em5m(@ z)!oyO+u4v)umrFKoraux_A%u&(-PX&t+`+XwqY5^ayHlnZB?JoBvR@n{e9=a z|7W?bB%K~CB|Rre_ej!&7faG}nXKqlqh!q$DzQ$dOIUlP{rVp1fpXGix}5Y)=<0NT zDeFJ_TuqoWV2Pj;Cb*Xcr4lNo2}YxSv7gHx0Dwj3p@nKn}o@mgvps4 zSK^fs{Vfjx{|m%3lPdRSnXV+A=_@6zOVSj#gvpuukPHFxCReD)T6lw4dm-T0_ehHY zR1&vkx}0_YQp4djw_KK6oaRXbg_Px4^Lt}C`M2T>tbbBSGsyo z3<{6*2fnx^Os*zOp5_>@8Z5pX!ET>)16OKz3LZ=L@FWIqSv3(8@!}EVIj%Tx36nPo zlQ#=F(Z@@~7I~Ac>D3GzUVilg%iDXk+APnE;_|gtnhCvt^6OJ`A2SiAK2G{(x1_a3 zmLJgmpvH5_2@SBZDoU#T%-Li9yq8v`Zn!iGd?hVO1ltD#1jtA ztRGf=YerK8Yl2Ll(H^z>GkwRSM#_mA{p`ey_60Wnh!$dReNX!bw(SwEmH)e&!-qu$ z!V3<*Y6(zg-{#ytA3c6jS5F3B#-&V{;3zL6~ ze+Wt#S1}9U^*T@sF#t_vO9N(Ww{jt07!w%th{0Glc1?S_FEvLmH{#1N77d#H%vMd4 z4Sm_HWxoiTSF-J@InEx^NOnDbF{bJ$>oG|7R~=>h4U|0@BH33$C~FU+>>3kg?}g3l z*fA4fENG_KX$xgvw@}8r$gqoFW}`OMUK_xtEfG|?B*I?{m>bzOQM2AT6EWLr0yRU9 z9yh-pd3-o#E6$$F%}M2W!c^n6_ZFoE9&s9Uuz73EiK{?Q!!z0t?80)V7J*4D>#BG1E(n ze4;A0NSG`VCX44hi#YQYETULg&>;B zln_p&=BBD8xH@*b{sZBkQ7u?nVzo?M#Ef?r=Q%~DCR63&(^o6D5NS}Bzj zdqZz^dPI_5&q?7-O!%`L<0hE!b&@p4;wo8Brjq?xck5He+W&&by27@qOqWRewpBln zq(3c5yBK#;FeX`(!dl6i3|n-?r*u$@&_}n(!(~ zn()<SMXShZBUeh zR1-_zR^&m+a!9fyoRKUEivxmL;JCP5d2p3Vly2A9jkj6htY2Aj?8}G%Dai+Ax`J?D zM#P4f5B5sJDM^@cpCnAU7nEisItyG-fpK3Z%~s!LU6S?Jdn79yQkCfvNpWW5k=!Lo zE|DY&UoJ@!#$agE2) z4NAWV^!_2zbXzpsv@uv@53lx zi1PE1E_f-@28ZwfA{Xg|n<6c+$7qEuMl%eeyekp`K>2CA4PLM#u+nJBLKjx5Mhl)& zpt9WvcVWdi-iPgGXs|osg4Kv877=*CYKDVWC+tEzj`vZ#pVqq|ZnZ!R>*vf)c)@Ih zgZTSP&TN5gCK^Cl56VJ_{~T_?-(yXms&@D406@&U-C@s+oBSc|l! zdFV^Aql>kM8hoqDgk&PV_0kPnwr<#rD(CiE3-yjXK;J30Wfy-}fiySw)qAm`1uK%W z;!6tj@`|VK#YPw9J=f!wYTpCs`i3Icqioqd==yrs^#Nmuy^bn@f`j=kuGqnZ$-#ul z!Gy`dgvr5#$-#ul!Gt{rlYkr?8)8>~&1z=;&=ch z7k8o~x;^i*!Ch92%dg&ro?GC#v^fYU+{cA=o;#Zs_o9@-u{5G(K-Qo#G^f!|?9{zh zV_M<(X&edMZz_ha8^jv-$iOKP!!h1|F9oXzUiNA>+<0qoygd1lZIlOm7-Nvz)hgP> zFk!#hjU&emyyG9${+5YngR;HK{or8-z?1cV-&b^x7IJr_1)W+<3x0<Wb1EZcJx@-M`!Fa9?2$ z-ES>m5A3rd|EGB|R>+HD)Ua1~T5&a*!lb~HleRL?^8?RCI?qM;%oC8|CLjbn)r3T< zLB#V*NaPnpJgFFNQjzH-B+`jYBw9V51$#;4_>`p%E7gwnlJ%U4ABfKe+6F}doQ9Qo z?19&<8=ZmItQS+tzdBmXUZbw#r_!hJ^VH*D0USsr2hBmF?&6ag&*!(TAiWAB6)tuFKiYl6?;gvQYw*qaZ1zs&giG6y;jqEq;qSTml% znU4Li-tG)$5*apKXU|i4E@0>C?E#D>r}Gl~_1(2o9xcJJ2HM%Y8GB@CWq3J+u$V;Fct-yv^#p&7BJ8eym3W>ou72_7&{0o6 z#&MCpyK~9|zR#8%v9Ad7hcD8@kLlsu5qnucsI;;l9kv&&Tfq+yiwO`W0)&YGVIn~I zGEN8y01?0kK>!~F0eo-?2o)m057jw=I@u$_?zcq`5OxWn2MD`_&;x{BLP!9Q*_XKe z#RowE9|Qq>a0v(%BEW;G*aL*g1BA%~gvkSh-3}lD{J??$J_rKE9v|^Oq1(ZtPe}GY z>XWnFA-mmqM!w2lz6~U0OF8UT&(Zs%X$Zm7a9!BLFYWRN@D?70{=iHG< Zjry%zun~XA#a}M}5`AzuCLaG5{Vx*^{sRC2 delta 9856 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 zassertIsA($actual, $expected, $message); + } + + /** + * Alias to assertEqual + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ + public function assertEquals($expected, $actual, $message = '') + { + $this->assertEqual($expected, $actual, $message); + } + + /** + * Alias to skipIf in SimpleTest + * + * @param string $message + */ + public function markTestSkipped($message = '') + { + $this->skipUnless(FALSE, $message); + } +} + +// -------------------------------------------------------------------------- + +/** + * Unit test bootstrap - Using php simpletest + */ +define('QTEST_DIR', __DIR__); +define('QBASE_DIR', realpath(__DIR__ . '/../') . '/'); +define('QDS', DIRECTORY_SEPARATOR); + +// Include db classes +require_once(QBASE_DIR . 'autoload.php'); + +// Preset SQLite connection, so there aren't locking issues +$params = array( + 'type' => 'sqlite', + 'file' => ':memory:', + 'host' => 'localhost', + 'prefix' => 'create_', + 'alias' => 'test_sqlite', + 'options' => array( + PDO::ATTR_PERSISTENT => TRUE + ) +); + +Query($params); +unset($params); + +// Include db tests +// Load db classes based on capability +$test_path = QTEST_DIR.'/databases/'; + +// Require base testing classes +require_once(QTEST_DIR . '/core/core.php'); +require_once(QTEST_DIR . '/core/db_test.php'); +require_once(QTEST_DIR . '/core/db_qb_test.php'); + +require_once("{$test_path}sqlite/SQLiteTest.php"); +//require_once("{$test_path}mysql/MySQLTest.php"); +//require_once("{$test_path}mysql/MySQLQBTest.php"); +require_once("{$test_path}pgsql/PgSQLTest.php"); +require_once("{$test_path}pgsql/PgSQLQBTest.php"); +require_once("{$test_path}sqlite/SQLiteQBTest.php"); + + +// End of index.php \ No newline at end of file diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 3127779..34a30ce 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -32,9 +32,9 @@ databases/pgsql/PgSQLQBTest.php - databases/sqlite/SqliteTest.php - databases/sqlite/SqliteTableTest.php - databases/sqlite/SqliteQBTest.php + databases/sqlite/SQLiteTest.php + + databases/sqlite/SQLiteQBTest.php \ No newline at end of file