Subversion-Projekte lars-tiefland.ci

Revision

Revision 2254 | Zur aktuellen Revision | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
68 lars 1
<?php
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
2257 lars 9
 * Copyright (c) 2014 - 2018, British Columbia Institute of Technology
68 lars 10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
2257 lars 32
 * @copyright	Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
68 lars 33
 * @license	http://opensource.org/licenses/MIT	MIT License
34
 * @link	https://codeigniter.com
35
 * @since	Version 3.0.0
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
 
40
/**
41
 * PDO PostgreSQL Database Adapter Class
42
 *
43
 * Note: _DB is an extender class that the app controller
44
 * creates dynamically based on whether the query builder
45
 * class is being used or not.
46
 *
47
 * @package		CodeIgniter
48
 * @subpackage	Drivers
49
 * @category	Database
50
 * @author		EllisLab Dev Team
51
 * @link		https://codeigniter.com/user_guide/database/
52
 */
53
class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
54
 
55
	/**
56
	 * Sub-driver
57
	 *
58
	 * @var	string
59
	 */
60
	public $subdriver = 'pgsql';
61
 
62
	/**
63
	 * Database schema
64
	 *
65
	 * @var	string
66
	 */
67
	public $schema = 'public';
68
 
69
	// --------------------------------------------------------------------
70
 
71
	/**
72
	 * ORDER BY random keyword
73
	 *
74
	 * @var	array
75
	 */
76
	protected $_random_keyword = array('RANDOM()', 'RANDOM()');
77
 
78
	// --------------------------------------------------------------------
79
 
80
	/**
81
	 * Class constructor
82
	 *
83
	 * Builds the DSN if not already set.
84
	 *
85
	 * @param	array	$params
86
	 * @return	void
87
	 */
88
	public function __construct($params)
89
	{
90
		parent::__construct($params);
91
 
92
		if (empty($this->dsn))
93
		{
94
			$this->dsn = 'pgsql:host='.(empty($this->hostname) ? '127.0.0.1' : $this->hostname);
95
 
96
			empty($this->port) OR $this->dsn .= ';port='.$this->port;
97
			empty($this->database) OR $this->dsn .= ';dbname='.$this->database;
98
 
99
			if ( ! empty($this->username))
100
			{
101
				$this->dsn .= ';username='.$this->username;
102
				empty($this->password) OR $this->dsn .= ';password='.$this->password;
103
			}
104
		}
105
	}
106
 
107
	// --------------------------------------------------------------------
108
 
109
	/**
110
	 * Database connection
111
	 *
112
	 * @param	bool	$persistent
113
	 * @return	object
114
	 */
115
	public function db_connect($persistent = FALSE)
116
	{
117
		$this->conn_id = parent::db_connect($persistent);
118
 
119
		if (is_object($this->conn_id) && ! empty($this->schema))
120
		{
121
			$this->simple_query('SET search_path TO '.$this->schema.',public');
122
		}
123
 
124
		return $this->conn_id;
125
	}
126
 
127
	// --------------------------------------------------------------------
128
 
129
	/**
130
	 * Insert ID
131
	 *
132
	 * @param	string	$name
133
	 * @return	int
134
	 */
135
	public function insert_id($name = NULL)
136
	{
137
		if ($name === NULL && version_compare($this->version(), '8.1', '>='))
138
		{
139
			$query = $this->query('SELECT LASTVAL() AS ins_id');
140
			$query = $query->row();
141
			return $query->ins_id;
142
		}
143
 
144
		return $this->conn_id->lastInsertId($name);
145
	}
146
 
147
	// --------------------------------------------------------------------
148
 
149
	/**
150
	 * Determines if a query is a "write" type.
151
	 *
152
	 * @param	string	An SQL query string
153
	 * @return	bool
154
	 */
155
	public function is_write_type($sql)
156
	{
1257 lars 157
		if (preg_match('#^(INSERT|UPDATE).*RETURNING\s.+(\,\s?.+)*$#is', $sql))
68 lars 158
		{
159
			return FALSE;
160
		}
161
 
162
		return parent::is_write_type($sql);
163
	}
164
 
165
	// --------------------------------------------------------------------
166
 
167
	/**
168
	 * "Smart" Escape String
169
	 *
170
	 * Escapes data based on type
171
	 *
172
	 * @param	string	$str
173
	 * @return	mixed
174
	 */
175
	public function escape($str)
176
	{
177
		if (is_bool($str))
178
		{
179
			return ($str) ? 'TRUE' : 'FALSE';
180
		}
181
 
182
		return parent::escape($str);
183
	}
184
 
185
	// --------------------------------------------------------------------
186
 
187
	/**
188
	 * ORDER BY
189
	 *
190
	 * @param	string	$orderby
191
	 * @param	string	$direction	ASC, DESC or RANDOM
192
	 * @param	bool	$escape
193
	 * @return	object
194
	 */
195
	public function order_by($orderby, $direction = '', $escape = NULL)
196
	{
197
		$direction = strtoupper(trim($direction));
198
		if ($direction === 'RANDOM')
199
		{
200
			if ( ! is_float($orderby) && ctype_digit((string) $orderby))
201
			{
202
				$orderby = ($orderby > 1)
203
					? (float) '0.'.$orderby
204
					: (float) $orderby;
205
			}
206
 
207
			if (is_float($orderby))
208
			{
209
				$this->simple_query('SET SEED '.$orderby);
210
			}
211
 
212
			$orderby = $this->_random_keyword[0];
213
			$direction = '';
214
			$escape = FALSE;
215
		}
216
 
217
		return parent::order_by($orderby, $direction, $escape);
218
	}
