blob: a5ace02e63f9f5af3ae59759ae846889bbaddfcf [file] [log] [blame]
Andrey Andreev4da24f82012-01-25 21:54:23 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev4da24f82012-01-25 21:54:23 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev4da24f82012-01-25 21:54:23 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * MS SQL Database Adapter Class
30 *
31 * Note: _DB is an extender class that the app controller
Jamie Rumbelow7efad202012-02-19 12:37:00 +000032 * creates dynamically based on whether the query builder
Derek Allard2067d1a2008-11-13 22:59:24 +000033 * class is being used or not.
34 *
35 * @package CodeIgniter
36 * @subpackage Drivers
37 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000039 * @link http://codeigniter.com/user_guide/database/
40 */
41class CI_DB_mssql_driver extends CI_DB {
42
Andrey Andreev4da24f82012-01-25 21:54:23 +020043 public $dbdriver = 'mssql';
Barry Mienydd671972010-10-04 16:33:58 +020044
Derek Allard2067d1a2008-11-13 22:59:24 +000045 // The character used for escaping
Andrey Andreev082ee2b2012-06-08 15:26:34 +030046 protected $_escape_char = '"';
Derek Jonese4ed5832009-02-20 21:44:59 +000047
Andrey Andreevdd7242b2012-01-26 00:43:38 +020048 protected $_random_keyword = ' NEWID()';
Derek Allard2067d1a2008-11-13 22:59:24 +000049
Andrey Andreev082ee2b2012-06-08 15:26:34 +030050 // MSSQL-specific properties
51 protected $_quoted_identifier = TRUE;
52
53 /*
54 * Constructor
55 *
56 * Appends the port number to the hostname, if needed.
57 *
58 * @param array
59 * @return void
60 */
Andrey Andreevbd601d32012-02-12 21:16:51 +020061 public function __construct($params)
62 {
63 parent::__construct($params);
64
Andrey Andreev2cb262f2012-03-28 13:45:04 +030065 if ( ! empty($this->port))
Andrey Andreevbd601d32012-02-12 21:16:51 +020066 {
67 $this->hostname .= (DIRECTORY_SEPARATOR === '\\' ? ',' : ':').$this->port;
68 }
69 }
70
Andrey Andreev082ee2b2012-06-08 15:26:34 +030071 // --------------------------------------------------------------------
72
Derek Allard2067d1a2008-11-13 22:59:24 +000073 /**
74 * Non-persistent database connection
75 *
Andrey Andreevfac37612012-07-02 14:56:20 +030076 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +000077 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +020078 */
Andrey Andreevfac37612012-07-02 14:56:20 +030079 public function db_connect($persistent = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000080 {
Andrey Andreevfac37612012-07-02 14:56:20 +030081 $this->conn_id = ($persistent)
82 ? @mssql_pconnect($this->hostname, $this->username, $this->password)
83 : @mssql_connect($this->hostname, $this->username, $this->password);
84
85 if ( ! $this->conn_id)
86 {
87 return FALSE;
88 }
89
90 // Determine how identifiers are escaped
91 $query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi');
92 $query = $query->row_array();
93 $this->_quoted_identifier = empty($query) ? FALSE : (bool) $query['qi'];
94 $this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']');
95
96 return $this->conn_id;
Derek Allard2067d1a2008-11-13 22:59:24 +000097 }
Barry Mienydd671972010-10-04 16:33:58 +020098
Derek Allard2067d1a2008-11-13 22:59:24 +000099 // --------------------------------------------------------------------
100
101 /**
102 * Persistent database connection
103 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +0200105 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200106 public function db_pconnect()
Derek Allard2067d1a2008-11-13 22:59:24 +0000107 {
Andrey Andreevfac37612012-07-02 14:56:20 +0300108 return $this->db_connect(TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 }
Barry Mienydd671972010-10-04 16:33:58 +0200110
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200112
Derek Jones87cbafc2009-02-27 16:29:59 +0000113 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 * Select the database
115 *
Andrey Andreev11454e02012-02-22 16:05:47 +0200116 * @param string database name
Andrey Andreev4da24f82012-01-25 21:54:23 +0200117 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200118 */
Andrey Andreev11454e02012-02-22 16:05:47 +0200119 public function db_select($database = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000120 {
Andrey Andreev024ba2d2012-02-24 11:40:36 +0200121 if ($database === '')
122 {
123 $database = $this->database;
124 }
125
Derek Allard2067d1a2008-11-13 22:59:24 +0000126 // Note: The brackets are required in the event that the DB name
127 // contains reserved characters
Andrey Andreev082ee2b2012-06-08 15:26:34 +0300128 if (@mssql_select_db($this->escape_identifiers($database), $this->conn_id))
Andrey Andreev024ba2d2012-02-24 11:40:36 +0200129 {
130 $this->database = $database;
131 return TRUE;
132 }
133
134 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 }
136
137 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200138
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 * Execute the query
141 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000142 * @param string an SQL query
Andrey Andreev4da24f82012-01-25 21:54:23 +0200143 * @return mixed resource if rows are returned, bool otherwise
Barry Mienydd671972010-10-04 16:33:58 +0200144 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200145 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 return @mssql_query($sql, $this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 }
149
150 // --------------------------------------------------------------------
151
152 /**
153 * Begin Transaction
154 *
Barry Mienydd671972010-10-04 16:33:58 +0200155 * @return bool
156 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200157 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000159 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev4da24f82012-01-25 21:54:23 +0200160 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000161 {
162 return TRUE;
163 }
164
165 // Reset the transaction failure flag.
166 // If the $test_mode flag is set to TRUE transactions will be rolled back
167 // even if the queries produce a successful result.
Andrey Andreev4da24f82012-01-25 21:54:23 +0200168 $this->_trans_failure = ($test_mode === TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000169
Andrey Andreev4da24f82012-01-25 21:54:23 +0200170 return $this->simple_query('BEGIN TRAN');
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 }
172
173 // --------------------------------------------------------------------
174
175 /**
176 * Commit Transaction
177 *
Barry Mienydd671972010-10-04 16:33:58 +0200178 * @return bool
179 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200180 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000182 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev4da24f82012-01-25 21:54:23 +0200183 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 {
185 return TRUE;
186 }
187
Andrey Andreev4da24f82012-01-25 21:54:23 +0200188 return $this->simple_query('COMMIT TRAN');
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 }
190
191 // --------------------------------------------------------------------
192
193 /**
194 * Rollback Transaction
195 *
Barry Mienydd671972010-10-04 16:33:58 +0200196 * @return bool
197 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200198 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev4da24f82012-01-25 21:54:23 +0200201 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 {
203 return TRUE;
204 }
205
Andrey Andreev4da24f82012-01-25 21:54:23 +0200206 return $this->simple_query('ROLLBACK TRAN');
Derek Allard2067d1a2008-11-13 22:59:24 +0000207 }
Barry Mienydd671972010-10-04 16:33:58 +0200208
Derek Allard2067d1a2008-11-13 22:59:24 +0000209 // --------------------------------------------------------------------
210
211 /**
212 * Escape String
213 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 * @param string
Derek Jonese4ed5832009-02-20 21:44:59 +0000215 * @param bool whether or not the string will be used in a LIKE condition
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 * @return string
217 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200218 public function escape_str($str, $like = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000220 if (is_array($str))
221 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -0500222 foreach ($str as $key => $val)
Barry Mienydd671972010-10-04 16:33:58 +0200223 {
Derek Jonese4ed5832009-02-20 21:44:59 +0000224 $str[$key] = $this->escape_str($val, $like);
Barry Mienydd671972010-10-04 16:33:58 +0200225 }
226
227 return $str;
228 }
229
Derek Allard2067d1a2008-11-13 22:59:24 +0000230 // Escape single quotes
Greg Aker757dda62010-04-14 19:06:19 -0500231 $str = str_replace("'", "''", remove_invisible_characters($str));
Barry Mienydd671972010-10-04 16:33:58 +0200232
Derek Jonese4ed5832009-02-20 21:44:59 +0000233 // escape LIKE condition wildcards
234 if ($like === TRUE)
235 {
Andrey Andreev4da24f82012-01-25 21:54:23 +0200236 return str_replace(
Phil Sturgeon36b0c942011-04-02 12:16:41 +0100237 array($this->_like_escape_chr, '%', '_'),
238 array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
239 $str
240 );
Derek Jonese4ed5832009-02-20 21:44:59 +0000241 }
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Jonese4ed5832009-02-20 21:44:59 +0000243 return $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000244 }
Barry Mienydd671972010-10-04 16:33:58 +0200245
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 // --------------------------------------------------------------------
247
248 /**
249 * Affected Rows
250 *
Andrey Andreev4da24f82012-01-25 21:54:23 +0200251 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000252 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200253 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 {
255 return @mssql_rows_affected($this->conn_id);
256 }
Barry Mienydd671972010-10-04 16:33:58 +0200257
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 // --------------------------------------------------------------------
259
260 /**
Andrey Andreev1f619a82012-03-20 16:03:04 +0200261 * Insert ID
262 *
263 * Returns the last id created in the Identity column.
264 *
265 * @return string
266 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200267 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 {
Andrey Andreev70c72c92012-06-25 00:04:51 +0300269 $query = version_compare($this->version(), '8', '>=')
Andrey Andreev4da24f82012-01-25 21:54:23 +0200270 ? 'SELECT SCOPE_IDENTITY() AS last_id'
271 : 'SELECT @@IDENTITY AS last_id';
272
Andrey Andreevb7a47a72012-01-26 02:13:33 +0200273 $query = $this->query($query);
274 $query = $query->row();
275 return $query->last_id;
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 }
277
278 // --------------------------------------------------------------------
279
280 /**
Andrey Andreev1f619a82012-03-20 16:03:04 +0200281 * Version number query string
282 *
283 * @return string
284 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200285 protected function _version()
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 {
Andrey Andreev4da24f82012-01-25 21:54:23 +0200287 return 'SELECT @@VERSION AS ver';
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 }
289
290 // --------------------------------------------------------------------
291
292 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 * List table query
294 *
295 * Generates a platform-specific query string so that the table names can be fetched
296 *
Andrey Andreev4da24f82012-01-25 21:54:23 +0200297 * @param bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 * @return string
299 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200300 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 {
Andrey Andreev70c72c92012-06-25 00:04:51 +0300302 $sql = 'SELECT '.$this->escape_identifiers('name')
303 .' FROM '.$this->escape_identifiers('sysobjects')
304 .' WHERE '.$this->escape_identifiers('type')." = 'U'";
Barry Mienydd671972010-10-04 16:33:58 +0200305
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100306 if ($prefix_limit !== FALSE AND $this->dbprefix !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 {
Andrey Andreev70c72c92012-06-25 00:04:51 +0300308 $sql .= ' AND '.$this->escape_identifiers('name')." LIKE '".$this->escape_like_str($this->dbprefix)."%' "
309 .sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 }
Barry Mienydd671972010-10-04 16:33:58 +0200311
Andrey Andreev70c72c92012-06-25 00:04:51 +0300312 return $sql.' ORDER BY '.$this->escape_identifiers('name');
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 }
314
315 // --------------------------------------------------------------------
316
317 /**
318 * List column query
319 *
320 * Generates a platform-specific query string so that the column names can be fetched
321 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 * @param string the table name
323 * @return string
324 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200325 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 {
Barry Mienydd671972010-10-04 16:33:58 +0200327 return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 }
329
330 // --------------------------------------------------------------------
331
332 /**
333 * Field data query
334 *
335 * Generates a platform-specific query so that the column data can be retrieved
336 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000337 * @param string the table name
Andrey Andreev4da24f82012-01-25 21:54:23 +0200338 * @return string
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200340 protected function _field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 {
Andrey Andreev70c72c92012-06-25 00:04:51 +0300342 return 'SELECT TOP 1 * FROM '.$this->protect_identifiers($table);
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 }
344
345 // --------------------------------------------------------------------
346
347 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200348 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200350 * Returns an array containing code and message of the last
351 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200353 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200355 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000356 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200357 $query = $this->query('SELECT @@ERROR AS code');
358 $query = $query->row();
359 return array('code' => $query->code, 'message' => mssql_get_last_message());
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 }
361
362 // --------------------------------------------------------------------
363
364 /**
Andrey Andreev00541ae2012-04-09 11:43:10 +0300365 * Update statement
366 *
367 * Generates a platform-specific update string from the supplied data
368 *
369 * @param string the table name
370 * @param array the update data
371 * @param array the where clause
372 * @param array the orderby clause (ignored)
373 * @param array the limit clause (ignored)
374 * @param array the like clause
375 * @return string
376 */
377 protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
378 {
379 foreach($values as $key => $val)
380 {
381 $valstr[] = $key.' = '.$val;
382 }
383
384 $where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
385
386 if ( ! empty($like))
387 {
388 $where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
389 }
390
391 return 'UPDATE '.$table.' SET '.implode(', ', $valstr).' WHERE '.$where;
392 }
393
394 // --------------------------------------------------------------------
395
396 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 * Truncate statement
398 *
399 * Generates a platform-specific truncate string from the supplied data
Andrey Andreev6d83cde2012-04-05 16:20:50 +0300400 *
401 * If the database does not support the truncate() command,
402 * then this method maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 * @param string the table name
405 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200406 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200407 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 {
Andrey Andreev6d83cde2012-04-05 16:20:50 +0300409 return 'TRUNCATE TABLE '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 }
Barry Mienydd671972010-10-04 16:33:58 +0200411
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 // --------------------------------------------------------------------
413
414 /**
415 * Delete statement
416 *
417 * Generates a platform-specific delete string from the supplied data
418 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 * @param string the table name
420 * @param array the where clause
Andrey Andreev5c0e9fe2012-04-09 12:28:11 +0300421 * @param array the like clause
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 * @param string the limit clause
423 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200424 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200425 protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000426 {
Andrey Andreev5c0e9fe2012-04-09 12:28:11 +0300427 $conditions = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000428
Andrey Andreev5c0e9fe2012-04-09 12:28:11 +0300429 empty($where) OR $conditions[] = implode(' ', $where);
430 empty($like) OR $conditions[] = implode(' ', $like);
Derek Allard2067d1a2008-11-13 22:59:24 +0000431
Andrey Andreev5c0e9fe2012-04-09 12:28:11 +0300432 $conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000433
Andrey Andreev5c0e9fe2012-04-09 12:28:11 +0300434 return ($limit)
435 ? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
436 : 'DELETE FROM '.$table.$conditions;
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 }
438
439 // --------------------------------------------------------------------
440
441 /**
442 * Limit string
443 *
444 * Generates a platform-specific LIMIT clause
445 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 * @param string the sql query string
Andrey Andreev1f619a82012-03-20 16:03:04 +0200447 * @param int the number of rows to limit the query to
448 * @param int the offset value
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 * @return string
450 */
Andrey Andreev4da24f82012-01-25 21:54:23 +0200451 protected function _limit($sql, $limit, $offset)
Derek Allard2067d1a2008-11-13 22:59:24 +0000452 {
Andrey Andreev71379ca2012-06-11 16:12:43 +0300453 // As of SQL Server 2012 (11.0.*) OFFSET is supported
454 if (version_compare($this->version(), '11', '>='))
455 {
456 return $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY';
457 }
458
459 $limit = $offset + $limit;
460
461 // As of SQL Server 2005 (9.0.*) ROW_NUMBER() is supported,
462 // however an ORDER BY clause is required for it to work
463 if (version_compare($this->version(), '9', '>=') && $offset && ! empty($this->qb_orderby))
464 {
465 $orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
466
467 // We have to strip the ORDER BY clause
Andrey Andreev97386682012-10-11 10:24:51 +0300468 $sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
Andrey Andreev71379ca2012-06-11 16:12:43 +0300469
470 return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
471 .preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
472 ."\n) ".$this->escape_identifiers('CI_subquery')
473 ."\nWHERE ".$this->escape_identifiers('CI_rownum').' BETWEEN '.((int) $offset + 1).' AND '.$limit;
474 }
475
476 return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 }
478
479 // --------------------------------------------------------------------
480
481 /**
482 * Close DB Connection
483 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 * @return void
485 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300486 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000487 {
Andrey Andreev79922c02012-05-23 12:27:17 +0300488 @mssql_close($this->conn_id);
Barry Mienydd671972010-10-04 16:33:58 +0200489 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000490
491}
492
Derek Allard2067d1a2008-11-13 22:59:24 +0000493/* End of file mssql_driver.php */
Andrey Andreev79922c02012-05-23 12:27:17 +0300494/* Location: ./system/database/drivers/mssql/mssql_driver.php */