blob: 5140dd859c52bc9f344d9370b29988d00828c951 [file] [log] [blame]
Derek Allardd2df9bc2007-04-15 17:41:17 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, EllisLab, Inc.
Derek Allard6838f002007-10-04 19:29:59 +000010 * @license http://www.codeigniter.com/user_guide/license.html
Derek Allardd2df9bc2007-04-15 17:41:17 +000011 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * MS SQL Database Adapter Class
20 *
21 * Note: _DB is an extender class that the app controller
22 * creates dynamically based on whether the active record
23 * class is being used or not.
24 *
25 * @package CodeIgniter
26 * @subpackage Drivers
27 * @category Database
28 * @author Rick Ellis
29 * @link http://www.codeigniter.com/user_guide/database/
30 */
31class CI_DB_mssql_driver extends CI_DB {
32
33 /**
34 * Non-persistent database connection
35 *
36 * @access private called by the base class
37 * @return resource
38 */
39 function db_connect()
40 {
41 return @mssql_connect($this->hostname, $this->username, $this->password);
42 }
43
44 // --------------------------------------------------------------------
45
46 /**
47 * Persistent database connection
48 *
49 * @access private called by the base class
50 * @return resource
51 */
52 function db_pconnect()
53 {
54 return @mssql_pconnect($this->hostname, $this->username, $this->password);
55 }
56
57 // --------------------------------------------------------------------
58
59 /**
60 * Select the database
61 *
62 * @access private called by the base class
63 * @return resource
64 */
65 function db_select()
66 {
67 return @mssql_select_db($this->database, $this->conn_id);
68 }
69
70 // --------------------------------------------------------------------
71
72 /**
Derek Allardd2df9bc2007-04-15 17:41:17 +000073 * Execute the query
74 *
75 * @access private called by the base class
76 * @param string an SQL query
77 * @return resource
78 */
79 function _execute($sql)
80 {
81 $sql = $this->_prep_query($sql);
82 return @mssql_query($sql, $this->conn_id);
83 }
84
85 // --------------------------------------------------------------------
86
87 /**
88 * Prep the query
89 *
90 * If needed, each database adapter can prep the query string
91 *
92 * @access private called by execute()
93 * @param string an SQL query
94 * @return string
95 */
96 function _prep_query($sql)
97 {
98 return $sql;
99 }
100
101 // --------------------------------------------------------------------
102
103 /**
104 * Begin Transaction
105 *
106 * @access public
107 * @return bool
108 */
109 function trans_begin($test_mode = FALSE)
110 {
111 if ( ! $this->trans_enabled)
112 {
113 return TRUE;
114 }
115
116 // When transactions are nested we only begin/commit/rollback the outermost ones
117 if ($this->_trans_depth > 0)
118 {
119 return TRUE;
120 }
121
122 // Reset the transaction failure flag.
123 // If the $test_mode flag is set to TRUE transactions will be rolled back
124 // even if the queries produce a successful result.
125 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
126
127 $this->simple_query('BEGIN TRAN');
128 return TRUE;
129 }
130
131 // --------------------------------------------------------------------
132
133 /**
134 * Commit Transaction
135 *
136 * @access public
137 * @return bool
138 */
139 function trans_commit()
140 {
141 if ( ! $this->trans_enabled)
142 {
143 return TRUE;
144 }
145
146 // When transactions are nested we only begin/commit/rollback the outermost ones
147 if ($this->_trans_depth > 0)
148 {
149 return TRUE;
150 }
151
152 $this->simple_query('COMMIT TRAN');
153 return TRUE;
154 }
155
156 // --------------------------------------------------------------------
157
158 /**
159 * Rollback Transaction
160 *
161 * @access public
162 * @return bool
163 */
164 function trans_rollback()
165 {
166 if ( ! $this->trans_enabled)
167 {
168 return TRUE;
169 }
170
171 // When transactions are nested we only begin/commit/rollback the outermost ones
172 if ($this->_trans_depth > 0)
173 {
174 return TRUE;
175 }
176
177 $this->simple_query('ROLLBACK TRAN');
178 return TRUE;
179 }
180
181 // --------------------------------------------------------------------
182
183 /**
184 * Escape String
185 *
186 * @access public
187 * @param string
188 * @return string
189 */
190 function escape_str($str)
191 {
192 // Escape single quotes
193 return str_replace("'", "''", $str);
194 }
195
196 // --------------------------------------------------------------------
197
198 /**
199 * Affected Rows
200 *
201 * @access public
202 * @return integer
203 */
204 function affected_rows()
205 {
206 return @mssql_rows_affected($this->conn_id);
207 }
208
209 // --------------------------------------------------------------------
210
211 /**
Rick Ellis1db17b52007-06-11 05:33:21 +0000212 * Insert ID
213 *
214 * Returns the last id created in the Identity column.
215 *
216 * @access public
217 * @return integer
218 */
Derek Allardd2df9bc2007-04-15 17:41:17 +0000219 function insert_id()
220 {
Rick Ellis1db17b52007-06-11 05:33:21 +0000221 $ver = self::_parse_major_version($this->version());
222 $sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
223 $query = $this->query($sql);
224 $row = $query->row();
225 return $row->last_id;
226 }
227
228 // --------------------------------------------------------------------
229
230 /**
231 * Parse major version
232 *
233 * Grabs the major version number from the
234 * database server version string passed in.
235 *
236 * @access private
237 * @param string $version
238 * @return int16 major version number
239 */
240 function _parse_major_version($version)
241 {
242 preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
243 return $ver_info[1]; // return the major version b/c that's all we're interested in.
244 }
245
246 // --------------------------------------------------------------------
247
248 /**
249 * Version number query string
250 *
251 * @access public
252 * @return string
253 */
254 function _version()
255 {
256 return "SELECT @@VERSION AS ver";
Derek Allardd2df9bc2007-04-15 17:41:17 +0000257 }
258
259 // --------------------------------------------------------------------
260
261 /**
262 * "Count All" query
263 *
264 * Generates a platform-specific query string that counts all records in
265 * the specified database
266 *
267 * @access public
268 * @param string
269 * @return string
270 */
271 function count_all($table = '')
272 {
273 if ($table == '')
274 return '0';
275
276 $query = $this->query("SELECT COUNT(*) AS numrows FROM ".$this->dbprefix.$table);
277
278 if ($query->num_rows() == 0)
279 return '0';
280
281 $row = $query->row();
282 return $row->numrows;
283 }
284
285 // --------------------------------------------------------------------
286
287 /**
288 * List table query
289 *
290 * Generates a platform-specific query string so that the table names can be fetched
291 *
292 * @access private
293 * @return string
294 */
295 function _list_tables()
296 {
297 return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
298 }
299
300 // --------------------------------------------------------------------
301
302 /**
303 * List column query
304 *
305 * Generates a platform-specific query string so that the column names can be fetched
306 *
307 * @access private
308 * @param string the table name
309 * @return string
310 */
311 function _list_columns($table = '')
312 {
313 return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'";
314 }
315
316 // --------------------------------------------------------------------
317
318 /**
319 * Field data query
320 *
321 * Generates a platform-specific query so that the column data can be retrieved
322 *
323 * @access public
324 * @param string the table name
325 * @return object
326 */
327 function _field_data($table)
328 {
329 return "SELECT TOP 1 * FROM ".$this->_escape_table($table);
330 }
331
332 // --------------------------------------------------------------------
333
334 /**
335 * The error message string
336 *
337 * @access private
338 * @return string
339 */
340 function _error_message()
341 {
342 // Are errros even supported in MS SQL?
343 return '';
344 }
345
346 // --------------------------------------------------------------------
347
348 /**
349 * The error message number
350 *
351 * @access private
352 * @return integer
353 */
354 function _error_number()
355 {
356 // Are error numbers supported?
357 return '';
358 }
359
360 // --------------------------------------------------------------------
361
362 /**
363 * Escape Table Name
364 *
365 * This function adds backticks if the table name has a period
366 * in it. Some DBs will get cranky unless periods are escaped
367 *
368 * @access private
369 * @param string the table name
370 * @return string
371 */
372 function _escape_table($table)
373 {
374 // I don't believe this is necessary with MS SQL. Not sure, though. - Rick
375
376 /*
377 if (stristr($table, '.'))
378 {
379 $table = preg_replace("/\./", "`.`", $table);
380 }
381 */
382
383 return $table;
384 }
385
386 // --------------------------------------------------------------------
387
388 /**
389 * Insert statement
390 *
391 * Generates a platform-specific insert string from the supplied data
392 *
393 * @access public
394 * @param string the table name
395 * @param array the insert keys
396 * @param array the insert values
397 * @return string
398 */
399 function _insert($table, $keys, $values)
400 {
401 return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
402 }
403
404 // --------------------------------------------------------------------
405
406 /**
407 * Update statement
408 *
409 * Generates a platform-specific update string from the supplied data
410 *
411 * @access public
412 * @param string the table name
413 * @param array the update data
414 * @param array the where clause
415 * @return string
416 */
417 function _update($table, $values, $where)
418 {
419 foreach($values as $key => $val)
420 {
421 $valstr[] = $key." = ".$val;
422 }
423
424 return "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
425 }
426
427 // --------------------------------------------------------------------
428
429 /**
430 * Delete statement
431 *
432 * Generates a platform-specific delete string from the supplied data
433 *
434 * @access public
435 * @param string the table name
436 * @param array the where clause
437 * @return string
438 */
439 function _delete($table, $where)
440 {
441 return "DELETE FROM ".$this->_escape_table($table)." WHERE ".implode(" ", $where);
442 }
443
444 // --------------------------------------------------------------------
445
446 /**
447 * Limit string
448 *
449 * Generates a platform-specific LIMIT clause
450 *
451 * @access public
452 * @param string the sql query string
453 * @param integer the number of rows to limit the query to
454 * @param integer the offset value
455 * @return string
456 */
457 function _limit($sql, $limit, $offset)
458 {
459 $i = $limit + $offset;
460
461 return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
462 }
463
464 // --------------------------------------------------------------------
465
466 /**
467 * Close DB Connection
468 *
469 * @access public
470 * @param resource
471 * @return void
472 */
473 function _close($conn_id)
474 {
475 @mssql_close($conn_id);
476 }
477
478}
479
480
adminea8ca452006-09-24 18:11:44 +0000481?>