summaryrefslogtreecommitdiffstats
path: root/system/database/drivers/sqlsrv/sqlsrv_driver.php
diff options
context:
space:
mode:
Diffstat (limited to 'system/database/drivers/sqlsrv/sqlsrv_driver.php')
-rw-r--r--system/database/drivers/sqlsrv/sqlsrv_driver.php172
1 files changed, 85 insertions, 87 deletions
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index bda450e88..de3d87312 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 2.0.3
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* SQLSRV Database Adapter Class
@@ -40,36 +41,52 @@
*/
class CI_DB_sqlsrv_driver extends CI_DB {
+ /**
+ * Database driver
+ *
+ * @var string
+ */
public $dbdriver = 'sqlsrv';
- // The character used for escaping
- protected $_escape_char = '"';
-
- // clause and character used for LIKE escape sequences
- protected $_like_escape_str = " ESCAPE '%s' ";
- protected $_like_escape_chr = '!';
+ // --------------------------------------------------------------------
+ /**
+ * ORDER BY random keyword
+ *
+ * @var string
+ */
protected $_random_keyword = ' NEWID()';
- // SQLSRV-specific properties
+ /**
+ * Quoted identifier flag
+ *
+ * Whether to use SQL-92 standard quoted identifier
+ * (double quotes) or brackets for identifier escaping.
+ *
+ * @var bool
+ */
protected $_quoted_identifier = TRUE;
+ // --------------------------------------------------------------------
+
/**
- * Non-persistent database connection
+ * Database connection
*
+ * @param bool $pooling
* @return resource
*/
public function db_connect($pooling = FALSE)
{
- // Check for a UTF-8 charset being passed as CI's default 'utf8'.
- $character_set = (0 === strcasecmp('utf8', $this->char_set)) ? 'UTF-8' : $this->char_set;
+ $charset = in_array(strtolower($this->char_set), array('utf-8', 'utf8'), TRUE)
+ ? 'UTF-8' : SQLSRV_ENC_CHAR;
$connection = array(
'UID' => empty($this->username) ? '' : $this->username,
'PWD' => empty($this->password) ? '' : $this->password,
'Database' => $this->database,
- 'ConnectionPooling' => $pooling ? 1 : 0,
- 'CharacterSet' => $character_set,
+ 'ConnectionPooling' => ($pooling === TRUE) ? 1 : 0,
+ 'CharacterSet' => $charset,
+ 'Encrypt' => ($this->encrypt === TRUE) ? 1 : 0,
'ReturnDatesAsStrings' => 1
);
@@ -108,7 +125,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
/**
* Select the database
*
- * @param string database name
+ * @param string $database
* @return bool
*/
public function db_select($database = '')
@@ -132,7 +149,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
/**
* Execute the query
*
- * @param string an SQL query
+ * @param string $sql an SQL query
* @return resource
*/
protected function _execute($sql)
@@ -147,6 +164,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
/**
* Begin Transaction
*
+ * @param bool $test_mode
* @return bool
*/
public function trans_begin($test_mode = FALSE)
@@ -206,8 +224,8 @@ class CI_DB_sqlsrv_driver extends CI_DB {
/**
* Escape String
*
- * @param string
- * @param bool whether or not the string will be used in a LIKE condition
+ * @param string $str
+ * @param bool $like Whether or not the string will be used in a LIKE condition
* @return string
*/
public function escape_str($str, $like = FALSE)
@@ -274,7 +292,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
* Generates a platform-specific query string so that the table names can be fetched
*
* @param bool
- * @return string
+ * @return string $prefix_limit
*/
protected function _list_tables($prefix_limit = FALSE)
{
@@ -298,7 +316,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*
* Generates a platform-specific query string so that the column names can be fetched
*
- * @param string the table name
+ * @param string $table
* @return string
*/
protected function _list_columns($table = '')
@@ -313,7 +331,7 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*
* Generates a platform-specific query so that the column data can be retrieved
*
- * @param string the table name
+ * @param string $table
* @return string
*/
protected function _field_data($table)
@@ -362,49 +380,19 @@ class CI_DB_sqlsrv_driver extends CI_DB {
// --------------------------------------------------------------------
/**
- * From Tables
- *
- * This function implicitly groups FROM tables so there is no confusion
- * about operator precedence in harmony with SQL standards
- *
- * @param array
- * @return string
- */
- protected function _from_tables($tables)
- {
- return is_array($tables) ? implode(', ', $tables) : $tables;
- }
-
- // --------------------------------------------------------------------
-
- /**
* Update statement
*
* Generates a platform-specific update string from the supplied data
*
- * @param string the table name
- * @param array the update data
- * @param array the where clause
- * @param array the orderby clause (ignored)
- * @param array the limit clause (ignored)
- * @param array the like clause
+ * @param string $table
+ * @param array $values
* @return string
*/
- protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
+ protected function _update($table, $values)
{
- foreach ($values as $key => $val)
- {
- $valstr[] = $key.' = '.$val;
- }
-
- $where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
-
- if ( ! empty($like))
- {
- $where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
- }
-
- return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
+ $this->qb_limit = FALSE;
+ $this->qb_orderby = array();
+ return parent::_update($table, $values);
}
// --------------------------------------------------------------------
@@ -414,10 +402,10 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*
* Generates a platform-specific truncate string from the supplied data
*
- * If the database does not support the truncate() command,
+ * If the database does not support the TRUNCATE statement,
* then this method maps to 'DELETE FROM table'
*
- * @param string the table name
+ * @param string $table
* @return string
*/
protected function _truncate($table)
@@ -432,60 +420,70 @@ class CI_DB_sqlsrv_driver extends CI_DB {
*
* Generates a platform-specific delete string from the supplied data
*
- * @param string the table name
- * @param array the where clause
- * @param array the like clause
- * @param string the limit clause
+ * @param string $table
* @return string
*/
- protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+ protected function _delete($table)
{
- $conditions = array();
-
- empty($where) OR $conditions[] = implode(' ', $where);
- empty($like) OR $conditions[] = implode(' ', $like);
-
- $conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
+ if ($this->qb_limit)
+ {
+ return 'WITH ci_delete AS (SELECT TOP '.$this->qb_limit.' * FROM '.$table.$this->_compile_wh('qb_where').') DELETE FROM ci_delete';
+ }
- return ($limit)
- ? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
- : 'DELETE FROM '.$table.$conditions;
+ return parent::_delete($table);
}
// --------------------------------------------------------------------
/**
- * Limit string
+ * LIMIT
*
* Generates a platform-specific LIMIT clause
*
- * @param string the sql query string
- * @param int the number of rows to limit the query to
- * @param int the offset value
+ * @param string $sql SQL Query
* @return string
*/
- protected function _limit($sql, $limit, $offset)
+ protected function _limit($sql)
{
// As of SQL Server 2012 (11.0.*) OFFSET is supported
if (version_compare($this->version(), '11', '>='))
{
- return $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY';
+ return $sql.' OFFSET '.(int) $this->qb_offset.' ROWS FETCH NEXT '.$this->qb_limit.' ROWS ONLY';
}
- $limit = $offset + $limit;
+ $limit = $this->qb_offset + $this->qb_limit;
// An ORDER BY clause is required for ROW_NUMBER() to work
- if ($offset && ! empty($this->qb_orderby))
+ if ($this->qb_offset && ! empty($this->qb_orderby))
{
- $orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
+ $orderby = $this->_compile_order_by();
// We have to strip the ORDER BY clause
- $sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
-
- return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
- .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
- ."\n) ".$this->escape_identifiers('CI_subquery')
- ."\nWHERE ".$this->escape_identifiers('CI_rownum').' BETWEEN '.((int) $offset + 1).' AND '.$limit;
+ $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
+
+ // Get the fields to select from our subquery, so that we can avoid CI_rownum appearing in the actual results
+ if (count($this->qb_select) === 0)
+ {
+ $select = '*'; // Inevitable
+ }
+ else
+ {
+ // Use only field names and their aliases, everything else is out of our scope.
+ $select = array();
+ $field_regexp = ($this->_quoted_identifier)
+ ? '("[^\"]+")' : '(\[[^\]]+\])';
+ for ($i = 0, $c = count($this->qb_select); $i < $c; $i++)
+ {
+ $select[] = preg_match('/(?:\s|\.)'.$field_regexp.'$/i', $this->qb_select[$i], $m)
+ ? $m[1] : $this->qb_select[$i];
+ }
+ $select = implode(', ', $select);
+ }
+
+ return 'SELECT '.$select." FROM (\n\n"
+ .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.trim($orderby).') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
+ ."\n\n) ".$this->escape_identifiers('CI_subquery')
+ ."\nWHERE ".$this->escape_identifiers('CI_rownum').' BETWEEN '.($this->qb_offset + 1).' AND '.$limit;
}
return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql);