Source for file sqlsrv.php
Documentation is available at sqlsrv.php
* @package Joomla.Platform
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* SQL Server database driver
* @package Joomla.Platform
* @see http://msdn.microsoft.com/en-us/library/cc296152(SQL.90).aspx
* The name of the database driver.
* The character(s) used to quote SQL statement names such as table names or field names,
* etc. The child classes should define this as necessary. If a single character string the
* same character is used for both sides of the quoted name, else the first character will be
* used for the opening quote and the second for the closing quote.
* The null or zero representation of a timestamp for the database driver. This should be
* defined in child classes to hold the appropriate value for the engine.
* @var string The minimum supported database version.
protected static $dbMinimum =
'10.50.1600.1';
* Test to see if the SQLSRV connector is available.
* @return boolean True on success, false otherwise.
* @param array $options List of options used to configure the connection
// Get some basic values from the options.
$options['host'] =
(isset
($options['host'])) ?
$options['host'] :
'localhost';
$options['user'] =
(isset
($options['user'])) ?
$options['user'] :
'';
$options['password'] =
(isset
($options['password'])) ?
$options['password'] :
'';
$options['database'] =
(isset
($options['database'])) ?
$options['database'] :
'';
$options['select'] =
(isset
($options['select'])) ? (bool)
$options['select'] :
true;
// Finalize initialisation
* Connects to the database if needed.
* @return void Returns void if the database connected successfully.
* @throws RuntimeException
// Build the connection configuration array.
'Database' =>
$this->options['database'],
'pwd' =>
$this->options['password'],
'CharacterSet' =>
'UTF-8',
'ReturnDatesAsStrings' =>
true);
// Make sure the SQLSRV extension for PHP is installed and enabled.
throw
new RuntimeException('PHP extension sqlsrv_connect is not available.');
// Attempt to connect to the server.
throw
new RuntimeException('Database sqlsrv_connect failed');
// Make sure that DB warnings are not returned as errors.
sqlsrv_configure('WarningsReturnAsErrors', 0);
// If auto-select is enabled select the given database.
* Disconnects the database.
* @param string $tableName The name of the database table.
* @return array Any constraints available for the table.
'SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = ' .
$query->quote($tableName)
* @param array $constraints Array(strings) of table constraints
* @param string $prefix A string
* @param string $backup A string
protected function renameConstraints($constraints =
array(), $prefix =
null, $backup =
null)
foreach ($constraints as $constraint)
$this->setQuery('sp_rename ' .
$constraint .
',' .
str_replace($prefix, $backup, $constraint));
* Method to escape a string for usage in an SQL statement.
* The escaping for MSSQL isn't handled in the driver though that would be nice. Because of this we need
* to handle the escaping ourselves.
* @param string $text The string to be escaped.
* @param boolean $extra Optional parameter to provide extra escaping.
* @return string The escaped string.
public function escape($text, $extra =
false)
// We need the below str_replace since the search in sql server doesn't recognize _ character.
* Determines if the connection to the server is active.
* @return boolean True if connected to the database engine.
// TODO: Run a blank query here
* Drops a table from the database.
* @param string $tableName The name of the database table to drop.
* @param boolean $ifExists Optionally specify that the table must exist before it is dropped.
* @return JDatabaseDriverSqlsrv Returns this object to support chaining.
public function dropTable($tableName, $ifExists =
true)
'IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ' .
$query->quote($tableName) .
') DROP TABLE ' .
$tableName
$this->setQuery('DROP TABLE ' .
$tableName);
* Get the number of affected rows for the previous executed SQL statement.
* @return integer The number of affected rows.
return sqlsrv_rows_affected($this->cursor);
* Method to get the database collation in use by sampling a text field of a table in the database.
* @return mixed The collation in use by the database or boolean false if not supported.
return 'MSSQL UTF-8 (UCS2)';
* Get the number of returned rows for the previous executed SQL statement.
* @param resource $cursor An optional database cursor resource to extract the row count from.
* @return integer The number of returned rows.
return sqlsrv_num_rows($cursor ?
$cursor :
$this->cursor);
* Retrieves field information about the given tables.
* @param mixed $table A table name
* @param boolean $typeOnly True to only return field types.
* @return array An array of fields.
* @throws RuntimeException
// Set the query to get the table fields statement.
'SELECT column_name as Field, data_type as Type, is_nullable as \'Null\', column_default as \'Default\'' .
' FROM information_schema.columns WHERE table_name = ' .
$this->quote($table_temp)
// If we only want the type as the value add just that to the list.
foreach ($fields as $field)
$result[$field->Field] =
preg_replace("/[(0-9)]/", '', $field->Type);
// If we want the whole field data object add that to the list.
foreach ($fields as $field)
$result[$field->Field] =
$field;
* Shows the table CREATE statement that creates the given tables.
* This is unsupported by MSSQL.
* @param mixed $tables A table name or a list of table names.
* @return array A list of the create SQL for the tables.
* @throws RuntimeException
* Get the details list of keys for a table.
* @param string $table The name of the table.
* @return array An array of the column specification for the table.
* @throws RuntimeException
* Method to get an array of all tables in the database.
* @return array An array of all the tables in the database.
* @throws RuntimeException
// Set the query to get the tables statement.
$this->setQuery('SELECT name FROM ' .
$this->getDatabase() .
'.sys.Tables WHERE type = \'U\';');
* Get the version of the database connector.
* @return string The database connector version.
return $version['SQLServerVersion'];
* Inserts a row into a table based on an object's properties.
* @param string $table The name of the database table to insert into.
* @param object &$object A reference to an object whose public properties match the table fields.
* @param string $key The name of the primary key. If provided the object property is updated.
* @return boolean True on success.
* @throws RuntimeException
$statement =
'INSERT INTO ' .
$this->quoteName($table) .
' (%s) VALUES (%s)';
// Only process non-null scalars.
if ($k ==
$key &&
$key ==
0)
$values[] =
$this->Quote($v);
// Set the query and execute the insert.
* Method to get the auto-incremented value from the last INSERT statement.
* @return integer The value of the auto-increment field from the last inserted row.
* Method to get the first field of the first row of the result set from the database query.
* @return mixed The return value or null if the query failed.
* @throws RuntimeException
// Execute the query and get the result set cursor.
// Get the first row from the result set as an array.
if ($row =
sqlsrv_fetch_array($cursor, SQLSRV_FETCH_NUMERIC))
// Free up system resources and return.
// For SQLServer - we need to strip slashes
* Execute the SQL statement.
* @return mixed A database cursor resource on success, boolean false on failure.
* @throws RuntimeException
// Take a local copy so that we don't modify the original query and cause issues later
// Increment the query counter.
// Reset the error values.
// If debugging is enabled then let's log the query.
// Add the query to the object queue.
// SQLSrv_num_rows requires a static or keyset cursor.
$array =
array('Scrollable' =>
SQLSRV_CURSOR_KEYSET);
// Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost.
if (defined('DEBUG_BACKTRACE_IGNORE_ARGS'))
// If an error occurred handle it.
// Check if the server was disconnected.
// If connect fails, ignore that exception and throw the normal exception.
catch
(RuntimeException $e)
// Get the error number and message.
$errors =
sqlsrv_errors();
$this->errorNum =
$errors[0]['SQLSTATE'];
$this->errorMsg =
$errors[0]['message'] .
'SQL=' .
$query;
// Throw the normal query exception.
// Since we were able to reconnect, run the query again.
// The server was not disconnected.
// Get the error number and message.
$errors =
sqlsrv_errors();
$this->errorNum =
$errors[0]['SQLSTATE'];
$this->errorMsg =
$errors[0]['message'] .
'SQL=' .
$query;
// Throw the normal query exception.
* This function replaces a string identifier <var>$prefix</var> with the string held is the
* <var>tablePrefix</var> class variable.
* @param string $query The SQL statement to prepare.
* @param string $prefix The common table prefix.
* @return string The processed SQL statement.
$ip =
strpos($query, $prefix, $startPos);
$j =
strpos($query, "N'", $startPos);
$k =
strpos($query, '"', $startPos);
if (($k !==
false) &&
(($k <
$j) ||
($j ===
false)))
// Quote comes first, find end of quote
$k =
strpos($query, $quoteChar, $j);
while ($l >=
0 &&
$query{$l} ==
'\\')
// Error in the query - no end quote; ignore it
$literal .=
substr($query, $startPos, $k -
$startPos +
1);
$literal .=
substr($query, $startPos, $n -
$startPos);
* Select a database for use.
* @param string $database The name of the database to select for use.
* @return boolean True if the database was successfully selected.
* @throws RuntimeException
public function select($database)
if (!sqlsrv_query($this->connection, 'USE ' .
$database, null, array('scrollable' =>
SQLSRV_CURSOR_STATIC)))
throw
new RuntimeException('Could not connect to database');
* Set the connection to use UTF-8 character encoding.
* @return boolean True on success.
* Method to commit a transaction.
* @param boolean $toSavepoint If true, commit to the last savepoint.
* @throws RuntimeException
if ($this->setQuery('COMMIT TRANSACTION')->execute())
* Method to roll back a transaction.
* @param boolean $toSavepoint If true, rollback to the last savepoint.
* @throws RuntimeException
if ($this->setQuery('ROLLBACK TRANSACTION')->execute())
* Method to initialize a transaction.
* @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created.
* @throws RuntimeException
if ($this->setQuery('BEGIN TRANSACTION')->execute())
* Method to fetch a row from the result set cursor as an array.
* @param mixed $cursor The optional result set cursor from which to fetch the row.
* @return mixed Either the next row from the result set or false if there are no more rows.
return sqlsrv_fetch_array($cursor ?
$cursor :
$this->cursor, SQLSRV_FETCH_NUMERIC);
* Method to fetch a row from the result set cursor as an associative array.
* @param mixed $cursor The optional result set cursor from which to fetch the row.
* @return mixed Either the next row from the result set or false if there are no more rows.
return sqlsrv_fetch_array($cursor ?
$cursor :
$this->cursor, SQLSRV_FETCH_ASSOC);
* Method to fetch a row from the result set cursor as an object.
* @param mixed $cursor The optional result set cursor from which to fetch the row.
* @param string $class The class name to use for the returned row object.
* @return mixed Either the next row from the result set or false if there are no more rows.
protected function fetchObject($cursor =
null, $class =
'stdClass')
return sqlsrv_fetch_object($cursor ?
$cursor :
$this->cursor, $class);
* Method to free up the memory used for the result set.
* @param mixed $cursor The optional result set cursor from which to fetch the row.
sqlsrv_free_stmt($cursor ?
$cursor :
$this->cursor);
* Method to check and see if a field exists in a table.
* @param string $table The table in which to verify the field.
* @param string $field The field to verify.
* @return boolean True if the field exists in the table.
$query =
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" .
" ORDER BY ORDINAL_POSITION";
* Method to wrap an SQL statement to provide a LIMIT and OFFSET behavior for scrolling through a result set.
* @param string $query The SQL statement to process.
* @param integer $limit The maximum affected rows to set.
* @param integer $offset The affected row offset to set.
* @return string The processed SQL statement.
protected function limit($query, $limit, $offset)
if ($limit ==
0 &&
$offset ==
0)
$orderBy =
stristr($query, 'ORDER BY');
if (is_null($orderBy) ||
empty($orderBy))
$orderBy =
'ORDER BY (select 0)';
$rowNumberText =
', ROW_NUMBER() OVER (' .
$orderBy .
') AS RowNumber FROM ';
$query =
preg_replace('/\sFROM\s/i', $rowNumberText, $query, 1);
$query =
'SELECT * FROM (' .
$query .
') _myResults WHERE RowNumber BETWEEN ' .
$start .
' AND ' .
$end;
* Renames a table in the database.
* @param string $oldTable The name of the table to be renamed
* @param string $newTable The new name for the table.
* @param string $backup Table prefix
* @param string $prefix For the table - used to rename constraints in non-mysql databases
* @return JDatabaseDriverSqlsrv Returns this object to support chaining.
* @throws RuntimeException
public function renameTable($oldTable, $newTable, $backup =
null, $prefix =
null)
if (!empty($constraints))
$this->setQuery("sp_rename '" .
$oldTable .
"', '" .
$newTable .
"'");
* Locks a table in the database.
* @param string $tableName The name of the table to lock.
* @return JDatabaseDriverSqlsrv Returns this object to support chaining.
* @throws RuntimeException
* Unlocks tables in the database.
* @return JDatabaseDriverSqlsrv Returns this object to support chaining.
* @throws RuntimeException
Documentation generated on Tue, 19 Nov 2013 15:14:14 +0100 by phpDocumentor 1.4.3