Moving certain datasources to the Datasources Plugin (http://github.com/cakephp/datasources)

This commit is contained in:
predominant 2009-12-11 01:07:23 +11:00 committed by Joël Perras
parent d550a5e82c
commit aaddd0d394
6 changed files with 0 additions and 2763 deletions

View file

@ -1,545 +0,0 @@
<?php
/**
* AdoDB layer for DBO.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Include AdoDB files.
*/
App::import('Vendor', 'NewADOConnection', array('file' => 'adodb' . DS . 'adodb.inc.php'));
/**
* AdoDB DBO implementation.
*
* Database abstraction implementation for the AdoDB library.
*
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
*/
class DboAdodb extends DboSource {
/**
* Enter description here...
*
* @var string
*/
var $description = "ADOdb DBO Driver";
/**
* ADOConnection object with which we connect.
*
* @var ADOConnection The connection object.
* @access private
*/
var $_adodb = null;
/**
* Array translating ADOdb column MetaTypes to cake-supported metatypes
*
* @var array
* @access private
*/
var $_adodbColumnTypes = array(
'string' => 'C',
'text' => 'X',
'date' => 'D',
'timestamp' => 'T',
'time' => 'T',
'datetime' => 'T',
'boolean' => 'L',
'float' => 'N',
'integer' => 'I',
'binary' => 'R',
);
/**
* ADOdb column definition
*
* @var array
*/
var $columns = array(
'primary_key' => array('name' => 'R', 'limit' => 11),
'string' => array('name' => 'C', 'limit' => '255'),
'text' => array('name' => 'X'),
'integer' => array('name' => 'I', 'limit' => '11', 'formatter' => 'intval'),
'float' => array('name' => 'N', 'formatter' => 'floatval'),
'timestamp' => array('name' => 'T', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'time' => array('name' => 'T', 'format' => 'H:i:s', 'formatter' => 'date'),
'datetime' => array('name' => 'T', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'date' => array('name' => 'D', 'format' => 'Y-m-d', 'formatter' => 'date'),
'binary' => array('name' => 'B'),
'boolean' => array('name' => 'L', 'limit' => '1')
);
/**
* Connects to the database using options in the given configuration array.
*
* @param array $config Configuration array for connecting
*/
function connect() {
$config = $this->config;
$persistent = strrpos($config['connect'], '|p');
if ($persistent === false) {
$adodb_driver = $config['connect'];
$connect = 'Connect';
} else {
$adodb_driver = substr($config['connect'], 0, $persistent);
$connect = 'PConnect';
}
if (!$this->enabled()) {
return false;
}
$this->_adodb = NewADOConnection($adodb_driver);
$this->_adodbDataDict = NewDataDictionary($this->_adodb, $adodb_driver);
$this->startQuote = $this->_adodb->nameQuote;
$this->endQuote = $this->_adodb->nameQuote;
$this->connected = $this->_adodb->$connect($config['host'], $config['login'], $config['password'], $config['database']);
$this->_adodbMetatyper = &$this->_adodb->execute('Select 1');
return $this->connected;
}
/**
* Check that AdoDB is available.
*
* @return boolean
*/
function enabled() {
return function_exists('NewADOConnection');
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
return $this->_adodb->Close();
}
/**
* Executes given SQL statement.
*
* @param string $sql SQL statement
* @return resource Result resource identifier
*/
function _execute($sql) {
global $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
return $this->_adodb->execute($sql);
}
/**
* Returns a row from current resultset as an array .
*
* @return array The fetched row as an array
*/
function fetchRow($sql = null) {
if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
if (!$this->execute($sql)) {
return null;
}
}
if (!$this->hasResult()) {
return null;
} else {
$resultRow = $this->_result->FetchRow();
$this->resultSet($resultRow);
return $this->fetchResult();
}
}
/**
* Begin a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions).
*/
function begin(&$model) {
if (parent::begin($model)) {
if ($this->_adodb->BeginTrans()) {
$this->_transactionStarted = true;
return true;
}
}
return false;
}
/**
* Commit a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function commit(&$model) {
if (parent::commit($model)) {
$this->_transactionStarted = false;
return $this->_adodb->CommitTrans();
}
return false;
}
/**
* Rollback a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function rollback(&$model) {
if (parent::rollback($model)) {
return $this->_adodb->RollbackTrans();
}
return false;
}
/**
* Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$tables = $this->_adodb->MetaTables('TABLES');
if (!count($tables) > 0) {
trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE);
exit;
}
return $tables;
}
/**
* Returns an array of the fields in the table used by the given model.
*
* @param AppModel $model Model object
* @return array Fields in table. Keys are name and type
*/
function describe(&$model) {
$cache = parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = false;
$cols = $this->_adodb->MetaColumns($this->fullTableName($model, false));
foreach ($cols as $column) {
$fields[$column->name] = array(
'type' => $this->column($column->type),
'null' => !$column->not_null,
'length' => $column->max_length,
);
if ($column->has_default) {
$fields[$column->name]['default'] = $column->default_value;
}
if ($column->primary_key == 1) {
$fields[$column->name]['key'] = 'primary';
}
}
$this->__cacheDescription($this->fullTableName($model, false), $fields);
return $fields;
}
/**
* Returns a formatted error message from previous database operation.
*
* @return string Error message
*/
function lastError() {
return $this->_adodb->ErrorMsg();
}
/**
* Returns number of affected rows in previous database operation, or false if no previous operation exists.
*
* @return integer Number of affected rows
*/
function lastAffected() {
return $this->_adodb->Affected_Rows();
}
/**
* Returns number of rows in previous resultset, or false if no previous resultset exists.
*
* @return integer Number of rows in resultset
*/
function lastNumRows() {
return $this->_result ? $this->_result->RecordCount() : false;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @return int
*
* @Returns the last autonumbering ID inserted. Returns false if function not supported.
*/
function lastInsertId() {
return $this->_adodb->Insert_ID();
}
/**
* Returns a LIMIT statement in the correct format for the particular database.
*
* @param integer $limit Limit of results returned
* @param integer $offset Offset from which to start results
* @return string SQL limit/offset statement
* @todo Please change output string to whatever select your database accepts. adodb doesn't allow us to get the correct limit string out of it.
*/
function limit($limit, $offset = null) {
if ($limit) {
$rt = '';
if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
$rt = ' LIMIT';
}
if ($offset) {
$rt .= ' ' . $offset . ',';
}
$rt .= ' ' . $limit;
return $rt;
}
return null;
// please change to whatever select your database accepts
// adodb doesn't allow us to get the correct limit string out of it
}
/**
* Converts database-layer column types to basic types
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return string Abstract column type (i.e. "string")
*/
function column($real) {
$metaTypes = array_flip($this->_adodbColumnTypes);
$interpreted_type = $this->_adodbMetatyper->MetaType($real);
if (!isset($metaTypes[$interpreted_type])) {
return 'text';
}
return $metaTypes[$interpreted_type];
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column_type The type of the column into which this data will be inserted
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
* @return string Quoted and escaped data
*/
function value($data, $column = null, $safe = false) {
$parent = parent::value($data, $column, $safe);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if ($data === '') {
return "''";
}
return $this->_adodb->qstr($data);
}
/**
* Generates the fields list of an SQL query.
*
* @param Model $model
* @param string $alias Alias tablename
* @param mixed $fields
* @return array
*/
function fields(&$model, $alias = null, $fields = array(), $quote = true) {
if (empty($alias)) {
$alias = $model->alias;
}
$fields = parent::fields($model, $alias, $fields, false);
if (!$quote) {
return $fields;
}
$count = count($fields);
if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
for ($i = 0; $i < $count; $i++) {
if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
$prepend = '';
if (strpos($fields[$i], 'DISTINCT') !== false) {
$prepend = 'DISTINCT ';
$fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
}
if (strrpos($fields[$i], '.') === false) {
$fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
} else {
$build = explode('.', $fields[$i]);
$fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
}
}
}
}
return $fields;
}
/**
* Build ResultSets and map data
*
* @param array $results
*/
function resultSet(&$results) {
$num_fields = count($results);
$fields = array_keys($results);
$this->results =& $results;
$this->map = array();
$index = 0;
$j = 0;
while ($j < $num_fields) {
$columnName = $fields[$j];
if (strpos($columnName, '__')) {
$parts = explode('__', $columnName);
$this->map[$index++] = array($parts[0], $parts[1]);
} else {
$this->map[$index++] = array(0, $columnName);
}
$j++;
}
}
/**
* Fetches the next row from the current result set
*
* @return unknown
*/
function fetchResult() {
if (!empty($this->results)) {
$row = $this->results;
$this->results = null;
} else {
$row = $this->_result->FetchRow();
}
if (empty($row)) {
return false;
}
$resultRow = array();
$fields = array_keys($row);
$count = count($fields);
$i = 0;
for ($i = 0; $i < $count; $i++) { //$row as $index => $field) {
list($table, $column) = $this->map[$i];
$resultRow[$table][$column] = $row[$fields[$i]];
}
return $resultRow;
}
/**
* Generate a database-native column schema string
*
* @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
* where options can be 'default', 'length', or 'key'.
* @return string
*/
function buildColumn($column) {
$name = $type = null;
extract(array_merge(array('null' => true), $column));
if (empty($name) || empty($type)) {
trigger_error('Column name or type not defined in schema', E_USER_WARNING);
return null;
}
//$metaTypes = array_flip($this->_adodbColumnTypes);
if (!isset($this->_adodbColumnTypes[$type])) {
trigger_error("Column type {$type} does not exist", E_USER_WARNING);
return null;
}
$metaType = $this->_adodbColumnTypes[$type];
$concreteType = $this->_adodbDataDict->ActualType($metaType);
$real = $this->columns[$type];
//UUIDs are broken so fix them.
if ($type == 'string' && isset($real['length']) && $real['length'] == 36) {
$concreteType = 'CHAR';
}
$out = $this->name($name) . ' ' . $concreteType;
if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
if (isset($column['length'])) {
$length = $column['length'];
} elseif (isset($column['limit'])) {
$length = $column['limit'];
} elseif (isset($real['length'])) {
$length = $real['length'];
} else {
$length = $real['limit'];
}
$out .= '(' . $length . ')';
}
$_notNull = $_default = $_autoInc = $_constraint = $_unsigned = false;
if (isset($column['key']) && $column['key'] == 'primary' && $type == 'integer') {
$_constraint = '';
$_autoInc = true;
} elseif (isset($column['key']) && $column['key'] == 'primary') {
$_notNull = '';
} elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
$_notNull = true;
$_default = $column['default'];
} elseif ( isset($column['null']) && $column['null'] == true) {
$_notNull = false;
$_default = 'NULL';
}
if (isset($column['default']) && $_default == false) {
$_default = $this->value($column['default']);
}
if (isset($column['null']) && $column['null'] == false) {
$_notNull = true;
}
//use concrete instance of DataDict to make the suffixes for us.
$out .= $this->_adodbDataDict->_CreateSuffix($out, $metaType, $_notNull, $_default, $_autoInc, $_constraint, $_unsigned);
return $out;
}
/**
* Checks if the result is valid
*
* @return boolean True if the result is valid, else false
*/
function hasResult() {
return is_object($this->_result) && !$this->_result->EOF;
}
}
?>

