Flesh out the table builder a bit, and add some missing driver methods to SQLite

This commit is contained in:
Timothy Warren 2014-04-10 15:54:43 -04:00
parent 3cc260b779
commit 32696a53ff
18 changed files with 316 additions and 65 deletions

View File

@ -77,6 +77,11 @@ function db_filter($array, $index)
/**
* Connection function
*
* Send an array or object as connection parameters to create a connection. If
* the array or object has an 'alias' parameter, passing that string to this
* function will return that connection. Passing no parameters returns the last
* connection created.
*
* @param string|object|array $params
* @return Query\Query_Builder|null
*/

View File

@ -95,6 +95,26 @@ abstract class Abstract_Driver extends \PDO implements Driver_Interface {
$this->table = new Table_Builder('', array(), $this);
}
// --------------------------------------------------------------------------
/**
* Allow invoke to work on table object
*
* @param string $name
* @param array $args
*/
public function __call($name, $args = array())
{
if (
isset($this->$name)
&& is_object($this->$name)
&& method_exists($this->$name, '__invoke')
)
{
return call_user_func_array(array($this->$name, '__invoke'), $args);
}
}
// --------------------------------------------------------------------------
// ! Concrete functions that can be overridden in child classes
// --------------------------------------------------------------------------

View File

@ -33,9 +33,9 @@ abstract class Abstract_Util {
/**
* Save a reference to the connection object for later use
*
* @param object $conn
* @param Driver_Interface $conn
*/
public function __construct($conn)
public function __construct(Driver_Interface $conn)
{
$this->conn = $conn;
}
@ -61,10 +61,10 @@ abstract class Abstract_Util {
/**
* Convienience public function to generate sql for creating a db table
*
* @deprecated Use the table builder class instead
* @param string $name
* @param array $fields
* @param array $constraints
*
* @return string
*/
public function create_table($name, $fields, array $constraints=array())

View File

@ -14,6 +14,9 @@
// --------------------------------------------------------------------------
namespace Query\Table;
use Query\Driver\Driver_Interface;
// --------------------------------------------------------------------------
/**
* Abstract class defining database / table creation methods
@ -64,23 +67,20 @@ class Table_Builder {
/**
* Constructor
*
* @param string $name
* @param array $options
* @param Driver_Interface $driver
* @param [string] $name
* @param [array] $options
* @param [Driver_Interface] $driver
* @return Table_Builder
*/
public function __construct($name, $options = array(), \Query\Driver\Driver_Interface $driver = NULL)
{
$this->name = $name;
if ( ! empty($options))
public function __construct($name = '', $options = array(), Driver_Interface $driver = NULL)
{
$this->table_options = array_merge($this->table_options, $options);
}
if ( ! is_null($driver))
$this->set_driver($driver);
if ($name !== '')
{
$this->driver = $driver;
$this->name = (isset($this->driver)) ? $this->driver->prefix_table($name) : $name;
}
return $this;
@ -91,13 +91,14 @@ class Table_Builder {
/**
* Alias to constructor
*
* @param string $name
* @param array $options
* @param \Query\Driver_Interface $driver
* @param [string] $name
* @param [array] $options
* @param [\Query\Driver\Driver_Interface] $driver
* @return Table_Builder
*/
public function __invoke($name, $options = array(), \Query\Driver\Driver_Interface $driver = NULL)
public function __invoke($name = '', $options = array(), Driver_Interface $driver = NULL)
{
$this->__construct($name, $options, $driver);
return $this->__construct($name, $options, $driver);
}
// --------------------------------------------------------------------------
@ -105,12 +106,15 @@ class Table_Builder {
/**
* Set the reference to the current database driver
*
* @param \Query\Driver_Interface $driver
* @return \Query\Table_Builder
* @param \Query\Driver\Driver_Interface $driver
* @return Table_Builder
*/
public function set_driver(\Query\Driver_Interface $driver)
public function set_driver(Driver_Interface $driver = NULL)
{
if ( ! is_null($driver))
{
$this->driver = $driver;
}
return $this;
}
@ -136,32 +140,35 @@ class Table_Builder {
* @param string $column_name
* @param string $type
* @param array $options
* @return Table_Builder
*/
public function add_column($column_name, $type = NULL, $options = array())
{
$col = new Table_Column($column_name, $type, $options);
$this->columns[] = $col;
return $this;
}
// --------------------------------------------------------------------------
public function remove_column($column_name)
{
return $this;
}
// --------------------------------------------------------------------------
public function rename_column($old_name, $new_name)
{
return $this;
}
// --------------------------------------------------------------------------
public function change_column($column_name, $new_column_type, $options = array())
{
return $this;
}
// --------------------------------------------------------------------------
@ -177,21 +184,24 @@ class Table_Builder {
public function add_index($columns, $options = array())
{
$col = new Table_Index($columns, $options);
$this->indexes[] = $col;
return $this;
}
// --------------------------------------------------------------------------
public function remove_index($columns, $options = array())
{
return $this;
}
// --------------------------------------------------------------------------
public function remove_index_by_name($name)
{
return $this;
}
// --------------------------------------------------------------------------
@ -207,7 +217,10 @@ class Table_Builder {
public function add_foreign_key($columns, $referenced_table, $referenced_columns = array('id'), $options = array())
{
$key = new Table_Foreign_Key($columns, $referenced_table, $referenced_columns, $options);
$this->foreign_keys[] = $key;
return $this;
}
// --------------------------------------------------------------------------
@ -230,7 +243,8 @@ class Table_Builder {
public function exists()
{
$tables = $this->driver->get_tables();
return in_array($this->name, $tables);
}
// --------------------------------------------------------------------------
@ -261,14 +275,14 @@ class Table_Builder {
public function create()
{
$this->reset();
}
// --------------------------------------------------------------------------
public function update()
{
$this->reset();
}
// --------------------------------------------------------------------------
@ -278,15 +292,23 @@ class Table_Builder {
($this->exists())
? $this->update()
: $this->create();
$this->reset();
}
// --------------------------------------------------------------------------
public function reset()
{
$skip = array(
'driver' => 'driver'
);
foreach($this as $key => $val)
{
if ( ! isset($skip[$key]))
{
$this->$key = NULL;
}
}
}
}

View File

@ -59,7 +59,11 @@ class Table_Column extends Abstract_Table {
*/
public function __construct($name, $type = NULL, $options = array())
{
$this->name = $name;
$this->type = $type;
$this->options = ( ! empty($options))
? $this->validate_options($options)
: array();
}
// --------------------------------------------------------------------------
@ -71,7 +75,7 @@ class Table_Column extends Abstract_Table {
*/
public function __toString()
{
$num_args = func_num_args();
}
}

View File

@ -15,6 +15,10 @@
namespace Query\Driver;
use Query\Table\Table_Builder;
// --------------------------------------------------------------------------
/**
* Firebird Database class
*
@ -77,14 +81,14 @@ class Firebird extends Abstract_Driver {
: '\\fbird_connect';
$this->conn = $connect_function($dbpath, $user, $pass, 'utf-8', 0);
$this->service = fbird_service_attach('localhost', $user, $pass);
$this->service = \fbird_service_attach('localhost', $user, $pass);
// Throw an exception to make this match other pdo classes
if ( ! \is_resource($this->conn)) throw new \PDOException(\fbird_errmsg(), \fbird_errcode(), NULL);
// Load these classes here because this
// driver does not call the constructor
// of DB_PDO, which defines these two
// of DB_PDO, which defines these
// class variables for the other drivers
// Load the sql class
@ -94,6 +98,9 @@ class Firebird extends Abstract_Driver {
// Load the util class
$class = __CLASS__."_util";
$this->util = new $class($this);
// Load the table builder class
$this->table = new Table_Builder('', array(), $this);
}
// --------------------------------------------------------------------------
@ -104,8 +111,7 @@ class Firebird extends Abstract_Driver {
*/
public function __destruct()
{
fbird_service_detach($this->service);
fbird_close($this->conn);
\fbird_service_detach($this->service);
}
// --------------------------------------------------------------------------
@ -130,7 +136,7 @@ class Firebird extends Abstract_Driver {
public function truncate($table)
{
// Firebird lacks a truncate command
$sql = 'DELETE FROM "'.$table.'"';
$sql = 'DELETE FROM '.$this->quote_table($table);
$this->statement = $this->query($sql);
}

View File

@ -99,6 +99,7 @@ class Firebird_SQL extends Abstract_SQL {
SELECT TRIM("RDB\$RELATION_NAME")
FROM "RDB\$RELATIONS"
WHERE "RDB\$SYSTEM_FLAG"=0
AND "RDB\$VIEW_BLR" IS NULL
ORDER BY "RDB\$RELATION_NAME" ASC
SQL;
}

View File

@ -30,7 +30,7 @@ class Firebird_Util extends Abstract_Util {
/**
* Convienience public function to generate sql for creating a db table
*
* @deprecated
* @deprecated Use the table builder class instead
* @param string $name
* @param array $fields
* @param array $constraints

View File

@ -79,20 +79,6 @@ class SQLite extends Abstract_Driver {
// --------------------------------------------------------------------------
/**
* List system tables for the current database
*
* @return string[]
*/
public function get_system_tables()
{
//SQLite only has the sqlite_master table
// that is of any importance.
return array('sqlite_master');
}
// --------------------------------------------------------------------------
/**
* Create sql for batch insert
*

View File

@ -51,7 +51,7 @@ class SQLite_SQL extends Abstract_SQL {
/**
* Returns sql to list other databases
*
* @return NULL
* @return string
*/
public function db_list()
{
@ -71,6 +71,7 @@ class SQLite_SQL extends Abstract_SQL {
SELECT DISTINCT "name"
FROM "sqlite_master"
WHERE "type"='table'
AND "name" NOT LIKE 'sqlite_%'
ORDER BY "name" DESC
SQL;
}
@ -84,7 +85,7 @@ SQL;
*/
public function system_table_list()
{
return NULL;
return array('sqlite_master', 'sqlite_temp_master', 'sqlite_sequence');
}
// --------------------------------------------------------------------------
@ -110,7 +111,7 @@ SQL;
*/
public function trigger_list()
{
return NULL;
return 'SELECT "name" FROM "sqlite_master" WHERE "type"=\'trigger\'';
}
// --------------------------------------------------------------------------
@ -180,7 +181,7 @@ SQL;
* Get the list of foreign keys for the current
* table
*
* @parma string $table
* @param string $table
* @return string
*/
public function fk_list($table)

View File

@ -84,6 +84,7 @@ require_once(QTEST_DIR . '/core/core.php');
require_once(QTEST_DIR . '/core/db_test.php');
require_once(QTEST_DIR . '/core/db_qp_test.php');
require_once(QTEST_DIR . '/core/db_qb_test.php');
require_once(QTEST_DIR . '/core/table_builder.php');
// Preset SQLite connection, so there aren't locking issues
if (extension_loaded('pdo_sqlite'))

View File

@ -0,0 +1,32 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Parent Table Builder Test Class
*/
abstract class TableBuilderTest extends Query_TestCase {
public function testExists()
{
$this->assertTrue($this->db->table('test')->exists());
}
public function testGetDriver()
{
$this->assertEqual($this->db, $this->db->table()->get_driver());
}
}
// End of table_builder.php

View File

@ -0,0 +1,37 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Parent Table Builder Test Class
*/
class FirebirdTableTest extends TableBuilderTest {
public function setUp()
{
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
if ( ! function_exists('\\fbird_connect'))
{
$this->markTestSkipped('Firebird extension does not exist');
}
// test the db driver directly
$this->db = new \Query\Driver\Firebird('localhost:'.$dbpath);
$this->db->table_prefix = 'create_';
$this->tables = $this->db->get_tables();
}
}
// End of FirebirdTableTest.php

View File

@ -0,0 +1,48 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Parent Table Builder Test Class
*/
class MySQLTableTest extends TableBuilderTest {
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"))
{
$params = json_decode(file_get_contents(QTEST_DIR . "/settings.json"));
$params = $params->mysql;
$this->db = new \Query\Driver\MySQL("mysql:host={$params->host};dbname={$params->database}", $params->user, $params->pass, array(
PDO::ATTR_PERSISTENT => TRUE
));
}
elseif (($var = getenv('CI')))
{
$this->db = new \Query\Driver\MySQL('host=127.0.0.1;port=3306;dbname=test', 'root');
}
$this->db->table_prefix = 'create_';
}
}
// End of MySQLTableTest.php

View File

@ -0,0 +1,48 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Parent Table Builder Test Class
*/
class PgSQLTableTest extends TableBuilderTest {
public function setUp()
{
$class = "\\Query\\Driver\\PgSQL";
// If the database isn't installed, skip the tests
if ( ! class_exists($class))
{
$this->markTestSkipped("Postgres extension for PDO not loaded");
}
// Attempt to connect, if there is a test config file
if (is_file(QTEST_DIR . "/settings.json"))
{
$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);
}
elseif (($var = getenv('CI')))
{
$this->db = new $class('host=127.0.0.1;port=5432;dbname=test', 'postgres');
}
$this->db->table_prefix = 'create_';
}
}
// End of PgSQLTableTest.php

View File

@ -0,0 +1,30 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Parent Table Builder Test Class
*/
class SQLiteTableTest extends TableBuilderTest {
public function setUp()
{
// Set up in the bootstrap to mitigate
// connection locking issues
$this->db = Query('test_sqlite');
$this->db->table_prefix = 'create_';
}
}
// End of SQLiteTableTest.php

View File

@ -232,12 +232,6 @@ SQL;
public function testNullMethods()
{
$sql = $this->db->sql->system_table_list();
$this->assertEqual(NULL, $sql);
$sql = $this->db->sql->trigger_list();
$this->assertEqual(NULL, $sql);
$sql = $this->db->sql->function_list();
$this->assertEqual(NULL, $sql);
@ -247,4 +241,16 @@ 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 testGetTriggers()
{
$sql = $this->db->get_triggers();
$this->assertTrue(is_array($sql));
}
}

View File

@ -18,18 +18,22 @@
</testsuite>
<testsuite name="FirebirdTests">
<file>databases/firebird/FirebirdTest.php</file>
<file>databases/firebird/FirebirdTableTest.php</file>
<file>databases/firebird/FirebirdQBTest.php</file>
</testsuite>
<testsuite name="MySQLTests">
<file>databases/mysql/MySQLTest.php</file>
<file>databases/mysql/MySQLTableTest.php</file>
<file>databases/mysql/MySQLQBTest.php</file>
</testsuite>
<testsuite name="PgSQLTests">
<file>databases/pgsql/PgSQLTest.php</file>
<file>databases/pgsql/PgSQLTableTest.php</file>
<file>databases/pgsql/PgSQLQBTest.php</file>
</testsuite>
<testsuite name="SQLiteTests">
<file>databases/sqlite/SqliteTest.php</file>
<file>databases/sqlite/SqliteTableTest.php</file>
<file>databases/sqlite/SqliteQBTest.php</file>
</testsuite>
</testsuites>