Remove unsupported Firebird driver
This commit is contained in:
parent
682a706130
commit
01f90d2224
@ -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];
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user