View file

@ -1,594 +0,0 @@
<?php
/**
* IBM DB2 for DBO
*
* This file supports IBM DB2 and Cloudscape (aka Apache Derby,
* Sun Java DB) using the native ibm_db2 extension:
* http://pecl.php.net/package/ibm_db2
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2007, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
* @since CakePHP(tm) v 0.10.5.1790
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* IBM DB2 for DBO
*
* This file supports IBM DB2 and Cloudscape (aka Apache Derby,
* Sun Java DB) using the native ibm_db2 extension:
* http://pecl.php.net/package/ibm_db2
*
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
*/
class DboDb2 extends DboSource {
/**
* A short description of the type of driver.
*
* @var string
*/
var $description = 'IBM DB2 DBO Driver';
/**
* The start quote in which database column and table names should be wrapped.
*
* @var string
*/
var $startQuote = '';
/**
* The end quote in which database column and table names should be wrapped.
*
* @var string
*/
var $endQuote = '';
/**
* An array of base configuration settings to be used if settings are not
* provided, i.e. default host, port, and connection method.
*
* @var array
*/
var $_baseConfig = array(
'persistent' => true,
'login' => 'db2inst1',
'password' => '',
'database' => 'cake',
'schema' => '',
'hostname' => '127.0.0.1',
'port' => '50001',
'encoding' => 'UTF-8',
'cataloged' => true,
'autocommit' => true
);
/**
* An array that maps Cake column types to database native column types.
* The mapped information can include a reference to a function that should
* be used to format the data, as well as a string that defines the
* formatting according to that function.
*
* @var array
*/
var $columns = array(
'primary_key' => array('name' => 'not null generated by default as identity (start with 1, increment by 1)'),
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'clob'),
'integer' => array('name' => 'integer', 'limit' => '10', 'formatter' => 'intval'),
'float' => array('name' => 'double', 'formatter' => 'floatval'),
'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d-H.i.s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d-H.i.s', 'formatter' => 'date'),
'time' => array('name' => 'time', 'format' => 'H.i.s', 'formatter' => 'date'),
'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
'binary' => array('name' => 'blob'),
'boolean' => array('name' => 'smallint', 'limit' => '1')
);
/**
* A map for every result mapping tables to columns
*
* @var array result -> ( table -> column )
*/
var $_resultMap = array();
/**
* Connects to the database using options in the given configuration array.
*
* @return boolean True if the database could be connected, else false
*/
function connect() {
$config = $this->config;
$connect = 'db2_connect';
if ($config['persistent']) {
$connect = 'db2_pconnect';
}
$this->connected = false;
if ($config['cataloged']) {
$this->connection = $connect($config['database'], $config['login'], $config['password']);
} else {
$connString = sprintf(
"DRIVER={IBM DB2 ODBC DRIVER};DATABASE=%s;HOSTNAME=%s;PORT=%d;PROTOCOL=TCPIP;UID=%s;PWD=%s;",
$config['database'],
$config['hostname'],
$config['port'],
$config['login'],
$config['password']
);
$this->connection = db2_connect($connString, '', '');
}
if ($this->connection) {
$this->connected = true;
}
if ($config['schema'] !== '') {
$this->_execute('SET CURRENT SCHEMA = ' . $config['schema']);
}
return $this->connected;
}
/**
* Check that the DB2 extension is installed/loaded
*
* @return boolean
*/
function enabled() {
return extension_loaded('ibm_db2');
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
@db2_free_result($this->results);
$this->connected = !@db2_close($this->connection);
return !$this->connected;
}
/**
* Executes given SQL statement. We should use prepare / execute to allow the
* database server to reuse its access plan and increase the efficiency
* of your database access
*
* @param string $sql SQL statement
* @return resource Result resource identifier
* @access protected
*/
function _execute($sql) {
// get result from db
$result = db2_exec($this->connection, $sql);
if (!is_bool($result)) {
// build table/column map for this result
$map = array();
$numFields = db2_num_fields($result);
$index = 0;
$j = 0;
$offset = 0;
while ($j < $numFields) {
$columnName = strtolower(db2_field_name($result, $j));
$tmp = strpos($sql, '.' . $columnName, $offset);
$tableName = substr($sql, $offset, ($tmp-$offset));
$tableName = substr($tableName, strrpos($tableName, ' ') + 1);
$map[$index++] = array($tableName, $columnName);
$j++;
$offset = strpos($sql, ' ', $tmp);
}
$this->_resultMap[$result] = $map;
}
return $result;
}
/**
* Returns an array of all the tables in the database.
* Should call parent::listSources twice in the method:
* once to see if the list is cached, and once to cache
* the list if not.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$cache = parent::listSources();
if ($cache != null) {
return $cache;
}
$result = db2_tables($this->connection);
$tables = array();
while (db2_fetch_row($result)) {
$tables[] = strtolower(db2_result($result, 'TABLE_NAME'));
}
parent::listSources($tables);
return $tables;
}
/**
* Returns an array of the fields in given table name.
*
* @param Model $model Model object to describe
* @return array Fields in table. Keys are name and type
*/
function &describe(&$model) {
$cache = parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = array();
$result = db2_columns($this->connection, '', '', strtoupper($this->fullTableName($model)));
while (db2_fetch_row($result)) {
$fields[strtolower(db2_result($result, 'COLUMN_NAME'))] = array(
'type' => $this->column(strtolower(db2_result($result, 'TYPE_NAME'))),
'null' => db2_result($result, 'NULLABLE'),
'default' => db2_result($result, 'COLUMN_DEF'),
'length' => db2_result($result, 'COLUMN_SIZE')
);
}
$this->__cacheDescription($model->tablePrefix . $model->table, $fields);
return $fields;
}
/**
* Returns a quoted name of $data for use in an SQL statement.
*
* @param string $data Name (table.field) to be prepared for use in an SQL statement
* @return string Quoted for MySQL
*/
function name($data) {
return $data;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @return string Quoted and escaped
* @todo Add logic that formats/escapes data based on column type
*/
function value($data, $column = null, $safe = false) {
$parent = parent::value($data, $column, $safe);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if ($data === '') {
return "''";
}
switch ($column) {
case 'boolean':
$data = $this->boolean((bool)$data);
break;
case 'integer':
$data = intval($data);
break;
default:
$data = str_replace("'", "''", $data);
break;
}
if ($column == 'integer' || $column == 'float') {
return $data;
}
return "'" . $data . "'";
}
/**
* Not sure about this one, MySQL needs it but does ODBC? Safer just to leave it
* Translates between PHP boolean values and MySQL (faked) boolean values
*
* @param mixed $data Value to be translated
* @return mixed Converted boolean value
*/
function boolean($data) {
if ($data === true || $data === false) {
if ($data === true) {
return 1;
}
return 0;
} else {
if (intval($data !== 0)) {
return true;
}
return false;
}
}
/**
* Begins a transaction. Returns true if the transaction was
* started successfully, otherwise false.
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions).
*/
function begin(&$model) {
if (parent::begin($model)) {
if (db2_autocommit($this->connection, DB2_AUTOCOMMIT_OFF)) {
$this->_transactionStarted = true;
return true;
}
}
return false;
}
/**
* Commit a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function commit(&$model) {
if (parent::commit($model)) {
if (db2_commit($this->connection)) {
$this->_transactionStarted = false;
db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
return true;
}
}
return false;
}
/**
* Rollback a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function rollback(&$model) {
if (parent::rollback($model)) {
$this->_transactionStarted = false;
db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
return db2_rollback($this->connection);
}
return false;
}
/**
* Removes Identity (primary key) column from update data before returning to parent
*
* @param Model $model
* @param array $fields
* @param array $values
* @return array
*/
function update(&$model, $fields = array(), $values = array()) {
foreach ($fields as $i => $field) {
if ($field == $model->primaryKey) {
unset ($fields[$i]);
unset ($values[$i]);
break;
}
}
return parent::update($model, $fields, $values);
}
/**
* Returns a formatted error message from previous database operation.
* DB2 distinguishes between statement and connnection errors so we
* must check for both.
*
* @return string Error message with error number
*/
function lastError() {
if (db2_stmt_error()) {
return db2_stmt_error() . ': ' . db2_stmt_errormsg();
} elseif (db2_conn_error()) {
return db2_conn_error() . ': ' . db2_conn_errormsg();
}
return null;
}
/**
* Returns number of affected rows in previous database operation. If no previous operation exists,
* this returns false.
*
* @return integer Number of affected rows
*/
function lastAffected() {
if ($this->_result) {
return db2_num_rows($this->_result);
}
return null;
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return integer Number of rows in resultset
*/
function lastNumRows() {
if ($this->_result) {
return db2_num_rows($this->_result);
}
return null;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param unknown_type $source
* @return in
*/
function lastInsertId($source = null) {
$data = $this->fetchRow(sprintf('SELECT SYSIBM.IDENTITY_VAL_LOCAL() AS ID FROM %s FETCH FIRST ROW ONLY', $source));
if ($data && isset($data[0]['id'])) {
return $data[0]['id'];
}
return null;
}
/**
* Returns a limit statement in the correct format for the particular database.
*
* @param integer $limit Limit of results returned
* @param integer $offset Offset from which to start results
* @return string SQL limit/offset statement
*/
function limit($limit, $offset = null) {
if ($limit) {
$rt = '';
// If limit is not in the passed value already, add a limit clause.
if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
$rt = sprintf('FETCH FIRST %d ROWS ONLY', $limit);
}
// TODO: Implement paging with the offset. This could get hairy.
/*
WITH WHOLE AS
(SELECT FIRSTNME, MIDINIT, LASTNAME, SALARY,
ROW_NUMBER() OVER (ORDER BY SALARY DESC) AS RN
FROM EMPLOYEE)
SELECT FIRSTNME, MIDINIT, LASTNAME, SALARY, RN
FROM WHOLE
WHERE RN BETWEEN 10 AND 15
*/
/*
if ($offset) {
$rt .= ' ' . $offset . ',';
}
$rt .= ' ' . $limit;
*/
return $rt;
}
return null;
}
/**
* Converts database-layer column types to basic types
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return string Abstract column type (i.e. "string")
*/
function column($real) {
if (is_array($real)) {
$col = $real['name'];
if (isset($real['limit'])) {
$col .= '(' . $real['limit'] . ')';
}
return $col;
}
$col = str_replace(')', '', $real);
$limit = null;
if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
return $col;
}
if ($col == 'smallint') {
return 'boolean';
}
if (strpos($col, 'char') !== false) {
return 'string';
}
if (strpos($col, 'clob') !== false) {
return 'text';
}
if (strpos($col, 'blob') !== false || $col == 'image') {
return 'binary';
}
if (in_array($col, array('double', 'real', 'decimal'))) {
return 'float';
}
return 'text';
}
/**
* Maps a result set to an array so that returned fields are
* grouped by model. Any calculated fields, or fields that
* do not correspond to a particular model belong under array
* key 0.
*
* 1. Gets the column headers
* {{{
* Post.id
* Post.title
*
* [0] => Array
* (
* [0] => Post
* [1] => id
* )
*
* [1] => Array
* (
* [0] => Post
* [1] => title
* )
* }}}
* @param unknown_type $results
*/
function resultSet(&$results, $sql = null) {
$this->results =& $results;
$this->map = $this->_resultMap[$this->results];
}
/**
* Fetches the next row from the current result set
* Maps the records in the $result property to the map
* created in resultSet().
*
* 2. Gets the actual values.
*
* @return unknown
*/
function fetchResult() {
if ($row = db2_fetch_array($this->results)) {
$resultRow = array();
$i = 0;
foreach ($row as $index => $field) {
$table = $this->map[$index][0];
$column = strtolower($this->map[$index][1]);
$resultRow[$table][$column] = $row[$index];
$i++;
}
return $resultRow;
}
return false;
}
}
?>

