Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2005 Aurelien 1
<?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		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008, EllisLab, Inc.
10
 * @license		http://codeigniter.com/user_guide/license.html
11
 * @link		http://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		ExpressionEngine Dev Team
29
 * @link		http://codeigniter.com/user_guide/database/
30
 */
31
class CI_DB_mssql_driver extends CI_DB {
32
33
	var $dbdriver = 'mssql';
34
35
	// The character used for escaping
36
	var $_escape_char = '';
37
	/**
38
	 * The syntax to count rows is slightly different across different
39
	 * database engines, so this string appears in each driver and is
40
	 * used for the count_all() and count_all_results() functions.
41
	 */
42
	var $_count_string = "SELECT COUNT(*) AS ";
43
	var $_random_keyword = ' ASC'; // not currently supported
44
45
	/**
46
	 * Non-persistent database connection
47
	 *
48
	 * @access	private called by the base class
49
	 * @return	resource
50
	 */
51
	function db_connect()
52
	{
53
		if ($this->port != '')
54
		{
55
			$this->hostname .= ','.$this->port;
56
		}
57
58
		return @mssql_connect($this->hostname, $this->username, $this->password);
59
	}
60
61
	// --------------------------------------------------------------------
62
63
	/**
64
	 * Persistent database connection
65
	 *
66
	 * @access	private called by the base class
67
	 * @return	resource
68
	 */
69
	function db_pconnect()
70
	{
71
		if ($this->port != '')
72
		{
73
			$this->hostname .= ','.$this->port;
74
		}
75
76
		return @mssql_pconnect($this->hostname, $this->username, $this->password);
77
	}
78
79
	// --------------------------------------------------------------------
80
81
	/**
82
	 * Select the database
83
	 *
84
	 * @access	private called by the base class
85
	 * @return	resource
86
	 */
87
	function db_select()
88
	{
89
		// Note: The brackets are required in the event that the DB name
90
		// contains reserved characters
91
		return @mssql_select_db('['.$this->database.']', $this->conn_id);
92
	}
93
94
	// --------------------------------------------------------------------
95
96
	/**
97
	 * Set client character set
98
	 *
99
	 * @access	public
100
	 * @param	string
101
	 * @param	string
102
	 * @return	resource
103
	 */
104
	function db_set_charset($charset, $collation)
105
	{
106
		// @todo - add support if needed
107
		return TRUE;
108
	}
109
110
	// --------------------------------------------------------------------
111
112
	/**
113
	 * Execute the query
114
	 *
115
	 * @access	private called by the base class
116
	 * @param	string	an SQL query
117
	 * @return	resource
118
	 */
119
	function _execute($sql)
120
	{
121
		$sql = $this->_prep_query($sql);
122
		return @mssql_query($sql, $this->conn_id);
123
	}
124
125
	// --------------------------------------------------------------------
126
127
	/**
128
	 * Prep the query
129
	 *
130
	 * If needed, each database adapter can prep the query string
131
	 *
132
	 * @access	private called by execute()
133
	 * @param	string	an SQL query
134
	 * @return	string
135
	 */
136
	function _prep_query($sql)
137
	{
138
		return $sql;
139
	}
140
141
	// --------------------------------------------------------------------
142
143
	/**
144
	 * Begin Transaction
145
	 *
146
	 * @access	public
147
	 * @return	bool
148
	 */
149
	function trans_begin($test_mode = FALSE)
150
	{
151
		if ( ! $this->trans_enabled)
152
		{
153
			return TRUE;
154
		}
155
156
		// When transactions are nested we only begin/commit/rollback the outermost ones
157
		if ($this->_trans_depth > 0)
158
		{
159
			return TRUE;
160
		}
161
162
		// Reset the transaction failure flag.
163
		// If the $test_mode flag is set to TRUE transactions will be rolled back
164
		// even if the queries produce a successful result.
165
		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
166
167
		$this->simple_query('BEGIN TRAN');
168
		return TRUE;
169
	}
170
171
	// --------------------------------------------------------------------
172
173
	/**
174
	 * Commit Transaction
175
	 *
176
	 * @access	public
177
	 * @return	bool
178
	 */
179
	function trans_commit()
180
	{
181
		if ( ! $this->trans_enabled)
182
		{
183
			return TRUE;
184
		}
185
186
		// When transactions are nested we only begin/commit/rollback the outermost ones
187
		if ($this->_trans_depth > 0)
188
		{
189
			return TRUE;
190
		}
191
192
		$this->simple_query('COMMIT TRAN');
193
		return TRUE;
194
	}
195
196
	// --------------------------------------------------------------------
197
198
	/**
199
	 * Rollback Transaction
200
	 *
201
	 * @access	public
202
	 * @return	bool
203
	 */
204
	function trans_rollback()
205
	{
206
		if ( ! $this->trans_enabled)
207
		{
208
			return TRUE;
209
		}
210
211
		// When transactions are nested we only begin/commit/rollback the outermost ones
212
		if ($this->_trans_depth > 0)
213
		{
214
			return TRUE;
215
		}
216
217
		$this->simple_query('ROLLBACK TRAN');
218
		return TRUE;
219
	}
220
221
	// --------------------------------------------------------------------
222
223
	/**
224
	 * Escape String
225
	 *
226
	 * @access	public
227
	 * @param	string
228
	 * @return	string
229
	 */
230
	function escape_str($str)
231
	{
232
		// Access the CI object
233
		$CI =& get_instance();
234
235
		// Escape single quotes
236
		return str_replace("'", "''", $CI->input->_remove_invisible_characters($str));
237
	}
238
239
	// --------------------------------------------------------------------
240
241
	/**
242
	 * Affected Rows
243
	 *
244
	 * @access	public
245
	 * @return	integer
246
	 */
247
	function affected_rows()
248
	{
249
		return @mssql_rows_affected($this->conn_id);
250
	}
251
252
	// --------------------------------------------------------------------
253
254
	/**
255
	* Insert ID
256
	*
257
	* Returns the last id created in the Identity column.
258
	*
259
	* @access public
260
	* @return integer
261
	*/
262
	function insert_id()
263
	{
264
		$ver = self::_parse_major_version($this->version());
265
		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
266
		$query = $this->query($sql);
267
		$row = $query->row();
268
		return $row->last_id;
269
	}
270
271
	// --------------------------------------------------------------------
272
273
	/**
274
	* Parse major version
275
	*
276
	* Grabs the major version number from the
277
	* database server version string passed in.
278
	*
279
	* @access private
280
	* @param string $version
281
	* @return int16 major version number
282
	*/
283
	function _parse_major_version($version)
284
	{
285
		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
286
		return $ver_info[1]; // return the major version b/c that's all we're interested in.
287
	}
288
289
	// --------------------------------------------------------------------
290
291
	/**
292
	* Version number query string
293
	*
294
	* @access public
295
	* @return string
296
	*/
297
	function _version()
298
	{
299
		return "SELECT @@VERSION AS ver";
300
	}
301
302
	// --------------------------------------------------------------------
303
304
	/**
305
	 * "Count All" query
306
	 *
307
	 * Generates a platform-specific query string that counts all records in
308
	 * the specified database
309
	 *
310
	 * @access	public
311
	 * @param	string
312
	 * @return	string
313
	 */
314
	function count_all($table = '')
315
	{
316
		if ($table == '')
317
			return '0';
318
319
		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
320
321
		if ($query->num_rows() == 0)
322
			return '0';
323
324
		$row = $query->row();
325
		return $row->numrows;
326
	}
327
328
	// --------------------------------------------------------------------
329
330
	/**
331
	 * List table query
332
	 *
333
	 * Generates a platform-specific query string so that the table names can be fetched
334
	 *
335
	 * @access	private
336
	 * @param	boolean
337
	 * @return	string
338
	 */
339
	function _list_tables($prefix_limit = FALSE)
340
	{
341
		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
342
343
		// for future compatibility
344
		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
345
		{
346
			//$sql .= " LIKE '".$this->dbprefix."%'";
347
			return FALSE; // not currently supported
348
		}
349
350
		return $sql;
351
	}
352
353
	// --------------------------------------------------------------------
354
355
	/**
356
	 * List column query
357
	 *
358
	 * Generates a platform-specific query string so that the column names can be fetched
359
	 *
360
	 * @access	private
361
	 * @param	string	the table name
362
	 * @return	string
363
	 */
364
	function _list_columns($table = '')
365
	{
366
		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
367
	}
368
369
	// --------------------------------------------------------------------
370
371
	/**
372
	 * Field data query
373
	 *
374
	 * Generates a platform-specific query so that the column data can be retrieved
375
	 *
376
	 * @access	public
377
	 * @param	string	the table name
378
	 * @return	object
379
	 */
380
	function _field_data($table)
381
	{
382
		return "SELECT TOP 1 * FROM ".$table;
383
	}
384
385
	// --------------------------------------------------------------------
386
387
	/**
388
	 * The error message string
389
	 *
390
	 * @access	private
391
	 * @return	string
392
	 */
393
	function _error_message()
394
	{
395
		// Are errros even supported in MS SQL?
396
		return '';
397
	}
398
399
	// --------------------------------------------------------------------
400
401
	/**
402
	 * The error message number
403
	 *
404
	 * @access	private
405
	 * @return	integer
406
	 */
407
	function _error_number()
408
	{
409
		// Are error numbers supported?
410
		return '';
411
	}
412
413
	// --------------------------------------------------------------------
414
415
	/**
416
	 * Escape the SQL Identifiers
417
	 *
418
	 * This function escapes column and table names
419
	 *
420
	 * @access	private
421
	 * @param	string
422
	 * @return	string
423
	 */
424
	function _escape_identifiers($item)
425
	{
426
		if ($this->_escape_char == '')
427
		{
428
			return $item;
429
		}
430
431
		if (strpos($item, '.') !== FALSE)
432
		{
433
			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
434
		}
435
		else
436
		{
437
			$str = $this->_escape_char.$item.$this->_escape_char;
438
		}
439
440
		// remove duplicates if the user already included the escape
441
		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
442
	}
443
444
	// --------------------------------------------------------------------
445
446
	/**
447
	 * From Tables
448
	 *
449
	 * This function implicitly groups FROM tables so there is no confusion
450
	 * about operator precedence in harmony with SQL standards
451
	 *
452
	 * @access	public
453
	 * @param	type
454
	 * @return	type
455
	 */
456
	function _from_tables($tables)
457
	{
458
		if ( ! is_array($tables))
459
		{
460
			$tables = array($tables);
461
		}
462
463
		return implode(', ', $tables);
464
	}
465
466
	// --------------------------------------------------------------------
467
468
	/**
469
	 * Insert statement
470
	 *
471
	 * Generates a platform-specific insert string from the supplied data
472
	 *
473
	 * @access	public
474
	 * @param	string	the table name
475
	 * @param	array	the insert keys
476
	 * @param	array	the insert values
477
	 * @return	string
478
	 */
479
	function _insert($table, $keys, $values)
480
	{
481
		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
482
	}
483
484
	// --------------------------------------------------------------------
485
486
	/**
487
	 * Update statement
488
	 *
489
	 * Generates a platform-specific update string from the supplied data
490
	 *
491
	 * @access	public
492
	 * @param	string	the table name
493
	 * @param	array	the update data
494
	 * @param	array	the where clause
495
	 * @param	array	the orderby clause
496
	 * @param	array	the limit clause
497
	 * @return	string
498
	 */
499
	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
500
	{
501
		foreach($values as $key => $val)
502
		{
503
			$valstr[] = $key." = ".$val;
504
		}
505
506
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
507
508
		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
509
510
		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
511
512
		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
513
514
		$sql .= $orderby.$limit;
515
516
		return $sql;
517
	}
518
519
520
	// --------------------------------------------------------------------
521
522
	/**
523
	 * Truncate statement
524
	 *
525
	 * Generates a platform-specific truncate string from the supplied data
526
	 * If the database does not support the truncate() command
527
	 * This function maps to "DELETE FROM table"
528
	 *
529
	 * @access	public
530
	 * @param	string	the table name
531
	 * @return	string
532
	 */
533
	function _truncate($table)
534
	{
535
		return "TRUNCATE ".$table;
536
	}
537
538
	// --------------------------------------------------------------------
539
540
	/**
541
	 * Delete statement
542
	 *
543
	 * Generates a platform-specific delete string from the supplied data
544
	 *
545
	 * @access	public
546
	 * @param	string	the table name
547
	 * @param	array	the where clause
548
	 * @param	string	the limit clause
549
	 * @return	string
550
	 */
551
	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
552
	{
553
		$conditions = '';
554
555
		if (count($where) > 0 OR count($like) > 0)
556
		{
557
			$conditions = "\nWHERE ";
558
			$conditions .= implode("\n", $this->ar_where);
559
560
			if (count($where) > 0 && count($like) > 0)
561
			{
562
				$conditions .= " AND ";
563
			}
564
			$conditions .= implode("\n", $like);
565
		}
566
567
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
568
569
		return "DELETE FROM ".$table.$conditions.$limit;
570
	}
571
572
	// --------------------------------------------------------------------
573
574
	/**
575
	 * Limit string
576
	 *
577
	 * Generates a platform-specific LIMIT clause
578
	 *
579
	 * @access	public
580
	 * @param	string	the sql query string
581
	 * @param	integer	the number of rows to limit the query to
582
	 * @param	integer	the offset value
583
	 * @return	string
584
	 */
585
	function _limit($sql, $limit, $offset)
586
	{
587
		$i = $limit + $offset;
588
589
		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
590
	}
591
592
	// --------------------------------------------------------------------
593
594
	/**
595
	 * Close DB Connection
596
	 *
597
	 * @access	public
598
	 * @param	resource
599
	 * @return	void
600
	 */
601
	function _close($conn_id)
602
	{
603
		@mssql_close($conn_id);
604
	}
605
606
}
607
608
609
610
/* End of file mssql_driver.php */
611
/* Location: ./system/database/drivers/mssql/mssql_driver.php */