Remove unsupported Firebird driver

This commit is contained in:
Timothy Warren 2018-01-22 15:37:31 -05:00
parent 682a706130
commit 01f90d2224
6 changed files with 0 additions and 1519 deletions

View File

@ -1,370 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7.1
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Drivers\Firebird;
use PDO;
use PDOException;
use Query\Drivers\AbstractDriver;
use Query\Drivers\DriverInterface;
/**
* Firebird Database class
*
* PDO-firebird isn't stable, so this is a wrapper of the fbird_ public functions.
*
*/
class Driver extends AbstractDriver implements DriverInterface {
/**
* Reference to the resource returned by
* the last query executed
*
* @var resource
*/
protected $statementLink = NULL;
/**
* Reference to the current transaction
*
* @var resource
*/
protected $trans = NULL;
/**
* Reference to the connection resource
*
* @var resource
*/
protected $conn = NULL;
/**
* Reference to the service resource
*
* @var resource
*/
protected $service = NULL;
/**
* Firebird doesn't have the truncate keyword
*
* @var boolean
*/
protected $hasTruncate = FALSE;
/**
* Open the link to the database
*
* @param string $dbpath
* @param string $user
* @param string $pass
* @param array $options
* @throws PDOException
*/
public function __construct($dbpath, $user='SYSDBA', $pass='masterkey', array $options = [])
{
$connectFunction = (isset($options[PDO::ATTR_PERSISTENT]) && $options[PDO::ATTR_PERSISTENT])
? '\\fbird_pconnect'
: '\\fbird_connect';
$this->conn = $connectFunction($dbpath, $user, $pass, 'utf-8', 0);
$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 AbstractDriver, which defines these
// class variables for the other drivers
$this->_loadSubClasses();
}
/**
* Cleanup some loose ends
* @codeCoverageIgnore
*/
public function __destruct()
{
\fbird_service_detach($this->service);
}
/**
* Return service handle
*
* @return resource
*/
public function getService()
{
return $this->service;
}
/**
* Execute an sql statement and return number of affected rows
*
* @param string $sql
* @return int
*/
public function exec($sql)
{
return NULL;
}
/**
* Implement for compatibility with PDO
*
* @param int $attribute
* @return mixed
*/
public function getAttribute($attribute)
{
return NULL;
}
/**
* Return whether the current statement is in a transaction
*
* @return bool
*/
public function inTransaction()
{
return ! is_null($this->trans);
}
/**
* Returns the last value of the specified generator
*
* @param string $name
* @return mixed
*/
public function lastInsertId($name = NULL)
{
return \fbird_gen_id($name, 0, $this->conn);
}
/**
* Wrapper public function to better match PDO
*
* @param string $sql
* @return Result
* @throws PDOException
*/
public function query($sql = '')
{
if (empty($sql))
{
throw new PDOException("Query method requires an sql query!", 0, NULL);
}
$this->statementLink = (isset($this->trans))
? \fbird_query($this->trans, $sql)
: \fbird_query($this->conn, $sql);
// Throw the error as a exception
$errString = \fbird_errmsg() . "Last query:" . $this->getLastQuery();
if ($this->statementLink === FALSE)
{
throw new PDOException($errString, \fbird_errcode(), NULL);
}
$this->statement = new Result($this->statementLink, $this);
return $this->statement;
}
/**
* Emulate PDO prepare
*
* @param string $query
* @param array $options
* @return Result
* @throws PDOException
*/
public function prepare($query, $options=[])
{
$this->statementLink = \fbird_prepare($this->conn, $query);
// Throw the error as an exception
if ($this->statementLink === FALSE)
{
throw new PDOException(\fbird_errmsg(), \fbird_errcode(), NULL);
}
$this->statement = new Result($this->statementLink, $this);
return $this->statement;
}
/**
* Start a database transaction
*
* @return boolean|null
*/
public function beginTransaction()
{
return (($this->trans = \fbird_trans($this->conn)) !== NULL) ? TRUE : NULL;
}
/**
* Commit a database transaction
*
* @return bool
*/
public function commit()
{
$res = \fbird_commit($this->trans);
$this->trans = NULL;
return $res;
}
/**
* Rollback a transaction
*
* @return bool
*/
public function rollBack()
{
$res = \fbird_rollback($this->trans);
$this->trans = NULL;
return $res;
}
/**
* Set a connection attribute
* @param int $attribute
* @param mixed $value
* @return bool
*/
public function setAttribute($attribute, $value)
{
return FALSE;
}
/**
* Prepare and execute a query
*
* @param string $sql
* @param array $args
* @return Result
*/
public function prepareExecute($sql, $args)
{
$query = $this->prepare($sql);
// Set the statement in the class variable for easy later access
$this->statementLink =& $query;
return $query->execute($args);
}
/**
* Method to emulate PDO->quote
*
* @param string $str
* @param int $paramType
* @return string
*/
public function quote($str, $paramType = PDO::PARAM_STR)
{
if(is_numeric($str))
{
return $str;
}
return "'".str_replace("'", "''", $str)."'";
}
/**
* Method to emulate PDO->errorInfo / PDOStatement->errorInfo
*
* @return array
*/
public function errorInfo()
{
$code = \fbird_errcode();
$msg = \fbird_errmsg();
return [0, $code, $msg];
}
/**
* Method to emulate PDO->errorCode
*
* @return array
*/
public function errorCode()
{
return \fbird_errcode();
}
/**
* Bind a prepared query with arguments for executing
*
* @param string $sql
* @param array $params
* @return NULL
*/
public function prepareQuery($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 array
*/
public function insertBatch($table, $data=[])
{
// Each member of the data array needs to be an array
if ( ! is_array(current($data)))
{
return NULL;
}
// Start the block of sql statements
$sql = "EXECUTE BLOCK AS BEGIN\n";
$table = $this->quoteTable($table);
$fields = \array_keys(\current($data));
$insertTemplate = "INSERT INTO {$table} ("
. implode(',', $this->quoteIdent($fields))
. ") VALUES (";
foreach($data as $item)
{
// Quote string values
$vals = array_map([$this, 'quote'], $item);
// Add the values in the sql
$sql .= $insertTemplate . implode(', ', $vals) . ");\n";
}
// End the block of SQL statements
$sql .= "END";
// Return a null array value so the query is run as it is,
// not as a prepared statement, because a prepared statement
// doesn't work for this type of query in Firebird.
return [$sql, NULL];
}
}

View File

@ -1,270 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7.1
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Drivers\Firebird;
use PDOStatement;
use Query\Drivers\PDOStatementInterface;
/**
* Firebird result class to emulate PDOStatement Class - only implements
* data-fetching methods
*
* @package Query
* @subpackage Drivers
*/
class Result extends PDOStatement implements PDOStatementInterface {
/**
* Reference to fbird resource
*
* @var resource
*/
private $statement;
/**
* Current row in result array
*
* @var integer
*/
private $row;
/**
* Data pulled from query
*
* @var mixed
*/
private $result = [];
/**
* Reference to the db drive to de-duplicate error functions
*
* @var Driver
*/
private $db;
/**
* Create the object by passing the resource for
* the query
*
* @param resource $link
* @param Driver|null $db
*/
public function __construct($link, Driver $db = NULL)
{
if ( ! is_null($db))
{
$this->db = $db;
}
$this->statement = $link;
$this->setFetchMode(\PDO::FETCH_ASSOC);
$this->row = -1;
$this->result = [];
// Create the result array, so that we can get row counts
// Check the resource type, because prepared statements are "interbase query"
// but we only want "interbase result" types when attempting to fetch data
if (\is_resource($link) && \get_resource_type($link) === "interbase result")
{
while($row = \fbird_fetch_assoc($link, \IBASE_FETCH_BLOBS))
{
$this->result[] = $row;
}
// Free the result resource
\fbird_free_result($link);
}
}
/**
* Invalidate method for data consistency
*
* @param mixed $column
* @param mixed $param
* @param int $type
* @param mixed $maxlen
* @param array $driverdata
* @return NULL
*/
public function bindColumn($column, &$param, $type=NULL, $maxlen=NULL, $driverdata=NULL)
{
return NULL;
}
/**
* Invalidate method for data consistency
*
* @param mixed $parameter
* @param mixed $variable
* @param int $dataType
* @param mixed $maxlen
* @param array $driverdata
* @return NULL
*/
public function bindParam($parameter, &$variable, $dataType=NULL, $maxlen=NULL, $driverdata=NULL)
{
return NULL;
}
/**
* Invalidate method for data consistency
*
* @param mixed $parameter
* @param mixed $variable
* @param int $dataType
* @return NULL
*/
public function bindValue($parameter, $variable, $dataType=NULL)
{
return NULL;
}
/**
* Run a prepared statement query
*
* @param array $boundInputParams
* @return Result
*/
public function execute($boundInputParams = NULL)
{
//Add the prepared statement as the first parameter
\array_unshift($boundInputParams, $this->statement);
// Let php do all the hard stuff in converting
// the array of arguments into a list of arguments
// Then pass the resource to the constructor
$this->__construct(\call_user_func_array('fbird_execute', $boundInputParams));
return $this;
}
/**
* Emulate PDO fetch public function
*
* @param int $fetchStyle
* @param mixed $cursorOrientation
* @param mixed $cursorOffset
* @return mixed
*/
public function fetch($fetchStyle=\PDO::FETCH_ASSOC, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset=NULL)
{
// If there is no result, continue
if (empty($this->result))
{
return NULL;
}
// Keep track of the current row being fetched
++$this->row;
// return NULL if the next row doesn't exist
if ( ! isset($this->result[$this->row]))
{
return NULL;
}
switch($fetchStyle)
{
case \PDO::FETCH_OBJ:
$row = (object) $this->result[$this->row];
break;
case \PDO::FETCH_NUM:
$row = \array_values($this->result[$this->row]);
break;
default:
$row = $this->result[$this->row];
break;
}
return $row;
}
/**
* Emulate PDO fetchAll public function
*
* @param int $fetchStyle
* @param mixed $statement
* @param mixed $ctorArgs
* @return mixed
*/
public function fetchAll($fetchStyle=\PDO::FETCH_ASSOC, $statement=NULL, $ctorArgs=NULL)
{
$all = [];
while($row = $this->fetch($fetchStyle, $statement))
{
$all[] = $row;
}
$this->result = $all;
return $all;
}
/**
* Emulate PDOStatement::fetchColumn
*
* @param int $columnNum
* @return mixed
*/
public function fetchColumn($columnNum=0)
{
$row = $this->fetch(\PDO::FETCH_NUM);
return $row[$columnNum];
}
/**
* Emulate PDOStatement::fetchObject, but only for the default use
*
* @param string $className
* @param array|null $ctorArgs
* @return object
*/
public function fetchObject($className='stdClass', $ctorArgs=NULL)
{
return $this->fetch(\PDO::FETCH_OBJ);
}
/**
* Return the number of rows affected by the previous query
*
* @return int
*/
public function rowCount()
{
return \fbird_affected_rows();
}
/**
* Method to emulate PDOStatement->errorCode
*
* @return string
*/
public function errorCode()
{
return $this->db->errorCode();
}
/**
* Method to emulate PDO->errorInfo / PDOStatement->errorInfo
*
* @return array
*/
public function errorInfo()
{
return $this->db->errorInfo();
}
}

View File

@ -1,287 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7.1
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Drivers\Firebird;
use Query\Drivers\AbstractSQL;
/**
* Firebird Specific SQL
*/
class SQL extends AbstractSQL {
/**
* Limit clause
*
* @param string $sql
* @param int $limit
* @param int|bool $offset
* @return string
*/
public function limit($sql, $limit, $offset=FALSE)
{
// Keep the current sql string safe for a moment
$origSql = $sql;
$sql = 'FIRST '. (int) $limit;
if ($offset > 0)
{
$sql .= ' SKIP '. (int) $offset;
}
$sql = preg_replace("`SELECT`i", "SELECT {$sql}", $origSql);
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 dbList()
{
return NULL;
}
/**
* Returns sql to list tables
*
* @return string
*/
public function tableList()
{
return <<<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;
}
/**
* Returns sql to list system tables
*
* @return string
*/
public function systemTableList()
{
return <<<SQL
SELECT TRIM("RDB\$RELATION_NAME")
FROM "RDB\$RELATIONS"
WHERE "RDB\$SYSTEM_FLAG"=1
ORDER BY "RDB\$RELATION_NAME" ASC
SQL;
}
/**
* Returns sql to list views
*
* @return string
*/
public function viewList()
{
return <<<SQL
SELECT DISTINCT TRIM("RDB\$VIEW_NAME")
FROM "RDB\$VIEW_RELATIONS"
SQL;
}
/**
* Returns sql to list triggers
*
* @return string
*/
public function triggerList()
{
return <<<SQL
SELECT * FROM "RDB\$FUNCTIONS"
WHERE "RDB\$SYSTEM_FLAG" = 0
SQL;
}
/**
* Return sql to list functions
*
* @return string
*/
public function functionList()
{
return 'SELECT * FROM "RDB$FUNCTIONS"';
}
/**
* Return sql to list stored procedures
*
* @return string
*/
public function procedureList()
{
return <<<SQL
SELECT "RDB\$PROCEDURE_NAME",
"RDB\$PROCEDURE_ID",
"RDB\$PROCEDURE_INPUTS",
"RDB\$PROCEDURE_OUTPUTS",
"RDB\$DESCRIPTION",
"RDB\$PROCEDURE_SOURCE",
"RDB\$SECURITY_CLASS",
"RDB\$OWNER_NAME",
"RDB\$RUNTIME",
"RDB\$SYSTEM_FLAG",
"RDB\$PROCEDURE_TYPE",
"RDB\$VALID_BLR"
FROM "RDB\$PROCEDURES"
ORDER BY "RDB\$PROCEDURE_NAME" ASC
SQL;
}
/**
* Return sql to list sequences
*
* @return string
*/
public function sequenceList()
{
return <<<SQL
SELECT TRIM("RDB\$GENERATOR_NAME")
FROM "RDB\$GENERATORS"
WHERE "RDB\$SYSTEM_FLAG" = 0
SQL;
}
/**
* Return sql to list columns of the specified table
*
* @param string $table
* @return string
*/
public function columnList($table)
{
return <<<SQL
SELECT r.RDB\$FIELD_NAME AS field_name,
r.RDB\$DESCRIPTION AS field_description,
r.RDB\$DEFAULT_VALUE AS field_default_value,
r.RDB\$NULL_FLAG AS field_not_null_constraint,
f.RDB\$FIELD_LENGTH AS field_length,
f.RDB\$FIELD_PRECISION AS field_precision,
f.RDB\$FIELD_SCALE AS field_scale,
CASE f.RDB\$FIELD_TYPE
WHEN 261 THEN 'BLOB'
WHEN 14 THEN 'CHAR'
WHEN 40 THEN 'CSTRING'
WHEN 11 THEN 'D_FLOAT'
WHEN 27 THEN 'DOUBLE'
WHEN 10 THEN 'FLOAT'
WHEN 16 THEN 'INT64'
WHEN 8 THEN 'INTEGER'
WHEN 9 THEN 'QUAD'
WHEN 7 THEN 'SMALLINT'
WHEN 12 THEN 'DATE'
WHEN 13 THEN 'TIME'
WHEN 35 THEN 'TIMESTAMP'
WHEN 37 THEN 'VARCHAR'
ELSE 'UNKNOWN'
END AS field_type,
f.RDB\$FIELD_SUB_TYPE AS field_subtype,
coll.RDB\$COLLATION_NAME AS field_collation,
cset.RDB\$CHARACTER_SET_NAME AS field_charset
FROM RDB\$RELATION_FIELDS r
LEFT JOIN RDB\$FIELDS f ON r.RDB\$FIELD_SOURCE = f.RDB\$FIELD_NAME
LEFT JOIN RDB\$COLLATIONS coll ON f.RDB\$COLLATION_ID = coll.RDB\$COLLATION_ID
LEFT JOIN RDB\$CHARACTER_SETS cset ON f.RDB\$CHARACTER_SET_ID = cset.RDB\$CHARACTER_SET_ID
WHERE r.RDB\$RELATION_NAME='{$table}'
ORDER BY r.RDB\$FIELD_POSITION
SQL;
}
/**
* SQL to show list of field types
*
* @return string
*/
public function typeList()
{
return <<<SQL
SELECT "RDB\$TYPE_NAME", "RDB\$FIELD_NAME" FROM "RDB\$TYPES"
WHERE "RDB\$FIELD_NAME" IN ('RDB\$FIELD_TYPE', 'RDB\$FIELD_SUB_TYPE')
ORDER BY "RDB\$FIELD_NAME" DESC, "RDB\$TYPE_NAME" ASC
SQL;
}
/**
* Get the list of foreign keys for the current
* table
*
* @param string $table
* @return string
*/
public function fkList($table)
{
return <<<SQL
SELECT DISTINCT
TRIM(d1.RDB\$FIELD_NAME) AS "child_column",
TRIM(d2.RDB\$DEPENDED_ON_NAME) AS "parent_table",
TRIM(d2.RDB\$FIELD_NAME) AS "parent_column",
TRIM(refc.RDB\$UPDATE_RULE) AS "update",
TRIM(refc.RDB\$DELETE_RULE) AS "delete"
FROM RDB\$RELATION_CONSTRAINTS AS rc
LEFT JOIN RDB\$REF_CONSTRAINTS refc ON rc.RDB\$CONSTRAINT_NAME = refc.RDB\$CONSTRAINT_NAME
LEFT JOIN RDB\$DEPENDENCIES d1 ON d1.RDB\$DEPENDED_ON_NAME = rc.RDB\$RELATION_NAME
LEFT JOIN RDB\$DEPENDENCIES d2 ON d1.RDB\$DEPENDENT_NAME = d2.RDB\$DEPENDENT_NAME
WHERE rc.RDB\$CONSTRAINT_TYPE = 'FOREIGN KEY'
AND d1.RDB\$DEPENDED_ON_NAME <> d2.RDB\$DEPENDED_ON_NAME
AND d1.RDB\$FIELD_NAME <> d2.RDB\$FIELD_NAME
AND rc.RDB\$RELATION_NAME = '{$table}' -- table name
SQL;
}
/**
* Get the list of indexes for the current table
*
* @param string $table
* @return array
*/
public function indexList($table)
{
return <<<SQL
SELECT "RDB\$INDEX_NAME", "RDB\$UNIQUE_FLAG", "RDB\$FOREIGN_KEY"
FROM "RDB\$INDICES"
WHERE "RDB\$RELATION_NAME"='{$table}'
SQL;
}
}

View File

@ -1,127 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7.1
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Drivers\Firebird;
use PDO;
use Query\Drivers\AbstractUtil;
/**
* Firebird-specific backup, import and creation methods
*/
class Util extends AbstractUtil {
/**
* Convenience public function to generate sql for creating a db table
*
* @param string $name
* @param array $fields
* @param array $constraints
* @param bool $ifNotExists
* @return string
*/
public function createTable($name, $fields, array $constraints=[], $ifNotExists=FALSE)
{
return parent::createTable($name, $fields, $constraints, FALSE);
}
/**
* Drop the selected table
*
* @param string $name
* @return string
*/
public function deleteTable($name)
{
return 'DROP TABLE '.$this->getDriver()->quoteTable($name);
}
/**
* Create an SQL backup file for the current database's structure
*
* @return string
*/
public function backupStructure(/* @param string $dbPath, @param string $newFile */)
{
list($dbPath, $newFile) = func_get_args();
return ibase_backup($this->getDriver()->getService(), $dbPath, $newFile, \IBASE_BKP_METADATA_ONLY);
}
/**
* Create an SQL backup file for the current database's data
*
* @param array $exclude
* @param bool $systemTables
* @return string
*/
public function backupData($exclude=[], $systemTables=FALSE)
{
// Determine which tables to use
$tables = $this->getDriver()->getTables();
if($systemTables == TRUE)
{
$tables = array_merge($tables, $this->getDriver()->getSystemTables());
}
// Filter out the tables you don't want
if( ! empty($exclude))
{
$tables = array_diff($tables, $exclude);
}
$outputSql = '';
// Get the data for each object
foreach($tables as $t)
{
$sql = 'SELECT * FROM "'.trim($t).'"';
$res = $this->getDriver()->query($sql);
$objRes = $res->fetchAll(PDO::FETCH_ASSOC);
// Don't add to the file if the table is empty
if (count($objRes) < 1)
{
continue;
}
// Nab the column names by getting the keys of the first row
$columns = @array_keys($objRes[0]);
$insertRows = [];
// Create the insert statements
foreach($objRes as $row)
{
$row = array_values($row);
// Quote values as needed by type
if(stripos($t, 'RDB$') === FALSE)
{
$row = array_map([$this->getDriver(), 'quote'], $row);
$row = array_map('trim', $row);
}
$rowString = 'INSERT INTO "'.trim($t).'" ("'.implode('","', $columns).'") VALUES ('.implode(',', $row).');';
$row = NULL;
$insertRows[] = $rowString;
}
$outputSql .= "\n\nSET TRANSACTION;\n".implode("\n", $insertRows)."\nCOMMIT;";
}
return $outputSql;
}
}

View File

@ -1,300 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2016 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Tests\Drivers;
use PDO;
use Query\Drivers\Firebird\Driver;
use Query\Tests\BaseDriverTest;
// --------------------------------------------------------------------------
@chmod(QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB', 0777);
/**
* Firebirdtest class.
*
* @extends DBtest
* @requires extension interbase
*/
class FirebirdDriverTest extends BaseDriverTest {
public static function setupBeforeClass()
{
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
// test the db driver directly
self::$db = new Driver('localhost:'.$dbpath);
self::$db->setTablePrefix('create_');
}
public function setUp()
{
if ( ! \function_exists('\\fbird_connect'))
{
$this->markTestSkipped('Firebird extension does not exist');
}
$this->tables = self::$db->getTables();
}
// --------------------------------------------------------------------------
public function tearDown()
{
unset($this->tables);
}
// --------------------------------------------------------------------------
/**
* coverage for methods in result class that aren't implemented
*/
public function testNullResultMethods()
{
$obj = self::$db->query('SELECT "id" FROM "create_test"');
$val = "bar";
$this->assertNull($obj->bindColumn('foo', $val));
$this->assertNull($obj->bindParam('foo', $val));
$this->assertNull($obj->bindValue('foo', $val));
}
// --------------------------------------------------------------------------
public function testExists()
{
$this->assertTrue(\function_exists('ibase_connect'));
$this->assertTrue(\function_exists('fbird_connect'));
}
// --------------------------------------------------------------------------
public function testConnection()
{
$this->assertIsA(self::$db, Driver::class);
}
// --------------------------------------------------------------------------
public function testGetSystemTables()
{
$onlySystem = TRUE;
$tables = self::$db->getSystemTables();
foreach($tables as $t)
{
if(stripos($t, 'rdb$') !== 0 && stripos($t, 'mon$') !== 0)
{
$onlySystem = FALSE;
break;
}
}
$this->assertTrue($onlySystem);
}
// --------------------------------------------------------------------------
// ! Create / Delete Tables
// --------------------------------------------------------------------------
public function testCreateTable()
{
//Attempt to create the table
$sql = self::$db->getUtil()->createTable('create_delete', array(
'id' => 'SMALLINT',
'key' => 'VARCHAR(64)',
'val' => 'BLOB SUB_TYPE TEXT'
));
self::$db->query($sql);
//Check
$this->assertTrue(\in_array('create_delete', self::$db->getTables(), TRUE));
}
// --------------------------------------------------------------------------
public function testDeleteTable()
{
//Attempt to delete the table
$sql = self::$db->getUtil()->deleteTable('create_delete');
self::$db->query($sql);
//Check
$tableExists = \in_array('create_delete', self::$db->getTables(), TRUE);
$this->assertFalse($tableExists);
}
// --------------------------------------------------------------------------
public function testTruncate()
{
self::$db->truncate('create_test');
$this->assertTrue(self::$db->affectedRows() > 0);
}
// --------------------------------------------------------------------------
public function testCommitTransaction()
{
$res = self::$db->beginTransaction();
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (10, 12, 14)';
self::$db->query($sql);
$res = self::$db->commit();
$this->assertTrue($res);
}
// --------------------------------------------------------------------------
public function testRollbackTransaction()
{
$res = self::$db->beginTransaction();
$sql = 'INSERT INTO "create_test" ("id", "key", "val") VALUES (182, 96, 43)';
self::$db->query($sql);
$res = self::$db->rollback();
$this->assertTrue($res);
}
// --------------------------------------------------------------------------
public function testPreparedStatements()
{
$sql = <<<SQL
INSERT INTO "create_test" ("id", "key", "val")
VALUES (?,?,?)
SQL;
$query = self::$db->prepare($sql);
$query->execute(array(1,"booger's", "Gross"));
}
// --------------------------------------------------------------------------
public function testPrepareExecute()
{
$sql = <<<SQL
INSERT INTO "create_test" ("id", "key", "val")
VALUES (?,?,?)
SQL;
self::$db->prepareExecute($sql, array(
2, "works", 'also?'
));
}
// --------------------------------------------------------------------------
public function testFetch()
{
$res = self::$db->query('SELECT "key","val" FROM "create_test"');
// Object
$fetchObj = $res->fetchObject();
$this->assertIsA($fetchObj, 'stdClass');
// Associative array
$fetchAssoc = $res->fetch(PDO::FETCH_ASSOC);
$this->assertTrue(array_key_exists('key', $fetchAssoc));
// Numeric array
$res2 = self::$db->query('SELECT "id","key","val" FROM "create_test"');
$fetch = $res2->fetch(PDO::FETCH_NUM);
$this->assertTrue(\is_array($fetch));
}
// --------------------------------------------------------------------------
public function testPrepareQuery()
{
$this->assertNull(self::$db->prepareQuery('', array()));
}
// --------------------------------------------------------------------------
public function testErrorInfo()
{
$result = self::$db->errorInfo();
$expected = array (
0 => 0,
1 => false,
2 => false,
);
$this->assertEqual($expected, $result);
}
// --------------------------------------------------------------------------
public function testErrorCode()
{
$result = self::$db->errorCode();
$this->assertFalse($result);
}
// --------------------------------------------------------------------------
public function testDBList()
{
$res = self::$db->getSql()->dbList();
$this->assertNULL($res);
}
// --------------------------------------------------------------------------
public function testExec()
{
$res = self::$db->exec('SELECT * FROM "create_test"');
$this->assertEquals(NULL, $res);
}
// --------------------------------------------------------------------------
public function testInTransaction()
{
self::$db->beginTransaction();
$this->assertTrue(self::$db->inTransaction());
self::$db->rollBack();
$this->assertFalse(self::$db->inTransaction());
}
// --------------------------------------------------------------------------
public function testGetAttribute()
{
$res = self::$db->getAttribute("foo");
$this->assertEquals(NULL, $res);
}
// --------------------------------------------------------------------------
public function testSetAttribute()
{
$this->assertFalse(self::$db->setAttribute(47, 'foo'));
}
public function testLastInsertId()
{
$this->assertEqual(0, self::$db->lastInsertId('NEWTABLE_SEQ'));
}
}

View File

@ -1,165 +0,0 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2016 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat4ion/Query
*/
namespace Query\Tests\Drivers;
use PDO;
use Query\Tests\BaseQueryBuilderTest;
use InvalidArgumentException;
// --------------------------------------------------------------------------
/**
* Firebird Query Builder Tests
* @requires extension interbase
*/
class FirebirdQueryBuilderTest extends BaseQueryBuilderTest {
public static function setUpBeforeClass()
{
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
// test the query builder
$params = new \Stdclass();
$params->alias = 'fire';
$params->type = 'firebird';
$params->file = $dbpath;
$params->host = '127.0.0.1';
$params->user = 'SYSDBA';
$params->pass = 'masterkey';
$params->prefix = 'create_';
self::$db = Query($params);
}
public function setUp()
{
if ( ! \function_exists('\\fbird_connect'))
{
$this->markTestSkipped('Firebird extension does not exist');
}
}
// --------------------------------------------------------------------------
public function testGetNamedConnectionException()
{
try
{
$db = Query('water');
}
catch(InvalidArgumentException $e)
{
$this->assertIsA($e, 'InvalidArgumentException');
}
}
// --------------------------------------------------------------------------
public function testQueryFunctionAlias()
{
$db = Query();
$this->assertTrue(self::$db === $db);
}
// --------------------------------------------------------------------------
public function testGetNamedConnection()
{
$dbpath = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
// test the query builder
$params = new \Stdclass();
$params->alias = 'wood';
$params->type = 'firebird';
$params->file = $dbpath;
$params->host = 'localhost';
$params->user = 'sysdba';
$params->pass = 'masterkey';
$params->prefix = '';
$fConn = Query($params);
$qConn = Query('wood');
$this->assertReference($fConn, $qConn);
}
// --------------------------------------------------------------------------
public function testTypeList()
{
$sql = self::$db->sql->typeList();
$query = self::$db->query($sql);
$this->assertIsA($query, 'PDOStatement');
$res = $query->fetchAll(PDO::FETCH_ASSOC);
$this->assertTrue(is_array($res));
}
// --------------------------------------------------------------------------
public function testQueryExplain()
{
$res = self::$db->select('id, key as k, val')
->explain()
->where('id >', 1)
->where('id <', 900)
->limit(2, 1)
->getCompiledSelect();
$res2 = self::$db->select('id, key as k, val')
->where('id >', 1)
->where('id <', 900)
->limit(2, 1)
->getCompiledSelect();
// Queries are equal because explain is not a keyword in Firebird
$this->assertEqual($res, $res2);
}
// --------------------------------------------------------------------------
public function testResultErrors()
{
$obj = self::$db->query('SELECT * FROM "create_test"');
// Test row count
$this->assertEqual(0, $obj->rowCount());
// Test error code
$this->assertFalse($obj->errorCode());
// Test error info
$error = $obj->errorInfo();
$expected = array (
0 => 0,
1 => false,
2 => false,
);
$this->assertEqual($expected, $error);
}
// --------------------------------------------------------------------------
public function testBackupStructure()
{
$existing = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_DB.FDB';
$backup = QTEST_DIR.QDS.'db_files'.QDS.'FB_TEST_BKP.FDB';
$this->assertTrue(self::$db->getUtil()->backupStructure($existing, $backup));
}
}