View file

@ -1,544 +0,0 @@
<?php
/**
* Firebird/Interbase layer for DBO
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.dbo
* @since CakePHP(tm) v 1.2.0.5152
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Short description for class.
*
* Long description for class
*
* @package cake
* @subpackage cake.cake.libs.model.dbo
*/
class DboFirebird extends DboSource {
/**
* Enter description here...
*
* @var unknown_type
*/
var $description = "Firebird/Interbase DBO Driver";
/**
* Saves the original table name
*
* @var unknown_type
*/
var $modeltmp = array();
/**
* Enter description here...
*
* @var unknown_type
*/
var $startQuote = "\'";
/**
* Enter description here...
*
* @var unknown_type
*/
var $endQuote = "\'";
/**
* Enter description here...
*
* @var unknown_type
*/
var $alias = ' ';
/**
* Enter description here...
*
* @var unknown_type
*/
var $goofyLimit = true;
/**
* Creates a map between field aliases and numeric indexes.
*
* @var array
*/
var $__fieldMappings = array();
/**
* Base configuration settings for Firebird driver
*
* @var array
*/
var $_baseConfig = array(
'persistent' => true,
'host' => 'localhost',
'login' => 'SYSDBA',
'password' => 'masterkey',
'database' => 'c:\\CAKE.FDB',
'port' => '3050',
'connect' => 'ibase_connect'
);
/**
* Firebird column definition
*
* @var array
*/
var $columns = array(
'primary_key' => array('name' => 'IDENTITY (1, 1) NOT NULL'),
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'BLOB SUB_TYPE 1 SEGMENT SIZE 100 CHARACTER SET NONE'),
'integer' => array('name' => 'integer'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'timestamp', 'format' => 'd.m.Y H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'd.m.Y H:i:s', 'formatter' => 'date'),
'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
'date' => array('name' => 'date', 'format' => 'd.m.Y', 'formatter' => 'date'),
'binary' => array('name' => 'blob'),
'boolean' => array('name' => 'smallint')
);
/**
* Firebird Transaction commands.
*
* @var array
*/
var $_commands = array(
'begin' => 'SET TRANSACTION',
'commit' => 'COMMIT',
'rollback' => 'ROLLBACK'
);
/**
* Connects to the database using options in the given configuration array.
*
* @return boolean True if the database could be connected, else false
*/
function connect() {
$config = $this->config;
$connect = $config['connect'];
$this->connected = false;
$this->connection = $connect($config['host'] . ':' . $config['database'], $config['login'], $config['password']);
$this->connected = true;
}
/**
* Check that the interbase extension is loaded
*
* @return boolean
*/
function enabled() {
return extension_loaded('interbase');
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
$this->connected = false;
return @ibase_close($this->connection);
}
/**
* Executes given SQL statement.
*
* @param string $sql SQL statement
* @return resource Result resource identifier
* @access protected
*/
function _execute($sql) {
return @ibase_query($this->connection, $sql);
}
/**
* Returns a row from given resultset as an array .
*
* @return array The fetched row as an array
*/
function fetchRow() {
if ($this->hasResult()) {
$this->resultSet($this->_result);
$resultRow = $this->fetchResult();
return $resultRow;
} else {
return null;
}
}
/**
* Returns an array of sources (tables) in the database.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$cache = parent::listSources();
if ($cache != null) {
return $cache;
}
$sql = "select RDB" . "$" . "RELATION_NAME as name
FROM RDB" ."$" . "RELATIONS
Where RDB" . "$" . "SYSTEM_FLAG =0";
$result = @ibase_query($this->connection,$sql);
$tables = array();
while ($row = ibase_fetch_row ($result)) {
$tables[] = strtolower(trim($row[0]));
}
parent::listSources($tables);
return $tables;
}
/**
* Returns an array of the fields in given table name.
*
* @param Model $model Model object to describe
* @return array Fields in table. Keys are name and type
*/
function describe(&$model) {
$this->modeltmp[$model->table] = $model->alias;
$cache = parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = false;
$sql = "SELECT * FROM " . $this->fullTableName($model, false);
$rs = ibase_query($sql);
$coln = ibase_num_fields($rs);
$fields = false;
for ($i = 0; $i < $coln; $i++) {
$col_info = ibase_field_info($rs, $i);
$fields[strtolower($col_info['name'])] = array(
'type' => $this->column($col_info['type']),
'null' => '',
'length' => $col_info['length']
);
}
$this->__cacheDescription($this->fullTableName($model, false), $fields);
return $fields;
}
/**
* Returns a quoted name of $data for use in an SQL statement.
*
* @param string $data Name (table.field) to be prepared for use in an SQL statement
* @return string Quoted for Firebird
*/
function name($data) {
if ($data == '*') {
return '*';
}
$pos = strpos($data, '"');
if ($pos === false) {
if (!strpos($data, ".")) {
$data = '"' . strtoupper($data) . '"';
} else {
$build = explode('.', $data);
$data = '"' . strtoupper($build[0]) . '"."' . strtoupper($build[1]) . '"';
}
}
return $data;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
* @return string Quoted and escaped data
*/
function value($data, $column = null, $safe = false) {
$parent = parent::value($data, $column, $safe);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if ($data === '') {
return "''";
}
switch($column) {
case 'boolean':
$data = $this->boolean((bool)$data);
break;
default:
if (get_magic_quotes_gpc()) {
$data = stripslashes(str_replace("'", "''", $data));
} else {
$data = str_replace("'", "''", $data);
}
break;
}
return "'" . $data . "'";
}
/**
* Removes Identity (primary key) column from update data before returning to parent
*
* @param Model $model
* @param array $fields
* @param array $values
* @return array
*/
function update(&$model, $fields = array(), $values = array()) {
foreach ($fields as $i => $field) {
if ($field == $model->primaryKey) {
unset ($fields[$i]);
unset ($values[$i]);
break;
}
}
return parent::update($model, $fields, $values);
}
/**
* Returns a formatted error message from previous database operation.
*
* @return string Error message with error number
*/
function lastError() {
$error = ibase_errmsg();
if ($error !== false) {
return $error;
}
return null;
}
/**
* Returns number of affected rows in previous database operation. If no previous operation exists,
* this returns false.
*
* @return integer Number of affected rows
*/
function lastAffected() {
if ($this->_result) {
return ibase_affected_rows($this->connection);
}
return null;
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return integer Number of rows in resultset
*/
function lastNumRows() {
return $this->_result? /*ibase_affected_rows($this->_result)*/ 1: false;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param unknown_type $source
* @return in
*/
function lastInsertId($source = null, $field = 'id') {
$query = "SELECT RDB\$TRIGGER_SOURCE
FROM RDB\$TRIGGERS WHERE RDB\$RELATION_NAME = '". strtoupper($source) . "' AND
RDB\$SYSTEM_FLAG IS NULL AND RDB\$TRIGGER_TYPE = 1 ";
$result = @ibase_query($this->connection,$query);
$generator = "";
while ($row = ibase_fetch_row($result, IBASE_TEXT)) {
if (strpos($row[0], "NEW." . strtoupper($field))) {
$pos = strpos($row[0], "GEN_ID(");
if ($pos > 0) {
$pos2 = strpos($row[0],",",$pos + 7);
if ($pos2 > 0) {
$generator = substr($row[0], $pos +7, $pos2 - $pos- 7);
}
}
break;
}
}
if (!empty($generator)) {
$sql = "SELECT GEN_ID(". $generator . ",0) AS maxi FROM RDB" . "$" . "DATABASE";
$res = $this->rawQuery($sql);
$data = $this->fetchRow($res);
return $data['maxi'];
} else {
return false;
}
}
/**
* Returns a limit statement in the correct format for the particular database.
*
* @param integer $limit Limit of results returned
* @param integer $offset Offset from which to start results
* @return string SQL limit/offset statement
*/
function limit($limit, $offset = null) {
if ($limit) {
$rt = '';
if (!strpos(strtolower($limit), 'top') || strpos(strtolower($limit), 'top') === 0) {
$rt = ' FIRST';
}
$rt .= ' ' . $limit;
if (is_int($offset) && $offset > 0) {
$rt .= ' SKIP ' . $offset;
}
return $rt;
}
return null;
}
/**
* Converts database-layer column types to basic types
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return string Abstract column type (i.e. "string")
*/
function column($real) {
if (is_array($real)) {
$col = $real['name'];
if (isset($real['limit'])) {
$col .= '(' . $real['limit'] . ')';
}
return $col;
}
$col = str_replace(')', '', $real);
$limit = null;
if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if (in_array($col, array('DATE', 'TIME'))) {
return strtolower($col);
}
if ($col == 'TIMESTAMP') {
return 'datetime';
}
if ($col == 'SMALLINT') {
return 'boolean';
}
if (strpos($col, 'int') !== false || $col == 'numeric' || $col == 'INTEGER') {
return 'integer';
}
if (strpos($col, 'char') !== false) {
return 'string';
}
if (strpos($col, 'text') !== false) {
return 'text';
}
if (strpos($col, 'VARCHAR') !== false) {
return 'string';
}
if (strpos($col, 'BLOB') !== false) {
return 'text';
}
if (in_array($col, array('FLOAT', 'NUMERIC', 'DECIMAL'))) {
return 'float';
}
return 'text';
}
/**
* Enter description here...
*
* @param unknown_type $results
*/
function resultSet(&$results) {
$this->results =& $results;
$this->map = array();
$num_fields = ibase_num_fields($results);
$index = 0;
$j = 0;
while ($j < $num_fields) {
$column = ibase_field_info($results, $j);
if (!empty($column[2])) {
$this->map[$index++] = array(ucfirst(strtolower($this->modeltmp[strtolower($column[2])])), strtolower($column[1]));
} else {
$this->map[$index++] = array(0, strtolower($column[1]));
}
$j++;
}
}
/**
* Builds final SQL statement
*
* @param string $type Query type
* @param array $data Query data
* @return string
*/
function renderStatement($type, $data) {
extract($data);
if (strtolower($type) == 'select') {
if (preg_match('/offset\s+([0-9]+)/i', $limit, $offset)) {
$limit = preg_replace('/\s*offset.*$/i', '', $limit);
preg_match('/top\s+([0-9]+)/i', $limit, $limitVal);
$offset = intval($offset[1]) + intval($limitVal[1]);
$rOrder = $this->__switchSort($order);
list($order2, $rOrder) = array($this->__mapFields($order), $this->__mapFields($rOrder));
return "SELECT * FROM (SELECT {$limit} * FROM (SELECT TOP {$offset} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}) AS Set1 {$rOrder}) AS Set2 {$order2}";
} else {
return "SELECT {$limit} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}";
}
} else {
return parent::renderStatement($type, $data);
}
}
/**
* Fetches the next row from the current result set
*
* @return unknown
*/
function fetchResult() {
if ($row = ibase_fetch_row($this->results, IBASE_TEXT)) {
$resultRow = array();
$i = 0;
foreach ($row as $index => $field) {
list($table, $column) = $this->map[$index];
if (trim($table) == "") {
$resultRow[0][$column] = $row[$index];
} else {
$resultRow[$table][$column] = $row[$index];
$i++;
}
}
return $resultRow;
} else {
return false;
}
}
}
?>

View file

@ -1,379 +0,0 @@
<?php
/**
* ODBC for DBO
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.dbo
* @since CakePHP(tm) v 0.10.5.1790
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Short description for class.
*
* Long description for class
*
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
*/
class DboOdbc extends DboSource {
/**
* Driver description
*
* @var string
*/
var $description = "ODBC DBO Driver";
/**
* Table/column starting quote
*
* @var string
*/
var $startQuote = "`";
/**
* Table/column end quote
*
* @var string
*/
var $endQuote = "`";
/**
* Driver base configuration
*
* @var array
*/
var $_baseConfig = array(
'persistent' => true,
'login' => 'root',
'password' => '',
'database' => 'cake',
'connect' => 'odbc_pconnect'
);
/**
* Enter description here...
*
* @var unknown_type
*/
var $columns = array();
// var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
// 'string' => array('name' => 'varchar', 'limit' => '255'),
// 'text' => array('name' => 'text'),
// 'integer' => array('name' => 'int', 'limit' => '11'),
// 'float' => array('name' => 'float'),
// 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
// 'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
// 'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
// 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
// 'binary' => array('name' => 'blob'),
// 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
/**
* Connects to the database using options in the given configuration array.
*
* @return boolean True if the database could be connected, else false
*/
function connect() {
$config = $this->config;
$connect = $config['connect'];
if (!$config['persistent']) {
$connect = 'odbc_connect';
}
if (!function_exists($connect)) {
exit('no odbc?');
}
$this->connected = false;
$this->connection = $connect($config['database'], $config['login'], $config['password'], SQL_CUR_USE_ODBC);
if ($this->connection) {
$this->connected = true;
}
return $this->connected;
}
/**
* Check if the ODBC extension is installed/loaded
*
* @return boolean
*/
function enabled() {
return extension_loaded('odbc');
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
return @odbc_close($this->connection);
}
/**
* Executes given SQL statement.
*
* @param string $sql SQL statement
* @return resource Result resource identifier
* @access protected
*/
function _execute($sql) {
switch ($sql) {
case 'BEGIN':
return odbc_autocommit($this->connection, false);
case 'COMMIT':
return odbc_commit($this->connection);
case 'ROLLBACK':
return odbc_rollback($this->connection);
}
// TODO: should flags be set? possible requirement: SQL_CURSOR_STATIC
return odbc_exec($this->connection, $sql);
}
/**
* Returns an array of sources (tables) in the database.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$cache = parent::listSources();
if ($cache != null) {
return $cache;
}
$result = odbc_tables($this->connection);
$tables = array();
while (odbc_fetch_row($result)) {
array_push($tables, odbc_result($result, 'TABLE_NAME'));
}
parent::listSources($tables);
return $tables;
}
/**
* Returns an array of the fields in given table name.
*
* @param Model $model Model object to describe
* @return array Fields in table. Keys are name and type
*/
function &describe(&$model) {
$cache=parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = array();
$sql = 'SELECT * FROM ' . $this->fullTableName($model);
$result = odbc_exec($this->connection, $sql);
$count = odbc_num_fields($result);
for ($i = 1; $i <= $count; $i++) {
$cols[$i - 1] = odbc_field_name($result, $i);
}
foreach ($cols as $column) {
$type = odbc_field_type(odbc_exec($this->connection, 'SELECT ' . $column . ' FROM ' . $this->fullTableName($model)), 1);
$fields[$column] = array('type' => $type);
}
$this->__cacheDescription($model->tablePrefix . $model->table, $fields);
return $fields;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @return string Quoted and escaped
* @todo Add logic that formats/escapes data based on column type
*/
function value($data, $column = null) {
$parent=parent::value($data, $column);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if (!is_numeric($data)) {
return "'" . $data . "'";
}
return $data;
}
/**
* Returns a formatted error message from previous database operation.
*
* @return string Error message with error number
*/
function lastError() {
if ($error = odbc_errormsg($this->connection)) {
return odbc_error($this->connection) . ': ' . $error;
}
return null;
}
/**
* Returns number of affected rows in previous database operation. If no previous operation exists,
* this returns false.
*
* @return integer Number of affected rows
*/
function lastAffected() {
if ($this->hasResult()) {
return odbc_num_rows($this->_result);
}
return null;
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return int Number of rows in resultset
*/
function lastNumRows() {
if ($this->hasResult()) {
return odbc_num_rows($this->_result);
}
return null;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param unknown_type $source
* @return int
*/
function lastInsertId($source = null) {
$result = $this->fetchRow('SELECT @@IDENTITY');
return $result[0];
}
/**
* Enter description here...
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
*/
function column($real) {
if (is_array($real)) {
$col=$real['name'];
if (isset($real['limit'])) {
$col .= '(' . $real['limit'] . ')';
}
return $col;
}
return $real;
}
/**
* Enter description here...
*
* @param unknown_type $results
*/
function resultSet(&$results) {
$this->results =& $results;
$num_fields = odbc_num_fields($results);
$this->map = array();
$index = 0;
$j = 0;
while ($j < $num_fields) {
$column = odbc_field_name($results, $j+1);
if (strpos($column, '_dot_') !== false) {
list($table, $column) = explode('_dot_', $column);
$this->map[$index++] = array($table, $column);
} else {
$this->map[$index++] = array(0, $column);
}
$j++;
}
}
/**
* Generates the fields list of an SQL query.
*
* @param Model $model
* @param string $alias Alias tablename
* @param mixed $fields
* @return array
*/
function fields(&$model, $alias = null, $fields = null, $quote = true) {
if (empty($alias)) {
$alias = $model->name;
}
if (!is_array($fields)) {
if ($fields != null) {
$fields = array_map('trim', explode(',', $fields));
} else {
foreach($model->tableToModel as $tableName => $modelName) {
foreach($this->__descriptions[$model->tablePrefix .$tableName] as $field => $type) {
$fields[] = $modelName .'.' .$field;
}
}
}
}
$count = count($fields);
if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
for ($i = 0; $i < $count; $i++) {
if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
$prepend = '';
if (strpos($fields[$i], 'DISTINCT') !== false) {
$prepend = 'DISTINCT ';
$fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
}
if (strrpos($fields[$i], '.') === false) {
$fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '_dot_' . $fields[$i]);
} else {
$build = explode('.', $fields[$i]);
$fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '_dot_' . $build[1]);
}
}
}
}
return $fields;
}
/**
* Fetches the next row from the current result set
*
* @return unknown
*/
function fetchResult() {
if ($row = odbc_fetch_row($this->results)) {
$resultRow = array();
$numFields = odbc_num_fields($this->results);
$i = 0;
for($i = 0; $i < $numFields; $i++) {
list($table, $column) = $this->map[$i];
$resultRow[$table][$column] = odbc_result($this->results, $i + 1);
}
return $resultRow;
}
return false;
}
}
?>

View file

@ -1,408 +0,0 @@
<?php
/**
* Sybase layer for DBO
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
* @since CakePHP(tm) v 1.2.0.3097
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Short description for class.
*
* Long description for class
*
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
*/
class DboSybase extends DboSource {
/**
* Driver description
*
* @var string
*/
var $description = "Sybase DBO Driver";
/**
* Start quote for quoted identifiers
*
* @var string
*/
var $startQuote = "";
/**
* End quote for quoted identifiers
*
* @var string
*/
var $endQuote = "";
/**
* Base configuration settings for Sybase driver
*
* @var array
*/
var $_baseConfig = array(
'persistent' => true,
'host' => 'localhost',
'login' => 'sa',
'password' => '',
'database' => 'cake',
'port' => '4100'
);
/**
* Sybase column definition
*
* @var array
*/
var $columns = array(
'primary_key' => array('name' => 'numeric(9,0) IDENTITY PRIMARY KEY'),
'string' => array('name' => 'varchar', 'limit' => '255'),
'text' => array('name' => 'text'),
'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
'time' => array('name' => 'datetime', 'format' => 'H:i:s', 'formatter' => 'date'),
'date' => array('name' => 'datetime', 'format' => 'Y-m-d', 'formatter' => 'date'),
'binary' => array('name' => 'image'),
'boolean' => array('name' => 'bit')
);
/**
* Connects to the database using options in the given configuration array.
*
* @return boolean True if the database could be connected, else false
*/
function connect() {
$config = $this->config;
$port = '';
if ($config['port'] !== null) {
$port = ':' . $config['port'];
}
if ($config['persistent']) {
$this->connection = sybase_pconnect($config['host'] . $port, $config['login'], $config['password']);
} else {
$this->connection = sybase_connect($config['host'] . $port, $config['login'], $config['password'], true);
}
$this->connected = sybase_select_db($config['database'], $this->connection);
return $this->connected;
}
/**
* Check that one of the sybase extensions is installed
*
* @return boolean
*/
function enabled() {
return extension_loaded('sybase') || extension_loaded('sybase_ct');
}
/**
* Disconnects from database.
*
* @return boolean True if the database could be disconnected, else false
*/
function disconnect() {
$this->connected = !@sybase_close($this->connection);
return !$this->connected;
}
/**
* Executes given SQL statement.
*
* @param string $sql SQL statement
* @return resource Result resource identifier
* @access protected
*/
function _execute($sql) {
return sybase_query($sql, $this->connection);
}
/**
* Returns an array of sources (tables) in the database.
*
* @return array Array of tablenames in the database
*/
function listSources() {
$cache = parent::listSources();
if ($cache != null) {
return $cache;
}
$result = $this->_execute("SELECT name FROM sysobjects WHERE type IN ('U', 'V')");
if (!$result) {
return array();
} else {
$tables = array();
while ($line = sybase_fetch_array($result)) {
$tables[] = $line[0];
}
parent::listSources($tables);
return $tables;
}
}
/**
* Returns an array of the fields in given table name.
*
* @param string $tableName Name of database table to inspect
* @return array Fields in table. Keys are name and type
*/
function describe(&$model) {
$cache = parent::describe($model);
if ($cache != null) {
return $cache;
}
$fields = false;
$cols = $this->query('DESC ' . $this->fullTableName($model));
foreach ($cols as $column) {
$colKey = array_keys($column);
if (isset($column[$colKey[0]]) && !isset($column[0])) {
$column[0] = $column[$colKey[0]];
}
if (isset($column[0])) {
$fields[$column[0]['Field']] = array(
'type' => $this->column($column[0]['Type']),
'null' => $column[0]['Null'],
'length' => $this->length($column[0]['Type']),
);
}
}
$this->__cacheDescription($model->tablePrefix.$model->table, $fields);
return $fields;
}
/**
* Returns a quoted and escaped string of $data for use in an SQL statement.
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
* @return string Quoted and escaped data
*/
function value($data, $column = null, $safe = false) {
$parent = parent::value($data, $column, $safe);
if ($parent != null) {
return $parent;
}
if ($data === null) {
return 'NULL';
}
if ($data === '') {
return "''";
}
switch ($column) {
case 'boolean':
$data = $this->boolean((bool)$data);
break;
default:
$data = str_replace("'", "''", $data);
break;
}
return "'" . $data . "'";
}
/**
* Begin a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions).
*/
function begin(&$model) {
if (parent::begin($model)) {
if ($this->execute('BEGIN TRAN')) {
$this->_transactionStarted = true;
return true;
}
}
return false;
}
/**
* Commit a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function commit(&$model) {
if (parent::commit($model)) {
$this->_transactionStarted = false;
return $this->execute('COMMIT TRAN');
}
return false;
}
/**
* Rollback a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions,
* or a transaction has not started).
*/
function rollback(&$model) {
if (parent::rollback($model)) {
return $this->execute('ROLLBACK TRAN');
}
return false;
}
/**
* Returns a formatted error message from previous database operation.
*
* @todo not implemented
* @return string Error message with error number
*/
function lastError() {
return null;
}
/**
* Returns number of affected rows in previous database operation. If no previous operation exists,
* this returns false.
*
* @return integer Number of affected rows
*/
function lastAffected() {
if ($this->_result) {
return sybase_affected_rows($this->connection);
}
return null;
}
/**
* Returns number of rows in previous resultset. If no previous resultset exists,
* this returns false.
*
* @return integer Number of rows in resultset
*/
function lastNumRows() {
if ($this->hasResult()) {
return @sybase_num_rows($this->_result);
}
return null;
}
/**
* Returns the ID generated from the previous INSERT operation.
*
* @param unknown_type $source
* @return in
*/
function lastInsertId($source = null) {
$result=$this->fetchRow('SELECT @@IDENTITY');
return $result[0];
}
/**
* Converts database-layer column types to basic types
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return string Abstract column type (i.e. "string")
*/
function column($real) {
if (is_array($real)) {
$col = $real['name'];
if (isset($real['limit']))
{
$col .= '('.$real['limit'].')';
}
return $col;
}
$col = str_replace(')', '', $real);
$limit = null;
if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if (in_array($col, array('datetime', 'smalldatetime'))) {
return 'datetime';
} elseif (in_array($col, array('int', 'bigint', 'smallint', 'tinyint'))) {
return 'integer';
} elseif (in_array($col, array('float', 'double', 'real', 'decimal', 'money', 'numeric', 'smallmoney'))) {
return 'float';
} elseif (strpos($col, 'text') !== false) {
return 'text';
} elseif (in_array($col, array('char', 'nchar', 'nvarchar', 'string', 'varchar'))) {
return 'binary';
} elseif (in_array($col, array('binary', 'image', 'varbinary'))) {
return 'binary';
}
return 'text';
}
/**
* Enter description here...
*
* @param unknown_type $results
*/
function resultSet(&$results) {
$this->results =& $results;
$this->map = array();
$num_fields = sybase_num_fields($results);
$index = 0;
$j = 0;
while ($j < $num_fields) {
$column = sybase_fetch_field($results,$j);
if (!empty($column->table)) {
$this->map[$index++] = array($column->table, $column->name);
} else {
$this->map[$index++] = array(0, $column->name);
}
$j++;
}
}
/**
* Fetches the next row from the current result set
*
* @return unknown
*/
function fetchResult() {
if ($row = sybase_fetch_row($this->results)) {
$resultRow = array();
$i = 0;
foreach ($row as $index => $field) {
list($table, $column) = $this->map[$index];
$resultRow[$table][$column] = $row[$index];
$i++;
}
return $resultRow;
} else {
return false;
}
}
}
?>

View file

@ -1,293 +0,0 @@
<?php
/**
* DboAdodbTest file
*
* AdoDB layer for DBO
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.model.datasources.dbo
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
require_once LIBS.'model'.DS.'model.php';
require_once LIBS.'model'.DS.'datasources'.DS.'datasource.php';
require_once LIBS.'model'.DS.'datasources'.DS.'dbo_source.php';
require_once LIBS.'model'.DS.'datasources'.DS.'dbo'.DS.'dbo_adodb.php';
/**
* DboAdoTestDb
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources
*/
class DboAdoTestDb extends DboAdodb {
/**
* simulated property
*
* @var array
* @access public
*/
var $simulated = array();
/**
* testing property
*
* @var bool true
* @access public
*/
var $testing = true;
/**
* execute method
*
* @param mixed $sql
* @access protected
* @return void
*/
function _execute($sql) {
if ($this->testing) {
$this->simulated[] = $sql;
return null;
}
return parent::_execute($sql);
}
/**
* getLastQuery method
*
* @access public
* @return void
*/
function getLastQuery() {
return $this->simulated[count($this->simulated) - 1];
}
}
/**
* AdodbTestModel
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources
*/
class AdodbTestModel extends CakeTestModel {
/**
* name property
*
* @var string 'AdodbTestModel'
* @access public
*/
var $name = 'AdodbTestModel';
/**
* useTable property
*
* @var bool false
* @access public
*/
var $useTable = false;
/**
* find method
*
* @param mixed $conditions
* @param mixed $fields
* @param mixed $order
* @param mixed $recursive
* @access public
* @return void
*/
function find($conditions = null, $fields = null, $order = null, $recursive = null) {
return $conditions;
}
/**
* findAll method
*
* @param mixed $conditions
* @param mixed $fields
* @param mixed $order
* @param mixed $recursive
* @access public
* @return void
*/
function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
return $conditions;
}
/**
* schema method
*
* @access public
* @return void
*/
function schema() {
return array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
'last_login'=> array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
);
}
}
if (!class_exists('Article')) {
/**
* Article class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources.dbo
*/
class Article extends CakeTestModel {
/**
* name property
*
* @var string 'Article'
* @access public
*/
var $name = 'Article';
}
}
/**
* DboAdodbTest class
*
* @package cake
* @subpackage cake.tests.cases.libs.model.datasources.dbo
*/
class DboAdodbTest extends CakeTestCase {
/**
* The Dbo instance to be tested
*
* @var DboSource
* @access public
*/
var $db = null;
/**
* fixtures property
*
* @var string
* @access public
*/
var $fixtures = array('core.article');
/**
* Skip if cannot connect to AdoDb
*
* @access public
*/
function skip() {
$this->_initDb();
$db =& ConnectionManager::getDataSource('test_suite');
$this->skipIf($db->config['driver'] != 'adodb', '%s Adodb connection not available');
}
/**
* Sets up a Dbo class instance for testing
*
* @access public
*/
function setUp() {
$db = ConnectionManager::getDataSource('test_suite');
$this->db = new DboAdoTestDb($db->config);
$this->model = new AdodbTestModel();
}
/**
* Sets up a Dbo class instance for testing
*
* @access public
*/
function tearDown() {
unset($this->db);
}
/**
* Test Dbo value method
*
* @access public
*/
function testQuoting() {
$result = $this->db->fields($this->model);
$expected = array(
'`AdodbTestModel`.`id` AS `AdodbTestModel__id`',
'`AdodbTestModel`.`client_id` AS `AdodbTestModel__client_id`',
'`AdodbTestModel`.`name` AS `AdodbTestModel__name`',
'`AdodbTestModel`.`login` AS `AdodbTestModel__login`',
'`AdodbTestModel`.`passwd` AS `AdodbTestModel__passwd`',
'`AdodbTestModel`.`addr_1` AS `AdodbTestModel__addr_1`',
'`AdodbTestModel`.`addr_2` AS `AdodbTestModel__addr_2`',
'`AdodbTestModel`.`zip_code` AS `AdodbTestModel__zip_code`',
'`AdodbTestModel`.`city` AS `AdodbTestModel__city`',
'`AdodbTestModel`.`country` AS `AdodbTestModel__country`',
'`AdodbTestModel`.`phone` AS `AdodbTestModel__phone`',
'`AdodbTestModel`.`fax` AS `AdodbTestModel__fax`',
'`AdodbTestModel`.`url` AS `AdodbTestModel__url`',
'`AdodbTestModel`.`email` AS `AdodbTestModel__email`',
'`AdodbTestModel`.`comments` AS `AdodbTestModel__comments`',
'`AdodbTestModel`.`last_login` AS `AdodbTestModel__last_login`',
'`AdodbTestModel`.`created` AS `AdodbTestModel__created`',
'`AdodbTestModel`.`updated` AS `AdodbTestModel__updated`'
);
$this->assertEqual($result, $expected);
$expected = "'1.2'";
$result = $this->db->value(1.2, 'float');
$this->assertEqual($expected, $result);
$expected = "'1,2'";
$result = $this->db->value('1,2', 'float');
$this->assertEqual($expected, $result);
$expected = "'4713e29446'";
$result = $this->db->value('4713e29446');
$this->assertEqual($expected, $result);
$expected = "'10010001'";
$result = $this->db->value('10010001');
$this->assertEqual($expected, $result);
$expected = "'00010010001'";
$result = $this->db->value('00010010001');
$this->assertEqual($expected, $result);
}
/**
* testColumns method
*
* @access public
* @return void
*/
function testColumns() {
}
}
?>