219
 
220
	// --------------------------------------------------------------------
221
 
222
	/**
223
	 * Show table query
224
	 *
225
	 * Generates a platform-specific query string so that the table names can be fetched
226
	 *
227
	 * @param	bool	$prefix_limit
228
	 * @return	string
229
	 */
230
	protected function _list_tables($prefix_limit = FALSE)
231
	{
232
		$sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \''.$this->schema."'";
233
 
234
		if ($prefix_limit === TRUE && $this->dbprefix !== '')
235
		{
236
			return $sql.' AND "table_name" LIKE \''
237
				.$this->escape_like_str($this->dbprefix)."%' "
238
				.sprintf($this->_like_escape_str, $this->_like_escape_chr);
239
		}
240
 
241
		return $sql;
242
	}
243
 
244
	// --------------------------------------------------------------------
245
 
246
	/**
247
	 * List column query
248
	 *
249
	 * Generates a platform-specific query string so that the column names can be fetched
250
	 *
251
	 * @param	string	$table
252
	 * @return	string
253
	 */
254
	protected function _list_columns($table = '')
255
	{
256
		return 'SELECT "column_name"
257
			FROM "information_schema"."columns"
258
			WHERE LOWER("table_name") = '.$this->escape(strtolower($table));
259
	}
260
 
261
	// --------------------------------------------------------------------
262
 
263
	/**
264
	 * Returns an object with field data
265
	 *
266
	 * @param	string	$table
267
	 * @return	array
268
	 */
269
	public function field_data($table)
270
	{
271
		$sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default"
272
			FROM "information_schema"."columns"
273
			WHERE LOWER("table_name") = '.$this->escape(strtolower($table));
274
 
275
		if (($query = $this->query($sql)) === FALSE)
276
		{
277
			return FALSE;
278
		}
279
		$query = $query->result_object();
280
 
281
		$retval = array();
282
		for ($i = 0, $c = count($query); $i < $c; $i++)
283
		{
284
			$retval[$i]			= new stdClass();
285
			$retval[$i]->name		= $query[$i]->column_name;
286
			$retval[$i]->type		= $query[$i]->data_type;
287
			$retval[$i]->max_length		= ($query[$i]->character_maximum_length > 0) ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision;
288
			$retval[$i]->default		= $query[$i]->column_default;
289
		}
290
 
291
		return $retval;
292
	}
293
 
294
	// --------------------------------------------------------------------
295
 
296
	/**
297
	 * Update statement
298
	 *
299
	 * Generates a platform-specific update string from the supplied data
300
	 *
301
	 * @param	string	$table
302
	 * @param	array	$values
303
	 * @return	string
304
	 */
305
	protected function _update($table, $values)
306
	{
307
		$this->qb_limit = FALSE;
308
		$this->qb_orderby = array();
309
		return parent::_update($table, $values);
310
	}
311
 
312
	// --------------------------------------------------------------------
313
 
314
	/**
315
	 * Update_Batch statement
316
	 *
317
	 * Generates a platform-specific batch update string from the supplied data
318
	 *
319
	 * @param	string	$table	Table name
320
	 * @param	array	$values	Update data
321
	 * @param	string	$index	WHERE key
322
	 * @return	string
323
	 */
324
	protected function _update_batch($table, $values, $index)
325
	{
326
		$ids = array();
327
		foreach ($values as $key => $val)
328
		{
2049 lars 329
			$ids[] = $val[$index]['value'];
68 lars 330
 
331
			foreach (array_keys($val) as $field)
332
			{
333
				if ($field !== $index)
334
				{
2049 lars 335
					$final[$val[$field]['field']][] = 'WHEN '.$val[$index]['value'].' THEN '.$val[$field]['value'];
68 lars 336
				}
337
			}
338
		}
339
 
340
		$cases = '';
341
		foreach ($final as $k => $v)
342
		{
2049 lars 343
			$cases .= $k.' = (CASE '.$val[$index]['field']."\n"
68 lars 344
				.implode("\n", $v)."\n"
345
				.'ELSE '.$k.' END), ';
346
		}
347
 
2049 lars 348
		$this->where($val[$index]['field'].' IN('.implode(',', $ids).')', NULL, FALSE);
68 lars 349
 
350
		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where');
351
	}
352
 
353
	// --------------------------------------------------------------------
354
 
355
	/**
356
	 * Delete statement
357
	 *
358
	 * Generates a platform-specific delete string from the supplied data
359
	 *
360
	 * @param	string	$table
361
	 * @return	string
362
	 */
363
	protected function _delete($table)
364
	{
365
		$this->qb_limit = FALSE;
366
		return parent::_delete($table);
367
	}
368
 
369
	// --------------------------------------------------------------------
370
 
371
	/**
372
	 * LIMIT
373
	 *
374
	 * Generates a platform-specific LIMIT clause
375
	 *
376
	 * @param	string	$sql	SQL Query
377
	 * @return	string
378
	 */
379
	protected function _limit($sql)
380
	{
381
		return $sql.' LIMIT '.$this->qb_limit.($this->qb_offset ? ' OFFSET '.$this->qb_offset : '');
382
	}
383
 
384
}