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
00031
00032
00033
00034
00035
00036
00037
00038
00039 class DboDb2 extends DboSource {
00040
00041
00042
00043
00044
00045 var $description = 'IBM DB2 DBO Driver';
00046
00047
00048
00049
00050
00051 var $startQuote = '';
00052
00053
00054
00055
00056
00057 var $endQuote = '';
00058
00059
00060
00061
00062
00063
00064 var $_baseConfig = array(
00065 'persistent' => true,
00066 'login' => 'db2inst1',
00067 'password' => '',
00068 'database' => 'cake',
00069 'schema' => '',
00070 'hostname' => '127.0.0.1',
00071 'port' => '50001',
00072 'encoding' => 'UTF-8',
00073 'cataloged' => true,
00074 'autocommit' => true
00075 );
00076
00077
00078
00079
00080
00081
00082
00083
00084 var $columns = array(
00085 'primary_key' => array('name' => 'not null generated by default as identity (start with 1, increment by 1)'),
00086 'string' => array('name' => 'varchar', 'limit' => '255'),
00087 'text' => array('name' => 'clob'),
00088 'integer' => array('name' => 'integer', 'limit' => '10', 'formatter' => 'intval'),
00089 'float' => array('name' => 'double', 'formatter' => 'floatval'),
00090 'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d-H.i.s', 'formatter' => 'date'),
00091 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d-H.i.s', 'formatter' => 'date'),
00092 'time' => array('name' => 'time', 'format' => 'H.i.s', 'formatter' => 'date'),
00093 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
00094 'binary' => array('name' => 'blob'),
00095 'boolean' => array('name' => 'smallint', 'limit' => '1')
00096 );
00097
00098
00099
00100
00101
00102 var $_resultMap = array();
00103
00104
00105
00106
00107
00108 function connect() {
00109 $config = $this->config;
00110 $connect = 'db2_connect';
00111 if ($config['persistent']) {
00112 $connect = 'db2_pconnect';
00113 }
00114 $this->connected = false;
00115
00116 if ($config['cataloged']) {
00117 $this->connection = $connect($config['database'], $config['login'], $config['password']);
00118 } else {
00119 $connString = sprintf(
00120 "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=%s;HOSTNAME=%s;PORT=%d;PROTOCOL=TCPIP;UID=%s;PWD=%s;",
00121 $config['database'],
00122 $config['hostname'],
00123 $config['port'],
00124 $config['login'],
00125 $config['password']
00126 );
00127 $this->connection = db2_connect($connString, '', '');
00128 }
00129
00130 if ($this->connection) {
00131 $this->connected = true;
00132 }
00133
00134 if ($config['schema'] !== '') {
00135 $this->_execute('SET CURRENT SCHEMA = ' . $config['schema']);
00136 }
00137 return $this->connected;
00138 }
00139
00140
00141
00142
00143
00144 function disconnect() {
00145 @db2_free_result($this->results);
00146 $this->connected = !@db2_close($this->connection);
00147 return !$this->connected;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 function _execute($sql) {
00159
00160 $result = db2_exec($this->connection, $sql);
00161
00162 if (!is_bool($result)) {
00163
00164 $map = array();
00165 $numFields = db2_num_fields($result);
00166 $index = 0;
00167 $j = 0;
00168 $offset = 0;
00169
00170 while ($j < $numFields) {
00171 $columnName = strtolower(db2_field_name($result, $j));
00172 $tmp = strpos($sql, '.' . $columnName, $offset);
00173 $tableName = substr($sql, $offset, ($tmp-$offset));
00174 $tableName = substr($tableName, strrpos($tableName, ' ') + 1);
00175 $map[$index++] = array($tableName, $columnName);
00176 $j++;
00177 $offset = strpos($sql, ' ', $tmp);
00178 }
00179
00180 $this->_resultMap[$result] = $map;
00181 }
00182
00183 return $result;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 function listSources() {
00194 $cache = parent::listSources();
00195
00196 if ($cache != null) {
00197 return $cache;
00198 }
00199 $result = db2_tables($this->connection);
00200 $tables = array();
00201
00202 while (db2_fetch_row($result)) {
00203 $tables[] = strtolower(db2_result($result, 'TABLE_NAME'));
00204 }
00205 parent::listSources($tables);
00206 return $tables;
00207 }
00208
00209
00210
00211
00212
00213
00214 function &describe(&$model) {
00215 $cache = parent::describe($model);
00216
00217 if ($cache != null) {
00218 return $cache;
00219 }
00220 $fields = array();
00221 $result = db2_columns($this->connection, '', '', strtoupper($this->fullTableName($model)));
00222
00223 while (db2_fetch_row($result)) {
00224 $fields[strtolower(db2_result($result, 'COLUMN_NAME'))] = array(
00225 'type' => $this->column(strtolower(db2_result($result, 'TYPE_NAME'))),
00226 'null' => db2_result($result, 'NULLABLE'),
00227 'default' => db2_result($result, 'COLUMN_DEF'),
00228 'length' => db2_result($result, 'COLUMN_SIZE')
00229 );
00230 }
00231 $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
00232 return $fields;
00233 }
00234
00235
00236
00237
00238
00239
00240 function name($data) {
00241 return $data;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 function value($data, $column = null, $safe = false) {
00252 $parent = parent::value($data, $column, $safe);
00253
00254 if ($parent != null) {
00255 return $parent;
00256 }
00257
00258 if ($data === null) {
00259 return 'NULL';
00260 }
00261
00262 if ($data === '') {
00263 return "''";
00264 }
00265
00266 switch ($column) {
00267 case 'boolean':
00268 $data = $this->boolean((bool)$data);
00269 break;
00270 case 'integer':
00271 $data = intval($data);
00272 break;
00273 default:
00274 $data = str_replace("'", "''", $data);
00275 break;
00276 }
00277
00278 if ($column == 'integer' || $column == 'float') {
00279 return $data;
00280 }
00281 return "'" . $data . "'";
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 function boolean($data) {
00291 if ($data === true || $data === false) {
00292 if ($data === true) {
00293 return 1;
00294 }
00295 return 0;
00296 } else {
00297 if (intval($data !== 0)) {
00298 return true;
00299 }
00300 return false;
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311 function begin(&$model) {
00312 if (parent::begin($model)) {
00313 if (db2_autocommit($this->connection, DB2_AUTOCOMMIT_OFF)) {
00314 $this->_transactionStarted = true;
00315 return true;
00316 }
00317 }
00318 return false;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 function commit(&$model) {
00329 if (parent::commit($model)) {
00330 if (db2_commit($this->connection)) {
00331 $this->_transactionStarted = false;
00332 db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
00333 return true;
00334 }
00335 }
00336 return false;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346 function rollback(&$model) {
00347 if (parent::rollback($model)) {
00348 $this->_transactionStarted = false;
00349 db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
00350 return db2_rollback($this->connection);
00351 }
00352 return false;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362 function update(&$model, $fields = array(), $values = array()) {
00363 foreach ($fields as $i => $field) {
00364 if ($field == $model->primaryKey) {
00365 unset ($fields[$i]);
00366 unset ($values[$i]);
00367 break;
00368 }
00369 }
00370 return parent::update($model, $fields, $values);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379 function lastError() {
00380 if (db2_stmt_error()) {
00381 return db2_stmt_error() . ': ' . db2_stmt_errormsg();
00382 } elseif (db2_conn_error()) {
00383 return db2_conn_error() . ': ' . db2_conn_errormsg();
00384 }
00385 return null;
00386 }
00387
00388
00389
00390
00391
00392
00393 function lastAffected() {
00394 if ($this->_result) {
00395 return db2_num_rows($this->_result);
00396 }
00397 return null;
00398 }
00399
00400
00401
00402
00403
00404
00405 function lastNumRows() {
00406 if ($this->_result) {
00407 return db2_num_rows($this->_result);
00408 }
00409 return null;
00410 }
00411
00412
00413
00414
00415
00416
00417 function lastInsertId($source = null) {
00418 $data = $this->fetchRow(sprintf('SELECT SYSIBM.IDENTITY_VAL_LOCAL() AS ID FROM %s FETCH FIRST ROW ONLY', $source));
00419
00420 if ($data && isset($data[0]['id'])) {
00421 return $data[0]['id'];
00422 }
00423 return null;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432 function limit($limit, $offset = null) {
00433 if ($limit) {
00434 $rt = '';
00435
00436
00437 if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
00438 $rt = sprintf('FETCH FIRST %d ROWS ONLY', $limit);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 return $rt;
00461 }
00462 return null;
00463 }
00464
00465
00466
00467
00468
00469
00470 function column($real) {
00471 if (is_array($real)) {
00472 $col = $real['name'];
00473
00474 if (isset($real['limit'])) {
00475 $col .= '(' . $real['limit'] . ')';
00476 }
00477 return $col;
00478 }
00479 $col = str_replace(')', '', $real);
00480 $limit = null;
00481 if (strpos($col, '(') !== false) {
00482 list($col, $limit) = explode('(', $col);
00483 }
00484
00485 if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
00486 return $col;
00487 }
00488
00489 if ($col == 'smallint') {
00490 return 'boolean';
00491 }
00492
00493 if (strpos($col, 'char') !== false) {
00494 return 'string';
00495 }
00496
00497 if (strpos($col, 'clob') !== false) {
00498 return 'text';
00499 }
00500
00501 if (strpos($col, 'blob') !== false || $col == 'image') {
00502 return 'binary';
00503 }
00504
00505 if (in_array($col, array('double', 'real', 'decimal'))) {
00506 return 'float';
00507 }
00508 return 'text';
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 function resultSet(&$results, $sql = null) {
00536 $this->results =& $results;
00537 $this->map = $this->_resultMap[$this->results];
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 function fetchResult() {
00549 if ($row = db2_fetch_array($this->results)) {
00550 $resultRow = array();
00551 $i = 0;
00552
00553 foreach ($row as $index => $field) {
00554 $table = $this->map[$index][0];
00555 $column = strtolower($this->map[$index][1]);
00556 $resultRow[$table][$column] = $row[$index];
00557 $i++;
00558 }
00559 return $resultRow;
00560 }
00561 return false;
00562 }
00563 }
00564 ?>