Subversion-Projekte lars-tiefland.codeigniter

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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
		{
318
			return 0;
319
		}
320
 
321
		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
322
 
323
		if ($query->num_rows() == 0)
324
		{
325
			return 0;
326
		}
327
 
328
		$row = $query->row();
329
		return (int) $row->numrows;
330
	}
331
 
332
	// --------------------------------------------------------------------
333
 
334
	/**
335
	 * List table query
336
	 *
337
	 * Generates a platform-specific query string so that the table names can be fetched
338
	 *
339
	 * @access	private
340
	 * @param	boolean
341
	 * @return	string
342
	 */
343
	function _list_tables($prefix_limit = FALSE)
344
	{
345
		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
346
 
347
		// for future compatibility
348
		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
349
		{
350
			//$sql .= " LIKE '".$this->dbprefix."%'";
351
			return FALSE; // not currently supported
352
		}
353
 
354
		return $sql;
355
	}
356
 
357
	// --------------------------------------------------------------------
358
 
359
	/**
360
	 * List column query
361
	 *
362
	 * Generates a platform-specific query string so that the column names can be fetched
363
	 *
364
	 * @access	private
365
	 * @param	string	the table name
366
	 * @return	string
367
	 */
368
	function _list_columns($table = '')
369
	{
370
		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
371
	}
372
 
373
	// --------------------------------------------------------------------
374
 
375
	/**
376
	 * Field data query
377
	 *
378
	 * Generates a platform-specific query so that the column data can be retrieved
379
	 *
380
	 * @access	public
381
	 * @param	string	the table name
382
	 * @return	object
383
	 */
384
	function _field_data($table)
385
	{
386
		return "SELECT TOP 1 * FROM ".$table;
387
	}
388
 
389
	// --------------------------------------------------------------------
390
 
391
	/**
392
	 * The error message string
393
	 *
394
	 * @access	private
395
	 * @return	string
396
	 */
397
	function _error_message()
398
	{
399
		// Are errros even supported in MS SQL?
400
		return '';
401
	}
402
 
403
	// --------------------------------------------------------------------
404
 
405
	/**
406
	 * The error message number
407
	 *
408
	 * @access	private
409
	 * @return	integer
410
	 */
411
	function _error_number()
412
	{
413
		// Are error numbers supported?
414
		return '';
415
	}
416
 
417
	// --------------------------------------------------------------------
418
 
419
	/**
420
	 * Escape the SQL Identifiers
421
	 *
422
	 * This function escapes column and table names
423
	 *
424
	 * @access	private
425
	 * @param	string
426
	 * @return	string
427
	 */
428
	function _escape_identifiers($item)
429
	{
430
		if ($this->_escape_char == '')
431
		{
432
			return $item;
433
		}
434
 
435
		foreach ($this->_reserved_identifiers as $id)
436
		{
437
			if (strpos($item, '.'.$id) !== FALSE)
438
			{
439
				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
440
 
441
				// remove duplicates if the user already included the escape
442
				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
443
			}
444
		}
445
 
446
		if (strpos($item, '.') !== FALSE)
447
		{
448
			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
449
		}
450
		else
451
		{
452
			$str = $this->_escape_char.$item.$this->_escape_char;
453
		}
454
 
455
		// remove duplicates if the user already included the escape
456
		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
457
	}
458
 
459
	// --------------------------------------------------------------------
460
 
461
	/**
462
	 * From Tables
463
	 *
464
	 * This function implicitly groups FROM tables so there is no confusion
465
	 * about operator precedence in harmony with SQL standards
466
	 *
467
	 * @access	public
468
	 * @param	type
469
	 * @return	type
470
	 */
471
	function _from_tables($tables)
472
	{
473
		if ( ! is_array($tables))
474
		{
475
			$tables = array($tables);
476
		}
477
 
478
		return implode(', ', $tables);
479
	}
480
 
481
	// --------------------------------------------------------------------
482
 
483
	/**
484
	 * Insert statement
485
	 *
486
	 * Generates a platform-specific insert string from the supplied data
487
	 *
488
	 * @access	public
489
	 * @param	string	the table name
490
	 * @param	array	the insert keys
491
	 * @param	array	the insert values
492
	 * @return	string
493
	 */
494
	function _insert($table, $keys, $values)
495
	{
496
		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
497
	}
498
 
499
	// --------------------------------------------------------------------
500
 
501
	/**
502
	 * Update statement
503
	 *
504
	 * Generates a platform-specific update string from the supplied data
505
	 *
506
	 * @access	public
507
	 * @param	string	the table name
508
	 * @param	array	the update data
509
	 * @param	array	the where clause
510
	 * @param	array	the orderby clause
511
	 * @param	array	the limit clause
512
	 * @return	string
513
	 */
514
	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
515
	{
516
		foreach($values as $key => $val)
517
		{
518
			$valstr[] = $key." = ".$val;
519
		}
520
 
521
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
522
 
523
		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
524
 
525
		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
526
 
527
		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
528
 
529
		$sql .= $orderby.$limit;
530
 
531
		return $sql;
532
	}
533
 
534
 
535
	// --------------------------------------------------------------------
536
 
537
	/**
538
	 * Truncate statement
539
	 *
540
	 * Generates a platform-specific truncate string from the supplied data
541
	 * If the database does not support the truncate() command
542
	 * This function maps to "DELETE FROM table"
543
	 *
544
	 * @access	public
545
	 * @param	string	the table name
546
	 * @return	string
547
	 */
548
	function _truncate($table)
549
	{
550
		return "TRUNCATE ".$table;
551
	}
552
 
553
	// --------------------------------------------------------------------
554
 
555
	/**
556
	 * Delete statement
557
	 *
558
	 * Generates a platform-specific delete string from the supplied data
559
	 *
560
	 * @access	public
561
	 * @param	string	the table name
562
	 * @param	array	the where clause
563
	 * @param	string	the limit clause
564
	 * @return	string
565
	 */
566
	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
567
	{
568
		$conditions = '';
569
 
570
		if (count($where) > 0 OR count($like) > 0)
571
		{
572
			$conditions = "\nWHERE ";
573
			$conditions .= implode("\n", $this->ar_where);
574
 
575
			if (count($where) > 0 && count($like) > 0)
576
			{
577
				$conditions .= " AND ";
578
			}
579
			$conditions .= implode("\n", $like);
580
		}
581
 
582
		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
583
 
584
		return "DELETE FROM ".$table.$conditions.$limit;
585
	}
586
 
587
	// --------------------------------------------------------------------
588
 
589
	/**
590
	 * Limit string
591
	 *
592
	 * Generates a platform-specific LIMIT clause
593
	 *
594
	 * @access	public
595
	 * @param	string	the sql query string
596
	 * @param	integer	the number of rows to limit the query to
597
	 * @param	integer	the offset value
598
	 * @return	string
599
	 */
600
	function _limit($sql, $limit, $offset)
601
	{
602
		$i = $limit + $offset;
603
 
604
		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
605
	}
606
 
607
	// --------------------------------------------------------------------
608
 
609
	/**
610
	 * Close DB Connection
611
	 *
612
	 * @access	public
613
	 * @param	resource
614
	 * @return	void
615
	 */
616
	function _close($conn_id)
617
	{
618
		@mssql_close($conn_id);
619
	}
620
 
621
}
622
 
623
 
624
 
625
/* End of file mssql_driver.php */
626
/* Location: ./system/database/drivers/mssql/mssql_driver.php */