Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* SVN FILE: $Id: dbo_odbc.php 7945 2008-12-19 02:16:01Z gwoo $ */
3
 
4
/**
5
 * ODBC for DBO
6
 *
7
 * Long description for file
8
 *
9
 * PHP versions 4 and 5
10
 *
11
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
12
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
13
 *
14
 * Licensed under The MIT License
15
 * Redistributions of files must retain the above copyright notice.
16
 *
17
 * @filesource
18
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
19
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
20
 * @package       cake
21
 * @subpackage    cake.cake.libs.model.dbo
22
 * @since         CakePHP(tm) v 0.10.5.1790
23
 * @version       $Revision: 7945 $
24
 * @modifiedby    $LastChangedBy: gwoo $
25
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
26
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
27
 */
28
 
29
/**
30
 * Short description for class.
31
 *
32
 * Long description for class
33
 *
34
 * @package       cake
35
 * @subpackage    cake.cake.libs.model.datasources.dbo
36
 */
37
class DboOdbc extends DboSource {
38
/**
39
 * Driver description
40
 *
41
 * @var string
42
 */
43
	var $description = "ODBC DBO Driver";
44
/**
45
 * Table/column starting quote
46
 *
47
 * @var string
48
 */
49
	var $startQuote = "`";
50
/**
51
 * Table/column end quote
52
 *
53
 * @var string
54
 */
55
	var $endQuote = "`";
56
/**
57
 * Driver base configuration
58
 *
59
 * @var array
60
 */
61
	var $_baseConfig = array(
62
		'persistent' => true,
63
		'login' => 'root',
64
		'password' => '',
65
		'database' => 'cake',
66
		'connect'  => 'odbc_pconnect'
67
	);
68
/**
69
 * Enter description here...
70
 *
71
 * @var unknown_type
72
 */
73
	var $columns = array();
74
 
75
	//	var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
76
	//						'string' => array('name' => 'varchar', 'limit' => '255'),
77
	//						'text' => array('name' => 'text'),
78
	//						'integer' => array('name' => 'int', 'limit' => '11'),
79
	//						'float' => array('name' => 'float'),
80
	//						'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
81
	//						'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
82
	//						'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
83
	//						'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
84
	//						'binary' => array('name' => 'blob'),
85
	//						'boolean' => array('name' => 'tinyint', 'limit' => '1'));
86
/**
87
 * Connects to the database using options in the given configuration array.
88
 *
89
 * @return boolean True if the database could be connected, else false
90
 */
91
	function connect() {
92
		$config = $this->config;
93
		$connect = $config['connect'];
94
		if (!$config['persistent']) {
95
			$connect = 'odbc_connect';
96
		}
97
		if (!function_exists($connect)) {
98
			die('no odbc?');
99
		}
100
		$this->connected = false;
101
		$this->connection = $connect($config['database'], $config['login'], $config['password'],  SQL_CUR_USE_ODBC);
102
		if ($this->connection) {
103
			$this->connected = true;
104
		}
105
 
106
		return $this->connected;
107
	}
108
/**
109
 * Disconnects from database.
110
 *
111
 * @return boolean True if the database could be disconnected, else false
112
 */
113
	function disconnect() {
114
		return @odbc_close($this->connection);
115
	}
116
/**
117
 * Executes given SQL statement.
118
 *
119
 * @param string $sql SQL statement
120
 * @return resource Result resource identifier
121
 * @access protected
122
 */
123
	function _execute($sql) {
124
		switch ($sql) {
125
			case 'BEGIN':
126
				return odbc_autocommit($this->connection, false);
127
			case 'COMMIT':
128
				return odbc_commit($this->connection);
129
			case 'ROLLBACK':
130
				return odbc_rollback($this->connection);
131
		}
132
		// TODO: should flags be set? possible requirement:  SQL_CURSOR_STATIC
133
		return odbc_exec($this->connection, $sql);
134
	}
135
/**
136
 * Returns an array of sources (tables) in the database.
137
 *
138
 * @return array Array of tablenames in the database
139
 */
140
	function listSources() {
141
		$cache = parent::listSources();
142
		if ($cache != null) {
143
			return $cache;
144
		}
145
 
146
		$result = odbc_tables($this->connection);
147
 
148
		$tables = array();
149
		while (odbc_fetch_row($result)) {
150
			array_push($tables, odbc_result($result, 'TABLE_NAME'));
151
		}
152
 
153
		parent::listSources($tables);
154
		return $tables;
155
	}
156
/**
157
 * Returns an array of the fields in given table name.
158
 *
159
 * @param Model $model Model object to describe
160
 * @return array Fields in table. Keys are name and type
161
 */
162
	function &describe(&$model) {
163
		$cache=parent::describe($model);
164
 
165
		if ($cache != null) {
166
				return $cache;
167
		}
168
 
169
		$fields = array();
170
		$sql = 'SELECT * FROM ' . $this->fullTableName($model);
171
		$result = odbc_exec($this->connection, $sql);
172
 
173
		$count = odbc_num_fields($result);
174
 
175
		for ($i = 1; $i <= $count; $i++) {
176
				$cols[$i - 1] = odbc_field_name($result, $i);
177
		}
178
 
179
		foreach ($cols as $column) {
180
			$type = odbc_field_type(odbc_exec($this->connection, 'SELECT ' . $column . ' FROM ' . $this->fullTableName($model)), 1);
181
			$fields[$column] = array('type' => $type);
182
		}
183
 
184
		$this->__cacheDescription($model->tablePrefix . $model->table, $fields);
185
		return $fields;
186
	}
187
/**
188
 * Returns a quoted and escaped string of $data for use in an SQL statement.
189
 *
190
 * @param string $data String to be prepared for use in an SQL statement
191
 * @param string $column The column into which this data will be inserted
192
 * @return string Quoted and escaped
193
 * @todo Add logic that formats/escapes data based on column type
194
 */
195
	function value($data, $column = null) {
196
		$parent=parent::value($data, $column);
197
 
198
		if ($parent != null) {
199
				return $parent;
200
		}
201
 
202
		if ($data === null) {
203
				return 'NULL';
204
		}
205
 
206
		if (!is_numeric($data)) {
207
				return "'" . $data . "'";
208
		}
209
 
210
		return $data;
211
	}
212
/**
213
 * Returns a formatted error message from previous database operation.
214
 *
215
 * @return string Error message with error number
216
 */
217
	function lastError() {
218
		if ($error = odbc_errormsg($this->connection)) {
219
			return odbc_error($this->connection) . ': ' . $error;
220
		}
221
		return null;
222
	}
223
/**
224
 * Returns number of affected rows in previous database operation. If no previous operation exists,
225
 * this returns false.
226
 *
227
 * @return integer Number of affected rows
228
 */
229
	function lastAffected() {
230
		if ($this->hasResult()) {
231
			return odbc_num_rows($this->_result);
232
		}
233
		return null;
234
	}
235
/**
236
 * Returns number of rows in previous resultset. If no previous resultset exists,
237
 * this returns false.
238
 *
239
 * @return int Number of rows in resultset
240
 */
241
	function lastNumRows() {
242
		if ($this->hasResult()) {
243
			return odbc_num_rows($this->_result);
244
		}
245
		return null;
246
	}
247
/**
248
 * Returns the ID generated from the previous INSERT operation.
249
 *
250
 * @param unknown_type $source
251
 * @return int
252
 */
253
	function lastInsertId($source = null) {
254
		$result = $this->fetchRow('SELECT @@IDENTITY');
255
		return $result[0];
256
	}
257
/**
258
 * Enter description here...
259
 *
260
 * @param string $real Real database-layer column type (i.e. "varchar(255)")
261
 */
262
	function column($real) {
263
		if (is_array($real)) {
264
			$col=$real['name'];
265
			if (isset($real['limit'])) {
266
				$col .= '(' . $real['limit'] . ')';
267
			}
268
			return $col;
269
		}
270
		return $real;
271
	}
272
/**
273
* Enter description here...
274
*
275
* @param unknown_type $results
276
*/
277
	function resultSet(&$results) {
278
		$this->results =& $results;
279
		$num_fields = odbc_num_fields($results);
280
		$this->map = array();
281
		$index = 0;
282
		$j = 0;
283
		while ($j < $num_fields) {
284
			$column = odbc_field_name($results, $j+1);
285
 
286
			if (strpos($column, '_dot_') !== false) {
287
				list($table, $column) = explode('_dot_', $column);
288
				$this->map[$index++] = array($table, $column);
289
			} else {
290
				$this->map[$index++] = array(0, $column);
291
			}
292
			$j++;
293
		}
294
	}
295
/**
296
* Generates the fields list of an SQL query.
297
*
298
* @param Model $model
299
* @param string $alias Alias tablename
300
* @param mixed $fields
301
* @return array
302
*/
303
	function fields(&$model, $alias = null, $fields = null, $quote = true) {
304
		if (empty($alias)) {
305
			$alias = $model->name;
306
		}
307
		if (!is_array($fields)) {
308
			if ($fields != null) {
309
				$fields = array_map('trim', explode(',', $fields));
310
			} else {
311
				foreach($model->tableToModel as $tableName => $modelName) {
312
					foreach($this->__descriptions[$model->tablePrefix .$tableName] as $field => $type) {
313
						$fields[] = $modelName .'.' .$field;
314
					}
315
				}
316
			}
317
		}
318
 
319
		$count = count($fields);
320
 
321
		if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
322
			for ($i = 0; $i < $count; $i++) {
323
				if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
324
					$prepend = '';
325
					if (strpos($fields[$i], 'DISTINCT') !== false) {
326
						$prepend = 'DISTINCT ';
327
						$fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
328
					}
329
 
330
					if (strrpos($fields[$i], '.') === false) {
331
						$fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '_dot_' . $fields[$i]);
332
					} else {
333
						$build = explode('.', $fields[$i]);
334
						$fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '_dot_' . $build[1]);
335
					}
336
				}
337
			}
338
		}
339
		return $fields;
340
	}
341
/**
342
 * Fetches the next row from the current result set
343
 *
344
 * @return unknown
345
 */
346
	function fetchResult() {
347
		if ($row = odbc_fetch_row($this->results)) {
348
			$resultRow = array();
349
			$numFields = odbc_num_fields($this->results);
350
			$i = 0;
351
			for($i = 0; $i < $numFields; $i++) {
352
				list($table, $column) = $this->map[$i];
353
				$resultRow[$table][$column] = odbc_result($this->results, $i + 1);
354
			}
355
			return $resultRow;
356
		}
357
		return false;
358
	}
359
}
360
?>