mirror of
https://github.com/dg/dibi.git
synced 2025-08-11 16:44:30 +02:00
Revert "removed MsSqlDriver (is not available with PHP 5.3 or later; replaced with SqlsrvDriver)"
This reverts commit ac1ab26e7a
.
This commit is contained in:
@@ -112,6 +112,22 @@ try {
|
|||||||
echo "</p>\n";
|
echo "</p>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// connects to MS SQL
|
||||||
|
echo '<p>Connecting to MS SQL: ';
|
||||||
|
try {
|
||||||
|
dibi::connect([
|
||||||
|
'driver' => 'mssql',
|
||||||
|
'host' => 'localhost',
|
||||||
|
'username' => 'root',
|
||||||
|
'password' => 'xxx',
|
||||||
|
]);
|
||||||
|
echo 'OK';
|
||||||
|
} catch (Dibi\Exception $e) {
|
||||||
|
echo get_class($e), ': ', $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
echo "</p>\n";
|
||||||
|
|
||||||
|
|
||||||
// connects to SQLSRV
|
// connects to SQLSRV
|
||||||
echo '<p>Connecting to Microsoft SQL Server: ';
|
echo '<p>Connecting to Microsoft SQL Server: ';
|
||||||
try {
|
try {
|
||||||
|
386
src/Dibi/Drivers/MsSqlDriver.php
Normal file
386
src/Dibi/Drivers/MsSqlDriver.php
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the "dibi" - smart database abstraction layer.
|
||||||
|
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
|
use Dibi;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dibi driver for MS SQL database.
|
||||||
|
*
|
||||||
|
* Driver options:
|
||||||
|
* - host => the MS SQL server host name. It can also include a port number (hostname:port)
|
||||||
|
* - username (or user)
|
||||||
|
* - password (or pass)
|
||||||
|
* - database => the database name to select
|
||||||
|
* - persistent (bool) => try to find a persistent link?
|
||||||
|
* - resource (resource) => existing connection resource
|
||||||
|
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
|
||||||
|
*/
|
||||||
|
class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||||
|
{
|
||||||
|
use Dibi\Strict;
|
||||||
|
|
||||||
|
/** @var resource Connection resource */
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/** @var resource Resultset resource */
|
||||||
|
private $resultSet;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $autoFree = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Dibi\NotSupportedException
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
if (!extension_loaded('mssql')) {
|
||||||
|
throw new Dibi\NotSupportedException("PHP extension 'mssql' is not loaded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to a database.
|
||||||
|
* @return void
|
||||||
|
* @throws Dibi\Exception
|
||||||
|
*/
|
||||||
|
public function connect(array & $config)
|
||||||
|
{
|
||||||
|
if (isset($config['resource'])) {
|
||||||
|
$this->connection = $config['resource'];
|
||||||
|
} elseif (empty($config['persistent'])) {
|
||||||
|
$this->connection = @mssql_connect($config['host'], $config['username'], $config['password'], TRUE); // intentionally @
|
||||||
|
} else {
|
||||||
|
$this->connection = @mssql_pconnect($config['host'], $config['username'], $config['password']); // intentionally @
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_resource($this->connection)) {
|
||||||
|
throw new Dibi\DriverException("Can't connect to DB.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['database']) && !@mssql_select_db($this->escapeIdentifier($config['database']), $this->connection)) { // intentionally @
|
||||||
|
throw new Dibi\DriverException("Can't select DB '$config[database]'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects from a database.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function disconnect()
|
||||||
|
{
|
||||||
|
mssql_close($this->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the SQL query.
|
||||||
|
* @param string SQL statement.
|
||||||
|
* @return Dibi\ResultDriver|NULL
|
||||||
|
* @throws Dibi\DriverException
|
||||||
|
*/
|
||||||
|
public function query($sql)
|
||||||
|
{
|
||||||
|
$res = @mssql_query($sql, $this->connection); // intentionally @
|
||||||
|
|
||||||
|
if ($res === FALSE) {
|
||||||
|
throw new Dibi\DriverException(mssql_get_last_message(), 0, $sql);
|
||||||
|
|
||||||
|
} elseif (is_resource($res)) {
|
||||||
|
return $this->createResultDriver($res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
|
||||||
|
* @return int|FALSE number of rows or FALSE on error
|
||||||
|
*/
|
||||||
|
public function getAffectedRows()
|
||||||
|
{
|
||||||
|
return mssql_rows_affected($this->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
|
||||||
|
* @return int|FALSE int on success or FALSE on failure
|
||||||
|
*/
|
||||||
|
public function getInsertId($sequence)
|
||||||
|
{
|
||||||
|
$res = mssql_query('SELECT @@IDENTITY', $this->connection);
|
||||||
|
if (is_resource($res)) {
|
||||||
|
$row = mssql_fetch_row($res);
|
||||||
|
return $row[0];
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a transaction (if supported).
|
||||||
|
* @param string optional savepoint name
|
||||||
|
* @return void
|
||||||
|
* @throws Dibi\DriverException
|
||||||
|
*/
|
||||||
|
public function begin($savepoint = NULL)
|
||||||
|
{
|
||||||
|
$this->query('BEGIN TRANSACTION');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commits statements in a transaction.
|
||||||
|
* @param string optional savepoint name
|
||||||
|
* @return void
|
||||||
|
* @throws Dibi\DriverException
|
||||||
|
*/
|
||||||
|
public function commit($savepoint = NULL)
|
||||||
|
{
|
||||||
|
$this->query('COMMIT');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback changes in a transaction.
|
||||||
|
* @param string optional savepoint name
|
||||||
|
* @return void
|
||||||
|
* @throws Dibi\DriverException
|
||||||
|
*/
|
||||||
|
public function rollback($savepoint = NULL)
|
||||||
|
{
|
||||||
|
$this->query('ROLLBACK');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection resource.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getResource()
|
||||||
|
{
|
||||||
|
return is_resource($this->connection) ? $this->connection : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection reflector.
|
||||||
|
* @return Dibi\Reflector
|
||||||
|
*/
|
||||||
|
public function getReflector()
|
||||||
|
{
|
||||||
|
return new MsSqlReflector($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result set driver factory.
|
||||||
|
* @param resource
|
||||||
|
* @return Dibi\ResultDriver
|
||||||
|
*/
|
||||||
|
public function createResultDriver($resource)
|
||||||
|
{
|
||||||
|
$res = clone $this;
|
||||||
|
$res->resultSet = $resource;
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************* SQL ****************d*g**/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes data for use in a SQL statement.
|
||||||
|
* @param mixed value
|
||||||
|
* @return string encoded value
|
||||||
|
*/
|
||||||
|
public function escapeText($value)
|
||||||
|
{
|
||||||
|
return "'" . str_replace("'", "''", $value) . "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function escapeBinary($value)
|
||||||
|
{
|
||||||
|
return "'" . str_replace("'", "''", $value) . "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function escapeIdentifier($value)
|
||||||
|
{
|
||||||
|
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
|
||||||
|
return '[' . str_replace(['[', ']'], ['[[', ']]'], $value) . ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function escapeBool($value)
|
||||||
|
{
|
||||||
|
return $value ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function escapeDate($value)
|
||||||
|
{
|
||||||
|
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
|
||||||
|
$value = new Dibi\DateTime($value);
|
||||||
|
}
|
||||||
|
return $value->format("'Y-m-d'");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function escapeDateTime($value)
|
||||||
|
{
|
||||||
|
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
|
||||||
|
$value = new Dibi\DateTime($value);
|
||||||
|
}
|
||||||
|
return $value->format("'Y-m-d H:i:s'");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes string for use in a LIKE statement.
|
||||||
|
* @param string
|
||||||
|
* @param int
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function escapeLike($value, $pos)
|
||||||
|
{
|
||||||
|
$value = strtr($value, ["'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]']);
|
||||||
|
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes data from result set.
|
||||||
|
* @param string
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function unescapeBinary($value)
|
||||||
|
{
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
public function escape($value, $type)
|
||||||
|
{
|
||||||
|
trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
|
||||||
|
return Dibi\Helpers::escape($this, $value, $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects LIMIT/OFFSET to the SQL query.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
|
{
|
||||||
|
if ($offset) {
|
||||||
|
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||||
|
|
||||||
|
} elseif ($limit < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL) {
|
||||||
|
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************* result set ****************d*g**/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically frees the resources allocated for this result set.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
$this->autoFree && $this->getResultResource() && $this->free();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows in a result set.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getRowCount()
|
||||||
|
{
|
||||||
|
return mssql_num_rows($this->resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the row at current position and moves the internal cursor to the next position.
|
||||||
|
* @param bool TRUE for associative array, FALSE for numeric
|
||||||
|
* @return array array on success, nonarray if no next record
|
||||||
|
*/
|
||||||
|
public function fetch($assoc)
|
||||||
|
{
|
||||||
|
return mssql_fetch_array($this->resultSet, $assoc ? MSSQL_ASSOC : MSSQL_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves cursor position without fetching row.
|
||||||
|
* @param int the 0-based cursor pos to seek to
|
||||||
|
* @return boolean TRUE on success, FALSE if unable to seek to specified record
|
||||||
|
*/
|
||||||
|
public function seek($row)
|
||||||
|
{
|
||||||
|
return mssql_data_seek($this->resultSet, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the resources allocated for this result set.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function free()
|
||||||
|
{
|
||||||
|
mssql_free_result($this->resultSet);
|
||||||
|
$this->resultSet = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns metadata for all columns in a result set.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getResultColumns()
|
||||||
|
{
|
||||||
|
$count = mssql_num_fields($this->resultSet);
|
||||||
|
$columns = [];
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
$row = (array) mssql_fetch_field($this->resultSet, $i);
|
||||||
|
$columns[] = [
|
||||||
|
'name' => $row['name'],
|
||||||
|
'fullname' => $row['column_source'] ? $row['column_source'] . '.' . $row['name'] : $row['name'],
|
||||||
|
'table' => $row['column_source'],
|
||||||
|
'nativetype' => $row['type'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the result set resource.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getResultResource()
|
||||||
|
{
|
||||||
|
$this->autoFree = FALSE;
|
||||||
|
return is_resource($this->resultSet) ? $this->resultSet : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
216
src/Dibi/Drivers/MsSqlReflector.php
Normal file
216
src/Dibi/Drivers/MsSqlReflector.php
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the "dibi" - smart database abstraction layer.
|
||||||
|
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
|
use Dibi;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dibi reflector for MS SQL databases.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class MsSqlReflector implements Dibi\Reflector
|
||||||
|
{
|
||||||
|
use Dibi\Strict;
|
||||||
|
|
||||||
|
/** @var Dibi\Driver */
|
||||||
|
private $driver;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct(Dibi\Driver $driver)
|
||||||
|
{
|
||||||
|
$this->driver = $driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns list of tables.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTables()
|
||||||
|
{
|
||||||
|
$res = $this->driver->query('
|
||||||
|
SELECT TABLE_NAME, TABLE_TYPE
|
||||||
|
FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
');
|
||||||
|
$tables = [];
|
||||||
|
while ($row = $res->fetch(FALSE)) {
|
||||||
|
$tables[] = [
|
||||||
|
'name' => $row[0],
|
||||||
|
'view' => isset($row[1]) && $row[1] === 'VIEW',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns count of rows in a table
|
||||||
|
* @param string
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTableCount($table, $fallback = TRUE)
|
||||||
|
{
|
||||||
|
if (empty($table)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
$result = $this->driver->query("
|
||||||
|
SELECT MAX(rowcnt)
|
||||||
|
FROM sys.sysindexes
|
||||||
|
WHERE id=OBJECT_ID({$this->driver->escapeIdentifier($table)})
|
||||||
|
");
|
||||||
|
$row = $result->fetch(FALSE);
|
||||||
|
|
||||||
|
if (!is_array($row) || count($row) < 1) {
|
||||||
|
if ($fallback) {
|
||||||
|
$row = $this->driver->query("SELECT COUNT(*) FROM {$this->driver->escapeIdentifier($table)}")->fetch(FALSE);
|
||||||
|
$count = intval($row[0]);
|
||||||
|
} else {
|
||||||
|
$count = FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$count = intval($row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns metadata for all columns in a table.
|
||||||
|
* @param string
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getColumns($table)
|
||||||
|
{
|
||||||
|
$res = $this->driver->query("
|
||||||
|
SELECT * FROM
|
||||||
|
INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_NAME = {$this->driver->escapeText($table)}
|
||||||
|
ORDER BY TABLE_NAME, ORDINAL_POSITION
|
||||||
|
");
|
||||||
|
$columns = [];
|
||||||
|
while ($row = $res->fetch(TRUE)) {
|
||||||
|
$size = FALSE;
|
||||||
|
$type = strtoupper($row['DATA_TYPE']);
|
||||||
|
|
||||||
|
$size_cols = [
|
||||||
|
'DATETIME' => 'DATETIME_PRECISION',
|
||||||
|
'DECIMAL' => 'NUMERIC_PRECISION',
|
||||||
|
'CHAR' => 'CHARACTER_MAXIMUM_LENGTH',
|
||||||
|
'NCHAR' => 'CHARACTER_OCTET_LENGTH',
|
||||||
|
'NVARCHAR' => 'CHARACTER_OCTET_LENGTH',
|
||||||
|
'VARCHAR' => 'CHARACTER_OCTET_LENGTH',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($size_cols[$type])) {
|
||||||
|
if ($size_cols[$type]) {
|
||||||
|
$size = $row[$size_cols[$type]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns[] = [
|
||||||
|
'name' => $row['COLUMN_NAME'],
|
||||||
|
'table' => $table,
|
||||||
|
'nativetype' => $type,
|
||||||
|
'size' => $size,
|
||||||
|
'unsigned' => NULL,
|
||||||
|
'nullable' => $row['IS_NULLABLE'] === 'YES',
|
||||||
|
'default' => $row['COLUMN_DEFAULT'],
|
||||||
|
'autoincrement' => FALSE,
|
||||||
|
'vendor' => $row,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns metadata for all indexes in a table.
|
||||||
|
* @param string
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getIndexes($table)
|
||||||
|
{
|
||||||
|
$res = $this->driver->query(
|
||||||
|
"SELECT ind.name index_name, ind.index_id, ic.index_column_id,
|
||||||
|
col.name column_name, ind.is_unique, ind.is_primary_key
|
||||||
|
FROM sys.indexes ind
|
||||||
|
INNER JOIN sys.index_columns ic ON
|
||||||
|
(ind.object_id = ic.object_id AND ind.index_id = ic.index_id)
|
||||||
|
INNER JOIN sys.columns col ON
|
||||||
|
(ic.object_id = col.object_id and ic.column_id = col.column_id)
|
||||||
|
INNER JOIN sys.tables t ON
|
||||||
|
(ind.object_id = t.object_id)
|
||||||
|
WHERE t.name = {$this->driver->escapeText($table)}
|
||||||
|
AND t.is_ms_shipped = 0
|
||||||
|
ORDER BY
|
||||||
|
t.name, ind.name, ind.index_id, ic.index_column_id
|
||||||
|
");
|
||||||
|
|
||||||
|
$indexes = [];
|
||||||
|
while ($row = $res->fetch(TRUE)) {
|
||||||
|
$index_name = $row['index_name'];
|
||||||
|
|
||||||
|
if (!isset($indexes[$index_name])) {
|
||||||
|
$indexes[$index_name] = [];
|
||||||
|
$indexes[$index_name]['name'] = $index_name;
|
||||||
|
$indexes[$index_name]['unique'] = (bool) $row['is_unique'];
|
||||||
|
$indexes[$index_name]['primary'] = (bool) $row['is_primary_key'];
|
||||||
|
$indexes[$index_name]['columns'] = [];
|
||||||
|
}
|
||||||
|
$indexes[$index_name]['columns'][] = $row['column_name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($indexes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns metadata for all foreign keys in a table.
|
||||||
|
* @param string
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getForeignKeys($table)
|
||||||
|
{
|
||||||
|
$res = $this->driver->query("
|
||||||
|
SELECT f.name AS foreign_key,
|
||||||
|
OBJECT_NAME(f.parent_object_id) AS table_name,
|
||||||
|
COL_NAME(fc.parent_object_id,
|
||||||
|
fc.parent_column_id) AS column_name,
|
||||||
|
OBJECT_NAME (f.referenced_object_id) AS reference_table_name,
|
||||||
|
COL_NAME(fc.referenced_object_id,
|
||||||
|
fc.referenced_column_id) AS reference_column_name,
|
||||||
|
fc.*
|
||||||
|
FROM sys.foreign_keys AS f
|
||||||
|
INNER JOIN sys.foreign_key_columns AS fc
|
||||||
|
ON f.OBJECT_ID = fc.constraint_object_id
|
||||||
|
WHERE OBJECT_NAME(f.parent_object_id) = {$this->driver->escapeText($table)}
|
||||||
|
");
|
||||||
|
|
||||||
|
$keys = [];
|
||||||
|
while ($row = $res->fetch(TRUE)) {
|
||||||
|
$key_name = $row['foreign_key'];
|
||||||
|
|
||||||
|
if (!isset($keys[$key_name])) {
|
||||||
|
$keys[$key_name]['name'] = $row['foreign_key']; // foreign key name
|
||||||
|
$keys[$key_name]['local'] = [$row['column_name']]; // local columns
|
||||||
|
$keys[$key_name]['table'] = $row['reference_table_name']; // referenced table
|
||||||
|
$keys[$key_name]['foreign'] = [$row['reference_column_name']]; // referenced columns
|
||||||
|
$keys[$key_name]['onDelete'] = FALSE;
|
||||||
|
$keys[$key_name]['onUpdate'] = FALSE;
|
||||||
|
} else {
|
||||||
|
$keys[$key_name]['local'][] = $row['column_name']; // local columns
|
||||||
|
$keys[$key_name]['foreign'][] = $row['reference_column_name']; // referenced columns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array_values($keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -291,6 +291,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
return '[' . strtr($value, '[]', ' ') . ']';
|
return '[' . strtr($value, '[]', ' ') . ']';
|
||||||
|
|
||||||
case 'odbc':
|
case 'odbc':
|
||||||
|
case 'mssql':
|
||||||
return '[' . str_replace(['[', ']'], ['[[', ']]'], $value) . ']';
|
return '[' . str_replace(['[', ']'], ['[[', ']]'], $value) . ']';
|
||||||
|
|
||||||
case 'dblib':
|
case 'dblib':
|
||||||
@@ -360,6 +361,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'") . " ESCAPE '\\'";
|
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'") . " ESCAPE '\\'";
|
||||||
|
|
||||||
case 'odbc':
|
case 'odbc':
|
||||||
|
case 'mssql':
|
||||||
case 'dblib':
|
case 'dblib':
|
||||||
case 'sqlsrv':
|
case 'sqlsrv':
|
||||||
$value = strtr($value, ["'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]']);
|
$value = strtr($value, ["'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]']);
|
||||||
@@ -437,6 +439,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'mssql':
|
||||||
case 'sqlsrv':
|
case 'sqlsrv':
|
||||||
case 'dblib':
|
case 'dblib':
|
||||||
if (version_compare($this->serverVersion, '11.0') >= 0) { // 11 == SQL Server 2012
|
if (version_compare($this->serverVersion, '11.0') >= 0) { // 11 == SQL Server 2012
|
||||||
|
@@ -26,6 +26,8 @@ spl_autoload_register(function ($class) {
|
|||||||
'Dibi\Drivers\FirebirdDriver' => 'Drivers/FirebirdDriver.php',
|
'Dibi\Drivers\FirebirdDriver' => 'Drivers/FirebirdDriver.php',
|
||||||
'Dibi\Drivers\SqlsrvDriver' => 'Drivers/SqlsrvDriver.php',
|
'Dibi\Drivers\SqlsrvDriver' => 'Drivers/SqlsrvDriver.php',
|
||||||
'Dibi\Drivers\SqlsrvReflector' => 'Drivers/SqlsrvReflector.php',
|
'Dibi\Drivers\SqlsrvReflector' => 'Drivers/SqlsrvReflector.php',
|
||||||
|
'Dibi\Drivers\MsSqlDriver' => 'Drivers/MsSqlDriver.php',
|
||||||
|
'Dibi\Drivers\MsSqlReflector' => 'Drivers/MsSqlReflector.php',
|
||||||
'Dibi\Drivers\MySqlDriver' => 'Drivers/MySqlDriver.php',
|
'Dibi\Drivers\MySqlDriver' => 'Drivers/MySqlDriver.php',
|
||||||
'Dibi\Drivers\MySqliDriver' => 'Drivers/MySqliDriver.php',
|
'Dibi\Drivers\MySqliDriver' => 'Drivers/MySqliDriver.php',
|
||||||
'Dibi\Drivers\MySqlReflector' => 'Drivers/MySqlReflector.php',
|
'Dibi\Drivers\MySqlReflector' => 'Drivers/MySqlReflector.php',
|
||||||
@@ -84,6 +86,8 @@ spl_autoload_register(function ($class) {
|
|||||||
'DibiLiteral' => 'Dibi\Literal',
|
'DibiLiteral' => 'Dibi\Literal',
|
||||||
'DibiMsSql2005Driver' => 'Dibi\Drivers\SqlsrvDriver',
|
'DibiMsSql2005Driver' => 'Dibi\Drivers\SqlsrvDriver',
|
||||||
'DibiMsSql2005Reflector' => 'Dibi\Drivers\SqlsrvReflector',
|
'DibiMsSql2005Reflector' => 'Dibi\Drivers\SqlsrvReflector',
|
||||||
|
'DibiMsSqlDriver' => 'Dibi\Drivers\MsSqlDriver',
|
||||||
|
'DibiMsSqlReflector' => 'Dibi\Drivers\MsSqlReflector',
|
||||||
'DibiMySqlDriver' => 'Dibi\Drivers\MySqlDriver',
|
'DibiMySqlDriver' => 'Dibi\Drivers\MySqlDriver',
|
||||||
'DibiMySqliDriver' => 'Dibi\Drivers\MySqliDriver',
|
'DibiMySqliDriver' => 'Dibi\Drivers\MySqliDriver',
|
||||||
'DibiMySqlReflector' => 'Dibi\Drivers\MySqlReflector',
|
'DibiMySqlReflector' => 'Dibi\Drivers\MySqlReflector',
|
||||||
|
@@ -57,6 +57,20 @@ username =
|
|||||||
password =
|
password =
|
||||||
system = odbc
|
system = odbc
|
||||||
|
|
||||||
|
[mssql]
|
||||||
|
driver = mssql
|
||||||
|
host = 127.0.0.1
|
||||||
|
username = dibi
|
||||||
|
password =
|
||||||
|
system = mssql
|
||||||
|
|
||||||
|
[mssql pdo]
|
||||||
|
driver = pdo
|
||||||
|
host = mssql:host=127.0.0.1;dbname=dibi_test
|
||||||
|
username = dibi
|
||||||
|
password =
|
||||||
|
system = mssql
|
||||||
|
|
||||||
[sqlsrv]
|
[sqlsrv]
|
||||||
driver = sqlsrv
|
driver = sqlsrv
|
||||||
host = (local)
|
host = (local)
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
[PHP]
|
[PHP]
|
||||||
extension_dir = "./ext"
|
extension_dir = "./ext"
|
||||||
|
;extension=php_mssql.dll
|
||||||
extension=php_mysql.dll
|
extension=php_mysql.dll
|
||||||
extension=php_mysqli.dll
|
extension=php_mysqli.dll
|
||||||
;extension=php_oci8.dll
|
;extension=php_oci8.dll
|
||||||
;extension=php_oci8_11g.dll
|
;extension=php_oci8_11g.dll
|
||||||
;extension=php_pdo_firebird.dll
|
;extension=php_pdo_firebird.dll
|
||||||
|
;extension=php_pdo_mssql.dll
|
||||||
extension=php_pdo_mysql.dll
|
extension=php_pdo_mysql.dll
|
||||||
;extension=php_pdo_oci.dll
|
;extension=php_pdo_oci.dll
|
||||||
extension=php_pdo_odbc.dll
|
extension=php_pdo_odbc.dll
|
||||||
|
Reference in New Issue
Block a user