00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 App::import('Vendor', 'NewADOConnection', array('file' => 'adodb' . DS . 'adodb.inc.php'));
00031
00032
00033
00034
00035
00036
00037
00038
00039 class DboAdodb extends DboSource {
00040
00041
00042
00043
00044
00045 var $description = "ADOdb DBO Driver";
00046
00047
00048
00049
00050
00051
00052 var $_adodb = null;
00053
00054
00055
00056
00057
00058
00059 var $_adodbColumnTypes = array(
00060 'string' => 'C',
00061 'text' => 'X',
00062 'date' => 'D',
00063 'timestamp' => 'T',
00064 'time' => 'T',
00065 'datetime' => 'T',
00066 'boolean' => 'L',
00067 'float' => 'N',
00068 'integer' => 'I',
00069 'binary' => 'R',
00070 );
00071
00072
00073
00074
00075
00076 var $columns = array(
00077 'primary_key' => array('name' => 'R', 'limit' => 11),
00078 'string' => array('name' => 'C', 'limit' => '255'),
00079 'text' => array('name' => 'X'),
00080 'integer' => array('name' => 'I', 'limit' => '11', 'formatter' => 'intval'),
00081 'float' => array('name' => 'N', 'formatter' => 'floatval'),
00082 'timestamp' => array('name' => 'T', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
00083 'time' => array('name' => 'T', 'format' => 'H:i:s', 'formatter' => 'date'),
00084 'datetime' => array('name' => 'T', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
00085 'date' => array('name' => 'D', 'format' => 'Y-m-d', 'formatter' => 'date'),
00086 'binary' => array('name' => 'B'),
00087 'boolean' => array('name' => 'L', 'limit' => '1')
00088 );
00089
00090
00091
00092
00093
00094 function connect() {
00095 $config = $this->config;
00096 $persistent = strrpos($config['connect'], '|p');
00097
00098 if ($persistent === false) {
00099 $adodb_driver = $config['connect'];
00100 $connect = 'Connect';
00101 } else {
00102 $adodb_driver = substr($config['connect'], 0, $persistent);
00103 $connect = 'PConnect';
00104 }
00105
00106 $this->_adodb = NewADOConnection($adodb_driver);
00107
00108 $this->_adodbDataDict = NewDataDictionary($this->_adodb, $adodb_driver);
00109
00110 $this->startQuote = $this->_adodb->nameQuote;
00111 $this->endQuote = $this->_adodb->nameQuote;
00112
00113 $this->connected = $this->_adodb->$connect($config['host'], $config['login'], $config['password'], $config['database']);
00114 $this->_adodbMetatyper = &$this->_adodb->execute('Select 1');
00115 return $this->connected;
00116 }
00117
00118
00119
00120
00121
00122 function disconnect() {
00123 return $this->_adodb->Close();
00124 }
00125
00126
00127
00128
00129
00130
00131 function _execute($sql) {
00132 global $ADODB_FETCH_MODE;
00133 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00134 return $this->_adodb->execute($sql);
00135 }
00136
00137
00138
00139
00140
00141 function fetchRow($sql = null) {
00142 if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
00143 if (!$this->execute($sql)) {
00144 return null;
00145 }
00146 }
00147
00148 if (!$this->hasResult()) {
00149 return null;
00150 } else {
00151 $resultRow = $this->_result->FetchRow();
00152 $this->resultSet($resultRow);
00153 return $this->fetchResult();
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 function begin(&$model) {
00164 if (parent::begin($model)) {
00165 if ($this->_adodb->BeginTrans()) {
00166 $this->_transactionStarted = true;
00167 return true;
00168 }
00169 }
00170 return false;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 function commit(&$model) {
00181 if (parent::commit($model)) {
00182 $this->_transactionStarted = false;
00183 return $this->_adodb->CommitTrans();
00184 }
00185 return false;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 function rollback(&$model) {
00196 if (parent::rollback($model)) {
00197 return $this->_adodb->RollbackTrans();
00198 }
00199 return false;
00200 }
00201
00202
00203
00204
00205
00206 function listSources() {
00207 $tables = $this->_adodb->MetaTables('TABLES');
00208
00209 if (!sizeof($tables) > 0) {
00210 trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE);
00211 exit;
00212 }
00213 return $tables;
00214 }
00215
00216
00217
00218
00219
00220
00221 function describe(&$model) {
00222 $cache = parent::describe($model);
00223 if ($cache != null) {
00224 return $cache;
00225 }
00226
00227 $fields = false;
00228 $cols = $this->_adodb->MetaColumns($this->fullTableName($model, false));
00229
00230 foreach ($cols as $column) {
00231 $fields[$column->name] = array(
00232 'type' => $this->column($column->type),
00233 'null' => !$column->not_null,
00234 'length' => $column->max_length,
00235 );
00236 if ($column->has_default) {
00237 $fields[$column->name]['default'] = $column->default_value;
00238 }
00239 if ($column->primary_key == 1) {
00240 $fields[$column->name]['key'] = 'primary';
00241 }
00242 }
00243
00244 $this->__cacheDescription($this->fullTableName($model, false), $fields);
00245 return $fields;
00246 }
00247
00248
00249
00250
00251
00252 function lastError() {
00253 return $this->_adodb->ErrorMsg();
00254 }
00255
00256
00257
00258
00259
00260 function lastAffected() {
00261 return $this->_adodb->Affected_Rows();
00262 }
00263
00264
00265
00266
00267
00268 function lastNumRows() {
00269 return $this->_result ? $this->_result->RecordCount() : false;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 function lastInsertId() {
00279 return $this->_adodb->Insert_ID();
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 function limit($limit, $offset = null) {
00290 if ($limit) {
00291 $rt = '';
00292 if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
00293 $rt = ' LIMIT';
00294 }
00295
00296 if ($offset) {
00297 $rt .= ' ' . $offset . ',';
00298 }
00299
00300 $rt .= ' ' . $limit;
00301 return $rt;
00302 }
00303 return null;
00304
00305
00306 }
00307
00308
00309
00310
00311
00312
00313 function column($real) {
00314 $metaTypes = array_flip($this->_adodbColumnTypes);
00315
00316 $interpreted_type = $this->_adodbMetatyper->MetaType($real);
00317
00318 if (!isset($metaTypes[$interpreted_type])) {
00319 return 'text';
00320 }
00321 return $metaTypes[$interpreted_type];
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331 function value($data, $column = null, $safe = false) {
00332 $parent = parent::value($data, $column, $safe);
00333 if ($parent != null) {
00334 return $parent;
00335 }
00336
00337 if ($data === null) {
00338 return 'NULL';
00339 }
00340
00341 if ($data === '') {
00342 return "''";
00343 }
00344 return $this->_adodb->qstr($data);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 function fields(&$model, $alias = null, $fields = array(), $quote = true) {
00356 if (empty($alias)) {
00357 $alias = $model->alias;
00358 }
00359 $fields = parent::fields($model, $alias, $fields, false);
00360
00361 if (!$quote) {
00362 return $fields;
00363 }
00364 $count = count($fields);
00365
00366 if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
00367 for ($i = 0; $i < $count; $i++) {
00368 if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
00369 $prepend = '';
00370 if (strpos($fields[$i], 'DISTINCT') !== false) {
00371 $prepend = 'DISTINCT ';
00372 $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
00373 }
00374
00375 if (strrpos($fields[$i], '.') === false) {
00376 $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
00377 } else {
00378 $build = explode('.', $fields[$i]);
00379 $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
00380 }
00381 }
00382 }
00383 }
00384 return $fields;
00385 }
00386
00387
00388
00389
00390
00391 function resultSet(&$results) {
00392 $num_fields = count($results);
00393 $fields = array_keys($results);
00394 $this->results =& $results;
00395 $this->map = array();
00396 $index = 0;
00397 $j = 0;
00398
00399 while ($j < $num_fields) {
00400 $columnName = $fields[$j];
00401
00402 if (strpos($columnName, '__')) {
00403 $parts = explode('__', $columnName);
00404 $this->map[$index++] = array($parts[0], $parts[1]);
00405 } else {
00406 $this->map[$index++] = array(0, $columnName);
00407 }
00408 $j++;
00409 }
00410 }
00411
00412
00413
00414
00415
00416 function fetchResult() {
00417 if (!empty($this->results)) {
00418 $row = $this->results;
00419 $this->results = null;
00420 } else {
00421 $row = $this->_result->FetchRow();
00422 }
00423
00424 if (empty($row)) {
00425 return false;
00426 }
00427
00428 $resultRow = array();
00429 $fields = array_keys($row);
00430 $count = count($fields);
00431 $i = 0;
00432 for ($i = 0; $i < $count; $i++) {
00433 list($table, $column) = $this->map[$i];
00434 $resultRow[$table][$column] = $row[$fields[$i]];
00435 }
00436 return $resultRow;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 function buildColumn($column) {
00446 $name = $type = null;
00447 extract(array_merge(array('null' => true), $column));
00448
00449 if (empty($name) || empty($type)) {
00450 trigger_error('Column name or type not defined in schema', E_USER_WARNING);
00451 return null;
00452 }
00453
00454
00455 if (!isset($this->_adodbColumnTypes[$type])) {
00456 trigger_error("Column type {$type} does not exist", E_USER_WARNING);
00457 return null;
00458 }
00459 $metaType = $this->_adodbColumnTypes[$type];
00460 $concreteType = $this->_adodbDataDict->ActualType($metaType);
00461 $real = $this->columns[$type];
00462
00463
00464 if ($type == 'string' && isset($real['length']) && $real['length'] == 36) {
00465 $concreteType = 'CHAR';
00466 }
00467
00468 $out = $this->name($name) . ' ' . $concreteType;
00469
00470 if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
00471 if (isset($column['length'])) {
00472 $length = $column['length'];
00473 } elseif (isset($column['limit'])) {
00474 $length = $column['limit'];
00475 } elseif (isset($real['length'])) {
00476 $length = $real['length'];
00477 } else {
00478 $length = $real['limit'];
00479 }
00480 $out .= '(' . $length . ')';
00481 }
00482 $_notNull = $_default = $_autoInc = $_constraint = $_unsigned = false;
00483
00484 if (isset($column['key']) && $column['key'] == 'primary' && $type == 'integer') {
00485 $_constraint = '';
00486 $_autoInc = true;
00487 } elseif (isset($column['key']) && $column['key'] == 'primary') {
00488 $_notNull = '';
00489 } elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
00490 $_notNull = true;
00491 $_default = $column['default'];
00492 } elseif ( isset($column['null']) && $column['null'] == true) {
00493 $_notNull = false;
00494 $_default = 'NULL';
00495 }
00496 if (isset($column['default']) && $_default == false) {
00497 $_default = $this->value($column['default']);
00498 }
00499 if (isset($column['null']) && $column['null'] == false) {
00500 $_notNull = true;
00501 }
00502
00503 $out .= $this->_adodbDataDict->_CreateSuffix($out, $metaType, $_notNull, $_default, $_autoInc, $_constraint, $_unsigned);
00504 return $out;
00505
00506 }
00507
00508
00509
00510
00511
00512 function hasResult() {
00513 return is_object($this->_result) && !$this->_result->EOF;
00514 }
00515 }
00516 ?>