Removed MDB2 classes; install seperately
parent
aadfa1f1dc
commit
4aaddb32e1
File diff suppressed because it is too large
Load Diff
@ -1,180 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Several methods to convert the MDB2 native timestamp format (ISO based)
|
||||
* to and from data structures that are convienient to worth with in side of php.
|
||||
* For more complex date arithmetic please take a look at the Date package in PEAR
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Date
|
||||
{
|
||||
// {{{ mdbNow()
|
||||
|
||||
/**
|
||||
* return the current datetime
|
||||
*
|
||||
* @return string current datetime in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbNow()
|
||||
{
|
||||
return date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mdbToday()
|
||||
|
||||
/**
|
||||
* return the current date
|
||||
*
|
||||
* @return string current date in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbToday()
|
||||
{
|
||||
return date('Y-m-d');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mdbTime()
|
||||
|
||||
/**
|
||||
* return the current time
|
||||
*
|
||||
* @return string current time in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbTime()
|
||||
{
|
||||
return date('H:i:s');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ date2Mdbstamp()
|
||||
|
||||
/**
|
||||
* convert a date into a MDB2 timestamp
|
||||
*
|
||||
* @param integer $hour hour of the date
|
||||
* @param integer $minute minute of the date
|
||||
* @param integer $second second of the date
|
||||
* @param integer $month month of the date
|
||||
* @param integer $day day of the date
|
||||
* @param integer $year year of the date
|
||||
* @return string a valid MDB2 timestamp
|
||||
* @access public
|
||||
*/
|
||||
function date2Mdbstamp($hour = null, $minute = null, $second = null,
|
||||
$month = null, $day = null, $year = null)
|
||||
{
|
||||
return MDB2_Date::unix2Mdbstamp(mktime($hour, $minute, $second, $month, $day, $year, -1));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unix2Mdbstamp()
|
||||
|
||||
/**
|
||||
* convert a unix timestamp into a MDB2 timestamp
|
||||
*
|
||||
* @param integer $unix_timestamp a valid unix timestamp
|
||||
* @return string a valid MDB2 timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unix2Mdbstamp($unix_timestamp)
|
||||
{
|
||||
return date('Y-m-d H:i:s', $unix_timestamp);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mdbstamp2Unix()
|
||||
|
||||
/**
|
||||
* convert a MDB2 timestamp into a unix timestamp
|
||||
*
|
||||
* @param integer $mdb_timestamp a valid MDB2 timestamp
|
||||
* @return string unix timestamp with the time stored in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbstamp2Unix($mdb_timestamp)
|
||||
{
|
||||
$arr = MDB2_Date::mdbstamp2Date($mdb_timestamp);
|
||||
|
||||
return mktime($arr['hour'], $arr['minute'], $arr['second'], $arr['month'], $arr['day'], $arr['year'], -1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mdbstamp2Date()
|
||||
|
||||
/**
|
||||
* convert a MDB2 timestamp into an array containing all
|
||||
* values necessary to pass to php's date() function
|
||||
*
|
||||
* @param integer $mdb_timestamp a valid MDB2 timestamp
|
||||
* @return array with the time split
|
||||
* @access public
|
||||
*/
|
||||
function mdbstamp2Date($mdb_timestamp)
|
||||
{
|
||||
list($arr['year'], $arr['month'], $arr['day'], $arr['hour'], $arr['minute'], $arr['second']) =
|
||||
sscanf($mdb_timestamp, "%04u-%02u-%02u %02u:%02u:%02u");
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
@ -1,555 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 FrontbaseSQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_fbsql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ convertResult()
|
||||
|
||||
/**
|
||||
* convert a value to a RDBMS indepdenant MDB2 type
|
||||
*
|
||||
* @param mixed $value value to be converted
|
||||
* @param int $type constant that specifies which type to convert to
|
||||
* @return mixed converted value
|
||||
* @access public
|
||||
*/
|
||||
function convertResult($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
return $value == 'T';
|
||||
case 'time':
|
||||
if ($value[0] == '+') {
|
||||
return substr($value, 1);
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
default:
|
||||
return $this->_baseConvertResult($value, $type);
|
||||
}
|
||||
return $this->_baseConvertResult($value, $type);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('unsigned', $field) && $field['unsigned']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being
|
||||
declared as signed integer";
|
||||
}
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' INT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTextDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to NULL.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTextDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'text') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
$length = array_key_exists('length', $field) ? $field['length'] : 32768;
|
||||
return $name.' VARCHAR ('.$length.')'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the
|
||||
* properties of the field being declared as array
|
||||
* indexes. Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field
|
||||
* is constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
return "$name CLOB".((array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
return "$name BLOB".((array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBooleanDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a boolean type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Boolean value to be used as default for this field.
|
||||
*
|
||||
* notnullL
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to NULL.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBooleanDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'boolean') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' BOOLEAN)'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field properties
|
||||
* are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT DATE '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATE'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an timestamp
|
||||
* type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time stamp value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT TIMESTAMP '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' TIMESTAMP'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an time type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT TIME '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' TIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' FLOAT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$type = 'DECIMAL(18,'.$db->options['decimal_places'].')';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
$value = $this->_readFile($value);
|
||||
return "'".addslashes($value)."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBoolean()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBoolean($value)
|
||||
{
|
||||
return ($value ? 'True' : 'False');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDate()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDate($value)
|
||||
{
|
||||
return 'DATE'.$this->_quoteText($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTimestamp()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteTimestamp($value)
|
||||
{
|
||||
return 'TIMESTAMP'.$this->_quoteText($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTime()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteTime($value)
|
||||
{
|
||||
return 'TIME'.$this->_quoteText($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,659 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 Firebird/Interbase driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_ibase extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ convertResult()
|
||||
|
||||
/**
|
||||
* convert a value to a RDBMS independent MDB2 type
|
||||
*
|
||||
* @param mixed $value value to be converted
|
||||
* @param int $type constant that specifies which type to convert to
|
||||
* @return mixed converted value or a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function convertResult($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'decimal':
|
||||
return sprintf('%.'.$db->options['decimal_places'].'f', doubleval($value)/pow(10.0, $db->options['decimal_places']));
|
||||
case 'timestamp':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD HH:MM:SS'));
|
||||
default:
|
||||
return $this->_baseConvertResult($value, $type);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$length = (array_key_exists('length', $field) ? $field['length'] : (!PEAR::isError($length = $db->options['default_text_field_length']) ? $length : 4000));
|
||||
return 'VARCHAR ('.$length.')';
|
||||
case 'clob':
|
||||
return 'BLOB SUB_TYPE 1';
|
||||
case 'blob':
|
||||
return 'BLOB SUB_TYPE 0';
|
||||
case 'integer':
|
||||
return 'INTEGER';
|
||||
case 'boolean':
|
||||
return 'CHAR (1)';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME';
|
||||
case 'timestamp':
|
||||
return 'TIMESTAMP';
|
||||
case 'float':
|
||||
return 'DOUBLE PRECISION';
|
||||
case 'decimal':
|
||||
return 'DECIMAL(18,'.$db->options['decimal_places'].')';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field should be
|
||||
* declared as unsigned integer if possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('unsigned', $field) && $field['unsigned']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
return $name.' PRIMARY KEY';
|
||||
}
|
||||
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' INT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTextDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTextDeclaration($name, $field)
|
||||
{
|
||||
$type = $this->getTypeDeclaration($field);
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'text') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a time
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a timestamp
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Timestamp value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Float value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Decimal value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteLOB($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (PEAR::isError($connect = $db->connect())) {
|
||||
return $connect;
|
||||
}
|
||||
$close = true;
|
||||
if (is_resource($value)) {
|
||||
$close = false;
|
||||
} elseif (preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
|
||||
if ($match[1] == 'file://') {
|
||||
$value = $match[2];
|
||||
}
|
||||
$value = @fopen($value, 'r');
|
||||
} else {
|
||||
$fp = @tmpfile();
|
||||
@fwrite($fp, $value);
|
||||
@rewind($fp);
|
||||
$value = $fp;
|
||||
}
|
||||
if ($db->in_transaction) {
|
||||
$blob_id = @ibase_blob_import($db->transaction_id, $value);
|
||||
} else {
|
||||
$blob_id = @ibase_blob_import($db->connection, $value);
|
||||
}
|
||||
if ($close) {
|
||||
@fclose($value);
|
||||
}
|
||||
return $blob_id;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return (strval(round($value*pow(10.0, $db->options['decimal_places']))));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _retrieveLOB()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _retrieveLOB(&$lob)
|
||||
{
|
||||
if (!array_key_exists('handle', $lob)) {
|
||||
$lob['handle'] = @ibase_blob_open($lob['ressource']);
|
||||
if (!$lob['handle']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_retrieveLOB: Could not open fetched large object field' . @ibase_errmsg());
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _readLOB()
|
||||
|
||||
/**
|
||||
* Read data from large object input stream.
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @param blob $data reference to a variable that will hold data to be
|
||||
* read from the large object input stream
|
||||
* @param int $length integer value that indicates the largest ammount of
|
||||
* data to be read from the large object input stream.
|
||||
* @return mixed length on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _readLOB($lob, $length)
|
||||
{
|
||||
$data = ibase_blob_get($lob['handle'], $length);
|
||||
if (!is_string($data)) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'Read Result LOB: ' . @ibase_errmsg());
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _destroyLOB()
|
||||
|
||||
/**
|
||||
* Free any resources allocated during the lifetime of the large object
|
||||
* handler object.
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @access protected
|
||||
*/
|
||||
function _destroyLOB($lob_index)
|
||||
{
|
||||
if (isset($this->lobs[$lob_index]['handle'])) {
|
||||
@ibase_blob_close($this->lobs[$lob_index]['handle']);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types and the length
|
||||
* @access public
|
||||
*/
|
||||
function mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = preg_replace('/\d/','', strtolower($field['typname']) );
|
||||
$length = $field['attlen'];
|
||||
if ($length == '-1') {
|
||||
$length = $field['atttypmod']-4;
|
||||
}
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'smallint':
|
||||
case 'integer':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
}
|
||||
break;
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double precision':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: unknown database attribute type');
|
||||
}
|
||||
|
||||
return array($type, $length);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
@ -1,521 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Lukas Smith <smith@pooteeweet.org> |
|
||||
// | Daniel Convissor <danielc@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MS SQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_mssql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ convertResult()
|
||||
|
||||
/**
|
||||
* convert a value to a RDBMS indepdenant MDB2 type
|
||||
*
|
||||
* @param mixed $value value to be converted
|
||||
* @param int $type constant that specifies which type to convert to
|
||||
* @return mixed converted value
|
||||
* @access public
|
||||
*/
|
||||
function convertResult($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
return $value == '1';
|
||||
case 'date':
|
||||
if (strlen($value) > 10) {
|
||||
$value = substr($value,0,10);
|
||||
}
|
||||
return $value;
|
||||
case 'time':
|
||||
if (strlen($value) > 8) {
|
||||
$value = substr($value,11,8);
|
||||
}
|
||||
return $value;
|
||||
default:
|
||||
return $this->_baseConvertResult($value,$type);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field should be
|
||||
* declared as unsigned integer if possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('unsigned', $field) && $field['unsigned']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' INT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTextDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTextDeclaration($name, $field)
|
||||
{
|
||||
$type = array_key_exists('length', $field) ? 'VARCHAR ('.$field['length'].')' : 'TEXT';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'text') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the
|
||||
* properties of the field being declared as array
|
||||
* indexes. Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field
|
||||
* is constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 8000) {
|
||||
$type = "VARCHAR($length)";
|
||||
} else {
|
||||
$type = 'TEXT';
|
||||
}
|
||||
} else {
|
||||
$type = 'TEXT';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 8000) {
|
||||
$type = "VARBINARY($length)";
|
||||
} else {
|
||||
$type = 'IMAGE';
|
||||
}
|
||||
} else {
|
||||
$type = 'IMAGE';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBooleanDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a boolean type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Boolean value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBooleanDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'boolean') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' BIT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' CHAR ('.strlen('YYYY-MM-DD').')'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a timestamp
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Timestamp value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a time
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' CHAR ('.strlen('HH:MM:SS').')'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' FLOAT'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$type = 'DECIMAL(18,'.$db->options['decimal_places'].')';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : ' NULL';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
$value = $this->_readFile($value);
|
||||
return bin2hex("0x".$value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBoolean()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBoolean($value)
|
||||
{
|
||||
return ($value ? 1 : 0);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,543 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_mysql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
$autoinc = ' AUTO_INCREMENT PRIMARY KEY';
|
||||
$default = '';
|
||||
} else {
|
||||
$autoinc = '';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
}
|
||||
|
||||
$unsigned = (array_key_exists('unsigned', $field) && $field['unsigned']) ? ' UNSIGNED' : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' INT'.$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the
|
||||
* properties of the field being declared as array
|
||||
* indexes. Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field
|
||||
* is constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYTEXT';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'TEXT';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMTEXT';
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYBLOB';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'BLOB';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMBLOB';
|
||||
} else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field properties
|
||||
* are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATE'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an timestamp
|
||||
* type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time stamp value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATETIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an time type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' TIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$type = 'DOUBLE';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$type = 'DECIMAL(18,'.$db->options['decimal_places'].')';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
$value = $this->_readFile($value);
|
||||
return "'".addslashes($value)."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types and the length
|
||||
* @access public
|
||||
*/
|
||||
function mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$db_type = strtok($db_type, '(), ');
|
||||
if ($db_type == 'national') {
|
||||
$db_type = strtok('(), ');
|
||||
}
|
||||
$length = strtok('(), ');
|
||||
$decimal = strtok('(), ');
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'tinyint':
|
||||
case 'smallint':
|
||||
case 'mediumint':
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^[is|has]/', $field['field'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/[is|has]/', $field['field'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'enum':
|
||||
preg_match_all('/\'.+\'/U', $field['type'], $matches);
|
||||
$length = 0;
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches[0] as $value) {
|
||||
$length = max($length, strlen($value)-2);
|
||||
}
|
||||
}
|
||||
case 'set':
|
||||
$type[] = 'text';
|
||||
$type[] = 'integer';
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
if ($decimal == 'binary') {
|
||||
$type[] = 'blob';
|
||||
}
|
||||
$type[] = 'clob';
|
||||
$type[] = 'text';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$type[] = 'text';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: unknown database attribute type');
|
||||
}
|
||||
|
||||
return array($type, $length);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,568 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_mysqli extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
$autoinc = ' AUTO_INCREMENT PRIMARY KEY';
|
||||
$default = '';
|
||||
} else {
|
||||
$autoinc = '';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
}
|
||||
|
||||
$unsigned = (array_key_exists('unsigned', $field) && $field['unsigned']) ? ' UNSIGNED' : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' INT'.$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the
|
||||
* properties of the field being declared as array
|
||||
* indexes. Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field
|
||||
* is constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYTEXT';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'TEXT';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMTEXT';
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('length', $field)) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYBLOB';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'BLOB';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMBLOB';
|
||||
} else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field properties
|
||||
* are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATE'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an timestamp
|
||||
* type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time stamp value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATETIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an time type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' TIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$type = 'DOUBLE';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$type = 'DECIMAL(18,'.$db->options['decimal_places'].')';
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
$value = $this->_readFile($value);
|
||||
return "'".addslashes($value)."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types and the length
|
||||
* @access public
|
||||
*/
|
||||
function mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$db_type = strtok($db_type, '(), ');
|
||||
if ($db_type == 'national') {
|
||||
$db_type = strtok('(), ');
|
||||
}
|
||||
$length = strtok('(), ');
|
||||
$decimal = strtok('(), ');
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'tinyint':
|
||||
case 'smallint':
|
||||
case 'mediumint':
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^[is|has]/', $field['field'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/[is|has]/', $field['field'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'enum':
|
||||
preg_match_all('/\'.+\'/U', $field['type'], $matches);
|
||||
$length = 0;
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches[0] as $value) {
|
||||
$length = max($length, strlen($value)-2);
|
||||
}
|
||||
}
|
||||
case 'set':
|
||||
$type[] = 'text';
|
||||
$type[] = 'integer';
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
if ($decimal == 'binary') {
|
||||
$type[] = 'blob';
|
||||
}
|
||||
$type[] = 'clob';
|
||||
$type[] = 'text';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$type[] = 'text';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: unknown database attribute type');
|
||||
}
|
||||
|
||||
return array($type, $length);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapPrepareDatatype()
|
||||
|
||||
/**
|
||||
* Maps an mdb2 datatype to mysqli prepare type
|
||||
*
|
||||
* @param string $type
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function mapPrepareDatatype($type)
|
||||
{
|
||||
switch($type) {
|
||||
case 'integer':
|
||||
return 'i';
|
||||
case 'float':
|
||||
return 'd';
|
||||
case 'blob':
|
||||
return 'b';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 's';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,607 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 OCI8 driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_oci8 extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ convertResult()
|
||||
|
||||
/**
|
||||
* convert a value to a RDBMS indepdenant MDB2 type
|
||||
*
|
||||
* @param mixed $value value to be converted
|
||||
* @param int $type constant that specifies which type to convert to
|
||||
* @return mixed converted value
|
||||
* @access public
|
||||
*/
|
||||
function convertResult($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'date':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD'));
|
||||
case 'time':
|
||||
return substr($value, strlen('YYYY-MM-DD '), strlen('HH:MI:SS'));
|
||||
default:
|
||||
return $this->_baseConvertResult($value, $type);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$length = (array_key_exists('length', $field) ? $field['length'] : (($length = $db->options['default_text_field_length']) ? $length : 4000));
|
||||
return 'VARCHAR ('.$length.')';
|
||||
case 'clob':
|
||||
return 'CLOB';
|
||||
case 'blob':
|
||||
return 'BLOB';
|
||||
case 'integer':
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'CHAR (1)';
|
||||
case 'date':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
return 'DATE';
|
||||
case 'float':
|
||||
return 'NUMBER';
|
||||
case 'decimal':
|
||||
return 'NUMBER(*,'.$db->options['decimal_places'].')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field should be
|
||||
* declared as unsigned integer if possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @param string $table name of the current table being processed
|
||||
* by alterTable(), used for autoincrement emulation
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field, $table = null)
|
||||
{
|
||||
if (array_key_exists('unsigned', $field) && $field['unsigned']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$db->warning[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTextDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTextDeclaration($name, $field)
|
||||
{
|
||||
$type = $this->getTypeDeclaration($field);
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'text') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a timestamp
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Timestamp value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull; }
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a time
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Float value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Decimal value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteCLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteCLOB($value)
|
||||
{
|
||||
return 'EMPTY_CLOB()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
return 'EMPTY_BLOB()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDate()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDate($value)
|
||||
{
|
||||
return $this->_quoteText("$value 00:00:00");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTimestamp()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteTimestamp($value)
|
||||
{
|
||||
return $this->_quoteText($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteTime()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteTime($value)
|
||||
{
|
||||
return $this->_quoteText("0001-01-01 $value");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ writeLOBToFile()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @param string $file name of the file into which the LOb should be fetched
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function writeLOBToFile($lob, $file)
|
||||
{
|
||||
$lob_data = stream_get_meta_data($lob);
|
||||
$lob_index = $lob_data['wrapper_data']->lob_index;
|
||||
if (!@$this->lobs[$lob_index]['value']->writelobtofile($file)) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError();
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _retrieveLOB()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param int $lob_index from the lob array
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _retrieveLOB(&$lob)
|
||||
{
|
||||
if (!array_key_exists('loaded', $lob)) {
|
||||
if (!is_object($lob['ressource'])) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'attemped to retrieve LOB from non existing or NULL column');
|
||||
}
|
||||
$lob['value'] = $lob['ressource']->load();
|
||||
$lob['loaded'] = true;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,863 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_pgsql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ convertResult()
|
||||
|
||||
/**
|
||||
* convert a value to a RDBMS independent MDB2 type
|
||||
*
|
||||
* @param mixed $value value to be converted
|
||||
* @param int $type constant that specifies which type to convert to
|
||||
* @return mixed converted value or a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function convertResult($value, $type)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
return $value == 't';
|
||||
case 'float':
|
||||
return doubleval($value);
|
||||
case 'date':
|
||||
return $value;
|
||||
case 'time':
|
||||
return $value;
|
||||
case 'timestamp':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD HH:MM:SS'));
|
||||
default:
|
||||
return $this->_baseConvertResult($value, $type);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
return array_key_exists('length', $field) ? 'VARCHAR ('.$field['length'].')' : 'TEXT';
|
||||
case 'clob':
|
||||
return 'OID';
|
||||
case 'blob':
|
||||
return 'OID';
|
||||
case 'integer':
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
return 'SERIAL PRIMARY KEY';
|
||||
}
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'BOOLEAN';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME without time zone';
|
||||
case 'timestamp':
|
||||
return 'TIMESTAMP without time zone';
|
||||
case 'float':
|
||||
return 'FLOAT8';
|
||||
case 'decimal':
|
||||
return 'NUMERIC(18, '.$db->options['decimal_places'].')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field should be
|
||||
* declared as unsigned integer if possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
if (array_key_exists('unsigned', $field) && $field['unsigned']) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
return $name.' '.$this->getTypeDeclaration($field);
|
||||
}
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTextDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTextDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'text') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the large
|
||||
* object field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBooleanDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a boolean type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Boolean value to be used as default for this field.
|
||||
*
|
||||
* notnullL
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBooleanDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'boolean') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a time
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a timestamp
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Timestamp value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Float value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare a decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Decimal value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = array_key_exists('default', $field) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (array_key_exists('notnull', $field) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteLOB($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$connect = $db->connect();
|
||||
if (PEAR::isError($connect)) {
|
||||
return $connect;
|
||||
}
|
||||
if (!$db->in_transaction && !@pg_query($db->connection, 'BEGIN')) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'error starting transaction');
|
||||
}
|
||||
if (is_resource($value)) {
|
||||
$close = false;
|
||||
} elseif (preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
|
||||
$close = true;
|
||||
if ($match[1] == 'file://') {
|
||||
$value = $match[2];
|
||||
}
|
||||
// disabled use of pg_lo_import() for now with the following line
|
||||
$value = @fopen($value, 'r');
|
||||
} else {
|
||||
$close = true;
|
||||
$fp = @tmpfile();
|
||||
@fwrite($fp, $value);
|
||||
@rewind($fp);
|
||||
$value = $fp;
|
||||
}
|
||||
$result = false;
|
||||
if (is_resource($value)) {
|
||||
if (($lo = @pg_lo_create($db->connection))) {
|
||||
if (($handle = @pg_lo_open($db->connection, $lo, 'w'))) {
|
||||
while (!@feof($value)) {
|
||||
$data = @fread($value, $db->options['lob_buffer_length']);
|
||||
if ($data === '') {
|
||||
break;
|
||||
}
|
||||
if (!@pg_lo_write($handle, $data)) {
|
||||
$result = $db->raiseError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!PEAR::isError($result)) {
|
||||
$result = strval($lo);
|
||||
}
|
||||
@pg_lo_close($handle);
|
||||
} else {
|
||||
$result = $db->raiseError();
|
||||
@pg_lo_unlink($db->connection, $lo);
|
||||
}
|
||||
}
|
||||
if ($close) {
|
||||
@fclose($value);
|
||||
}
|
||||
} else {
|
||||
if (!@pg_lo_import($db->connection, $value)) {
|
||||
$result = $db->raiseError();
|
||||
}
|
||||
}
|
||||
if (!$db->in_transaction) {
|
||||
if (PEAR::isError($result)) {
|
||||
@pg_query($db->connection, 'ROLLBACK');
|
||||
} else {
|
||||
@pg_query($db->connection, 'COMMIT');
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteCLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteCLOB($value)
|
||||
{
|
||||
return $this->_quoteLOB($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param $value
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value)
|
||||
{
|
||||
return $this->_quoteLOB($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBoolean()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBoolean($value)
|
||||
{
|
||||
return ($value ? "'t'" : "'f'");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->escape($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ writeLOBToFile()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @param string $file name of the file into which the LOb should be fetched
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function writeLOBToFile($lob, $file)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$lob_data = stream_get_meta_data($lob);
|
||||
$lob_index = $lob_data['wrapper_data']->lob_index;
|
||||
if (!pg_lo_export($db->connection, $this->lobs[$lob_index]['ressource'], $file)) {
|
||||
return $db->raiseError();
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _retrieveLOB()
|
||||
|
||||
/**
|
||||
* retrieve LOB from the database
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _retrieveLOB(&$lob)
|
||||
{
|
||||
if (!array_key_exists('handle', $lob)) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if (!$db->in_transaction) {
|
||||
if (!@pg_query($db->connection, 'BEGIN')) {
|
||||
return $db->raiseError();
|
||||
}
|
||||
$lob['in_transaction'] = true;
|
||||
}
|
||||
$lob['handle'] = @pg_lo_open($db->connection, $lob['ressource'], 'r');
|
||||
if (!$lob['handle']) {
|
||||
if (array_key_exists('in_transaction', $lob)) {
|
||||
@pg_query($db->connection, 'END');
|
||||
unset($lob['in_transaction']);
|
||||
}
|
||||
return $db->raiseError();
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _readLOB()
|
||||
|
||||
/**
|
||||
* Read data from large object input stream.
|
||||
*
|
||||
* @param resource $lob stream handle
|
||||
* @param blob $data reference to a variable that will hold data to be
|
||||
* read from the large object input stream
|
||||
* @param int $length integer value that indicates the largest ammount of
|
||||
* data to be read from the large object input stream.
|
||||
* @return mixed length on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _readLOB($lob, $length)
|
||||
{
|
||||
$data = @pg_lo_read($lob['handle'], $length);
|
||||
if (!is_string($data)) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _destroyLOB()
|
||||
|
||||
/**
|
||||
* Free any resources allocated during the lifetime of the large object
|
||||
* handler object.
|
||||
*
|
||||
* @param int $lob_index from the lob array
|
||||
* @access protected
|
||||
*/
|
||||
function _destroyLOB($lob_index)
|
||||
{
|
||||
if (isset($this->lobs[$lob_index]['handle'])) {
|
||||
@pg_lo_close($this->lobs[$lob_index]['handle']);
|
||||
unset($this->lobs[$lob_index]['handle']);
|
||||
if (isset($this->lobs[$lob_index]['in_transaction'])) {
|
||||
/*
|
||||
for some reason this piece of code causes an apache crash
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
@pg_query($db->connection, 'END');
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types and the length
|
||||
* @access public
|
||||
*/
|
||||
function mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = preg_replace('/\d/','', strtolower($field['typname']) );
|
||||
$length = $field['attlen'];
|
||||
if ($length == '-1') {
|
||||
$length = $field['atttypmod']-4;
|
||||
}
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'int':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
}
|
||||
break;
|
||||
case 'bool':
|
||||
$type[] = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'text':
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
case 'bpchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
} elseif (strstr($db_type, 'text'))
|
||||
$type[] = 'clob';
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'oid':
|
||||
$type[] = 'blob';
|
||||
$type[] = 'clob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: unknown database attribute type');
|
||||
}
|
||||
|
||||
return array($type, $length);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
@ -1,506 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@backendmedia.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_sqlite extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$unsigned = (isset($field['unsigned']) && $field['unsigned']) ? ' UNSIGNED' : '';
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'integer') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' INT'.$unsigned.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an character
|
||||
* large object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the
|
||||
* properties of the field being declared as array
|
||||
* indexes. Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field
|
||||
* is constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getCLOBDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if (isset($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYTEXT';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'TEXT';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMTEXT';
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = 'LONGTEXT';
|
||||
}
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getBLOBDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an binary large
|
||||
* object type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length
|
||||
* of the large object field. If this argument is
|
||||
* missing the field should be declared to have the
|
||||
* longest length allowed by the DBMS.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getBLOBDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if (isset($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
$type = 'TINYBLOB';
|
||||
} else {
|
||||
if ($length <= 65535) {
|
||||
$type = 'BLOB';
|
||||
} else {
|
||||
if ($length <= 16777215) {
|
||||
$type = 'MEDIUMBLOB';
|
||||
} else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$type = 'LONGBLOB';
|
||||
}
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDateDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an date type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field properties
|
||||
* are as follows:
|
||||
*
|
||||
* default
|
||||
* Date value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDateDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'date') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATE'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimestampDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an timestamp
|
||||
* type field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time stamp value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimestampDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'timestamp') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' DATETIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTimeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an time type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Time value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getTimeDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'time') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' TIME'.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$type = 'DOUBLE'.($db->options['fixed_float'] ? '('.
|
||||
($db->options['fixed_float']+2).','.$db->options['fixed_float'].')' : '');
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'float') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$type = 'BIGINT';
|
||||
$default = isset($field['default']) ? ' DEFAULT '.
|
||||
$this->quote($field['default'], 'decimal') : '';
|
||||
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
|
||||
return $name.' '.$type.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteFloat()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteFloat($value)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteDecimal()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteDecimal($value)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->escape($value);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types and the length
|
||||
* @access public
|
||||
*/
|
||||
function mapNativeDatatype($field)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$db_type = $field['type'];
|
||||
$length = isset($field['length']) ? $field['length'] : null;
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'tinyint':
|
||||
case 'smallint':
|
||||
case 'mediumint':
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
$type[] = 'integer';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^[is|has]/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
case "varchar2":
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/[is|has]/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($db_type, 'text'))
|
||||
$type[] = 'clob';
|
||||
break;
|
||||
case 'enum':
|
||||
preg_match_all('/\'.+\'/U',$row[$type_column], $matches);
|
||||
$length = 0;
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches[0] as $value) {
|
||||
$length = max($length, strlen($value)-2);
|
||||
}
|
||||
}
|
||||
case 'set':
|
||||
$type[] = 'text';
|
||||
$type[] = 'integer';
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'text';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: unknown database attribute type');
|
||||
}
|
||||
|
||||
return array($type, $length);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,616 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for the management modules that is extended by each MDB2 driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Manager_Common extends MDB2_Module_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ getFieldDeclarationList()
|
||||
|
||||
/**
|
||||
* get declaration of a number of field in bulk
|
||||
*
|
||||
* @param string $fields a multidimensional associative array.
|
||||
* The first dimension determines the field name, while the second
|
||||
* dimension is keyed with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* default
|
||||
* Boolean value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
*
|
||||
* @return mixed string on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getFieldDeclarationList($fields)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_array($fields)) {
|
||||
foreach ($fields as $field_name => $field) {
|
||||
$query = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($query)) {
|
||||
return $query;
|
||||
}
|
||||
$query_fields[] = $query;
|
||||
}
|
||||
return implode(',', $query_fields);
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'getFieldDeclarationList: the definition of the table "'.$table_name.'" does not contain any fields');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _isSequenceName()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @param string $sqn string that containts name of a potential sequence
|
||||
* @return mixed name of the sequence if $sqn is a name of a sequence, else false
|
||||
* @access protected
|
||||
*/
|
||||
function _isSequenceName($sqn)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$seq_pattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $db->options['seqname_format']).'$/i';
|
||||
$seq_name = preg_replace($seq_pattern, '\\1', $sqn);
|
||||
if ($seq_name && $sqn == $db->getSequenceName($seq_name)) {
|
||||
return $seq_name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($database)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'createDatabase: database creation is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($database)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'dropDatabase: database dropping is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createTable()
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
*
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createTable($name, $fields)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no valid table name specified');
|
||||
}
|
||||
if (empty($fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no fields specified for table "'.$name.'"');
|
||||
}
|
||||
$query_fields = $this->getFieldDeclarationList($fields);
|
||||
if (PEAR::isError($query_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: unkown error');
|
||||
}
|
||||
$query = "CREATE TABLE $name ($query_fields)";
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropTable()
|
||||
|
||||
/**
|
||||
* drop an existing table
|
||||
*
|
||||
* @param string $name name of the table that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropTable($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("DROP TABLE $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'alterTable: database table alterations are not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listDatabases: list databases is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listUsers: list user is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list all views in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listViews()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listViews: list view is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listFunctions()
|
||||
|
||||
/**
|
||||
* list all functions in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listFunctions()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listFunctions: list function is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listTables: list tables is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listTableFields: list table fields is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'createIndex: Creating Indexes is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropIndex()
|
||||
|
||||
/**
|
||||
* drop existing index
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the index to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("DROP INDEX $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listTableIndexes: List Indexes is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'createSequence: sequence creation not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'dropSequence: sequence dropping not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listSequences: List sequences is not supported');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,608 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 FrontBase driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Frank M. Kromann <frank@kromann.info>
|
||||
*/
|
||||
class MDB2_Driver_Manager_fbsql extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (PEAR::isError($result = $db->connect())) {
|
||||
return $result;
|
||||
}
|
||||
$query = "CREATE DATABASE $name";
|
||||
if (PEAR::isError($result = $db->query($query))) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (PEAR::isError($result = $db->connect())) {
|
||||
return $result;
|
||||
}
|
||||
$query = "DELETE DATABASE $name";
|
||||
if (PEAR::isError($result = $db->query($query))) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropTable()
|
||||
|
||||
/**
|
||||
* drop an existing table
|
||||
*
|
||||
* @param object $dbs database object that is extended by this class
|
||||
* @param string $name name of the table that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropTable($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("DROP TABLE $name CASCADE");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change){
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = (array_key_exists('name', $changes) ? 'RENAME AS '.$changes['name'] : '');
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $type_declaration;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$rename[$field['name']] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$field_name])) {
|
||||
$old_field_name = $rename[$field_name];
|
||||
unset($rename[$field_name]);
|
||||
} else {
|
||||
$old_field_name = $field_name;
|
||||
}
|
||||
$query.= "CHANGE $old_field_name " . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rename)) {
|
||||
foreach ($rename as $renamed_field_name => $renamed_field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$old_field_name = $rename[$renamed_field_name];
|
||||
$field = $changes['rename'][$old_field_name];
|
||||
$query.= 'CHANGE ' . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->queryCol('SELECT "user_name" FROM information_schema.users');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SELECT "table_name"'
|
||||
. ' FROM information_schema.tables'
|
||||
. ' t0, information_schema.schemata t1'
|
||||
. ' WHERE t0.schema_pk=t1.schema_pk AND'
|
||||
. ' "table_type" = \'BASE TABLE\''
|
||||
. ' AND "schema_name" = current_schema');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
for ($i = 0, $j = count($table_names), $tables = array(); $i < $j; ++$i) {
|
||||
if (!$this->_isSequenceName($table_names[$i]))
|
||||
$tables[] = $table_names[$i];
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$fields = $db->queryCol("SHOW COLUMNS FROM $table");
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$fields = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $fields);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function support() to determine whether the DBMS driver can manage indexes.
|
||||
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "CREATE ".(array_key_exists('unique', $definition) ? 'UNIQUE INDEX' : 'INDEX')." $name on $table (";
|
||||
$query.= implode(', ', array_keys($definition['fields']));
|
||||
$query.= ')';
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropIndex()
|
||||
|
||||
/**
|
||||
* drop existing index
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the index to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $table DROP INDEX $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$key_name = 'Key_name';
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes_all = $db->queryCol($query, 'text', $key_name);
|
||||
if (PEAR::isError($indexes_all)) {
|
||||
return $indexes_all;
|
||||
}
|
||||
|
||||
$indexes = array_unique($indexes_all);
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$indexes = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $indexes);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
$seqcol_name = $db->options['seqcol_name'];
|
||||
$query = "CREATE TABLE $sequence_name ($seqcol_name INTEGER DEFAULT UNIQUE, PRIMARY KEY($seqcol_name))";
|
||||
$res = $db->query($query);
|
||||
$res = $db->query("SET UNIQUE = 1 FOR $sequence_name");
|
||||
if (PEAR::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
if ($start == 1) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$res = $db->query("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')');
|
||||
if (!PEAR::isError($res)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
// Handle error
|
||||
$result = $db->query("DROP TABLE $sequence_name");
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not drop inconsistent sequence table ('.
|
||||
$result->getMessage().' ('.$result->getUserinfo().'))');
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not create sequence table ('.
|
||||
$res->getMessage().' ('.$res->getUserinfo().'))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP TABLE $sequence_name CASCADE");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SHOW TABLES', 'text');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i]))
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
return $sequences;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
@ -1,684 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 FireBird/InterBase driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Manager_ibase extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 'Create database',
|
||||
'createDatabase: PHP Interbase API does not support direct queries. You have to '.
|
||||
'create the db manually by using isql command or a similar program');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 'Drop database',
|
||||
'dropDatabase: PHP Interbase API does not support direct queries. You have '.
|
||||
'to drop the db manually by using isql command or a similar program');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _makeAutoincrement()
|
||||
|
||||
/**
|
||||
* add an autoincrement sequence + trigger
|
||||
*
|
||||
* @param string $name name of the PK field
|
||||
* @param string $table name of the table
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _makeAutoincrement($name, $table, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->manager->createSequence($table, $start);
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_makeAutoincrement: sequence for autoincrement PK could not be created');
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($table);
|
||||
$trigger_name = $table . '_autoincrement_pk';
|
||||
$trigger_sql = 'CREATE TRIGGER ' . $trigger_name . ' FOR ' . $table . '
|
||||
ACTIVE BEFORE INSERT POSITION 0
|
||||
AS
|
||||
BEGIN
|
||||
IF (NEW.' . $name . ' IS NULL) THEN
|
||||
NEW.' . $name . ' = GEN_ID('.strtoupper($sequence_name).', 1);
|
||||
END';
|
||||
|
||||
return $db->query($trigger_sql);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _dropAutoincrement()
|
||||
|
||||
/**
|
||||
* drop an existing autoincrement PK / trigger
|
||||
*
|
||||
* @param string $name name of the PK field
|
||||
* @param string $table name of the table
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _dropAutoincrement($name, $table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->manager->dropSequence($table);
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_dropAutoincrement: sequence for autoincrement PK could not be dropped');
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createTable()
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
*
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1,
|
||||
* 'notnull' => 1,
|
||||
* 'default' => 0,
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12,
|
||||
* ),
|
||||
* 'description' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12,
|
||||
* )
|
||||
* );
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createTable($name, $fields)
|
||||
{
|
||||
$result = parent::createTable($name, $fields);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
foreach($fields as $field_name => $field) {
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
return $this->_makeAutoincrement($field_name, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ checkSupportedChanges()
|
||||
|
||||
/**
|
||||
* check if planned changes are supported
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function checkSupportedChanges(&$changes)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'notnull':
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'checkSupportedChanges: it is not supported changes to field not null constraint');
|
||||
case 'default':
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'checkSupportedChanges: it is not supported changes to field default value');
|
||||
case 'length':
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'checkSupportedChanges: it is not supported changes to field default length');
|
||||
case 'unsigned':
|
||||
case 'type':
|
||||
case 'declaration':
|
||||
case 'definition':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'checkSupportedChanges: it is not supported change of type' . $change_name);
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropTable()
|
||||
|
||||
/**
|
||||
* drop an existing table
|
||||
*
|
||||
* @param string $name name of the table that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropTable($name)
|
||||
{
|
||||
//remove triggers associated with the table
|
||||
$name = strtoupper($name);
|
||||
$triggers = $db->queryCol("SELECT RDB\$TRIGGER_NAME FROM RDB\$TRIGGERS WHERE RDB\$RELATION_NAME='$name'");
|
||||
if (PEAR::isError($triggers)) {
|
||||
return $triggers;
|
||||
}
|
||||
foreach ($triggers as $trigger) {
|
||||
$result = $db->query('DROP TRIGGER ' . $trigger);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::dropTable($name);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'rename':
|
||||
break;
|
||||
case 'change':
|
||||
foreach ($changes['change'] as $field) {
|
||||
if (PEAR::isError($err = $this->checkSupportedChanges($field))) {
|
||||
return $err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'alterTable: change type ' . $change_name . ' not yet supported');
|
||||
}
|
||||
}
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$query = '';
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field, $name);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
if (strlen($query)) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $type_declaration;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if (strlen($query)) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
if (strlen($query)) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ALTER ' . $field_name . ' TO ' . $field['name'];
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
// missing support to change DEFAULT and NULLability
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if (PEAR::isError($err = $this->checkSupportedChanges($field))) {
|
||||
return $err;
|
||||
}
|
||||
if (strlen($query)) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$db->loadModule('Datatype');
|
||||
$query.= 'ALTER ' . $field_name.' TYPE ' . $db->datatype->getTypeDeclaration($field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlen($query)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$query = 'SELECT DISTINCT R.RDB$RELATION_NAME FROM RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0';
|
||||
$tables = $db->queryCol($query);
|
||||
if (PEAR::isError($tables)) {
|
||||
return $tables;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$tables = array_flip(array_change_key_case(array_flip($tables), $db->options['field_case']));
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$table = strtoupper($table);
|
||||
$query = "SELECT RDB\$FIELD_NAME FROM RDB\$RELATION_FIELDS WHERE RDB\$RELATION_NAME='$table'";
|
||||
$columns = $db->queryCol($query);
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_flip(array_change_key_case(array_flip($columns), $db->options['field_case']));
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list the views in the database
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listViews()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->queryCol('SELECT RDB$VIEW_NAME');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function support() to determine whether the DBMS driver can manage indexes.
|
||||
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if (array_key_exists('primary', $definition) && $definition['primary']) {
|
||||
$query = "ALTER TABLE $table ADD CONSTRAINT $name PRIMARY KEY (";
|
||||
} else {
|
||||
$query = 'CREATE';
|
||||
if (array_key_exists('unique', $definition) && $definition['unique']) {
|
||||
$query.= ' UNIQUE';
|
||||
}
|
||||
$query_sort = '';
|
||||
foreach ($definition['fields'] as $field) {
|
||||
if (!strcmp($query_sort, '') && isset($field['sorting'])) {
|
||||
switch ($field['sorting']) {
|
||||
case 'ascending':
|
||||
$query_sort = ' ASC';
|
||||
break;
|
||||
case 'descending':
|
||||
$query_sort = ' DESC';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$query .= $query_sort. " INDEX $name ON $table (";
|
||||
}
|
||||
$query .= implode(', ', array_keys($definition['fields'])) . ')';
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return $db->queryCol("SELECT RDB\$INDEX_NAME FROM RDB\$INDICES WHERE RDB\$RELATION_NAME='$table'");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
if (PEAR::isError($result = $db->query('CREATE GENERATOR '.strtoupper($sequence_name)))) {
|
||||
return $result;
|
||||
}
|
||||
if (PEAR::isError($result = $db->query('SET GENERATOR '.strtoupper($sequence_name).' TO '.($start-1)))) {
|
||||
if (PEAR::isError($err = $db->dropSequence($seq_name))) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: Could not setup sequence start value and then it was not possible to drop it: '.
|
||||
$err->getMessage().' - ' .$err->getUserInfo());
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query('DELETE FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME=\''.strtoupper($sequence_name).'\'');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS';
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i]))
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
return $sequences;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,475 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Frank M. Kromann <frank@kromann.info> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
// {{{ class MDB2_Driver_Manager_mssql
|
||||
/**
|
||||
* MDB2 MSSQL driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Frank M. Kromann <frank@kromann.info>
|
||||
*/
|
||||
class MDB2_Driver_Manager_mssql extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "CREATE DATABASE $name";
|
||||
if($db->options['database_device']) {
|
||||
$query.= ' ON '.$db->options['database_device'];
|
||||
$query.= $db->options['database_size'] ? '='.$db->options['database_size'] : '';
|
||||
}
|
||||
return $db->standaloneQuery($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->standaloneQuery("DROP DATABASE $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
break;
|
||||
case 'remove':
|
||||
break;
|
||||
case 'name':
|
||||
case 'rename':
|
||||
case 'change':
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if (array_key_exists('add', $changes)) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ';
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= $db->getDeclaration($field['type'], $field_name, $field);
|
||||
}
|
||||
}
|
||||
if(array_key_exists('remove', $changes)) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP COLUMN';
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= $db->getDeclaration($field['type'], $field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'EXEC sp_tables @table_type = "\'TABLE\'"';
|
||||
$table_names = $db->queryCol($query, null, 2);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
for ($i = 0, $j = count($table_names); $i <$j; ++$i) {
|
||||
if (!$this->_isSequenceName($db, $table_names[$i])) {
|
||||
$tables[] = $table_names[$i];
|
||||
}
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->query("SELECT * FROM [$table]");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $result->getColumnNames();
|
||||
$result->free();
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
return array_flip($columns);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$key_name = 'INDEX_NAME';
|
||||
$pk_name = 'PK_NAME';
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
$pk_name = strtolower($pk_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
$pk_name = strtoupper($pk_name);
|
||||
}
|
||||
}
|
||||
$query = "EXEC sp_statistics @table_name='$table'";
|
||||
$indexes_all = $db->queryCol($query, 'text', $key_name);
|
||||
if (PEAR::isError($indexes_all)) {
|
||||
return $indexes_all;
|
||||
}
|
||||
$query = "EXEC sp_pkeys @table_name='$table'";
|
||||
$pk_all = $db->queryCol($query, 'text', $pk_name);
|
||||
$found = $indexes = array();
|
||||
for ($index = 0, $j = count($indexes_all); $index < $j; ++$index) {
|
||||
if (!in_array($indexes_all[$index], $pk_all)
|
||||
&& $indexes_all[$index] != null
|
||||
&& !isset($found[$indexes_all[$index]])
|
||||
) {
|
||||
$indexes[] = $indexes_all[$index];
|
||||
$found[$indexes_all[$index]] = 1;
|
||||
}
|
||||
}
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
$seqcol_name = $db->options['seqcol_name'];
|
||||
$query = "CREATE TABLE $sequence_name ($seqcol_name " .
|
||||
"INT PRIMARY KEY CLUSTERED IDENTITY($start,1) NOT NULL)";
|
||||
|
||||
$res = $db->query($query);
|
||||
if(PEAR::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
if ($start == 1) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = "SET IDENTITY_INSERT $sequence_name ON ".
|
||||
"INSERT INTO $sequence_name ($seqcol_name) VALUES ($start)";
|
||||
$res = $db->query($query);
|
||||
|
||||
if(!PEAR::isError($res)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$result = $db->query("DROP TABLE $sequence_name");
|
||||
if(PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not drop inconsistent sequence table ('.
|
||||
$result->getMessage().' ('.$result->getUserInfo(). '))');
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not create sequence table ('.
|
||||
$res->getMessage(). ' ('.$res->getUserInfo(). '))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
/**
|
||||
* Adds an index to a table.
|
||||
*
|
||||
* @param string $table The name of the table
|
||||
* @param string $name The name of the field
|
||||
* @param array $definition The definition of the new field.
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP TABLE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT name FROM sysobjects WHERE xtype = 'U'";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i <$j; ++$i) {
|
||||
if ($this->_isSequenceName($db, $table_names[$i])) {
|
||||
$sequences[] = $table_names[$i];
|
||||
}
|
||||
}
|
||||
return $sequences;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
?>
|
@ -1,749 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Manager_mysql extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $verified_table_types = array();#
|
||||
// }}}
|
||||
|
||||
// }}}
|
||||
// {{{ _verifyTableType()
|
||||
|
||||
/**
|
||||
* verify that chosen transactional table hanlder is available in the database
|
||||
*
|
||||
* @param string $table_type name of the table handler
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _verifyTableType($table_type)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch (strtoupper($table_type)) {
|
||||
case 'BERKELEYDB':
|
||||
case 'BDB':
|
||||
$check = array('have_bdb');
|
||||
break;
|
||||
case 'INNODB':
|
||||
$check = array('have_innobase', 'have_innodb');
|
||||
break;
|
||||
case 'GEMINI':
|
||||
$check = array('have_gemini');
|
||||
break;
|
||||
case 'HEAP':
|
||||
case 'ISAM':
|
||||
case 'MERGE':
|
||||
case 'MRG_MYISAM':
|
||||
case 'MYISAM':
|
||||
case '':
|
||||
return MDB2_OK;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
$table_type.' is not a supported table type');
|
||||
}
|
||||
if (isset($this->verified_table_types[$table_type])
|
||||
&& $this->verified_table_types[$table_type] == $db->connection
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$not_supported = false;
|
||||
for ($i = 0, $j = count($check); $i < $j; ++$i) {
|
||||
$query = 'SHOW VARIABLES LIKE '.$db->quote($check[$i], 'text');
|
||||
$has = $db->queryRow($query, null, MDB2_FETCHMODE_ORDERED);
|
||||
if (PEAR::isError($has)) {
|
||||
return $has;
|
||||
}
|
||||
if (is_array($has)) {
|
||||
$not_supported = true;
|
||||
if ($has[1] == 'YES') {
|
||||
$this->verified_table_types[$table_type] = $db->connection;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($not_supported) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
$table_type.' is not a supported table type by this MySQL database server');
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'could not tell if '.$table_type.' is a supported table type');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'CREATE DATABASE '.$name;
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'DROP DATABASE '.$name;
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createTable()
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
*
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createTable($name, $fields)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no valid table name specified');
|
||||
}
|
||||
if (empty($fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no fields specified for table "'.$name.'"');
|
||||
}
|
||||
$verify = $this->_verifyTableType($db->options['default_table_type']);
|
||||
if (PEAR::isError($verify)) {
|
||||
return $verify;
|
||||
}
|
||||
$query_fields = $this->getFieldDeclarationList($fields);
|
||||
if (PEAR::isError($query_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: '.$this->getUserinfo());
|
||||
}
|
||||
$query = "CREATE TABLE $name ($query_fields)".(strlen($db->options['default_table_type'])
|
||||
? ' TYPE='.$db->options['default_table_type'] : '');
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = (array_key_exists('name', $changes) ? 'RENAME AS '.$changes['name'] : '');
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $type_declaration;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$rename[$field['name']] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$field_name])) {
|
||||
$old_field_name = $rename[$field_name];
|
||||
unset($rename[$field_name]);
|
||||
} else {
|
||||
$old_field_name = $field_name;
|
||||
}
|
||||
$query.= "CHANGE $field_name " . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rename)) {
|
||||
foreach ($rename as $rename_name => $renamed_field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$old_field_name = $renamed_field;
|
||||
$field = $changes['rename'][$old_field_name];
|
||||
$query.= 'CHANGE ' . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$databases = $db->queryCol('SHOW DATABASES');
|
||||
return $databases;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$users = $db->queryCol('SELECT DISTINCT USER FROM USER');
|
||||
return $users;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SHOW TABLES');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if (!$this->_isSequenceName($table_names[$i]))
|
||||
$tables[] = $table_names[$i];
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$tables = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $tables);
|
||||
}
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$fields = $db->queryCol("SHOW COLUMNS FROM $table");
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$fields = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $fields);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (array_key_exists('primary', $definition) && $definition['primary']) {
|
||||
$type = 'PRIMARY';
|
||||
$name = 'KEY';
|
||||
} elseif (array_key_exists('unique', $definition) && $definition['unique']) {
|
||||
$type = 'UNIQUE';
|
||||
} else {
|
||||
$type = 'INDEX';
|
||||
}
|
||||
|
||||
$query = "ALTER TABLE $table ADD $type $name (";
|
||||
$query.= implode(', ', array_keys($definition['fields']));
|
||||
$query.= ')';
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropIndex()
|
||||
|
||||
/**
|
||||
* drop existing index
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the index to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $table DROP INDEX $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$key_name = 'Key_name';
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes_all = $db->queryCol($query, 'text', $key_name);
|
||||
if (PEAR::isError($indexes_all)) {
|
||||
return $indexes_all;
|
||||
}
|
||||
|
||||
$indexes = array_unique($indexes_all);
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$indexes = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $indexes);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
$seqcol_name = $db->options['seqcol_name'];
|
||||
$result = $this->_verifyTableType($db->options['default_table_type']);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$res = $db->query("CREATE TABLE $sequence_name".
|
||||
"($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))".
|
||||
(strlen($db->options['default_table_type']) ? ' TYPE='.$db->options['default_table_type'] : '')
|
||||
);
|
||||
|
||||
if (PEAR::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
if ($start == 1) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$res = $db->query("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')');
|
||||
if (!PEAR::isError($res)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// Handle error
|
||||
$result = $db->query("DROP TABLE $sequence_name");
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not drop inconsistent sequence table ('.
|
||||
$result->getMessage().' ('.$result->getUserinfo().'))');
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not create sequence table ('.
|
||||
$res->getMessage().' ('.$res->getUserinfo().'))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP TABLE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SHOW TABLES');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i])) {
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
}
|
||||
|
||||
return $sequences;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
@ -1,749 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQLi driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Manager_mysqli extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $verified_table_types = array();#
|
||||
// }}}
|
||||
|
||||
// }}}
|
||||
// {{{ _verifyTableType()
|
||||
|
||||
/**
|
||||
* verify that chosen transactional table hanlder is available in the database
|
||||
*
|
||||
* @param string $table_type name of the table handler
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _verifyTableType($table_type)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch (strtoupper($table_type)) {
|
||||
case 'BERKELEYDB':
|
||||
case 'BDB':
|
||||
$check = array('have_bdb');
|
||||
break;
|
||||
case 'INNODB':
|
||||
$check = array('have_innobase', 'have_innodb');
|
||||
break;
|
||||
case 'GEMINI':
|
||||
$check = array('have_gemini');
|
||||
break;
|
||||
case 'HEAP':
|
||||
case 'ISAM':
|
||||
case 'MERGE':
|
||||
case 'MRG_MYISAM':
|
||||
case 'MYISAM':
|
||||
case '':
|
||||
return MDB2_OK;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
$table_type.' is not a supported table type');
|
||||
}
|
||||
if (isset($this->verified_table_types[$table_type])
|
||||
&& $this->verified_table_types[$table_type] == $db->connection
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$not_supported = false;
|
||||
for ($i = 0, $j = count($check); $i < $j; ++$i) {
|
||||
$query = 'SHOW VARIABLES LIKE '.$db->quote($check[$i], 'text');
|
||||
$has = $db->queryRow($query, null, MDB2_FETCHMODE_ORDERED);
|
||||
if (PEAR::isError($has)) {
|
||||
return $has;
|
||||
}
|
||||
if (is_array($has)) {
|
||||
$not_supported = true;
|
||||
if ($has[1] == 'YES') {
|
||||
$this->verified_table_types[$table_type] = $db->connection;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($not_supported) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
$table_type.' is not a supported table type by this MySQL database server');
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'could not tell if '.$table_type.' is a supported table type');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'CREATE DATABASE '.$name;
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'DROP DATABASE '.$name;
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createTable()
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
*
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createTable($name, $fields)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no valid table name specified');
|
||||
}
|
||||
if (empty($fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: no fields specified for table "'.$name.'"');
|
||||
}
|
||||
$verify = $this->_verifyTableType($db->options['default_table_type']);
|
||||
if (PEAR::isError($verify)) {
|
||||
return $verify;
|
||||
}
|
||||
$query_fields = $this->getFieldDeclarationList($fields);
|
||||
if (PEAR::isError($query_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createTable: '.$this->getUserinfo());
|
||||
}
|
||||
$query = "CREATE TABLE $name ($query_fields)".(strlen($db->options['default_table_type'])
|
||||
? ' TYPE='.$db->options['default_table_type'] : '');
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = (array_key_exists('name', $changes) ? 'RENAME AS '.$changes['name'] : '');
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $type_declaration;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$rename[$field['name']] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$field_name])) {
|
||||
$old_field_name = $rename[$field_name];
|
||||
unset($rename[$field_name]);
|
||||
} else {
|
||||
$old_field_name = $field_name;
|
||||
}
|
||||
$query.= "CHANGE $field_name " . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rename)) {
|
||||
foreach ($rename as $rename_name => $renamed_field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$old_field_name = $renamed_field;
|
||||
$field = $changes['rename'][$old_field_name];
|
||||
$query.= 'CHANGE ' . $db->getDeclaration($field['type'], $old_field_name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$databases = $db->queryCol('SHOW DATABASES');
|
||||
return $databases;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$users = $db->queryCol('SELECT DISTINCT USER FROM USER');
|
||||
return $users;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SHOW TABLES');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if (!$this->_isSequenceName($table_names[$i]))
|
||||
$tables[] = $table_names[$i];
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$tables = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $tables);
|
||||
}
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$fields = $db->queryCol("SHOW COLUMNS FROM $table");
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$fields = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $fields);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (array_key_exists('primary', $definition) && $definition['primary']) {
|
||||
$type = 'PRIMARY';
|
||||
$name = 'KEY';
|
||||
} elseif (array_key_exists('unique', $definition) && $definition['unique']) {
|
||||
$type = 'UNIQUE';
|
||||
} else {
|
||||
$type = 'INDEX';
|
||||
}
|
||||
|
||||
$query = "ALTER TABLE $table ADD $type $name (";
|
||||
$query.= implode(', ', array_keys($definition['fields']));
|
||||
$query.= ')';
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropIndex()
|
||||
|
||||
/**
|
||||
* drop existing index
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the index to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $table DROP INDEX $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$key_name = 'Key_name';
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes_all = $db->queryCol($query, 'text', $key_name);
|
||||
if (PEAR::isError($indexes_all)) {
|
||||
return $indexes_all;
|
||||
}
|
||||
|
||||
$indexes = array_unique($indexes_all);
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$indexes = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $indexes);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
$seqcol_name = $db->options['seqcol_name'];
|
||||
$result = $this->_verifyTableType($db->options['default_table_type']);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$res = $db->query("CREATE TABLE $sequence_name".
|
||||
"($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))".
|
||||
(strlen($db->options['default_table_type']) ? ' TYPE='.$db->options['default_table_type'] : '')
|
||||
);
|
||||
|
||||
if (PEAR::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
if ($start == 1) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$res = $db->query("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')');
|
||||
if (!PEAR::isError($res)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// Handle error
|
||||
$result = $db->query("DROP TABLE $sequence_name");
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not drop inconsistent sequence table ('.
|
||||
$result->getMessage().' ('.$result->getUserinfo().'))');
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not create sequence table ('.
|
||||
$res->getMessage().' ('.$res->getUserinfo().'))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP TABLE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table_names = $db->queryCol('SHOW TABLES');
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i])) {
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
}
|
||||
|
||||
return $sequences;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
@ -1,673 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 oci8 driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Manager_oci8 extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param object $db database object that is extended by this class
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$username = $db->options['database_name_prefix'].$name;
|
||||
$password = $db->dsn['password'] ? $db->dsn['password'] : $name;
|
||||
$tablespace = $db->options['default_tablespace']
|
||||
? ' DEFAULT TABLESPACE '.$db->options['default_tablespace'] : '';
|
||||
|
||||
$query = 'CREATE USER '.$username.' IDENTIFIED BY '.$password.$tablespace;
|
||||
$result = $db->standaloneQuery($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE TO '.$username;
|
||||
$result = $db->standaloneQuery($query);
|
||||
if (PEAR::isError($result)) {
|
||||
$query = 'DROP USER '.$username.' CASCADE';
|
||||
$result2 = $db->standaloneQuery($query);
|
||||
if (PEAR::isError($result2)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createDatabase: could not setup the database user ('.$result->getUserinfo().
|
||||
') and then could drop its records ('.$result2->getUserinfo().')');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param object $db database object that is extended by this class
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$username = $db->options['database_name_prefix'].$name;
|
||||
return $db->standaloneQuery('DROP USER '.$username.' CASCADE');
|
||||
}
|
||||
|
||||
function _makeAutoincrement($name, $table, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$index_name = $table . '_autoincrement_pk';
|
||||
$definition = array(
|
||||
'primary' => true,
|
||||
'fields' => array($name),
|
||||
);
|
||||
$result = $db->manager->createIndex($table, $index_name, $definition);
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_makeAutoincrement: primary key for autoincrement PK could not be created');
|
||||
}
|
||||
|
||||
$result = $db->manager->createSequence($table, $start);
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_makeAutoincrement: sequence for autoincrement PK could not be created');
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($table);
|
||||
$trigger_name = $table . '_autoincrement_pk';
|
||||
$trigger_sql = "CREATE TRIGGER $trigger_name BEFORE INSERT ON $table";
|
||||
$trigger_sql.= " FOR EACH ROW BEGIN IF (:new.$name IS NULL) THEN SELECT ";
|
||||
$trigger_sql.= "$sequence_name.NEXTVAL INTO :new.$name FROM DUAL; END IF; END;";
|
||||
|
||||
return $db->query($trigger_sql);
|
||||
}
|
||||
|
||||
function _dropAutoincrement($name, $table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->manager->dropSequence($table);
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'_dropAutoincrement: sequence for autoincrement PK could not be dropped');
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($table);
|
||||
$trigger_name = $table . '_autoincrement_pk';
|
||||
$trigger_sql = 'DROP TRIGGER ' . $trigger_name;
|
||||
|
||||
return $db->query($trigger_sql);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createTable()
|
||||
|
||||
/**
|
||||
* create a new table
|
||||
*
|
||||
* @param string $name Name of the database that should be created
|
||||
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||
* The indexes of the array entries are the names of the fields of the table an
|
||||
* the array entry values are associative arrays like those that are meant to be
|
||||
* passed with the field definitions to get[Type]Declaration() functions.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
*
|
||||
* 'id' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* 'notnull' => 1
|
||||
* 'default' => 0
|
||||
* ),
|
||||
* 'name' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* ),
|
||||
* 'password' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 12
|
||||
* )
|
||||
* );
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createTable($name, $fields)
|
||||
{
|
||||
$result = parent::createTable($name, $fields);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
foreach($fields as $field_name => $field) {
|
||||
if (array_key_exists('autoincrement', $field) && $field['autoincrement']) {
|
||||
return $this->_makeAutoincrement($field_name, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param object $db database object that is extended by this class
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'name':
|
||||
break;
|
||||
case 'rename':
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
$query = ' DROP (';
|
||||
$fields = $changes['remove'];
|
||||
$query.= implode(', ', array_keys($fields));
|
||||
$query.= ')';
|
||||
if (PEAR::isError($result = $db->query("ALTER TABLE $name $query"))) {
|
||||
return $result;
|
||||
}
|
||||
$query = '';
|
||||
}
|
||||
|
||||
$query = (array_key_exists('name', $changes) ? 'RENAME TO '.$changes['name'] : '');
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
$query.= ' ADD (' . $type_declaration . ')';
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
$query.= "MODIFY ($field_name " . $db->getDeclaration($field['type'], $field_name, $field).')';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->options['database_name_prefix']) {
|
||||
$query = 'SELECT SUBSTR(username, '
|
||||
.(strlen($db->options['database_name_prefix'])+1)
|
||||
.") FROM sys.dba_users WHERE username LIKE '"
|
||||
.$db->options['database_name_prefix']."%'";
|
||||
} else {
|
||||
$query = 'SELECT username FROM sys.dba_users';
|
||||
}
|
||||
$result = $db->standaloneQuery($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$databases = $result->fetchCol();
|
||||
if (PEAR::isError($databases)) {
|
||||
return $databases;
|
||||
}
|
||||
// is it legit to force this to lowercase?
|
||||
$databases = array_keys(array_change_key_case(array_flip($databases), $db->options['field_case']));
|
||||
$result->free();
|
||||
return $databases;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT username FROM sys.all_users';
|
||||
$users = $db->queryCol($query);
|
||||
if (PEAR::isError($users)) {
|
||||
return $users;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$users = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $users);
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list all views in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listViews()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT view_name FROM sys.user_views';
|
||||
$views = $db->queryCol($query);
|
||||
if (PEAR::isError($views)) {
|
||||
return $views;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$views = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $views);
|
||||
}
|
||||
return $views;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listFunctions()
|
||||
|
||||
/**
|
||||
* list all functions in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listFunctions()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT name FROM sys.user_source WHERE line = 1 AND type = 'FUNCTION'";
|
||||
$functions = $db->queryCol($query);
|
||||
if (PEAR::isError($functions)) {
|
||||
return $functions;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$functions = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $functions);
|
||||
}
|
||||
return $functions;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT table_name FROM sys.user_tables';
|
||||
return $db->queryCol($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$table = strtoupper($table);
|
||||
$query = "SELECT column_name FROM user_tab_columns WHERE table_name='$table' ORDER BY column_id";
|
||||
$fields = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$fields = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $fields);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if (array_key_exists('primary', $definition) && $definition['primary']) {
|
||||
$query = "ALTER TABLE $table ADD CONSTRAINT $name PRIMARY KEY (";
|
||||
} else {
|
||||
$query = 'CREATE';
|
||||
if (array_key_exists('unique', $definition) && $definition['unique']) {
|
||||
$query.= ' UNIQUE';
|
||||
}
|
||||
$query .= " INDEX $name ON $table (";
|
||||
}
|
||||
$query .= implode(', ', array_keys($definition['fields'])) . ')';
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param object $db database object that is extended by this class
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("CREATE SEQUENCE $sequence_name START WITH $start INCREMENT BY 1".
|
||||
($start < 1 ? " MINVALUE $start" : ''));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param object $db database object that is extended by this class
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP SEQUENCE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT sequence_name FROM sys.user_sequences";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i]))
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$sequences = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $sequences);
|
||||
}
|
||||
return $sequences;
|
||||
}}
|
||||
?>
|
@ -1,570 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->standaloneQuery("CREATE DATABASE $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->standaloneQuery("DROP DATABASE $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the Metabase parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the Metabase parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'gender' => array(
|
||||
* 'default' => 'M',
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'name':
|
||||
break;
|
||||
case 'rename':
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'alterTable: change type "'.$change_name.'\" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = (array_key_exists('name', $changes) ? 'RENAME TO '.$changes['name'] : '');
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$type_declaration = $db->getDeclaration($field['type'], $field_name, $field);
|
||||
if (PEAR::isError($type_declaration)) {
|
||||
return $err;
|
||||
}
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $type_declaration;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
// missing support to change DEFAULT and NULLability
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$db->loadModule('Datatype');
|
||||
$query.= "ALTER $field_name TYPE ".$db->datatype->getTypeDeclaration($field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
return $db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->standaloneQuery('SELECT datname FROM pg_database');
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$col = $result->fetchCol();
|
||||
$result->free();
|
||||
return $col;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->standaloneQuery('SELECT usename FROM pg_user');
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$col = $result->fetchCol();
|
||||
$result->free();
|
||||
return $col;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list the views in the database
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listViews()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT viewname FROM pg_views';
|
||||
return $db->queryCol($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listFunctions()
|
||||
|
||||
/**
|
||||
* list all functions in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listFunctions()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
proname
|
||||
FROM
|
||||
pg_proc pr,
|
||||
pg_type tp
|
||||
WHERE
|
||||
tp.oid = pr.prorettype
|
||||
AND pr.proisagg = FALSE
|
||||
AND tp.typname <> 'trigger'
|
||||
AND pr.pronamespace IN
|
||||
(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
|
||||
return $db->queryCol($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
// gratuitously stolen from PEAR DB _getSpecialQuery in pgsql.php
|
||||
$query = 'SELECT c.relname AS "Name"'
|
||||
. ' FROM pg_class c, pg_user u'
|
||||
. ' WHERE c.relowner = u.usesysid'
|
||||
. " AND c.relkind = 'r'"
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_views'
|
||||
. ' WHERE viewname = c.relname)'
|
||||
. " AND c.relname !~ '^(pg_|sql_)'"
|
||||
. ' UNION'
|
||||
. ' SELECT c.relname AS "Name"'
|
||||
. ' FROM pg_class c'
|
||||
. " WHERE c.relkind = 'r'"
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_views'
|
||||
. ' WHERE viewname = c.relname)'
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_user'
|
||||
. ' WHERE usesysid = c.relowner)'
|
||||
. " AND c.relname !~ '^pg_'";
|
||||
return $db->queryCol($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->query("SELECT * FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $result->getColumnNames();
|
||||
$result->free();
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
return array_flip($columns);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (array_key_exists('primary', $definition) && $definition['primary']) {
|
||||
$query = "ALTER TABLE $table ADD CONSTRAINT $name PRIMARY KEY (";
|
||||
} else {
|
||||
$query = 'CREATE';
|
||||
if (array_key_exists('unique', $definition) && $definition['unique']) {
|
||||
$query.= ' UNIQUE';
|
||||
}
|
||||
$query.= " INDEX $name ON $table (";
|
||||
}
|
||||
$query.= implode(', ', array_keys($definition['fields']));
|
||||
$query.= ')';
|
||||
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$subquery = "SELECT indexrelid FROM pg_index, pg_class";
|
||||
$subquery.= " WHERE (pg_class.relname='$table') AND (pg_class.oid=pg_index.indrelid)";
|
||||
return $db->queryCol("SELECT relname FROM pg_class WHERE oid IN ($subquery)");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("CREATE SEQUENCE $sequence_name INCREMENT 1".
|
||||
($start < 1 ? " MINVALUE $start" : '')." START $start");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP SEQUENCE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
**/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT relname FROM pg_class WHERE relkind = 'S' AND relnamespace IN";
|
||||
$query.= "(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i]))
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
return $sequences;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,375 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@backendmedia.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
*/
|
||||
class MDB2_Driver_Manager_sqlite extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$database_file = $db->_getDatabaseFile($name);
|
||||
if (file_exists($database_file)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createDatabase: database already exists');
|
||||
}
|
||||
$php_errormsg = '';
|
||||
$handle = @sqlite_open($database_file, $db->dsn['mode'], $php_errormsg);
|
||||
if (!$handle) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||
'createDatabase: '.(isset($php_errormsg) ? $php_errormsg : 'could not create the database file'));
|
||||
}
|
||||
@sqlite_close($handle);
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$database_file = $db->_getDatabaseFile($name);
|
||||
if (!@file_exists($database_file)) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_DROP, null, null,
|
||||
'dropDatabase: database does not exist');
|
||||
}
|
||||
$result = @unlink($database_file);
|
||||
if (!$result) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_DROP, null, null,
|
||||
'dropDatabase: '.(isset($php_errormsg) ? $php_errormsg : 'could not remove the database file'));
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'listDatabases: list databases is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->queryCol('SELECT DISTINCT USER FROM USER');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables()
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$tables = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if (!$this->_isSequenceName($table_names[$i]))
|
||||
$tables[] = $table_names[$i];
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a tables in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$query = "SELECT * FROM $table";
|
||||
$db->setLimit(1);
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $result->getColumnNames();
|
||||
$result->free();
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
return array_flip($columns);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createIndex()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of the table on which the index is to be created
|
||||
* @param string $name name of the index to be created
|
||||
* @param array $definition associative array that defines properties of the index to be created.
|
||||
* Currently, only one property named FIELDS is supported. This property
|
||||
* is also an associative with the names of the index fields as array
|
||||
* indexes. Each entry of this array is set to another type of associative
|
||||
* array that specifies properties of the index that are specific to
|
||||
* each field.
|
||||
*
|
||||
* Currently, only the sorting property is supported. It should be used
|
||||
* to define the sorting direction of the index. It may be set to either
|
||||
* ascending or descending.
|
||||
*
|
||||
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||
* drivers of those that do not support it ignore this property. Use the
|
||||
* function support() to determine whether the DBMS driver can manage indexes.
|
||||
|
||||
* Example
|
||||
* array(
|
||||
* 'fields' => array(
|
||||
* 'user_name' => array(
|
||||
* 'sorting' => 'ascending'
|
||||
* ),
|
||||
* 'last_login' => array()
|
||||
* )
|
||||
* )
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createIndex($table, $name, $definition)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$query = 'CREATE '.(isset($definition['unique']) ? 'UNIQUE' : '')." INDEX $name ON $table (";
|
||||
$skipped_first = false;
|
||||
foreach ($definition['fields'] as $field_name => $field) {
|
||||
if ($skipped_first) {
|
||||
$query .= ',';
|
||||
}
|
||||
$query .= $field_name;
|
||||
$skipped_first = true;
|
||||
}
|
||||
$query .= ')';
|
||||
return $db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropIndex()
|
||||
|
||||
/**
|
||||
* drop existing index
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the index to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->query("DROP INDEX $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$query = "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='$table' AND sql NOT NULL ORDER BY name";
|
||||
$indexes_all = $db->queryCol($query);
|
||||
if (PEAR::isError($indexes_all)) {
|
||||
return $indexes_all;
|
||||
}
|
||||
$found = $indexes = array();
|
||||
foreach ($indexes_all as $index => $index_name) {
|
||||
if ($indexes_all[$index] != 'PRIMARY' && !isset($found[$index_name])) {
|
||||
$indexes[] = $index_name;
|
||||
$found[$index_name] = true;
|
||||
}
|
||||
}
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
$seqcol_name = $db->options['seqcol_name'];
|
||||
$query = "CREATE TABLE $sequence_name ($seqcol_name INTEGER PRIMARY KEY DEFAULT 0 NOT NULL)";
|
||||
$res = $db->query($query);
|
||||
if (PEAR::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
if ($start == 1) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$res = $db->query("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')');
|
||||
if (!PEAR::isError($res)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
// Handle error
|
||||
$result = $db->query("DROP TABLE $sequence_name");
|
||||
if (PEAR::isError($result)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not drop inconsistent sequence table ('.
|
||||
$result->getMessage().' ('.$result->getUserinfo().'))');
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'createSequence: could not create sequence table ('.
|
||||
$res->getMessage().' ('.$res->getUserinfo().'))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$sequence_name = $db->getSequenceName($seq_name);
|
||||
return $db->query("DROP TABLE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences()
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$sequences = array();
|
||||
for ($i = 0, $j = count($table_names); $i < $j; ++$i) {
|
||||
if ($sqn = $this->_isSequenceName($table_names[$i]))
|
||||
$sequences[] = $sqn;
|
||||
}
|
||||
return $sequences;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 FrontBase driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Native_fbsql extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 InterbaseBase driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Native_ibase extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 MSSQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Native_mssql extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_mysql extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_mysqli extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 Oracle driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Native_oci8 extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
@ -1,80 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Native_pgsql extends MDB2_Module_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ deleteOID()
|
||||
|
||||
/**
|
||||
* delete an OID
|
||||
*
|
||||
* @param integer $OID
|
||||
* @return mixed MDB2_OK on success or MDB2 Error Object on failure
|
||||
* @access public
|
||||
*/
|
||||
function deleteOID($OID)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!@pg_lo_unlink($db->connection, $OID)) {
|
||||
return $db->raiseError();
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@backendmedia.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
*/
|
||||
class MDB2_Driver_Native_sqlite
|
||||
{
|
||||
var $db_index;
|
||||
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($db_index)
|
||||
{
|
||||
$this->db_index = $db_index;
|
||||
}
|
||||
|
||||
function MDB2_Driver_Native_sqlite($db_index)
|
||||
{
|
||||
$this->__construct($db_index);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getInsertID()
|
||||
|
||||
/**
|
||||
* get last insert ID
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function getInsertID()
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return @sqlite_last_insert_rowid($db->connection);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,284 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
*/
|
||||
|
||||
/**
|
||||
* These are constants for the tableInfo-function
|
||||
* they are bitwised or'ed. so if there are more constants to be defined
|
||||
* in the future, adjust MDB2_TABLEINFO_FULL accordingly
|
||||
*/
|
||||
|
||||
define('MDB2_TABLEINFO_ORDER', 1);
|
||||
define('MDB2_TABLEINFO_ORDERTABLE', 2);
|
||||
define('MDB2_TABLEINFO_FULL', 3);
|
||||
|
||||
/**
|
||||
* Base class for the schema reverse engineering module that is extended by each MDB2 driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_Common extends MDB2_Module_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $fields name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'getTableFieldDefinition: table field definition is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'getTableIndexDefinition: getting index definition is not supported');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSequenceDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a sequence into an array
|
||||
*
|
||||
* @param string $sequence name of sequence that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getSequenceDefinition($sequence)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$start = $db->currId($sequence);
|
||||
if (PEAR::isError($start)) {
|
||||
return $start;
|
||||
}
|
||||
if ($db->supports('current_id')) {
|
||||
$start++;
|
||||
} else {
|
||||
$db->warnings[] = 'database does not support getting current
|
||||
sequence value, the sequence value was incremented';
|
||||
}
|
||||
$definition = array();
|
||||
if ($start != 1) {
|
||||
$definition = array('start' => $start);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* The format of the resulting array depends on which <var>$mode</var>
|
||||
* you select. The sample output below is based on this query:
|
||||
* <pre>
|
||||
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
|
||||
* FROM tblFoo
|
||||
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
*
|
||||
* <kbd>null</kbd> (default)
|
||||
* <pre>
|
||||
* [0] => Array (
|
||||
* [table] => tblFoo
|
||||
* [name] => fldId
|
||||
* [type] => int
|
||||
* [len] => 11
|
||||
* [flags] => primary_key not_null
|
||||
* )
|
||||
* [1] => Array (
|
||||
* [table] => tblFoo
|
||||
* [name] => fldPhone
|
||||
* [type] => string
|
||||
* [len] => 20
|
||||
* [flags] =>
|
||||
* )
|
||||
* [2] => Array (
|
||||
* [table] => tblBar
|
||||
* [name] => fldId
|
||||
* [type] => int
|
||||
* [len] => 11
|
||||
* [flags] => primary_key not_null
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li><li>
|
||||
*
|
||||
* <kbd>MDB2_TABLEINFO_ORDER</kbd>
|
||||
*
|
||||
* <p>In addition to the information found in the default output,
|
||||
* a notation of the number of columns is provided by the
|
||||
* <samp>num_fields</samp> element while the <samp>order</samp>
|
||||
* element provides an array with the column names as the keys and
|
||||
* their location index number (corresponding to the keys in the
|
||||
* the default output) as the values.</p>
|
||||
*
|
||||
* <p>If a result set has identical field names, the last one is
|
||||
* used.</p>
|
||||
*
|
||||
* <pre>
|
||||
* [num_fields] => 3
|
||||
* [order] => Array (
|
||||
* [fldId] => 2
|
||||
* [fldTrans] => 1
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li><li>
|
||||
*
|
||||
* <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>
|
||||
*
|
||||
* <p>Similar to <kbd>MDB2_TABLEINFO_ORDER</kbd> but adds more
|
||||
* dimensions to the array in which the table names are keys and
|
||||
* the field names are sub-keys. This is helpful for queries that
|
||||
* join tables which have identical field names.</p>
|
||||
*
|
||||
* <pre>
|
||||
* [num_fields] => 3
|
||||
* [ordertable] => Array (
|
||||
* [tblFoo] => Array (
|
||||
* [fldId] => 0
|
||||
* [fldPhone] => 1
|
||||
* )
|
||||
* [tblBar] => Array (
|
||||
* [fldId] => 2
|
||||
* )
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* The <samp>flags</samp> element contains a space separated list
|
||||
* of extra information about the field. This data is inconsistent
|
||||
* between DBMS's due to the way each DBMS works.
|
||||
* + <samp>primary_key</samp>
|
||||
* + <samp>unique_key</samp>
|
||||
* + <samp>multiple_key</samp>
|
||||
* + <samp>not_null</samp>
|
||||
*
|
||||
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
|
||||
* elements if <var>$result</var> is a table name. The following DBMS's
|
||||
* provide full information from queries:
|
||||
* + fbsql
|
||||
* + mysql
|
||||
*
|
||||
* If the 'portability' option has <samp>MDB2_PORTABILITY_FIX_CASE</samp>
|
||||
* turned on, the names of tables and fields will be lower or upper cased.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode either unused or one of the tableInfo modes:
|
||||
* <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>,
|
||||
* <kbd>MDB2_TABLEINFO_ORDER</kbd> or
|
||||
* <kbd>MDB2_TABLEINFO_FULL</kbd> (which does both).
|
||||
* These are bitwise, so the first two can be
|
||||
* combined using <kbd>|</kbd>.
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'tableInfo: method not implemented');
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,157 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 FrontBase driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_fbsql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
|
||||
$connected = $db->connect();
|
||||
if (PEAR::isError($connected)) {
|
||||
return $connected;
|
||||
}
|
||||
$id = @fbsql_list_fields($db->database_name, $result, $db->connection);
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @fbsql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func(@fbsql_field_table($id, $i)),
|
||||
'name' => $case_func(@fbsql_field_name($id, $i)),
|
||||
'type' => @fbsql_field_type($id, $i),
|
||||
'len' => @fbsql_field_len($id, $i),
|
||||
'flags' => @fbsql_field_flags($id, $i),
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@fbsql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,238 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 InterbaseBase driver for the reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_ibase extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = $db->_doQuery("SELECT * FROM $result WHERE 1=0");
|
||||
if (PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @ibase_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$info = @ibase_field_info($id, $i);
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func($info['name']),
|
||||
'type' => $info['type'],
|
||||
'len' => $info['length'],
|
||||
'flags' => ($got_string)
|
||||
? $this->_ibaseFieldFlags($info['name'], $result) : '',
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@ibase_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _ibaseFieldFlags()
|
||||
|
||||
/**
|
||||
* Get the column's flags
|
||||
*
|
||||
* Supports "primary_key", "unique_key", "not_null", "default",
|
||||
* "computed" and "blob".
|
||||
*
|
||||
* @param string $field_name the name of the field
|
||||
* @param string $table_name the name of the table
|
||||
*
|
||||
* @return string the flags
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
function _ibaseFieldFlags($field_name, $table_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
|
||||
.' FROM RDB$INDEX_SEGMENTS I'
|
||||
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
|
||||
.' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\''
|
||||
.' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'';
|
||||
|
||||
$result = $db->_doQuery($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$flags = '';
|
||||
if ($obj = @ibase_fetch_object($result)) {
|
||||
@ibase_free_result($result);
|
||||
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') {
|
||||
$flags.= 'primary_key ';
|
||||
}
|
||||
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') {
|
||||
$flags.= 'unique_key ';
|
||||
}
|
||||
}
|
||||
|
||||
$query = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
|
||||
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,'
|
||||
.' F.RDB$FIELD_TYPE AS FTYPE,'
|
||||
.' F.RDB$COMPUTED_SOURCE AS CSOURCE'
|
||||
.' FROM RDB$RELATION_FIELDS R '
|
||||
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
|
||||
.' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''
|
||||
.' AND R.RDB$FIELD_NAME=\'' . $field_name . '\'';
|
||||
|
||||
$result = $db->_doQuery($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($obj = @ibase_fetch_object($result)) {
|
||||
@ibase_free_result($result);
|
||||
if (isset($obj->NFLAG)) {
|
||||
$flags.= 'not_null ';
|
||||
}
|
||||
if (isset($obj->DSOURCE)) {
|
||||
$flags.= 'default ';
|
||||
}
|
||||
if (isset($obj->CSOURCE)) {
|
||||
$flags.= 'computed ';
|
||||
}
|
||||
if (isset($obj->FTYPE) && $obj->FTYPE == 261) {
|
||||
$flags.= 'blob ';
|
||||
}
|
||||
}
|
||||
|
||||
return trim($flags);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,269 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MSSQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_mssql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = $db->_doQuery("SELECT TOP 0 * FROM [$result]");
|
||||
if (PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mssql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@mssql_field_name($id, $i)),
|
||||
'type' => @mssql_field_type($id, $i),
|
||||
'len' => @mssql_field_length($id, $i),
|
||||
// We only support flags for table
|
||||
'flags' => $got_string
|
||||
? $this->_mssql_field_flags($result, @mssql_field_name($id, $i)) : '',
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@mssql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mssql_field_flags()
|
||||
|
||||
/**
|
||||
* Get a column's flags
|
||||
*
|
||||
* Supports "not_null", "primary_key",
|
||||
* "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
|
||||
* "unique_key" (mssql unique index, unique check or primary_key) and
|
||||
* "multiple_key" (multikey index)
|
||||
*
|
||||
* mssql timestamp is NOT similar to the mysql timestamp so this is maybe
|
||||
* not useful at all - is the behaviour of mysql_field_flags that primary
|
||||
* keys are alway unique? is the interpretation of multiple_key correct?
|
||||
*
|
||||
* @param string $table the table name
|
||||
* @param string $column the field name
|
||||
*
|
||||
* @return string the flags
|
||||
*
|
||||
* @access protected
|
||||
* @author Joern Barthel <j_barthel@web.de>
|
||||
*/
|
||||
function _mssql_field_flags($table, $column)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
static $tableName = null;
|
||||
static $flags = array();
|
||||
|
||||
if ($table != $tableName) {
|
||||
|
||||
$flags = array();
|
||||
$tableName = $table;
|
||||
|
||||
// get unique and primary keys
|
||||
$res = $db->queryAll("EXEC SP_HELPINDEX[$table]", null, MDB2_FETCHMODE_ASSOC);
|
||||
|
||||
foreach ($res as $val) {
|
||||
$keys = explode(', ', $val['index_keys']);
|
||||
|
||||
if (sizeof($keys) > 1) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'multiple_key');
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($val['index_description'], 'primary key')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'primary_key');
|
||||
}
|
||||
} elseif (strpos($val['index_description'], 'unique')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'unique_key');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get auto_increment, not_null and timestamp
|
||||
$res = $db->queryAll("EXEC SP_COLUMNS[$table]", null, MDB2_FETCHMODE_ASSOC);
|
||||
|
||||
foreach ($res as $val) {
|
||||
$val = array_change_key_case($val, $db->options['field_case']);
|
||||
if ($val['nullable'] == '0') {
|
||||
$this->_add_flag($flags[$val['column_name']], 'not_null');
|
||||
}
|
||||
if (strpos($val['type_name'], 'identity')) {
|
||||
$this->_add_flag($flags[$val['column_name']], 'auto_increment');
|
||||
}
|
||||
if (strpos($val['type_name'], 'timestamp')) {
|
||||
$this->_add_flag($flags[$val['column_name']], 'timestamp');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($column, $flags)) {
|
||||
return(implode(' ', $flags[$column]));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _add_flag()
|
||||
|
||||
/**
|
||||
* Adds a string to the flags array if the flag is not yet in there
|
||||
* - if there is no flag present the array is created
|
||||
*
|
||||
* @param array &$array the reference to the flag-array
|
||||
* @param string $value the flag value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access protected
|
||||
* @author Joern Barthel <j_barthel@web.de>
|
||||
*/
|
||||
function _add_flag(&$array, $value)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
$array = array($value);
|
||||
} elseif (!in_array($value, $array)) {
|
||||
array_push($array, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,298 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype');
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $db->queryAll("SHOW COLUMNS FROM $table", null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
foreach ($columns as $column) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column['field'] = strtolower($column['field']);
|
||||
} else {
|
||||
$column['field'] = strtoupper($column['field']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['field']) {
|
||||
list($types, $length) = $db->datatype->mapNativeDatatype($column);
|
||||
$notnull = false;
|
||||
if (array_key_exists('null', $column) && $column['null'] != 'YES') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if (is_null($default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (array_key_exists('extra', $column) && $column['extra'] == 'auto_increment') {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$definition = array();
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = array(
|
||||
'type' => $type,
|
||||
'notnull' => $notnull,
|
||||
);
|
||||
if ($length > 0) {
|
||||
$definition[$key]['length'] = $length;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[$key]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[$key]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: it was not specified an existing table column');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
if (!($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE)
|
||||
|| $db->options['field_case'] != CASE_LOWER
|
||||
) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
$key_name = $row['key_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
if ($index_name == $key_name) {
|
||||
if ($row['key_name'] == 'PRIMARY') {
|
||||
$definition['primary'] = true;
|
||||
} elseif (!$row['non_unique']) {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (!array_key_exists('fields', $definition)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableIndexDefinition: it was not specified an existing table index');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$connected = $db->connect();
|
||||
if (PEAR::isError($connected)) {
|
||||
return $connected;
|
||||
}
|
||||
$id = @mysql_list_fields($db->database_name, $result, $db->connection);
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mysql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func(@mysql_field_table($id, $i)),
|
||||
'name' => $case_func(@mysql_field_name($id, $i)),
|
||||
'type' => @mysql_field_type($id, $i),
|
||||
'len' => @mysql_field_len($id, $i),
|
||||
'flags' => @mysql_field_flags($id, $i),
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@mysql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,368 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_mysqli extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
/**
|
||||
* Array for converting MYSQLI_*_FLAG constants to text values
|
||||
* @var array
|
||||
* @access public
|
||||
* @since Property available since Release 1.6.5
|
||||
*/
|
||||
var $flags = array(
|
||||
MYSQLI_NOT_NULL_FLAG => 'not_null',
|
||||
MYSQLI_PRI_KEY_FLAG => 'primary_key',
|
||||
MYSQLI_UNIQUE_KEY_FLAG => 'unique_key',
|
||||
MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key',
|
||||
MYSQLI_BLOB_FLAG => 'blob',
|
||||
MYSQLI_UNSIGNED_FLAG => 'unsigned',
|
||||
MYSQLI_ZEROFILL_FLAG => 'zerofill',
|
||||
MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment',
|
||||
MYSQLI_TIMESTAMP_FLAG => 'timestamp',
|
||||
MYSQLI_SET_FLAG => 'set',
|
||||
// MYSQLI_NUM_FLAG => 'numeric', // unnecessary
|
||||
// MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie
|
||||
MYSQLI_GROUP_FLAG => 'group_by'
|
||||
);
|
||||
|
||||
/**
|
||||
* Array for converting MYSQLI_TYPE_* constants to text values
|
||||
* @var array
|
||||
* @access public
|
||||
* @since Property available since Release 1.6.5
|
||||
*/
|
||||
var $types = array(
|
||||
MYSQLI_TYPE_DECIMAL => 'decimal',
|
||||
MYSQLI_TYPE_TINY => 'tinyint',
|
||||
MYSQLI_TYPE_SHORT => 'int',
|
||||
MYSQLI_TYPE_LONG => 'int',
|
||||
MYSQLI_TYPE_FLOAT => 'float',
|
||||
MYSQLI_TYPE_DOUBLE => 'double',
|
||||
// MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it
|
||||
MYSQLI_TYPE_TIMESTAMP => 'timestamp',
|
||||
MYSQLI_TYPE_LONGLONG => 'bigint',
|
||||
MYSQLI_TYPE_INT24 => 'mediumint',
|
||||
MYSQLI_TYPE_DATE => 'date',
|
||||
MYSQLI_TYPE_TIME => 'time',
|
||||
MYSQLI_TYPE_DATETIME => 'datetime',
|
||||
MYSQLI_TYPE_YEAR => 'year',
|
||||
MYSQLI_TYPE_NEWDATE => 'date',
|
||||
MYSQLI_TYPE_ENUM => 'enum',
|
||||
MYSQLI_TYPE_SET => 'set',
|
||||
MYSQLI_TYPE_TINY_BLOB => 'tinyblob',
|
||||
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
|
||||
MYSQLI_TYPE_LONG_BLOB => 'longblob',
|
||||
MYSQLI_TYPE_BLOB => 'blob',
|
||||
MYSQLI_TYPE_VAR_STRING => 'varchar',
|
||||
MYSQLI_TYPE_STRING => 'char',
|
||||
MYSQLI_TYPE_GEOMETRY => 'geometry',
|
||||
);
|
||||
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype');
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $db->queryAll("SHOW COLUMNS FROM $table", null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
foreach ($columns as $column) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column['field'] = strtolower($column['field']);
|
||||
} else {
|
||||
$column['field'] = strtoupper($column['field']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['field']) {
|
||||
list($types, $length) = $db->datatype->mapNativeDatatype($column);
|
||||
$notnull = false;
|
||||
if (array_key_exists('null', $column) && $column['null'] != 'YES') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if (is_null($default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (array_key_exists('extra', $column) && $column['extra'] == 'auto_increment') {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$definition = array();
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = array(
|
||||
'type' => $type,
|
||||
'notnull' => $notnull,
|
||||
);
|
||||
if ($length > 0) {
|
||||
$definition[$key]['length'] = $length;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[$key]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[$key]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: it was not specified an existing table column');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
if (!($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE)
|
||||
|| $db->options['field_case'] != CASE_LOWER
|
||||
) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
$key_name = $row['key_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
if ($index_name == $key_name) {
|
||||
if ($row['key_name'] == 'PRIMARY') {
|
||||
$definition['primary'] = true;
|
||||
} elseif (!$row['non_unique']) {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (!array_key_exists('fields', $definition)) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableIndexDefinition: it was not specified an existing table index');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = $db->_doQuery("SELECT * FROM $result LIMIT 0");
|
||||
if (PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_a($id, 'mysqli_result')) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mysqli_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$tmp = @mysqli_fetch_field($id);
|
||||
|
||||
$flags = '';
|
||||
foreach ($this->flags as $const => $means) {
|
||||
if ($tmp->flags & $const) {
|
||||
$flags.= $means . ' ';
|
||||
}
|
||||
}
|
||||
if ($tmp->def) {
|
||||
$flags.= 'default_' . rawurlencode($tmp->def);
|
||||
}
|
||||
$flags = trim($flags);
|
||||
|
||||
$res[$i] = array(
|
||||
'table' => $case_func($tmp->table),
|
||||
'name' => $case_func($tmp->name),
|
||||
'type' => isset($this->types[$tmp->type])
|
||||
? $this->types[$tmp->type]
|
||||
: 'unknown',
|
||||
'len' => $tmp->max_length,
|
||||
'flags' => $flags,
|
||||
);
|
||||
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@mysqli_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,178 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 Oracle driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@dybnet.de>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_oci8 extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* NOTE: flags won't contain index information.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$res = array();
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$result = strtoupper($result);
|
||||
$query = 'SELECT column_name, data_type, data_length, '
|
||||
. 'nullable '
|
||||
. 'FROM user_tab_columns '
|
||||
. "WHERE table_name='$result' ORDER BY column_id";
|
||||
|
||||
$stmt = $db->_doQuery($query);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
while (@OCIFetch($stmt)) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func($result),
|
||||
'name' => $case_func(@OCIResult($stmt, 1)),
|
||||
'type' => @OCIResult($stmt, 2),
|
||||
'len' => @OCIResult($stmt, 3),
|
||||
'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '',
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $i;
|
||||
}
|
||||
@OCIFreeStatement($stmt);
|
||||
|
||||
} else {
|
||||
if (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$result = $result->getResource();
|
||||
}
|
||||
|
||||
$res = array();
|
||||
|
||||
if ($result === $db->last_stmt) {
|
||||
$count = @OCINumCols($result);
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => '',
|
||||
'name' => $case_func(@OCIColumnName($result, $i+1)),
|
||||
'type' => @OCIColumnType($result, $i+1),
|
||||
'len' => @OCIColumnSize($result, $i+1),
|
||||
'flags' => '',
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,356 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_pgsql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype');
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$column = $db->queryRow("SELECT
|
||||
attnum,attname,typname,attlen,attnotnull,
|
||||
atttypmod,usename,usesysid,pg_class.oid,relpages,
|
||||
reltuples,relhaspkey,relhasrules,relacl,adsrc
|
||||
FROM pg_class,pg_user,pg_type,
|
||||
pg_attribute left outer join pg_attrdef on
|
||||
pg_attribute.attrelid=pg_attrdef.adrelid
|
||||
WHERE (pg_class.relname='$table')
|
||||
and (pg_class.oid=pg_attribute.attrelid)
|
||||
and (pg_class.relowner=pg_user.usesysid)
|
||||
and (pg_attribute.atttypid=pg_type.oid)
|
||||
and attnum > 0
|
||||
and attname = '$field_name'
|
||||
ORDER BY attnum
|
||||
", null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($column)) {
|
||||
return $column;
|
||||
}
|
||||
|
||||
list($types, $length) = $db->datatype->mapNativeDatatype($column);
|
||||
$notnull = false;
|
||||
if (array_key_exists('attnotnull', $column) && $column['attnotnull'] == 't') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = false;
|
||||
// todo .. check how default look like
|
||||
if (!preg_match("/nextval\('([^']+)'/", $column['adsrc'])
|
||||
&& strlen($column['adsrc']) > 2
|
||||
) {
|
||||
$default = substr($column['adsrc'], 1, -1);
|
||||
if (is_null($default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (preg_match("/nextval\('([^']+)'/", $column['adsrc'], $nextvals)) {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$definition = array();
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = array(
|
||||
'type' => $type,
|
||||
'notnull' => $notnull,
|
||||
);
|
||||
if ($length > 0) {
|
||||
$definition[$key]['length'] = $length;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[$key]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[$key]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
/**
|
||||
* get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM pg_index, pg_class
|
||||
WHERE (pg_class.relname='$index_name') AND (pg_class.oid=pg_index.indexrelid)";
|
||||
$row = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if ($row['relname'] != $index_name) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableIndexDefinition: it was not specified an existing table index');
|
||||
}
|
||||
|
||||
$db->loadModule('Manager');
|
||||
$columns = $db->manager->listTableFields($table);
|
||||
|
||||
$definition = array();
|
||||
if ($row['indisunique'] == 't') {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array('sorting' => 'ascending');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = $db->_doQuery("SELECT * FROM $result LIMIT 0");
|
||||
if (PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
$got_string = true;
|
||||
} elseif (MDB2::isResultCommon($result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->getResource();
|
||||
$got_string = false;
|
||||
} else {
|
||||
/*
|
||||
* Probably received a result resource identifier.
|
||||
* Copy it.
|
||||
* Deprecated. Here for compatibility only.
|
||||
*/
|
||||
$id = $result;
|
||||
$got_string = false;
|
||||
}
|
||||
|
||||
if (!is_resource($id)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @pg_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@pg_field_name($id, $i)),
|
||||
'type' => @pg_field_type($id, $i),
|
||||
'len' => @pg_field_size($id, $i),
|
||||
'flags' => $got_string
|
||||
? $this->_pgFieldFlags($id, $i, $result)
|
||||
: '',
|
||||
);
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// free the result only if we were called on a table
|
||||
if ($got_string) {
|
||||
@pg_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _pgFieldFlags()
|
||||
|
||||
/**
|
||||
* Get a column's flags
|
||||
*
|
||||
* Supports "not_null", "default_value", "primary_key", "unique_key"
|
||||
* and "multiple_key". The default value is passed through
|
||||
* rawurlencode() in case there are spaces in it.
|
||||
*
|
||||
* @param int $resource the PostgreSQL result identifier
|
||||
* @param int $num_field the field number
|
||||
*
|
||||
* @return string the flags
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
function _pgFieldFlags($resource, $num_field, $table_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$field_name = @pg_field_name($resource, $num_field);
|
||||
|
||||
$result = @pg_query($db->connection, "SELECT f.attnotnull, f.atthasdef
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ
|
||||
WHERE tab.relname = typ.typname
|
||||
AND typ.typrelid = f.attrelid
|
||||
AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name'");
|
||||
if (@pg_num_rows($result) > 0) {
|
||||
$row = @pg_fetch_row($result, 0);
|
||||
$flags = ($row[0] == 't') ? 'not_null ' : '';
|
||||
|
||||
if ($row[1] == 't') {
|
||||
$result = @pg_query($db->connection, "SELECT a.adsrc
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
|
||||
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
|
||||
AND f.attrelid = a.adrelid AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name' AND f.attnum = a.adnum");
|
||||
$row = @pg_fetch_row($result, 0);
|
||||
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]);
|
||||
$flags.= 'default_' . rawurlencode($num) . ' ';
|
||||
}
|
||||
} else {
|
||||
$flags = '';
|
||||
}
|
||||
$result = @pg_query($db->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
|
||||
WHERE tab.relname = typ.typname
|
||||
AND typ.typrelid = f.attrelid
|
||||
AND f.attrelid = i.indrelid
|
||||
AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name'");
|
||||
$count = @pg_num_rows($result);
|
||||
|
||||
for ($i = 0; $i < $count ; $i++) {
|
||||
$row = @pg_fetch_row($result, $i);
|
||||
$keys = explode(' ', $row[2]);
|
||||
|
||||
if (in_array($num_field + 1, $keys)) {
|
||||
$flags.= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : '';
|
||||
$flags.= ($row[1] == 't') ? 'primary_key ' : '';
|
||||
if (count($keys) > 1)
|
||||
$flags.= 'multiple_key ';
|
||||
}
|
||||
}
|
||||
|
||||
return trim($flags);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,308 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@backendmedia.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQlite driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_sqlite extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
|
||||
function _getTableColumns($query)
|
||||
{
|
||||
$start_pos = strpos($query, '(');
|
||||
$end_pos = strrpos($query, ')');
|
||||
$column_def = substr($query, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_sql = split(',', $column_def);
|
||||
$columns = array();
|
||||
$count = count($column_sql);
|
||||
if ($count == 0) {
|
||||
return $db->raiseError('unexpected empty table column definition list');
|
||||
}
|
||||
$regexp = '/^([^ ]+) (CHAR|VARCHAR|VARCHAR2|TEXT|INT|INTEGER|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( PRIMARY)?( \(([1-9][0-9]*)(,([1-9][0-9]*))?\))?( DEFAULT (\'[^\']*\'|[^ ]+))?( NOT NULL)?$/i';
|
||||
for ($i=0, $j=0; $i<$count; ++$i) {
|
||||
if (!preg_match($regexp, $column_sql[$i], $matches)) {
|
||||
return $db->raiseError('unexpected table column SQL definition');
|
||||
}
|
||||
$columns[$j]['name'] = $matches[1];
|
||||
$columns[$j]['type'] = strtolower($matches[2]);
|
||||
if (isset($matches[5]) && strlen($matches[5])) {
|
||||
$columns[$j]['length'] = $matches[5];
|
||||
}
|
||||
if (isset($matches[7]) && strlen($matches[7])) {
|
||||
$columns[$j]['decimal'] = $matches[7];
|
||||
}
|
||||
if (isset($matches[9]) && strlen($matches[9])) {
|
||||
$default = $matches[9];
|
||||
if (strlen($default) && $default[0]=="'") {
|
||||
$default = str_replace("''", "'", substr($default, 1, strlen($default)-2));
|
||||
}
|
||||
$columns[$j]['default'] = $default;
|
||||
}
|
||||
if (isset($matches[10]) && strlen($matches[10])) {
|
||||
$columns[$j]['notnull'] = true;
|
||||
}
|
||||
++$j;
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field_name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$result = $db->loadModule('Datatype');
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND name='$table'";
|
||||
$query = $db->queryOne($query);
|
||||
if (PEAR::isError($query)) {
|
||||
return $query;
|
||||
}
|
||||
if (PEAR::isError($columns = $this->_getTableColumns($query))) {
|
||||
return $columns;
|
||||
}
|
||||
foreach ($columns as $column) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
|
||||
$column['name'] = strtolower($column['name']);
|
||||
} else {
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
}
|
||||
if ($field_name == $column['name']) {
|
||||
list($types, $length) = $db->datatype->mapNativeDatatype($column);
|
||||
unset($notnull);
|
||||
if (isset($column['null']) && $column['null'] != 'YES') {
|
||||
$notnull = true;
|
||||
}
|
||||
unset($default);
|
||||
if (isset($column['default'])) {
|
||||
$default = $column['default'];
|
||||
}
|
||||
$definition = array();
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[0][$key] = array('type' => $type);
|
||||
if (isset($notnull)) {
|
||||
$definition[0][$key]['notnull'] = true;
|
||||
}
|
||||
if (isset($default)) {
|
||||
$definition[0][$key]['default'] = $default;
|
||||
}
|
||||
if (isset($length)) {
|
||||
$definition[0][$key]['length'] = $length;
|
||||
}
|
||||
}
|
||||
// todo .. handle auto_inrement and primary keys
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableFieldDefinition: it was not specified an existing table column');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if ($index_name == 'PRIMARY') {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableIndexDefinition: PRIMARY is an hidden index');
|
||||
}
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND name='$index_name' AND tbl_name='$table' AND sql NOT NULL ORDER BY name";
|
||||
$result = $db->query($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$columns = $result->getColumnNames();
|
||||
$column = 'sql';
|
||||
if (!isset($columns[$column])) {
|
||||
$result->free();
|
||||
return $db->raiseError('getTableIndexDefinition: show index does not return the table creation sql');
|
||||
}
|
||||
|
||||
$query = strtolower($result->fetchOne());
|
||||
$unique = strstr($query, ' unique ');
|
||||
$key_name = $index_name;
|
||||
$start_pos = strpos($query, '(');
|
||||
$end_pos = strrpos($query, ')');
|
||||
$column_names = substr($query, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_names = split(',', $column_names);
|
||||
|
||||
$definition = array();
|
||||
if ($unique) {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$count = count($column_names);
|
||||
for ($i=0; $i<$count; ++$i) {
|
||||
$column_name = strtok($column_names[$i]," ");
|
||||
$collation = strtok(" ");
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (!empty($collation)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($collation=='ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
|
||||
$result->free();
|
||||
if (!isset($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR, null, null,
|
||||
'getTableIndexDefinition: it was not specified an existing table index');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table
|
||||
*
|
||||
* @param string $result a string containing the name of a table
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = $db->queryAll("PRAGMA table_info('$result');", null, MDB2_FETCHMODE_ASSOC);
|
||||
$got_string = true;
|
||||
} else {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE, null, null,
|
||||
'This DBMS can not obtain tableInfo' .
|
||||
' from result sets');
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = count($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (strpos($id[$i]['type'], '(') !== false) {
|
||||
$bits = explode('(', $id[$i]['type']);
|
||||
$type = $bits[0];
|
||||
$len = rtrim($bits[1],')');
|
||||
} else {
|
||||
$type = $id[$i]['type'];
|
||||
$len = 0;
|
||||
}
|
||||
|
||||
$flags = '';
|
||||
if ($id[$i]['pk']) {
|
||||
$flags .= 'primary_key ';
|
||||
}
|
||||
if ($id[$i]['notnull']) {
|
||||
$flags .= 'not_null ';
|
||||
}
|
||||
if ($id[$i]['dflt_value'] !== null) {
|
||||
$flags .= 'default_' . rawurlencode($id[$i]['dflt_value']);
|
||||
}
|
||||
$flags = trim($flags);
|
||||
|
||||
$res[$i] = array(
|
||||
'table' => $case_func($result),
|
||||
'name' => $case_func($id[$i]['name']),
|
||||
'type' => $type,
|
||||
'len' => $len,
|
||||
'flags' => $flags,
|
||||
);
|
||||
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,695 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 FrontBase driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Frank M. Kromann <frank@kromann.info>
|
||||
*/
|
||||
class MDB2_Driver_fbsql extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "'";
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'fbsql';
|
||||
$this->dbsyntax = 'fbsql';
|
||||
|
||||
$this->supported['sequences'] = 'emulated';
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = true;
|
||||
$this->supported['transactions'] = true;
|
||||
$this->supported['summary_functions'] = true;
|
||||
$this->supported['order_by_text'] = true;
|
||||
$this->supported['current_id'] = 'emulated';
|
||||
$this->supported['limit_queries'] = 'emulated';
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] ='emulated';
|
||||
$this->supported['sub_selects'] = true;
|
||||
$this->supported['auto_increment'] = false; // not implemented
|
||||
$this->supported['primary_key'] = false; // not implemented
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorInfo()
|
||||
|
||||
/**
|
||||
* This method is used to collect information about an error
|
||||
*
|
||||
* @param integer $error
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function errorInfo($error = null)
|
||||
{
|
||||
if ($this->connection) {
|
||||
$native_code = @fbsql_errno($this->connection);
|
||||
$native_msg = @fbsql_error($this->connection);
|
||||
} else {
|
||||
$native_code = @fbsql_errno();
|
||||
$native_msg = @fbsql_error();
|
||||
}
|
||||
if (is_null($error)) {
|
||||
static $ecode_map;
|
||||
if (empty($ecode_map)) {
|
||||
$ecode_map = array(
|
||||
22 => MDB2_ERROR_SYNTAX,
|
||||
85 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
108 => MDB2_ERROR_SYNTAX,
|
||||
116 => MDB2_ERROR_NOSUCHTABLE,
|
||||
124 => MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||
215 => MDB2_ERROR_NOSUCHFIELD,
|
||||
217 => MDB2_ERROR_INVALID_NUMBER,
|
||||
226 => MDB2_ERROR_NOSUCHFIELD,
|
||||
231 => MDB2_ERROR_INVALID,
|
||||
239 => MDB2_ERROR_TRUNCATED,
|
||||
251 => MDB2_ERROR_SYNTAX,
|
||||
266 => MDB2_ERROR_NOT_FOUND,
|
||||
357 => MDB2_ERROR_CONSTRAINT_NOT_NULL,
|
||||
358 => MDB2_ERROR_CONSTRAINT,
|
||||
360 => MDB2_ERROR_CONSTRAINT,
|
||||
361 => MDB2_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
if (isset($ecode_map[$native_code])) {
|
||||
$error = $ecode_map[$native_code];
|
||||
}
|
||||
}
|
||||
return array($error, $native_code, $native_msg);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ beginTransaction()
|
||||
|
||||
/**
|
||||
* Start a transaction.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
$this->debug('starting transaction', 'beginTransaction');
|
||||
if ($this->in_transaction) {
|
||||
return MDB2_OK; //nothing to do
|
||||
}
|
||||
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||
$this->destructor_registered = true;
|
||||
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||
}
|
||||
$result = $this->_doQuery('SET COMMIT FALSE;', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit the database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$this->debug('commit transaction', 'commit');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'commit: transaction changes are being auto commited');
|
||||
}
|
||||
$result = $this->_doQuery('COMMIT;', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->_doQuery('SET COMMIT TRUE;', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$this->debug('rolling back transaction', 'rollback');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('ROLLBACK;', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->_doQuery('SET COMMIT TRUE;', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return true on success, MDB2 Error Object on failure
|
||||
**/
|
||||
function connect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||
&& $this->opened_persistent == $this->options['persistent']
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$this->disconnect(false);
|
||||
}
|
||||
|
||||
if (!PEAR::loadExtension($this->phptype)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||
}
|
||||
|
||||
$params = array(
|
||||
$this->dsn['hostspec'] ? $this->dsn['hostspec'] : 'localhost',
|
||||
$this->dsn['username'] ? $this->dsn['username'] : null,
|
||||
$this->dsn['password'] ? $this->dsn['password'] : null,
|
||||
);
|
||||
|
||||
$connect_function = $this->options['persistent'] ? 'fbsql_pconnect' : 'fbsql_connect';
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
$php_errormsg = '';
|
||||
$connection = @call_user_func_array($connect_function, $params);
|
||||
@ini_restore('track_errors');
|
||||
if ($connection <= 0) {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
|
||||
$this->connection = $connection;
|
||||
$this->connected_dsn = $this->dsn;
|
||||
$this->connected_database_name = '';
|
||||
$this->opened_persistent = $this->options['persistent'];
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect($force = true)
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (!$this->opened_persistent || $force) {
|
||||
@fbsql_close($this->connection);
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->options['disable_query']) {
|
||||
if ($isManip) {
|
||||
return 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($connection)) {
|
||||
$err = $this->connect();
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$connection = $this->connection;
|
||||
}
|
||||
if (is_null($database_name)) {
|
||||
$database_name = $this->database_name;
|
||||
}
|
||||
|
||||
if ($database_name) {
|
||||
if ($database_name != $this->connected_database_name) {
|
||||
if (!@fbsql_select_db($database_name, $connection)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
$this->connected_database_name = $database_name;
|
||||
}
|
||||
}
|
||||
|
||||
$result = @fbsql_query($query, $connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return @fbsql_affected_rows($connection);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @return the new (modified) query
|
||||
* @access protected
|
||||
*/
|
||||
function _modifyQuery($query, $isManip, $limit, $offset)
|
||||
{
|
||||
if ($limit > 0) {
|
||||
if ($isManip) {
|
||||
return preg_replace('/^([\s(])*SELECT(?!\s*TOP\s*\()/i',
|
||||
"\\1SELECT TOP($limit)", $query);
|
||||
} else {
|
||||
return preg_replace('/([\s(])*SELECT(?!\s*TOP\s*\()/i',
|
||||
"\\1SELECT TOP($offset,$limit)", $query);
|
||||
}
|
||||
}
|
||||
// Add ; to the end of the query. This is required by FrontBase
|
||||
return $query.';';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function nextID($seq_name, $ondemand = true)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "INSERT INTO $sequence_name (".$this->options['seqcol_name'].") VALUES (NULL);";
|
||||
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = $this->_doQuery($query, true);
|
||||
$this->popExpect();
|
||||
if (PEAR::isError($result)) {
|
||||
if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||
$this->loadModule('Manager');
|
||||
// Since we are creating the sequence on demand
|
||||
// we know the first id = 1 so initialize the
|
||||
// sequence at 2
|
||||
$result = $this->manager->createSequence($seq_name, 2);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'nextID: on demand sequence '.$seq_name.' could not be created');
|
||||
} else {
|
||||
// First ID of a newly created sequence is 1
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
$value = $this->queryOne("SELECT UNIQUE FROM $sequence_name", 'integer');
|
||||
if (is_numeric($value)) {
|
||||
$query = "DELETE FROM $sequence_name WHERE ".$this->options['seqcol_name']." < $value;";
|
||||
$result = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ lastInsertID()
|
||||
|
||||
/**
|
||||
* returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed $id value as returned by getBeforeId()
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function lastInsertID($table = null, $field = null)
|
||||
{
|
||||
$value = @fbsql_insert_id($this->connection);
|
||||
if (!$value) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ currID()
|
||||
|
||||
/**
|
||||
* returns the current id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function currID($seq_name)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "SELECT MAX(".$this->options['seqcol_name'].") FROM $sequence_name";
|
||||
return $this->queryOne($query, 'integer');
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Result_fbsql extends MDB2_Result_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$row = @fbsql_fetch_assoc($this->result);
|
||||
if (is_array($row)
|
||||
&& $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
) {
|
||||
$row = array_change_key_case($row, $this->db->options['field_case']);
|
||||
}
|
||||
} else {
|
||||
$row = @fbsql_fetch_row($this->result);
|
||||
}
|
||||
if (!$row) {
|
||||
if (is_null($this->result)) {
|
||||
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
return $err;
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||
$this->db->_fixResultArrayValues($row, MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||
}
|
||||
if (!empty($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (!empty($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
$columns = array();
|
||||
$numcols = $this->numCols();
|
||||
if (PEAR::isError($numcols)) {
|
||||
return $numcols;
|
||||
}
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @fbsql_field_name($this->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
* @access public
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
$cols = @fbsql_num_fields($this->result);
|
||||
if (is_null($cols)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal result pointer to the next available result
|
||||
* Currently not supported
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
* @access public
|
||||
*/
|
||||
function nextResult()
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'nextResult: resultset has already been freed');
|
||||
}
|
||||
return @fbsql_next_result($this->result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return boolean true on success, false if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$free = @fbsql_free_result($this->result);
|
||||
if (!$free) {
|
||||
if (is_null($this->result)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
$this->result = null;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_fbsql extends MDB2_Result_fbsql
|
||||
{
|
||||
// }}}
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if ($this->rownum != ($rownum - 1) && !@fbsql_data_seek($this->result, $rownum)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
$rows = @fbsql_num_rows($this->result);
|
||||
if (is_null($rows)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Statement_fbsql extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
@ -1,766 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Frank M. Kromann <frank@kromann.info> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// {{{ Class MDB2_Driver_mssql
|
||||
/**
|
||||
* MDB2 MSSQL Server driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Frank M. Kromann <frank@kromann.info>
|
||||
*/
|
||||
class MDB2_Driver_mssql extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "'";
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'mssql';
|
||||
$this->dbsyntax = 'mssql';
|
||||
|
||||
$this->supported['sequences'] = 'emulated';
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = true;
|
||||
$this->supported['transactions'] = true;
|
||||
$this->supported['summary_functions'] = true;
|
||||
$this->supported['order_by_text'] = true;
|
||||
$this->supported['current_id'] = 'emulated';
|
||||
$this->supported['limit_queries'] = 'emulated';
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] = 'emulated';
|
||||
$this->supported['sub_selects'] = true;
|
||||
$this->supported['auto_increment'] = true;
|
||||
$this->supported['primary_key'] = true;
|
||||
|
||||
$this->options['database_device'] = false;
|
||||
$this->options['database_size'] = false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorInfo()
|
||||
|
||||
/**
|
||||
* This method is used to collect information about an error
|
||||
*
|
||||
* @param integer $error
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function errorInfo($error = null)
|
||||
{
|
||||
$native_code = null;
|
||||
if ($this->connection) {
|
||||
$result = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
|
||||
if ($result) {
|
||||
$native_code = @mssql_result($result, 0, 0);
|
||||
@mssql_free_result($result);
|
||||
}
|
||||
}
|
||||
$native_msg = @mssql_get_last_message();
|
||||
if (is_null($error)) {
|
||||
static $ecode_map;
|
||||
if (empty($ecode_map)) {
|
||||
$ecode_map = array(
|
||||
110 => MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||
155 => MDB2_ERROR_NOSUCHFIELD,
|
||||
170 => MDB2_ERROR_SYNTAX,
|
||||
207 => MDB2_ERROR_NOSUCHFIELD,
|
||||
208 => MDB2_ERROR_NOSUCHTABLE,
|
||||
245 => MDB2_ERROR_INVALID_NUMBER,
|
||||
515 => MDB2_ERROR_CONSTRAINT_NOT_NULL,
|
||||
547 => MDB2_ERROR_CONSTRAINT,
|
||||
1913 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
2627 => MDB2_ERROR_CONSTRAINT,
|
||||
2714 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
3701 => MDB2_ERROR_NOSUCHTABLE,
|
||||
8134 => MDB2_ERROR_DIVZERO,
|
||||
);
|
||||
}
|
||||
if (isset($ecode_map[$native_code])) {
|
||||
if ($native_code == 3701
|
||||
&& preg_match('/Cannot drop the index/i', $native_msg)
|
||||
) {
|
||||
$error = MDB2_ERROR_NOT_FOUND;
|
||||
} else {
|
||||
$error = $ecode_map[$native_code];
|
||||
}
|
||||
}
|
||||
}
|
||||
return array($error, $native_code, $native_msg);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quote a string so it can be safely used as a table / column name
|
||||
*
|
||||
* Quoting style depends on which database driver is being used.
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
return '[' . str_replace(']', ']]', $str) . ']';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ beginTransaction()
|
||||
|
||||
/**
|
||||
* Start a transaction.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
$this->debug('starting transaction', 'beginTransaction');
|
||||
if ($this->in_transaction) {
|
||||
return MDB2_OK; //nothing to do
|
||||
}
|
||||
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||
$this->destructor_registered = true;
|
||||
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||
}
|
||||
$result = $this->_doQuery('BEGIN TRANSACTION', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit the database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$this->debug('commit transaction', 'commit');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'commit: transaction changes are being auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('COMMIT TRANSACTION', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$this->debug('rolling back transaction', 'rollback');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('ROLLBACK TRANSACTION', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return true on success, MDB2 Error Object on failure
|
||||
*/
|
||||
function connect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||
&& $this->opened_persistent == $this->options['persistent']
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$this->disconnect(false);
|
||||
}
|
||||
|
||||
if (!PEAR::loadExtension($this->phptype)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||
}
|
||||
|
||||
$params = array(
|
||||
$this->dsn['hostspec'] ? $this->dsn['hostspec'] : 'localhost',
|
||||
$this->dsn['username'] ? $this->dsn['username'] : null,
|
||||
$this->dsn['password'] ? $this->dsn['password'] : null,
|
||||
);
|
||||
if ($this->dsn['port']) {
|
||||
$params[0].= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':')
|
||||
. $this->dsn['port'];
|
||||
}
|
||||
|
||||
$connect_function = $this->options['persistent'] ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
$connection = @call_user_func_array($connect_function, $params);
|
||||
if ($connection <= 0) {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
|
||||
$this->connection = $connection;
|
||||
$this->connected_dsn = $this->dsn;
|
||||
$this->connected_database_name = '';
|
||||
$this->opened_persistent = $this->options['persistent'];
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
|
||||
if ((bool) ini_get('mssql.datetimeconvert')) {
|
||||
ini_set('mssql.datetimeconvert', '0');
|
||||
}
|
||||
@mssql_query('SET DATEFORMAT ymd', $this->connection);
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect($force = true)
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (!$this->opened_persistent || $force) {
|
||||
@mssql_close($this->connection);
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->getOption('disable_query')) {
|
||||
if ($isManip) {
|
||||
return 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($connection)) {
|
||||
$err = $this->connect();
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$connection = $this->connection;
|
||||
}
|
||||
if (is_null($database_name)) {
|
||||
$database_name = $this->database_name;
|
||||
}
|
||||
|
||||
if ($database_name) {
|
||||
if ($database_name != $this->connected_database_name) {
|
||||
if (!@mssql_select_db($database_name, $connection)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
$this->connected_database_name = $database_name;
|
||||
}
|
||||
}
|
||||
|
||||
$result = @mssql_query($query, $connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return @mssql_rows_affected($connection);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @return the new (modified) query
|
||||
* @access protected
|
||||
*/
|
||||
function _modifyQuery($query, $isManip, $limit, $offset)
|
||||
{
|
||||
if ($limit > 0) {
|
||||
$fetch = $offset + $limit;
|
||||
if (!$isManip) {
|
||||
return preg_replace('/^([\s(])*SELECT(?!\s*TOP\s*\()/i',
|
||||
"\\1SELECT TOP $fetch", $query);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
// }}}
|
||||
// {{{ _checkSequence
|
||||
/**
|
||||
* Checks if there's a sequence that exists.
|
||||
*
|
||||
* @param string $seq_name The sequence name to verify.
|
||||
* @return bool $tableExists The value if the table exists or not
|
||||
* @access private
|
||||
*/
|
||||
function _checkSequence($seq_name)
|
||||
{
|
||||
$query = "SELECT * FROM $seq_name";
|
||||
$tableExists = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($tableExists)) {
|
||||
if ($tableExists->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ nextID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function nextID($seq_name, $ondemand = true)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
if (!$this->_checkSequence($sequence_name)) {
|
||||
$query = "INSERT INTO $sequence_name (".$this->options['seqcol_name'].") VALUES (0)";
|
||||
} else {
|
||||
$query = "SET IDENTITY_INSERT $sequence_name ON ".
|
||||
"INSERT INTO $sequence_name (".$this->options['seqcol_name'].") VALUES (0)";
|
||||
}
|
||||
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = $this->_doQuery($query, true);
|
||||
$this->popExpect();
|
||||
if (PEAR::isError($result)) {
|
||||
if ($ondemand && !$this->_checkSequence($sequence_name)) {
|
||||
$this->loadModule('Manager');
|
||||
// Since we are creating the sequence on demand
|
||||
// we know the first id = 1 so initialize the
|
||||
// sequence at 2
|
||||
$result = $this->manager->createSequence($seq_name, 2);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'nextID: on demand sequence '.$seq_name.' could not be created');
|
||||
} else {
|
||||
// First ID of a newly created sequence is 1
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// TODO: Make sure that this works.
|
||||
$value = $this->queryRow("SELECT @@IDENTITY", 'integer');
|
||||
if (is_numeric($value)) {
|
||||
$query = "DELETE FROM $sequence_name WHERE ".
|
||||
$this->options['seqcol_name']." < $value";
|
||||
$result = $this->_doQuery($query, true);
|
||||
|
||||
if (PEAR::isError($result)) {
|
||||
$this->warnings[] = 'nextID: could not delete previous sequence table values';
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
// }}}
|
||||
// {{{ lastInsertID()
|
||||
/**
|
||||
* returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed $id value as returned by getBeforeId()
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function lastInsertID($table = null, $field = null)
|
||||
{
|
||||
return $this->queryOne("SELECT @@IDENTITY FROM $table", 'integer');
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
// {{{ Class MDB2_Result_mssql
|
||||
|
||||
class MDB2_Result_mssql extends MDB2_Result_Common
|
||||
{
|
||||
// {{{ _skipLimitOffset()
|
||||
|
||||
/**
|
||||
* Skip the first row of a result set.
|
||||
*
|
||||
* @param resource $result
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _skipLimitOffset()
|
||||
{
|
||||
if ($this->limit) {
|
||||
if ($this->rownum >= $this->limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->offset) {
|
||||
while ($this->offset_count < $this->offset) {
|
||||
++$this->offset_count;
|
||||
if (!is_array(@mysql_fetch_row($this->result))) {
|
||||
$this->offset_count = $this->limit;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (!$this->_skipLimitOffset()) {
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$row = @mssql_fetch_assoc($this->result);
|
||||
if (is_array($row)
|
||||
&& $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
) {
|
||||
$row = array_change_key_case($row, $this->db->options['field_case']);
|
||||
}
|
||||
} else {
|
||||
$row = @mssql_fetch_row($this->result);
|
||||
}
|
||||
if (!$row) {
|
||||
if (is_null($this->result)) {
|
||||
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
return $err;
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||
$this->db->_fixResultArrayValues($row, MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||
}
|
||||
if (!empty($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (!empty($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @param resource $result result identifier
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
$columns = array();
|
||||
$numcols = $this->numCols();
|
||||
if (PEAR::isError($numcols)) {
|
||||
return $numcols;
|
||||
}
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @mssql_field_name($this->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
* @access public
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
$cols = @mssql_num_fields($this->result);
|
||||
if (is_null($cols)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal result pointer to the next available result
|
||||
* Currently not supported
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
* @access public
|
||||
*/
|
||||
function nextResult()
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'nextResult: resultset has already been freed');
|
||||
}
|
||||
return @mssql_next_result($this->result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @return boolean true on success, false if $result is invalid
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$free = @mssql_free_result($this->result);
|
||||
if (!$free) {
|
||||
if (is_null($this->result)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
$this->result = null;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_mssql extends MDB2_Result_mssql
|
||||
{
|
||||
// }}}
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if ($this->rownum != ($rownum - 1) && !@mssql_data_seek($this->result, $rownum)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
$rows = @mssql_num_rows($this->result);
|
||||
if (is_null($rows)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
return $this->raiseError();
|
||||
}
|
||||
if ($this->limit) {
|
||||
$rows -= $this->limit;
|
||||
if ($rows < 0) {
|
||||
$rows = 0;
|
||||
}
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ MDB2_Statement_mssql
|
||||
class MDB2_Statement_mssql extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
// }}}
|
||||
|
||||
?>
|
@ -1,911 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_mysql extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "\\";
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'mysql';
|
||||
$this->dbsyntax = 'mysql';
|
||||
|
||||
$this->supported['sequences'] = 'emulated';
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = true;
|
||||
$this->supported['transactions'] = false;
|
||||
$this->supported['summary_functions'] = true;
|
||||
$this->supported['order_by_text'] = true;
|
||||
$this->supported['current_id'] = 'emulated';
|
||||
$this->supported['limit_queries'] = true;
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] = true;
|
||||
$this->supported['sub_selects'] = 'emulated';
|
||||
$this->supported['auto_increment'] = true;
|
||||
$this->supported['primary_key'] = true;
|
||||
|
||||
$this->options['default_table_type'] = null;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorInfo()
|
||||
|
||||
/**
|
||||
* This method is used to collect information about an error
|
||||
*
|
||||
* @param integer $error
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function errorInfo($error = null)
|
||||
{
|
||||
if ($this->connection) {
|
||||
$native_code = @mysql_errno($this->connection);
|
||||
$native_msg = @mysql_error($this->connection);
|
||||
} else {
|
||||
$native_code = @mysql_errno();
|
||||
$native_msg = @mysql_error();
|
||||
}
|
||||
if (is_null($error)) {
|
||||
static $ecode_map;
|
||||
if (empty($ecode_map)) {
|
||||
$ecode_map = array(
|
||||
1004 => MDB2_ERROR_CANNOT_CREATE,
|
||||
1005 => MDB2_ERROR_CANNOT_CREATE,
|
||||
1006 => MDB2_ERROR_CANNOT_CREATE,
|
||||
1007 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
1008 => MDB2_ERROR_CANNOT_DROP,
|
||||
1022 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
1044 => MDB2_ERROR_ACCESS_VIOLATION,
|
||||
1046 => MDB2_ERROR_NODBSELECTED,
|
||||
1048 => MDB2_ERROR_CONSTRAINT,
|
||||
1049 => MDB2_ERROR_NOSUCHDB,
|
||||
1050 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
1051 => MDB2_ERROR_NOSUCHTABLE,
|
||||
1054 => MDB2_ERROR_NOSUCHFIELD,
|
||||
1061 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
1062 => MDB2_ERROR_ALREADY_EXISTS,
|
||||
1064 => MDB2_ERROR_SYNTAX,
|
||||
1091 => MDB2_ERROR_NOT_FOUND,
|
||||
1100 => MDB2_ERROR_NOT_LOCKED,
|
||||
1136 => MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||
1142 => MDB2_ERROR_ACCESS_VIOLATION,
|
||||
1146 => MDB2_ERROR_NOSUCHTABLE,
|
||||
1216 => MDB2_ERROR_CONSTRAINT,
|
||||
1217 => MDB2_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
if ($this->options['portability'] & MDB2_PORTABILITY_ERRORS) {
|
||||
$ecode_map[1022] = MDB2_ERROR_CONSTRAINT;
|
||||
$ecode_map[1048] = MDB2_ERROR_CONSTRAINT_NOT_NULL;
|
||||
$ecode_map[1062] = MDB2_ERROR_CONSTRAINT;
|
||||
} else {
|
||||
// Doing this in case mode changes during runtime.
|
||||
$ecode_map[1022] = MDB2_ERROR_ALREADY_EXISTS;
|
||||
$ecode_map[1048] = MDB2_ERROR_CONSTRAINT;
|
||||
$ecode_map[1062] = MDB2_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
if (isset($ecode_map[$native_code])) {
|
||||
$error = $ecode_map[$native_code];
|
||||
}
|
||||
}
|
||||
return array($error, $native_code, $native_msg);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ escape()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used in a query. It will quote
|
||||
* the text so it can safely be used within a query.
|
||||
*
|
||||
* @param string $text the input string to quote
|
||||
* @return string quoted string
|
||||
* @access public
|
||||
*/
|
||||
function escape($text)
|
||||
{
|
||||
return @mysql_real_escape_string($text);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quote a string so it can be safely used as a table or column name
|
||||
*
|
||||
* Quoting style depends on which database driver is being used.
|
||||
*
|
||||
* MySQL can't handle the backtick character (<kbd>`</kbd>) in
|
||||
* table or column names.
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @access public
|
||||
* @internal
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
return '`' . $str . '`';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ beginTransaction()
|
||||
|
||||
/**
|
||||
* Start a transaction.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
$this->debug('starting transaction', 'beginTransaction');
|
||||
if (!$this->supports('transactions')) {
|
||||
return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'beginTransaction: transactions are not in use');
|
||||
}
|
||||
if ($this->in_transaction) {
|
||||
return MDB2_OK; //nothing to do
|
||||
}
|
||||
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||
$this->destructor_registered = true;
|
||||
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||
}
|
||||
$result = $this->_doQuery('SET AUTOCOMMIT = 0', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit the database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$this->debug('commit transaction', 'commit');
|
||||
if (!$this->supports('transactions')) {
|
||||
return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'commit: transactions are not in use');
|
||||
}
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'commit: transaction changes are being auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('COMMIT', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->_doQuery('SET AUTOCOMMIT = 1', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$this->debug('rolling back transaction', 'rollback');
|
||||
if (!$this->supports('transactions')) {
|
||||
return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'rollback: transactions are not in use');
|
||||
}
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('ROLLBACK', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->_doQuery('SET AUTOCOMMIT = 1', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return true on success, MDB2 Error Object on failure
|
||||
*/
|
||||
function connect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||
&& $this->opened_persistent == $this->options['persistent']
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$this->disconnect(false);
|
||||
}
|
||||
|
||||
if (!PEAR::loadExtension($this->phptype)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||
}
|
||||
|
||||
$params = array();
|
||||
if ($this->dsn['protocol'] && $this->dsn['protocol'] == 'unix') {
|
||||
$params[0] = ':' . $this->dsn['socket'];
|
||||
} else {
|
||||
$params[0] = $this->dsn['hostspec'] ? $this->dsn['hostspec']
|
||||
: 'localhost';
|
||||
if ($this->dsn['port']) {
|
||||
$params[0].= ':' . $this->dsn['port'];
|
||||
}
|
||||
}
|
||||
$params[] = $this->dsn['username'] ? $this->dsn['username'] : null;
|
||||
$params[] = $this->dsn['password'] ? $this->dsn['password'] : null;
|
||||
if (!$this->options['persistent']) {
|
||||
if (isset($this->dsn['new_link'])
|
||||
&& ($this->dsn['new_link'] == 'true' || $this->dsn['new_link'] === true)
|
||||
) {
|
||||
$params[] = true;
|
||||
} else {
|
||||
$params[] = false;
|
||||
}
|
||||
}
|
||||
if (version_compare(phpversion(), '4.3.0', '>=')) {
|
||||
$params[] = isset($this->dsn['client_flags'])
|
||||
? $this->dsn['client_flags'] : null;
|
||||
}
|
||||
|
||||
$connect_function = $this->options['persistent'] ? 'mysql_pconnect' : 'mysql_connect';
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
$php_errormsg = '';
|
||||
$connection = @call_user_func_array($connect_function, $params);
|
||||
@ini_restore('track_errors');
|
||||
if (!$connection) {
|
||||
if (($err = @mysql_error()) != '') {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, $err);
|
||||
} else {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
$this->connection = $connection;
|
||||
$this->connected_dsn = $this->dsn;
|
||||
$this->connected_database_name = '';
|
||||
$this->opened_persistent = $this->options['persistent'];
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
|
||||
$this->supported['transactions'] = false;
|
||||
if ($this->options['default_table_type']) {
|
||||
switch (strtoupper($this->options['default_table_type'])) {
|
||||
case 'BERKELEYDB':
|
||||
$this->options['default_table_type'] = 'BDB';
|
||||
case 'BDB':
|
||||
case 'INNODB':
|
||||
case 'GEMINI':
|
||||
$this->supported['transactions'] = true;
|
||||
break;
|
||||
case 'HEAP':
|
||||
case 'ISAM':
|
||||
case 'MERGE':
|
||||
case 'MRG_MYISAM':
|
||||
case 'MYISAM':
|
||||
break;
|
||||
default:
|
||||
$this->warnings[] = $default_table_type.
|
||||
' is not a supported default table type';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->options['use_transactions'] && !$this->supports('transactions')) {
|
||||
$this->warnings[] = $this->options['default_table_type'].
|
||||
' is not a transaction-safe default table type; switched to INNODB';
|
||||
$this->options['default_table_type'] = 'INNODB';
|
||||
$this->supported['transactions'] = true;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect($force = true)
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (!$this->opened_persistent || $force) {
|
||||
@mysql_close($this->connection);
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->options['disable_query']) {
|
||||
if ($isManip) {
|
||||
return 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($connection)) {
|
||||
$err = $this->connect();
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$connection = $this->connection;
|
||||
}
|
||||
if (is_null($database_name)) {
|
||||
$database_name = $this->database_name;
|
||||
}
|
||||
|
||||
if ($database_name) {
|
||||
if ($database_name != $this->connected_database_name) {
|
||||
if (!@mysql_select_db($database_name, $connection)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
$this->connected_database_name = $database_name;
|
||||
}
|
||||
}
|
||||
|
||||
$function = $this->options['result_buffering']
|
||||
? 'mysql_query' : 'mysql_unbuffered_query';
|
||||
$result = @$function($query, $connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return @mysql_affected_rows($connection);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @return the new (modified) query
|
||||
* @access protected
|
||||
*/
|
||||
function _modifyQuery($query, $isManip, $limit, $offset)
|
||||
{
|
||||
if ($this->options['portability'] & MDB2_PORTABILITY_DELETE_COUNT) {
|
||||
// "DELETE FROM table" gives 0 affected rows in MySQL.
|
||||
// This little hack lets you know how many rows were deleted.
|
||||
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
|
||||
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
|
||||
'DELETE FROM \1 WHERE 1=1', $query);
|
||||
}
|
||||
}
|
||||
if ($limit > 0
|
||||
&& !preg_match('/LIMIT\s*\d(\s*(,|OFFSET)\s*\d+)?/i', $query)
|
||||
) {
|
||||
$query = rtrim($query);
|
||||
if (substr($query, -1) == ';') {
|
||||
$query = substr($query, 0, -1);
|
||||
}
|
||||
if ($isManip) {
|
||||
return $query . " LIMIT $limit";
|
||||
} else {
|
||||
return $query . " LIMIT $offset, $limit";
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
|
||||
* query, except that if there is already a row in the table with the same
|
||||
* key field values, the REPLACE query just updates its values instead of
|
||||
* inserting a new row.
|
||||
*
|
||||
* The REPLACE type of query does not make part of the SQL standards. Since
|
||||
* practically only MySQL implements it natively, this type of query is
|
||||
* emulated through this method for other DBMS using standard types of
|
||||
* queries inside a transaction to assure the atomicity of the operation.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $table name of the table on which the REPLACE query will
|
||||
* be executed.
|
||||
* @param array $fields associative array that describes the fields and the
|
||||
* values that will be inserted or updated in the specified table. The
|
||||
* indexes of the array are the names of all the fields of the table. The
|
||||
* values of the array are also associative arrays that describe the
|
||||
* values and other properties of the table fields.
|
||||
*
|
||||
* Here follows a list of field properties that need to be specified:
|
||||
*
|
||||
* value:
|
||||
* Value to be assigned to the specified field. This value may be
|
||||
* of specified in database independent type format as this
|
||||
* function can perform the necessary datatype conversions.
|
||||
*
|
||||
* Default:
|
||||
* this property is required unless the Null property
|
||||
* is set to 1.
|
||||
*
|
||||
* type
|
||||
* Name of the type of the field. Currently, all types Metabase
|
||||
* are supported except for clob and blob.
|
||||
*
|
||||
* Default: no type conversion
|
||||
*
|
||||
* null
|
||||
* Boolean property that indicates that the value for this field
|
||||
* should be set to null.
|
||||
*
|
||||
* The default value for fields missing in INSERT queries may be
|
||||
* specified the definition of a table. Often, the default value
|
||||
* is already null, but since the REPLACE may be emulated using
|
||||
* an UPDATE query, make sure that all fields of the table are
|
||||
* listed in this function argument array.
|
||||
*
|
||||
* Default: 0
|
||||
*
|
||||
* key
|
||||
* Boolean property that indicates that this field should be
|
||||
* handled as a primary key or at least as part of the compound
|
||||
* unique index of the table that will determine the row that will
|
||||
* updated if it exists or inserted a new row otherwise.
|
||||
*
|
||||
* This function will fail if no key field is specified or if the
|
||||
* value of a key field is set to null because fields that are
|
||||
* part of unique index they may not be null.
|
||||
*
|
||||
* Default: 0
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function replace($table, $fields)
|
||||
{
|
||||
$count = count($fields);
|
||||
$query = $values = '';
|
||||
$keys = $colnum = 0;
|
||||
for (reset($fields); $colnum < $count; next($fields), $colnum++) {
|
||||
$name = key($fields);
|
||||
if ($colnum > 0) {
|
||||
$query .= ',';
|
||||
$values.= ',';
|
||||
}
|
||||
$query.= $name;
|
||||
if (isset($fields[$name]['null']) && $fields[$name]['null']) {
|
||||
$value = 'NULL';
|
||||
} else {
|
||||
$value = $this->quote($fields[$name]['value'], $fields[$name]['type']);
|
||||
}
|
||||
$values.= $value;
|
||||
if (isset($fields[$name]['key']) && $fields[$name]['key']) {
|
||||
if ($value === 'NULL') {
|
||||
return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null,
|
||||
'replace: key value '.$name.' may not be NULL');
|
||||
}
|
||||
$keys++;
|
||||
}
|
||||
}
|
||||
if ($keys == 0) {
|
||||
return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null,
|
||||
'replace: not specified which fields are keys');
|
||||
}
|
||||
$query = "REPLACE INTO $table ($query) VALUES ($values)";
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
return $this->_doQuery($query, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function nextID($seq_name, $ondemand = true)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "INSERT INTO $sequence_name (".$this->options['seqcol_name'].") VALUES (NULL)";
|
||||
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = $this->_doQuery($query, true);
|
||||
$this->popExpect();
|
||||
if (PEAR::isError($result)) {
|
||||
if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||
$this->loadModule('Manager');
|
||||
// Since we are creating the sequence on demand
|
||||
// we know the first id = 1 so initialize the
|
||||
// sequence at 2
|
||||
$result = $this->manager->createSequence($seq_name, 2);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'nextID: on demand sequence '.$seq_name.' could not be created');
|
||||
} else {
|
||||
// First ID of a newly created sequence is 1
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
$value = $this->queryOne('SELECT LAST_INSERT_ID()', 'integer');
|
||||
if (is_numeric($value)) {
|
||||
$query = "DELETE FROM $sequence_name WHERE ".$this->options['seqcol_name']." < $value";
|
||||
$result = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ lastInsertID()
|
||||
|
||||
/**
|
||||
* returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed $id value as returned by getBeforeId()
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function lastInsertID($table = null, $field = null)
|
||||
{
|
||||
return $this->queryOne('SELECT LAST_INSERT_ID()', 'integer');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ currID()
|
||||
|
||||
/**
|
||||
* returns the current id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function currID($seq_name)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "SELECT MAX(".$this->options['seqcol_name'].") FROM $sequence_name";
|
||||
return $this->queryOne($query, 'integer');
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Result_mysql extends MDB2_Result_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$row = @mysql_fetch_assoc($this->result);
|
||||
if (is_array($row)
|
||||
&& $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
) {
|
||||
$row = array_change_key_case($row, $this->db->options['field_case']);
|
||||
}
|
||||
} else {
|
||||
$row = @mysql_fetch_row($this->result);
|
||||
}
|
||||
|
||||
if (!$row) {
|
||||
if (is_null($this->result)) {
|
||||
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
return $err;
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||
$this->db->_fixResultArrayValues($row, MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||
}
|
||||
if (!empty($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (!empty($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
$columns = array();
|
||||
$numcols = $this->numCols();
|
||||
if (PEAR::isError($numcols)) {
|
||||
return $numcols;
|
||||
}
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @mysql_field_name($this->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
* @access public
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
$cols = @mysql_num_fields($this->result);
|
||||
if (is_null($cols)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return boolean true on success, false if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$free = @mysql_free_result($this->result);
|
||||
if (!$free) {
|
||||
if (is_null($this->result)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
$this->result = null;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_mysql extends MDB2_Result_mysql
|
||||
{
|
||||
// }}}
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if ($this->rownum != ($rownum - 1) && !@mysql_data_seek($this->result, $rownum)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
$rows = @mysql_num_rows($this->result);
|
||||
if (is_null($rows)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Statement_mysql extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,771 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_pgsql extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "\\";
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'pgsql';
|
||||
$this->dbsyntax = 'pgsql';
|
||||
|
||||
$this->supported['sequences'] = true;
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = true;
|
||||
$this->supported['summary_functions'] = true;
|
||||
$this->supported['order_by_text'] = true;
|
||||
$this->supported['transactions'] = true;
|
||||
$this->supported['current_id'] = true;
|
||||
$this->supported['limit_queries'] = true;
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] = 'emulated';
|
||||
$this->supported['sub_selects'] = true;
|
||||
$this->supported['auto_increment'] = 'emulated';
|
||||
$this->supported['primary_key'] = true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorInfo()
|
||||
|
||||
/**
|
||||
* This method is used to collect information about an error
|
||||
*
|
||||
* @param integer $error
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function errorInfo($error = null)
|
||||
{
|
||||
// Fall back to MDB2_ERROR if there was no mapping.
|
||||
$error_code = MDB2_ERROR;
|
||||
|
||||
$native_msg = '';
|
||||
if (is_resource($error)) {
|
||||
$native_msg = @pg_result_error($error);
|
||||
} elseif ($this->connection) {
|
||||
$native_msg = @pg_last_error($this->connection);
|
||||
if (!$native_msg && @pg_connection_status($this->connection) === PGSQL_CONNECTION_BAD) {
|
||||
$native_msg = 'Database connection has been lost.';
|
||||
$error_code = MDB2_ERROR_CONNECT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
static $error_regexps;
|
||||
if (empty($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/column .* (of relation .*)?does not exist/i'
|
||||
=> MDB2_ERROR_NOSUCHFIELD,
|
||||
'/(relation|sequence|table).*does not exist|class .* not found/i'
|
||||
=> MDB2_ERROR_NOSUCHTABLE,
|
||||
'/index .* does not exist/'
|
||||
=> MDB2_ERROR_NOT_FOUND,
|
||||
'/relation .* already exists/i'
|
||||
=> MDB2_ERROR_ALREADY_EXISTS,
|
||||
'/(divide|division) by zero$/i'
|
||||
=> MDB2_ERROR_DIVZERO,
|
||||
'/pg_atoi: error in .*: can\'t parse /i'
|
||||
=> MDB2_ERROR_INVALID_NUMBER,
|
||||
'/invalid input syntax for( type)? (integer|numeric)/i'
|
||||
=> MDB2_ERROR_INVALID_NUMBER,
|
||||
'/value .* is out of range for type \w*int/i'
|
||||
=> MDB2_ERROR_INVALID_NUMBER,
|
||||
'/integer out of range/i'
|
||||
=> MDB2_ERROR_INVALID_NUMBER,
|
||||
'/value too long for type character/i'
|
||||
=> MDB2_ERROR_INVALID,
|
||||
'/attribute .* not found|relation .* does not have attribute/i'
|
||||
=> MDB2_ERROR_NOSUCHFIELD,
|
||||
'/column .* specified in USING clause does not exist in (left|right) table/i'
|
||||
=> MDB2_ERROR_NOSUCHFIELD,
|
||||
'/parser: parse error at or near/i'
|
||||
=> MDB2_ERROR_SYNTAX,
|
||||
'/syntax error at/'
|
||||
=> MDB2_ERROR_SYNTAX,
|
||||
'/column reference .* is ambiguous/i'
|
||||
=> MDB2_ERROR_SYNTAX,
|
||||
'/permission denied/'
|
||||
=> MDB2_ERROR_ACCESS_VIOLATION,
|
||||
'/violates not-null constraint/'
|
||||
=> MDB2_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'/violates [\w ]+ constraint/'
|
||||
=> MDB2_ERROR_CONSTRAINT,
|
||||
'/referential integrity violation/'
|
||||
=> MDB2_ERROR_CONSTRAINT,
|
||||
'/more expressions than target columns/i'
|
||||
=> MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $native_msg)) {
|
||||
$error_code = $code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array($error_code, null, $native_msg);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ beginTransaction()
|
||||
|
||||
/**
|
||||
* Start a transaction.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
$this->debug('starting transaction', 'beginTransaction');
|
||||
if ($this->in_transaction) {
|
||||
return MDB2_OK; //nothing to do
|
||||
}
|
||||
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||
$this->destructor_registered = true;
|
||||
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||
}
|
||||
$result = $this->_doQuery('BEGIN', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit the database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$this->debug('commit transaction', 'commit');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'commit: transaction changes are being auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('COMMIT', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$this->debug('rolling back transaction', 'rollback');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||
}
|
||||
$result = $this->_doQuery('ROLLBACK', true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doConnect()
|
||||
|
||||
/**
|
||||
* Does the grunt work of connecting to the database
|
||||
*
|
||||
* @return mixed connection resource on success, MDB2 Error Object on failure
|
||||
* @access protected
|
||||
**/
|
||||
function _doConnect($database_name, $persistent = false)
|
||||
{
|
||||
if ($database_name == '') {
|
||||
$database_name = 'template1';
|
||||
}
|
||||
|
||||
$protocol = $this->dsn['protocol'] ? $this->dsn['protocol'] : 'tcp';
|
||||
|
||||
$params = array('');
|
||||
if ($protocol == 'tcp') {
|
||||
if ($this->dsn['hostspec']) {
|
||||
$params[0].= 'host=' . $this->dsn['hostspec'];
|
||||
}
|
||||
if ($this->dsn['port']) {
|
||||
$params[0].= ' port=' . $this->dsn['port'];
|
||||
}
|
||||
} elseif ($protocol == 'unix') {
|
||||
// Allow for pg socket in non-standard locations.
|
||||
if ($this->dsn['socket']) {
|
||||
$params[0].= 'host=' . $this->dsn['socket'];
|
||||
}
|
||||
if ($this->dsn['port']) {
|
||||
$params[0].= ' port=' . $this->dsn['port'];
|
||||
}
|
||||
}
|
||||
if ($database_name) {
|
||||
$params[0].= ' dbname=\'' . addslashes($database_name) . '\'';
|
||||
}
|
||||
if ($this->dsn['username']) {
|
||||
$params[0].= ' user=\'' . addslashes($this->dsn['username']) . '\'';
|
||||
}
|
||||
if ($this->dsn['password']) {
|
||||
$params[0].= ' password=\'' . addslashes($this->dsn['password']) . '\'';
|
||||
}
|
||||
if (!empty($this->dsn['options'])) {
|
||||
$params[0].= ' options=' . $this->dsn['options'];
|
||||
}
|
||||
if (!empty($this->dsn['tty'])) {
|
||||
$params[0].= ' tty=' . $this->dsn['tty'];
|
||||
}
|
||||
if (!empty($this->dsn['connect_timeout'])) {
|
||||
$params[0].= ' connect_timeout=' . $this->dsn['connect_timeout'];
|
||||
}
|
||||
if (!empty($this->dsn['sslmode'])) {
|
||||
$params[0].= ' sslmode=' . $this->dsn['sslmode'];
|
||||
}
|
||||
if (!empty($this->dsn['service'])) {
|
||||
$params[0].= ' service=' . $this->dsn['service'];
|
||||
}
|
||||
|
||||
if (isset($this->dsn['new_link'])
|
||||
&& ($this->dsn['new_link'] == 'true' || $this->dsn['new_link'] === true))
|
||||
{
|
||||
if (version_compare(phpversion(), '4.3.0', '>=')) {
|
||||
$params[] = PGSQL_CONNECT_FORCE_NEW;
|
||||
}
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
|
||||
|
||||
putenv('PGDATESTYLE=ISO');
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
$php_errormsg = '';
|
||||
$connection = @call_user_func_array($connect_function, $params);
|
||||
@ini_restore('track_errors');
|
||||
if (!$connection) {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED,
|
||||
null, null, strip_tags($php_errormsg));
|
||||
}
|
||||
return $connection;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return true on success, MDB2 Error Object on failure
|
||||
* @access public
|
||||
**/
|
||||
function connect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||
&& $this->connected_database_name == $this->database_name
|
||||
&& ($this->opened_persistent == $this->options['persistent'])
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$this->disconnect(false);
|
||||
}
|
||||
|
||||
if (!PEAR::loadExtension($this->phptype)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||
}
|
||||
|
||||
if ($this->database_name) {
|
||||
$connection = $this->_doConnect($this->database_name, $this->options['persistent']);
|
||||
if (PEAR::isError($connection)) {
|
||||
return $connection;
|
||||
}
|
||||
$this->connection = $connection;
|
||||
$this->connected_dsn = $this->dsn;
|
||||
$this->connected_database_name = $this->database_name;
|
||||
$this->opened_persistent = $this->options['persistent'];
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect($force = true)
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (!$this->opened_persistent || $force) {
|
||||
@pg_close($this->connection);
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ standaloneQuery()
|
||||
|
||||
/**
|
||||
* execute a query as DBA
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &standaloneQuery($query, $types = null)
|
||||
{
|
||||
$connection = $this->_doConnect('template1', false);
|
||||
if (PEAR::isError($connection)) {
|
||||
$err =& $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null,
|
||||
'Cannot connect to template1');
|
||||
return $err;
|
||||
}
|
||||
|
||||
$isManip = MDB2::isManip($query);
|
||||
$offset = $this->row_offset;
|
||||
$limit = $this->row_limit;
|
||||
$this->row_offset = $this->row_limit = 0;
|
||||
$query = $this->_modifyQuery($query, $isManip, $limit, $offset);
|
||||
|
||||
$result = $this->_doQuery($query, $isManip, $connection, false);
|
||||
@pg_close($connection);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result =& $this->_wrapResult($result, $types, true, false, $limit, $offset);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->options['disable_query']) {
|
||||
if ($isManip) {
|
||||
return 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($connection)) {
|
||||
$err = $this->connect();
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$connection = $this->connection;
|
||||
}
|
||||
|
||||
$result = @pg_query($connection, $query);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return @pg_affected_rows($result);
|
||||
} elseif (!preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW)\s/si', $query)) {
|
||||
return 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @return the new (modified) query
|
||||
* @access protected
|
||||
*/
|
||||
function _modifyQuery($query, $isManip, $limit, $offset)
|
||||
{
|
||||
if ($limit > 0
|
||||
&& !preg_match('/LIMIT\s*\d(\s*(,|OFFSET)\s*\d+)?/i', $query)
|
||||
) {
|
||||
$query = rtrim($query);
|
||||
if (substr($query, -1) == ';') {
|
||||
$query = substr($query, 0, -1);
|
||||
}
|
||||
if ($isManip) {
|
||||
$manip = preg_replace('/^(DELETE FROM|UPDATE).*$/', '\\1', $query);
|
||||
$from = $match[2];
|
||||
$where = $match[3];
|
||||
$query = $manip.' '.$from.' WHERE ctid=(SELECT ctid FROM '.$from.' '.$where.' LIMIT '.$limit.')';
|
||||
} else {
|
||||
$query.= " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function nextID($seq_name, $ondemand = true)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "SELECT NEXTVAL('$sequence_name')";
|
||||
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = $this->queryOne($query, 'integer');
|
||||
$this->popExpect();
|
||||
if (PEAR::isError($result)) {
|
||||
if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||
$this->loadModule('Manager');
|
||||
$result = $this->manager->createSequence($seq_name, 1);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'nextID: on demand sequence could not be created');
|
||||
}
|
||||
return $this->nextId($seq_name, false);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ currID()
|
||||
|
||||
/**
|
||||
* returns the current id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function currID($seq_name)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
return $this->queryOne("SELECT last_value FROM $sequence_name", 'integer');
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Result_pgsql extends MDB2_Result_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$row = @pg_fetch_array($this->result, null, PGSQL_ASSOC);
|
||||
if (is_array($row)
|
||||
&& $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
) {
|
||||
$row = array_change_key_case($row, $this->db->options['field_case']);
|
||||
}
|
||||
} else {
|
||||
$row = @pg_fetch_row($this->result);
|
||||
}
|
||||
if (!$row) {
|
||||
if (is_null($this->result)) {
|
||||
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
return $err;
|
||||
}
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||
$this->db->_fixResultArrayValues($row, MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||
}
|
||||
if (!empty($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (!empty($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
$columns = array();
|
||||
$numcols = $this->numCols();
|
||||
if (PEAR::isError($numcols)) {
|
||||
return $numcols;
|
||||
}
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @pg_field_name($this->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
$cols = @pg_num_fields($this->result);
|
||||
if (is_null($cols)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return boolean true on success, false if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$free = @pg_free_result($this->result);
|
||||
if (!$free) {
|
||||
if (is_null($this->result)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
$this->result = null;
|
||||
return MDB2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_pgsql extends MDB2_Result_pgsql
|
||||
{
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if ($this->rownum != ($rownum - 1) && !@pg_result_seek($this->result, $rownum)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
$rows = @pg_num_rows($this->result);
|
||||
if (is_null($rows)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Statement_pgsql extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
?>
|
@ -1,684 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Original QuerySim Concept & ColdFusion Author: Hal Helms |
|
||||
// | <hal.helms@teamallaire.com> |
|
||||
// | Bert Dawson <bdawson@redbanner.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Original PHP Author: Alan Richmond <arichmond@bigfoot.com> |
|
||||
// | David Huyck <b@bombusbee.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Special note concerning code documentation: |
|
||||
// | QuerySim was originally created for use during development of |
|
||||
// | applications built using the Fusebox framework. (www.fusebox.org) |
|
||||
// | Fusebox uses an XML style of documentation called Fusedoc. (Which |
|
||||
// | is admittedly not well suited to documenting classes and functions. |
|
||||
// | This short-coming is being addressed by the Fusebox community.) PEAR |
|
||||
// | uses a Javadoc style of documentation called PHPDoc. (www.phpdoc.de) |
|
||||
// | Since this class extension spans two groups of users, it is asked |
|
||||
// | that the members of each respect the documentation standard of the |
|
||||
// | other. So it is a further requirement that both documentation |
|
||||
// | standards be included and maintained. If assistance is required |
|
||||
// | please contact Alan Richmond. |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/*
|
||||
<fusedoc fuse="querysim.php" language="PHP">
|
||||
<responsibilities>
|
||||
I take information and turn it into a recordset that can be accessed
|
||||
through the PEAR MDB2 API. Based on Hal Helms' QuerySim.cfm ColdFusion
|
||||
custom tag available at halhelms.com.
|
||||
</responsibilities>
|
||||
<properties>
|
||||
<property name="API" value="PEAR MDB2" />
|
||||
<property name="version" value="0.2.1" />
|
||||
<property name="status" value="beta" />
|
||||
<history author="Hal Helms" email="hal.helms@teamallaire.com" type="Create" />
|
||||
<history author="Bert Dawson" email="bdawson@redbanner.com" type="Update">
|
||||
Extensive revision that is backwardly compatible but eliminates the
|
||||
need for a separate .sim file.
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Create" date="10-July-2002">
|
||||
Rewrote in PHP as an extention to the PEAR DB API.
|
||||
Functions supported:
|
||||
connect, disconnect, query, fetchRow, freeResult,
|
||||
numCols, numRows, getSpecialQuery
|
||||
David Huyck (bombusbee.com) added ability to escape special
|
||||
characters (i.e., delimiters) using a '\'.
|
||||
Extended PEAR DB options[] for adding incoming parameters. Added
|
||||
options: columnDelim, dataDelim, eolDelim
|
||||
</history>
|
||||
<history author="David Huyck" email="b@bombusbee.com" type="Update" date="19-July-2002">
|
||||
Added the ability to set the QuerySim options at runtime.
|
||||
Default options are:
|
||||
'columnDelim' => ',', // Commas split the column names
|
||||
'dataDelim' => '|', // Pipes split the data fields
|
||||
'eolDelim' => chr(13).chr(10) // Carriage returns split the
|
||||
// lines of data
|
||||
Affected functions are:
|
||||
DB_querysim(): set the default options when the
|
||||
constructor method is called
|
||||
_parseQuerySim($query): altered the parsing of lines, column
|
||||
names, and data fields
|
||||
_empty2null: altered the way this function is called
|
||||
to simplify calling it
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Update" date="24-July-2002">
|
||||
Added error catching for malformed QuerySim text.
|
||||
Bug fix _empty2null(): altered version was returning unmodified
|
||||
lineData.
|
||||
Cleanup:
|
||||
PEAR compliant formatting, finished PHPDocs and added 'out' to
|
||||
Fusedoc 'io'.
|
||||
Broke up _parseQuerySim() into _buildResult() and _parseOnDelim()
|
||||
to containerize duplicate parse code.
|
||||
</history>
|
||||
<history author="David Huyck" email="b@bombusbee.com" type="Update" date="25-July-2002">
|
||||
Edited the _buildResult() and _parseOnDelim() functions to improve
|
||||
reliability of special character escaping.
|
||||
Re-introduced a custom setOption() method to throw an error when a
|
||||
person tries to set one of the delimiters to '\'.
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Update" date="27-July-2002">
|
||||
Added '/' delimiter param to preg_quote() in _empty2null() and
|
||||
_parseOnDelim() so '/' can be used as a delimiter.
|
||||
Added error check for columnDelim == eolDelim or dataDelim == eolDelim.
|
||||
Renamed some variables for consistancy.
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Update" date="30-July-2002">
|
||||
Removed protected function _empty2null(). Turns out preg_split()
|
||||
deals with empty elemants by making them zero length strings, just
|
||||
what they ended up being anyway. This should speed things up a little.
|
||||
Affected functions:
|
||||
_parseOnDelim() perform trim on line here, instead of in
|
||||
_empty2null().
|
||||
_buildResult() remove call to _empty2null().
|
||||
_empty2null() removed function.
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Update" date="1-Jan-2003">
|
||||
Ported to PEAR MDB2.
|
||||
Methods supported:
|
||||
connect, query, getColumnNames, numCols, valid, fetch,
|
||||
numRows, free, fetchRow, nextResult, setLimit
|
||||
(inherited).
|
||||
</history>
|
||||
<history
|
||||
Removed array_change_key_case() work around for <4.2.0 in
|
||||
getColumnNames(), found it already done in MDB2/Common.php.
|
||||
</history>
|
||||
<history author="Alan Richmond" email="arichmond@bigfoot.com" type="Update" date="3-Feb-2003">
|
||||
Changed default eolDelim to a *nix file eol, since we're trimming
|
||||
the result anyway, it makes no difference for Windows. Now only
|
||||
Mac file eols should need to be set (and other kinds of chars).
|
||||
</history>
|
||||
<note author="Alan Richmond">
|
||||
Got WAY too long. See querysim_readme.txt for instructions and some
|
||||
examples.
|
||||
io section only documents elements of DB_result that DB_querysim uses,
|
||||
adds or changes; see MDB2 and MDB2_Driver_Common for more info.
|
||||
io section uses some elements that are not Fusedoc 2.0 compliant:
|
||||
object and resource.
|
||||
</note>
|
||||
</properties>
|
||||
<io>
|
||||
<in>
|
||||
<file path="MDB2/Common.php" action="require_once" />
|
||||
</in>
|
||||
<out>
|
||||
<object name="MDB2_querysim" extends="MDB2_Driver_Common" instantiatedby="MDB2::connect()">
|
||||
<resource type="file" name="connection" oncondition="source is external file" scope="class" />
|
||||
<string name="phptype" default="querysim" />
|
||||
<string name="dbsyntax" default="querysim" />
|
||||
<array name="supported" comments="most of these don't actually do anything, they are enabled to simulate the option being available if checked">
|
||||
<boolean name="sequences" default="true" />
|
||||
<boolean name="indexes" default="true" />
|
||||
<boolean name="affected_rows" default="true" />
|
||||
<boolean name="summary_functions" default="true" />
|
||||
<boolean name="order_by_text" default="true" />
|
||||
<boolean name="current_id" default="true" />
|
||||
<boolean name="limit_querys" default="true" comments="this one is functional" />
|
||||
<boolean name="LOBs" default="true" />
|
||||
<boolean name="replace" default="true" />
|
||||
<boolean name="sub_selects" default="true" />
|
||||
<boolean name="transactions" default="true" />
|
||||
</array>
|
||||
<string name="last_query" comments="last value passed in with query()" />
|
||||
<array name="options" comments="these can be changed at run time">
|
||||
<string name="columnDelim" default="," />
|
||||
<string name="dataDelim" default="|" />
|
||||
<string name="eolDelim" default="chr(13).chr(10)" />
|
||||
</array>
|
||||
</object>
|
||||
<array name="result" comments="the simulated record set returned by ::query()">
|
||||
<array comments="columns">
|
||||
<string comments="column name" />
|
||||
</array>
|
||||
<array comments="data">
|
||||
<array comments="row">
|
||||
<string comments="data element" />
|
||||
</array>
|
||||
</array>
|
||||
</array>
|
||||
</out>
|
||||
</io>
|
||||
</fusedoc>
|
||||
*/
|
||||
|
||||
/**
|
||||
* MDB2 QuerySim driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Alan Richmond <arichmond@bigfoot.com>
|
||||
*/
|
||||
class MDB2_Driver_querysim extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "\\";
|
||||
// }}}
|
||||
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'querysim';
|
||||
$this->dbsyntax = 'querysim';
|
||||
|
||||
// Most of these are dummies to simulate availability if checked
|
||||
$this->supported['sequences'] = 'emulated';
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = false;
|
||||
$this->supported['summary_functions'] = false;
|
||||
$this->supported['order_by_text'] = false;
|
||||
$this->supported['current_id'] = 'emulated';
|
||||
$this->supported['limit_queries'] = true;// this one is real
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] = 'emulated';
|
||||
$this->supported['sub_selects'] = 'emulated';
|
||||
$this->supported['transactions'] = false;
|
||||
$this->supported['auto_increment'] = false;
|
||||
$this->supported['primary_key'] = false;
|
||||
|
||||
$this->options['columnDelim'] = ',';
|
||||
$this->options['dataDelim'] = '|';
|
||||
$this->options['eolDelim'] = "\n";
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Open a file or simulate a successful database connect
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK string on success, a MDB2 error object on failure
|
||||
*/
|
||||
function connect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if ($this->connected_database_name == $this->database_name
|
||||
&& ($this->opened_persistent == $this->options['persistent'])
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
if ($this->connected_database_name) {
|
||||
$this->_close($this->connection);
|
||||
}
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
$connection = 1;// sim connect
|
||||
// if external, check file...
|
||||
if ($this->database_name) {
|
||||
$file = $this->database_name;
|
||||
if (!file_exists($file)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'file not found');
|
||||
}
|
||||
if (!is_file($file)) {
|
||||
return $this->raiseError(MDB2_ERROR_INVALID, null, null, 'not a file');
|
||||
}
|
||||
if (!is_readable($file)) {
|
||||
return $this->raiseError(MDB2_ERROR_ACCESS_VIOLATION, null, null,
|
||||
'could not open file - check permissions');
|
||||
}
|
||||
// ...and open if persistent
|
||||
if ($this->options['persistent']) {
|
||||
$connection = @fopen($file, 'r');
|
||||
}
|
||||
}
|
||||
$this->connection = $connection;
|
||||
$this->connected_database_name = $this->database_name;
|
||||
$this->opened_persistent = $this->options['persistent'];
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (($this->opened_persistent) && (is_resource($this->connection))) {
|
||||
if (!@fclose($this->connection)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
if ($isManip) {
|
||||
return $this->raiseError(MDB2_ERROR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->options['disable_query']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = $this->_buildResult($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($limit > 0) {
|
||||
$result[1] = array_slice($result[1], $offset-1, $limit);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ _readFile()
|
||||
|
||||
/**
|
||||
* Read an external file
|
||||
*
|
||||
* @param string filepath/filename
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return string the contents of a file
|
||||
*/
|
||||
function _readFile()
|
||||
{
|
||||
$buffer = '';
|
||||
if ($this->opened_persistent) {
|
||||
while (!feof($this->connection)) {
|
||||
$buffer.= fgets($this->connection, 1024);
|
||||
}
|
||||
} else {
|
||||
$this->connection = @fopen($this->connected_database_name, 'r');
|
||||
while (!feof($this->connection)) {
|
||||
$buffer.= fgets($this->connection, 1024);
|
||||
}
|
||||
$this->connection = @fclose($this->connection);
|
||||
}
|
||||
return $buffer;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ _buildResult()
|
||||
|
||||
/**
|
||||
* Convert QuerySim text into an array
|
||||
*
|
||||
* @param string Text of simulated query
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return multi-dimensional array containing the column names and data
|
||||
* from the QuerySim
|
||||
*/
|
||||
function _buildResult($query)
|
||||
{
|
||||
$eolDelim = $this->options['eolDelim'];
|
||||
$columnDelim = $this->options['columnDelim'];
|
||||
$dataDelim = $this->options['dataDelim'];
|
||||
|
||||
$columnNames = array();
|
||||
$data = array();
|
||||
|
||||
if ($columnDelim == $eolDelim) {
|
||||
return $this->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'columnDelim and eolDelim must be different');
|
||||
} elseif ($dataDelim == $eolDelim){
|
||||
return $this->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'dataDelim and eolDelim must be different');
|
||||
}
|
||||
|
||||
$query = trim($query);
|
||||
//tokenize escaped slashes
|
||||
$query = str_replace('\\\\', '[$double-slash$]', $query);
|
||||
|
||||
if (!strlen($query)) {
|
||||
return $this->raiseError(MDB2_ERROR_SYNTAX, null, null,
|
||||
'empty querysim text');
|
||||
}
|
||||
$lineData = $this->_parseOnDelim($query, $eolDelim);
|
||||
//kill the empty last row created by final eol char if it exists
|
||||
if (!strlen(trim($lineData[count($lineData) - 1]))) {
|
||||
unset($lineData[count($lineData) - 1]);
|
||||
}
|
||||
//populate columnNames array
|
||||
$thisLine = each($lineData);
|
||||
$columnNames = $this->_parseOnDelim($thisLine[1], $columnDelim);
|
||||
if ((in_array('', $columnNames)) || (in_array('NULL', $columnNames))) {
|
||||
return $this->raiseError(MDB2_ERROR_SYNTAX, null, null,
|
||||
'all column names must be defined');
|
||||
}
|
||||
//replace double-slash tokens with single-slash
|
||||
$columnNames = str_replace('[$double-slash$]', '\\', $columnNames);
|
||||
$columnCount = count($columnNames);
|
||||
$rowNum = 0;
|
||||
//loop through data lines
|
||||
if (count($lineData) > 1) {
|
||||
while ($thisLine = each($lineData)) {
|
||||
$thisData = $this->_parseOnDelim($thisLine[1], $dataDelim);
|
||||
$thisDataCount = count($thisData);
|
||||
if ($thisDataCount != $columnCount) {
|
||||
$fileLineNo = $rowNum + 2;
|
||||
return $this->raiseError(MDB2_ERROR_SYNTAX, null, null,
|
||||
"number of data elements ($thisDataCount) in line $fileLineNo not equal to number of defined columns ($columnCount)");
|
||||
}
|
||||
//loop through data elements in data line
|
||||
foreach ($thisData as $thisElement) {
|
||||
if (strtoupper($thisElement) == 'NULL'){
|
||||
$thisElement = '';
|
||||
}
|
||||
//replace double-slash tokens with single-slash
|
||||
$data[$rowNum][] = str_replace('[$double-slash$]', '\\', $thisElement);
|
||||
}//end foreach
|
||||
++$rowNum;
|
||||
}//end while
|
||||
}//end if
|
||||
return array($columnNames, $data);
|
||||
}//end function _buildResult()
|
||||
// }}}
|
||||
|
||||
// {{{ _parseOnDelim()
|
||||
|
||||
/**
|
||||
* Split QuerySim string into an array on a delimiter
|
||||
*
|
||||
* @param string $thisLine Text of simulated query
|
||||
* @param string $delim The delimiter to split on
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return array containing parsed string
|
||||
*/
|
||||
function _parseOnDelim($thisLine, $delim)
|
||||
{
|
||||
$delimQuoted = preg_quote($delim, '/');
|
||||
$thisLine = trim($thisLine);
|
||||
|
||||
$parsed = preg_split('/(?<!\\\\)' .$delimQuoted. '/', $thisLine);
|
||||
//replaces escaped delimiters
|
||||
$parsed = preg_replace('/\\\\' .$delimQuoted. '/', $delim, $parsed);
|
||||
if ($delim != $this->options['eolDelim']) {
|
||||
//replaces escape chars
|
||||
$parsed = preg_replace('/\\\\/', '', $parsed);
|
||||
}
|
||||
return $parsed;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
class MDB2_Result_querysim extends MDB2_Result_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
return $err;
|
||||
}
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
$target_rownum = $this->rownum + 1;
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if (!isset($this->result[1][$target_rownum])) {
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
$row = $this->result[1][$target_rownum];
|
||||
// make row associative
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$column_names = $this->getColumnNames();
|
||||
foreach ($column_names as $name => $i) {
|
||||
$column_names[$name] = $row[$i];
|
||||
}
|
||||
$row = $column_names;
|
||||
}
|
||||
if (($mode = ($this->db->options['portability'] & MDB2_PORTABILITY_RTRIM)
|
||||
+ ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL))
|
||||
) {
|
||||
$this->db->_fixResultArrayValues($row, $mode);
|
||||
}
|
||||
if (!empty($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (!empty($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'getColumnNames: resultset has already been freed');
|
||||
}
|
||||
$columns = array_flip($this->result[0]);
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
$cols = count($this->result[0]);
|
||||
return $cols;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_querysim extends MDB2_Result_querysim
|
||||
{
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
$rows = count($this->result[1]);
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MDB2_Statement_querysim extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,805 +0,0 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@backendmedia.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@backendmedia.com>
|
||||
*/
|
||||
class MDB2_Driver_sqlite extends MDB2_Driver_Common
|
||||
{
|
||||
// {{{ properties
|
||||
var $escape_quotes = "'";
|
||||
|
||||
var $_lasterror = '';
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->phptype = 'sqlite';
|
||||
$this->dbsyntax = 'sqlite';
|
||||
|
||||
$this->supported['sequences'] = true;
|
||||
$this->supported['indexes'] = true;
|
||||
$this->supported['affected_rows'] = true;
|
||||
$this->supported['summary_functions'] = true;
|
||||
$this->supported['order_by_text'] = true;
|
||||
$this->supported['current_id'] = true;
|
||||
$this->supported['limit_queries'] = true;
|
||||
$this->supported['LOBs'] = true;
|
||||
$this->supported['replace'] = true;
|
||||
$this->supported['transactions'] = true;
|
||||
$this->supported['sub_selects'] = true;
|
||||
$this->supported['auto_increment'] = true;
|
||||
|
||||
$this->options['base_transaction_name'] = '___php_MDB2_sqlite_auto_commit_off';
|
||||
$this->options['fixed_float'] = 0;
|
||||
$this->options['database_path'] = '';
|
||||
$this->options['database_extension'] = '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorInfo()
|
||||
|
||||
/**
|
||||
* This method is used to collect information about an error
|
||||
*
|
||||
* @param integer $error
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function errorInfo($error = null)
|
||||
{
|
||||
$native_code = null;
|
||||
if ($this->connection) {
|
||||
$native_code = @sqlite_last_error($this->connection);
|
||||
}
|
||||
$native_msg = @sqlite_error_string($native_code);
|
||||
|
||||
if (is_null($error)) {
|
||||
static $error_regexps;
|
||||
if (empty($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/^no such table:/' => MDB2_ERROR_NOSUCHTABLE,
|
||||
'/^no such index:/' => MDB2_ERROR_NOT_FOUND,
|
||||
'/^(table|index) .* already exists$/' => MDB2_ERROR_ALREADY_EXISTS,
|
||||
'/PRIMARY KEY must be unique/i' => MDB2_ERROR_CONSTRAINT,
|
||||
'/is not unique/' => MDB2_ERROR_CONSTRAINT,
|
||||
'/columns .* are not unique/i' => MDB2_ERROR_CONSTRAINT,
|
||||
'/uniqueness constraint failed/' => MDB2_ERROR_CONSTRAINT,
|
||||
'/may not be NULL/' => MDB2_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'/^no such column:/' => MDB2_ERROR_NOSUCHFIELD,
|
||||
'/column not present in both tables/i' => MDB2_ERROR_NOSUCHFIELD,
|
||||
'/^near ".*": syntax error$/' => MDB2_ERROR_SYNTAX,
|
||||
'/[0-9]+ values for [0-9]+ columns/i' => MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $this->_lasterror)) {
|
||||
$error = $code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array($error, $native_code, $native_msg);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ escape()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used in a query. It will quote
|
||||
* the text so it can safely be used within a query.
|
||||
*
|
||||
* @param string $text the input string to quote
|
||||
* @return string quoted string
|
||||
* @access public
|
||||
*/
|
||||
function escape($text)
|
||||
{
|
||||
return @sqlite_escape_string($text);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ beginTransaction()
|
||||
|
||||
/**
|
||||
* Start a transaction.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
$this->debug('starting transaction', 'beginTransaction');
|
||||
if ($this->in_transaction) {
|
||||
return MDB2_OK; //nothing to do
|
||||
}
|
||||
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||
$this->destructor_registered = true;
|
||||
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||
}
|
||||
$query = 'BEGIN TRANSACTION '.$this->options['base_transaction_name'];
|
||||
$result = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = true;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit the database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$this->debug('commit transaction', 'commit');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'commit: transaction changes are being auto committed');
|
||||
}
|
||||
$query = 'COMMIT TRANSACTION '.$this->options['base_transaction_name'];
|
||||
$result = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Cancel any database changes done during a transaction that is in
|
||||
* progress.
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$this->debug('rolling back transaction', 'rollback');
|
||||
if (!$this->in_transaction) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||
}
|
||||
$query = 'ROLLBACK TRANSACTION '.$this->options['base_transaction_name'];
|
||||
$result = $this->_doQuery($query, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$this->in_transaction = false;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDatabaseFile()
|
||||
|
||||
/**
|
||||
* Builds the string with path+dbname+extension
|
||||
*
|
||||
* @return string full database path+file
|
||||
* @access protected
|
||||
*/
|
||||
function _getDatabaseFile($database_name)
|
||||
{
|
||||
if ($database_name == '') {
|
||||
return $database_name;
|
||||
}
|
||||
return $this->options['database_path'].$database_name.$this->options['database_extension'];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database
|
||||
*
|
||||
* @return true on success, MDB2 Error Object on failure
|
||||
**/
|
||||
function connect()
|
||||
{
|
||||
$database_file = $this->_getDatabaseFile($this->database_name);
|
||||
if (is_resource($this->connection)) {
|
||||
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||
&& $this->connected_database_name == $database_file
|
||||
&& $this->opened_persistent == $this->options['persistent']
|
||||
) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
$this->disconnect(false);
|
||||
}
|
||||
|
||||
if (!PEAR::loadExtension($this->phptype)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||
}
|
||||
|
||||
if (!empty($this->database_name)) {
|
||||
if (!file_exists($database_file)) {
|
||||
if (!touch($database_file)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND);
|
||||
}
|
||||
if (!isset($this->dsn['mode'])
|
||||
|| !is_numeric($this->dsn['mode'])
|
||||
) {
|
||||
$mode = 0644;
|
||||
} else {
|
||||
$mode = octdec($this->dsn['mode']);
|
||||
}
|
||||
if (!chmod($database_file, $mode)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND);
|
||||
}
|
||||
if (!file_exists($database_file)) {
|
||||
return $this->raiseError(MDB2_ERROR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
if (!is_file($database_file)) {
|
||||
return $this->raiseError(MDB2_ERROR_INVALID);
|
||||
}
|
||||
if (!is_readable($database_file)) {
|
||||
return $this->raiseError(MDB2_ERROR_ACCESS_VIOLATION);
|
||||
}
|
||||
|
||||
$connect_function = ($this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open');
|
||||
$php_errormsg = '';
|
||||
@ini_set('track_errors', true);
|
||||
$connection = @$connect_function($database_file);
|
||||
@ini_restore('track_errors');
|
||||
$this->_lasterror = isset($php_errormsg) ? $php_errormsg : '';
|
||||
if (!$connection) {
|
||||
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
$this->connection = $connection;
|
||||
$this->connected_dsn = $this->dsn;
|
||||
$this->connected_database_name = $database_file;
|
||||
$this->opened_persistent = $this->getoption('persistent');
|
||||
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return mixed true on success, false if not connected and error
|
||||
* object on error
|
||||
* @access public
|
||||
*/
|
||||
function disconnect($force = true)
|
||||
{
|
||||
if (is_resource($this->connection)) {
|
||||
if (!$this->opened_persistent || $force) {
|
||||
@sqlite_close($this->connection);
|
||||
}
|
||||
$this->connection = 0;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _doQuery()
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
* @param string $query query
|
||||
* @param boolean $isManip if the query is a manipulation query
|
||||
* @param resource $connection
|
||||
* @param string $database_name
|
||||
* @return result or error object
|
||||
* @access protected
|
||||
*/
|
||||
function _doQuery($query, $isManip = false, $connection = null, $database_name = null)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
if ($this->options['disable_query']) {
|
||||
if ($isManip) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($connection)) {
|
||||
$error = $this->connect();
|
||||
if (PEAR::isError($error)) {
|
||||
return $error;
|
||||
}
|
||||
$connection = $this->connection;
|
||||
}
|
||||
|
||||
$function = $this->options['result_buffering']
|
||||
? 'sqlite_query' : 'sqlite_unbuffered_query';
|
||||
$php_errormsg = '';
|
||||
ini_set('track_errors', true);
|
||||
$result = @$function($query.';', $connection);
|
||||
ini_restore('track_errors');
|
||||
$this->_lasterror = isset($php_errormsg) ? $php_errormsg : '';
|
||||
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
|
||||
if ($isManip) {
|
||||
return @sqlite_changes($connection);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _modifyQuery()
|
||||
|
||||
/**
|
||||
* Changes a query string for various DBMS specific reasons
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @return the new (modified) query
|
||||
* @access protected
|
||||
*/
|
||||
function _modifyQuery($query, $isManip, $limit, $offset)
|
||||
{
|
||||
if ($this->options['portability'] & MDB2_PORTABILITY_DELETE_COUNT) {
|
||||
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
|
||||
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
|
||||
'DELETE FROM \1 WHERE 1=1', $query);
|
||||
}
|
||||
}
|
||||
if ($limit > 0
|
||||
&& !preg_match('/LIMIT\s*\d(\s*(,|OFFSET)\s*\d+)?/i', $query)
|
||||
) {
|
||||
$query = rtrim($query);
|
||||
if (substr($query, -1) == ';') {
|
||||
$query = substr($query, 0, -1);
|
||||
}
|
||||
if ($isManip) {
|
||||
$query .= " LIMIT $limit";
|
||||
} else {
|
||||
$query .= " LIMIT $offset,$limit";
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
|
||||
* query, except that if there is already a row in the table with the same
|
||||
* key field values, the REPLACE query just updates its values instead of
|
||||
* inserting a new row.
|
||||
*
|
||||
* The REPLACE type of query does not make part of the SQL standards. Since
|
||||
* practically only SQLite implements it natively, this type of query is
|
||||
* emulated through this method for other DBMS using standard types of
|
||||
* queries inside a transaction to assure the atomicity of the operation.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $table name of the table on which the REPLACE query will
|
||||
* be executed.
|
||||
* @param array $fields associative array that describes the fields and the
|
||||
* values that will be inserted or updated in the specified table. The
|
||||
* indexes of the array are the names of all the fields of the table. The
|
||||
* values of the array are also associative arrays that describe the
|
||||
* values and other properties of the table fields.
|
||||
*
|
||||
* Here follows a list of field properties that need to be specified:
|
||||
*
|
||||
* value:
|
||||
* Value to be assigned to the specified field. This value may be
|
||||
* of specified in database independent type format as this
|
||||
* function can perform the necessary datatype conversions.
|
||||
*
|
||||
* Default:
|
||||
* this property is required unless the Null property
|
||||
* is set to 1.
|
||||
*
|
||||
* type
|
||||
* Name of the type of the field. Currently, all types Metabase
|
||||
* are supported except for clob and blob.
|
||||
*
|
||||
* Default: no type conversion
|
||||
*
|
||||
* null
|
||||
* Boolean property that indicates that the value for this field
|
||||
* should be set to null.
|
||||
*
|
||||
* The default value for fields missing in INSERT queries may be
|
||||
* specified the definition of a table. Often, the default value
|
||||
* is already null, but since the REPLACE may be emulated using
|
||||
* an UPDATE query, make sure that all fields of the table are
|
||||
* listed in this function argument array.
|
||||
*
|
||||
* Default: 0
|
||||
*
|
||||
* key
|
||||
* Boolean property that indicates that this field should be
|
||||
* handled as a primary key or at least as part of the compound
|
||||
* unique index of the table that will determine the row that will
|
||||
* updated if it exists or inserted a new row otherwise.
|
||||
*
|
||||
* This function will fail if no key field is specified or if the
|
||||
* value of a key field is set to null because fields that are
|
||||
* part of unique index they may not be null.
|
||||
*
|
||||
* Default: 0
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function replace($table, $fields)
|
||||
{
|
||||
$count = count($fields);
|
||||
$query = $values = '';
|
||||
$keys = $colnum = 0;
|
||||
for (reset($fields); $colnum < $count; next($fields), $colnum++) {
|
||||
$name = key($fields);
|
||||
if ($colnum > 0) {
|
||||
$query .= ',';
|
||||
$values .= ',';
|
||||
}
|
||||
$query .= $name;
|
||||
if (isset($fields[$name]['null']) && $fields[$name]['null']) {
|
||||
$value = 'NULL';
|
||||
} else {
|
||||
$value = $this->quote($fields[$name]['value'], $fields[$name]['type']);
|
||||
}
|
||||
$values .= $value;
|
||||
if (isset($fields[$name]['key']) && $fields[$name]['key']) {
|
||||
if ($value === 'NULL') {
|
||||
return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null,
|
||||
'replace: key value '.$name.' may not be NULL');
|
||||
}
|
||||
$keys++;
|
||||
}
|
||||
}
|
||||
if ($keys == 0) {
|
||||
return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null,
|
||||
'replace: not specified which fields are keys');
|
||||
}
|
||||
$query = "REPLACE INTO $table ($query) VALUES ($values)";
|
||||
$this->last_query = $query;
|
||||
$this->debug($query, 'query');
|
||||
return $this->_doQuery($query, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function nextID($seq_name, $ondemand = true)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
$query = "INSERT INTO $sequence_name (".$this->options['seqcol_name'].") VALUES (NULL)";
|
||||
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||
$result = $this->_doQuery($query, true);
|
||||
$this->popExpect();
|
||||
if (PEAR::isError($result)) {
|
||||
if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||
$this->loadModule('Manager');
|
||||
// Since we are creating the sequence on demand
|
||||
// we know the first id = 1 so initialize the
|
||||
// sequence at 2
|
||||
$result = $this->manager->createSequence($seq_name, 2);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError(MDB2_ERROR, null, null,
|
||||
'nextID: on demand sequence '.$seq_name.' could not be created');
|
||||
} else {
|
||||
// First ID of a newly created sequence is 1
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
$value = @sqlite_last_insert_rowid($this->connection);
|
||||
if (is_numeric($value)
|
||||
&& PEAR::isError($this->_doQuery("DELETE FROM $sequence_name WHERE ".$this->options['seqcol_name']." < $value", true))
|
||||
) {
|
||||
$this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAfterID()
|
||||
|
||||
/**
|
||||
* returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed $id value as returned by getBeforeId()
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function getAfterID($id, $table)
|
||||
{
|
||||
$this->loadModule('Native');
|
||||
return $this->native->getInsertID();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ currID()
|
||||
|
||||
/**
|
||||
* returns the current id of a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function currID($seq_name)
|
||||
{
|
||||
$sequence_name = $this->getSequenceName($seq_name);
|
||||
return $this->queryOne("SELECT MAX(".$this->options['seqcol_name'].") FROM $sequence_name", 'integer');
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Result_sqlite extends MDB2_Result_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ fetchRow()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param int $fetchmode how the array data should be indexed
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return int data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
if (!is_null($rownum)) {
|
||||
$seek = $this->seek($rownum);
|
||||
if (PEAR::isError($seek)) {
|
||||
return $seek;
|
||||
}
|
||||
}
|
||||
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->db->fetchmode;
|
||||
}
|
||||
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||
$row = @sqlite_fetch_array($this->result, SQLITE_ASSOC);
|
||||
if (is_array($row)
|
||||
&& $this->db->options['portability'] & MDB2_PORTABILITY_LOWERCASE
|
||||
) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$row = @sqlite_fetch_array($this->result, SQLITE_NUM);
|
||||
}
|
||||
if (!$row) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'fetchRow: resultset has already been freed');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||
$this->db->_convertEmptyArrayValuesToNull($row);
|
||||
}
|
||||
if (isset($this->values)) {
|
||||
$this->_assignBindColumns($row);
|
||||
}
|
||||
if (isset($this->types)) {
|
||||
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||
}
|
||||
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||
$object_class = $this->db->options['fetch_class'];
|
||||
if ($object_class == 'stdClass') {
|
||||
$row = (object) $row;
|
||||
} else {
|
||||
$row = &new $object_class($row);
|
||||
}
|
||||
}
|
||||
++$this->rownum;
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getColumnNames()
|
||||
|
||||
/**
|
||||
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @return mixed an associative array variable
|
||||
* that will hold the names of columns. The
|
||||
* indexes of the array are the column names
|
||||
* mapped to lower case and the values are the
|
||||
* respective numbers of the columns starting
|
||||
* from 0. Some DBMS may not return any
|
||||
* columns when the result set does not
|
||||
* contain any rows.
|
||||
*
|
||||
* a MDB2 error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _getColumnNames()
|
||||
{
|
||||
$columns = array();
|
||||
$numcols = $this->numCols();
|
||||
if (PEAR::isError($numcols)) {
|
||||
return $numcols;
|
||||
}
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @sqlite_field_name($this->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
if ($this->db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
|
||||
$columns = array_change_key_case($columns, CASE_LOWER);
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Count the number of columns returned by the DBMS in a query result.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed integer value with the number of columns, a MDB2 error
|
||||
* on failure
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
$cols = @sqlite_num_fields($this->result);
|
||||
if (is_null($cols)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numCols: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedResult_sqlite extends MDB2_Result_sqlite
|
||||
{
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function seek($rownum = 0)
|
||||
{
|
||||
if (!@sqlite_seek($this->result, $rownum)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'seek: resultset has already been freed');
|
||||
}
|
||||
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||
}
|
||||
$this->rownum = $rownum - 1;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
$numrows = $this->numRows();
|
||||
if (PEAR::isError($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
return $this->rownum < ($numrows - 1);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
$rows = @sqlite_num_rows($this->result);
|
||||
if (is_null($rows)) {
|
||||
if (is_null($this->result)) {
|
||||
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'numRows: resultset has already been freed');
|
||||
}
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_Statement_sqlite extends MDB2_Statement_Common
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,605 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used by autoPrepare()
|
||||
*/
|
||||
define('MDB2_AUTOQUERY_INSERT', 1);
|
||||
define('MDB2_AUTOQUERY_UPDATE', 2);
|
||||
|
||||
/**
|
||||
* MDB2_Extended: class which adds several high level methods to MDB2
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Extended extends MDB2_Module_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ autoPrepare()
|
||||
|
||||
/**
|
||||
* Make automaticaly an insert or update query and call prepare() with it
|
||||
*
|
||||
* @param string $table name of the table
|
||||
* @param array $table_fields ordered array containing the fields names
|
||||
* @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
|
||||
* @param string $where in case of update queries, this string will be put after the sql WHERE statement
|
||||
* @return resource handle for the query
|
||||
* @param mixed $types array that contains the types of the placeholders
|
||||
* @param mixed $result_types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @see buildManipSQL
|
||||
* @access public
|
||||
*/
|
||||
function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_types = null)
|
||||
{
|
||||
$query = $this->buildManipSQL($table, $table_fields, $mode, $where);
|
||||
if (PEAR::isError($query)) {
|
||||
return $query;
|
||||
}
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->prepare($query, $types, $result_types);
|
||||
}
|
||||
|
||||
// {{{
|
||||
// }}} autoExecute()
|
||||
|
||||
/**
|
||||
* Make automaticaly an insert or update query and call prepare() and execute() with it
|
||||
*
|
||||
* @param string $table name of the table
|
||||
* @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value
|
||||
* @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
|
||||
* @param string $where in case of update queries, this string will be put after the sql WHERE statement
|
||||
* @param mixed $types array that contains the types of the placeholders
|
||||
* @param mixed $result_types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @return mixed a new MDB2_Result or a MDB2 Error Object when fail
|
||||
* @see buildManipSQL
|
||||
* @see autoPrepare
|
||||
* @access public
|
||||
*/
|
||||
function &autoExecute($table, $fields_values, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_types = null, $result_class = true)
|
||||
{
|
||||
$stmt = $this->autoPrepare($table, array_keys($fields_values), $mode, $where, $types, $result_types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$params = array_values($fields_values);
|
||||
$stmt->bindParamArray($params);
|
||||
$result =& $stmt->execute($result_class);
|
||||
$stmt->free();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// {{{
|
||||
// }}} buildManipSQL()
|
||||
|
||||
/**
|
||||
* Make automaticaly an sql query for prepare()
|
||||
*
|
||||
* Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), MDB2_AUTOQUERY_INSERT)
|
||||
* will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
|
||||
* NB : - This belongs more to a SQL Builder class, but this is a simple facility
|
||||
* - Be carefull ! If you don't give a $where param with an UPDATE query, all
|
||||
* the records of the table will be updated !
|
||||
*
|
||||
* @param string $table name of the table
|
||||
* @param array $table_fields ordered array containing the fields names
|
||||
* @param int $mode type of query to make (MDB2_AUTOQUERY_INSERT or MDB2_AUTOQUERY_UPDATE)
|
||||
* @param string $where in case of update queries, this string will be put after the sql WHERE statement
|
||||
* @return string sql query for prepare()
|
||||
* @access public
|
||||
*/
|
||||
function buildManipSQL($table, $table_fields, $mode, $where = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (count($table_fields) == 0) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
switch ($mode) {
|
||||
case MDB2_AUTOQUERY_INSERT:
|
||||
$cols = implode(', ', $table_fields);
|
||||
$values = '?'.str_repeat(', ?', count($table_fields)-1);
|
||||
return 'INSERT INTO '.$table.' ('.$cols.') VALUES ('.$values.')';
|
||||
break;
|
||||
case MDB2_AUTOQUERY_UPDATE:
|
||||
$set = implode(' = ?, ', $table_fields).' = ?';
|
||||
$sql = 'UPDATE '.$table.' SET '.$set;
|
||||
if ($where !== false) {
|
||||
$sql.= ' WHERE '.$where;
|
||||
}
|
||||
return $sql;
|
||||
break;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_SYNTAX);
|
||||
}
|
||||
|
||||
// {{{
|
||||
// }}} limitQuery()
|
||||
|
||||
/**
|
||||
* Generates a limited query
|
||||
*
|
||||
* @param string $query query
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param integer $from the row to start to fetching
|
||||
* @param integer $count the numbers of rows to fetch
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @return mixed a valid ressource pointer or a MDB2 Error Object
|
||||
* @access public
|
||||
*/
|
||||
function &limitQuery($query, $types, $count, $from = 0, $result_class = true)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->setLimit($count, $from);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result =& $db->query($query, $types, $result_class);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// {{{
|
||||
// }}} getOne()
|
||||
|
||||
/**
|
||||
* Fetch the first column of the first row of data returned from
|
||||
* a query. Takes care of doing the query and freeing the results
|
||||
* when finished.
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param string $type string that contains the type of the column in the
|
||||
* result set
|
||||
* @param array $params if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array $param_types array that contains the types of the values
|
||||
* defined in $params
|
||||
* @param mixed $colnum which column to return
|
||||
* @return mixed MDB2_OK or data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getOne($query, $type = null, $params = array(),
|
||||
$param_types = null, $colnum = 0)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
settype($type, 'array');
|
||||
if (count($params) == 0) {
|
||||
return $db->queryOne($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$stmt->bindParamArray($params);
|
||||
$result = $stmt->execute();
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$one = $result->fetchOne($colnum);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $one;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getRow()
|
||||
|
||||
/**
|
||||
* Fetch the first row of data returned from a query. Takes care
|
||||
* of doing the query and freeing the results when finished.
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param array $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param array $params array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array $param_types array that contains the types of the values
|
||||
* defined in $params
|
||||
* @param integer $fetchmode the fetch mode to use
|
||||
* @return mixed MDB2_OK or data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getRow($query, $types = null, $params = array(),
|
||||
$param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (count($params) == 0) {
|
||||
return $db->queryRow($query, $types, $fetchmode);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$stmt->bindParamArray($params);
|
||||
$result = $stmt->execute();
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetchRow($fetchmode);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getCol()
|
||||
|
||||
/**
|
||||
* Fetch a single column from a result set and return it as an
|
||||
* indexed array.
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param string $type string that contains the type of the column in the
|
||||
* result set
|
||||
* @param array $params array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array $param_types array that contains the types of the values
|
||||
* defined in $params
|
||||
* @param mixed $colnum which column to return
|
||||
* @return mixed MDB2_OK or data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getCol($query, $type = null, $params = array(),
|
||||
$param_types = null, $colnum = 0)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
settype($type, 'array');
|
||||
if (count($params) == 0) {
|
||||
return $db->queryCol($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$stmt->bindParamArray($params);
|
||||
$result = $stmt->execute();
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$col = $result->fetchCol($colnum);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $col;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAll()
|
||||
|
||||
/**
|
||||
* Fetch all the rows returned from a query.
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param array $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param array $params array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array $param_types array that contains the types of the values
|
||||
* defined in $params
|
||||
* @param integer $fetchmode the fetch mode to use
|
||||
* @param boolean $rekey if set to true, the $all will have the first
|
||||
* column as its first dimension
|
||||
* @param boolean $force_array used only when the query returns exactly
|
||||
* two columns. If true, the values of the returned array will be
|
||||
* one-element arrays instead of scalars.
|
||||
* @param boolean $group if true, the values of the returned array is
|
||||
* wrapped in another array. If the same key value (in the first
|
||||
* column) repeats itself, the values will be appended to this array
|
||||
* instead of overwriting the existing values.
|
||||
* @return mixed MDB2_OK or data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getAll($query, $types = null, $params = array(),
|
||||
$param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT,
|
||||
$rekey = false, $force_array = false, $group = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (count($params) == 0) {
|
||||
return $db->queryAll($query, $types, $fetchmode, $rekey, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$stmt->bindParamArray($params);
|
||||
$result = $stmt->execute();
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$all = $result->fetchAll($fetchmode, $rekey, $force_array, $group);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $all;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAssoc()
|
||||
|
||||
/**
|
||||
* Fetch the entire result set of a query and return it as an
|
||||
* associative array using the first column as the key.
|
||||
*
|
||||
* If the result set contains more than two columns, the value
|
||||
* will be an array of the values from column 2-n. If the result
|
||||
* set contains only two columns, the returned value will be a
|
||||
* scalar with the value of the second column (unless forced to an
|
||||
* array with the $force_array parameter). A MDB error code is
|
||||
* returned on errors. If the result set contains fewer than two
|
||||
* columns, a MDB2_ERROR_TRUNCATED error is returned.
|
||||
*
|
||||
* For example, if the table 'mytable' contains:
|
||||
*
|
||||
* ID TEXT DATE
|
||||
* --------------------------------
|
||||
* 1 'one' 944679408
|
||||
* 2 'two' 944679408
|
||||
* 3 'three' 944679408
|
||||
*
|
||||
* Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
||||
* array(
|
||||
* '1' => 'one',
|
||||
* '2' => 'two',
|
||||
* '3' => 'three',
|
||||
* )
|
||||
*
|
||||
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
||||
* array(
|
||||
* '1' => array('one', '944679408'),
|
||||
* '2' => array('two', '944679408'),
|
||||
* '3' => array('three', '944679408')
|
||||
* )
|
||||
*
|
||||
* If the more than one row occurs with the same value in the
|
||||
* first column, the last row overwrites all previous ones by
|
||||
* default. Use the $group parameter if you don't want to
|
||||
* overwrite like this. Example:
|
||||
*
|
||||
* getAssoc('SELECT category,id,name FROM mytable', null, null
|
||||
* MDB2_FETCHMODE_ASSOC, false, true) returns:
|
||||
* array(
|
||||
* '1' => array(array('id' => '4', 'name' => 'number four'),
|
||||
* array('id' => '6', 'name' => 'number six')
|
||||
* ),
|
||||
* '9' => array(array('id' => '4', 'name' => 'number four'),
|
||||
* array('id' => '6', 'name' => 'number six')
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* Keep in mind that database functions in PHP usually return string
|
||||
* values for results regardless of the database's internal type.
|
||||
*
|
||||
* @param string $query the SQL query
|
||||
* @param array $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param array $params array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array $param_types array that contains the types of the values
|
||||
* defined in $params
|
||||
* @param boolean $force_array used only when the query returns
|
||||
* exactly two columns. If TRUE, the values of the returned array
|
||||
* will be one-element arrays instead of scalars.
|
||||
* @param boolean $group if TRUE, the values of the returned array
|
||||
* is wrapped in another array. If the same key value (in the first
|
||||
* column) repeats itself, the values will be appended to this array
|
||||
* instead of overwriting the existing values.
|
||||
* @return array associative array with results from the query.
|
||||
* @access public
|
||||
*/
|
||||
function getAssoc($query, $types = null, $params = array(), $param_types = null,
|
||||
$fetchmode = MDB2_FETCHMODE_DEFAULT, $force_array = false, $group = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (count($params) == 0) {
|
||||
return $db->queryAll($query, $types, $fetchmode, true, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$stmt->bindParamArray($params);
|
||||
$result = $stmt->execute();
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$all = $result->fetchAll($fetchmode, true, $force_array, $group);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $all;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ executeMultiple()
|
||||
|
||||
/**
|
||||
* This function does several execute() calls on the same statement handle.
|
||||
* $params must be an array indexed numerically from 0, one execute call is
|
||||
* done for every 'row' in the array.
|
||||
*
|
||||
* If an error occurs during execute(), executeMultiple() does not execute
|
||||
* the unfinished rows, but rather returns that error.
|
||||
*
|
||||
* @param resource $stmt query handle from prepare()
|
||||
* @param array $params numeric array containing the
|
||||
* data to insert into the query
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
* @see prepare(), execute()
|
||||
*/
|
||||
function executeMultiple(&$stmt, $params = null)
|
||||
{
|
||||
for ($i = 0, $j = count($params); $i < $j; $i++) {
|
||||
$stmt->bindParamArray($params[$i]);
|
||||
$result = $stmt->execute();
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getBeforeID()
|
||||
|
||||
/**
|
||||
* returns the next free id of a sequence if the RDBMS
|
||||
* does not support auto increment
|
||||
*
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @param boolean $ondemand when true the seqence is
|
||||
* automatic created, if it
|
||||
* not exists
|
||||
*
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function getBeforeID($table, $field, $ondemand = true)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->supports('auto_increment') !== true) {
|
||||
$seq = $table.(empty($field) ? '' : '_'.$field);
|
||||
$id = $db->nextID($seq, $ondemand);
|
||||
if (PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
return $db->quote($id, 'integer');
|
||||
}
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAfterID()
|
||||
|
||||
/**
|
||||
* returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed $id value as returned by getBeforeId()
|
||||
* @param string $table name of the table into which a new row was inserted
|
||||
* @return mixed MDB2 Error Object or id
|
||||
* @access public
|
||||
*/
|
||||
function getAfterID($id, $table, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->supports('auto_increment') !== true) {
|
||||
return $id;
|
||||
}
|
||||
return $db->lastInsertID($table, $field);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
@ -1,285 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Iterator implements Iterator
|
||||
{
|
||||
protected $fetchmode;
|
||||
protected $result;
|
||||
protected $row;
|
||||
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($result, $fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->fetchmode = $fetchmode;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* seek forward to a specific row in a result set
|
||||
*
|
||||
* @param int $rownum number of the row where the data can be found
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
$this->row = null;
|
||||
if ($this->result) {
|
||||
$this->result->seek($rownum);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ next()
|
||||
|
||||
/**
|
||||
* Fetch next row of data
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->row = null;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ current()
|
||||
|
||||
/**
|
||||
* return a row of data
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if (is_null($this->row)) {
|
||||
$row = $this->result->fetchRow($this->fetchmode);
|
||||
if (PEAR::isError($row)) {
|
||||
$row = false;
|
||||
}
|
||||
$this->row = $row;
|
||||
}
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return (bool)$this->current();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return boolean true on success, false if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function free()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->free();
|
||||
}
|
||||
$this->result = null;
|
||||
$this->row = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ key()
|
||||
|
||||
/**
|
||||
* nothing, but Iterator wants to implement this.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->rowCount();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rewind()
|
||||
|
||||
/**
|
||||
* seek to the first row in a result set
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ destructor
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->free();
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_BufferedIterator extends MDB2_Iterator implements SeekableIterator
|
||||
{
|
||||
// }}}
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* check if the end of the result set has been reached
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->valid();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{count()
|
||||
|
||||
/**
|
||||
* returns the number of rows in a result object
|
||||
*
|
||||
* @return mixed MDB2 Error Object or the number of rows
|
||||
* @access public
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->numRows();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ hasPrev()
|
||||
|
||||
/**
|
||||
* check if there is a previous row
|
||||
*
|
||||
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
public function hasPrev()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->rowCount() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rewind()
|
||||
|
||||
/**
|
||||
* seek to the first row in a result set
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ prev()
|
||||
|
||||
/**
|
||||
* move internal row point to the previous row
|
||||
* Fetch and return a row of data
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function prev()
|
||||
{
|
||||
if ($this->hasPrev()) {
|
||||
$this->seek($this->result->rowCount() - 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return $this->next();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,146 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
require_once 'MDB2.php';
|
||||
|
||||
class MDB2_LOB
|
||||
{
|
||||
var $db_index;
|
||||
var $lob_index;
|
||||
var $lob;
|
||||
|
||||
function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
if (!preg_match('/^rb?\+?$/', $mode)) {
|
||||
return false;
|
||||
}
|
||||
$url = parse_url($path);
|
||||
if (!array_key_exists('host', $url) && !array_key_exists('user', $url)) {
|
||||
return false;
|
||||
}
|
||||
$this->db_index = $url['host'];
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return false;
|
||||
}
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$this->lob_index = $url['user'];
|
||||
if (!isset($db->datatype->lobs[$this->lob_index])) {
|
||||
return false;
|
||||
}
|
||||
$this->lob =& $db->datatype->lobs[$this->lob_index];
|
||||
$db->datatype->_retrieveLOB($this->lob);
|
||||
return true;
|
||||
}
|
||||
|
||||
function stream_read($count)
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
|
||||
$data = $db->datatype->_readLOB($this->lob, $count);
|
||||
$length = strlen($data);
|
||||
if ($length == 0) {
|
||||
$this->lob['endOfLOB'] = true;
|
||||
}
|
||||
$this->lob['position'] += $length;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
function stream_write($data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function stream_tell()
|
||||
{
|
||||
return $this->lob['position'];
|
||||
}
|
||||
|
||||
function stream_eof()
|
||||
{
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return true;
|
||||
}
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$result = $db->datatype->_endOfLOB($this->lob);
|
||||
if (version_compare(phpversion(), "5.0", ">=")
|
||||
&& version_compare(phpversion(), "5.1", "<")
|
||||
) {
|
||||
return !$result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function stream_seek($offset, $whence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function stream_close()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if (isset($db->datatype->lobs[$this->lob_index])) {
|
||||
$db->datatype->_destroyLOB($this->lob_index);
|
||||
unset($db->datatype->lobs[$this->lob_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream_wrapper_register("MDB2LOB", "MDB2_LOB")) {
|
||||
MDB2::raiseError();
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
@ -1,750 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | |
|
||||
// | Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution. |
|
||||
// | |
|
||||
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||
// | or promote products derived from this software without specific prior|
|
||||
// | written permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* Wrapper that makes MDB2 behave like PEAR DB
|
||||
* WARNING: this wrapper is broken and unmaintained
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
require_once 'MDB2.php';
|
||||
|
||||
/*
|
||||
* The method mapErrorCode in each MDB2_dbtype implementation maps
|
||||
* native error codes to one of these.
|
||||
*
|
||||
* If you add an error code here, make sure you also add a textual
|
||||
* version of it in DB::errorMessage().
|
||||
*/
|
||||
|
||||
define('DB_OK', MDB2_OK);
|
||||
define('DB_ERROR', MDB2_ERROR);
|
||||
define('DB_ERROR_SYNTAX', MDB2_ERROR_SYNTAX);
|
||||
define('DB_ERROR_CONSTRAINT', MDB2_ERROR_CONSTRAINT);
|
||||
define('DB_ERROR_NOT_FOUND', MDB2_ERROR_NOT_FOUND);
|
||||
define('DB_ERROR_ALREADY_EXISTS', MDB2_ERROR_ALREADY_EXISTS);
|
||||
define('DB_ERROR_UNSUPPORTED', MDB2_ERROR_UNSUPPORTED);
|
||||
define('DB_ERROR_MISMATCH', MDB2_ERROR_MISMATCH);
|
||||
define('DB_ERROR_INVALID', MDB2_ERROR_INVALID);
|
||||
define('DB_ERROR_NOT_CAPABLE', MDB2_ERROR_NOT_CAPABLE);
|
||||
define('DB_ERROR_TRUNCATED', MDB2_ERROR_TRUNCATED);
|
||||
define('DB_ERROR_INVALID_NUMBER', MDB2_ERROR_INVALID_NUMBER);
|
||||
define('DB_ERROR_INVALID_DATE', MDB2_ERROR_INVALID_DATE);
|
||||
define('DB_ERROR_DIVZERO', MDB2_ERROR_DIVZERO);
|
||||
define('DB_ERROR_NODBSELECTED', MDB2_ERROR_NODBSELECTED);
|
||||
define('DB_ERROR_CANNOT_CREATE', MDB2_ERROR_CANNOT_CREATE);
|
||||
define('DB_ERROR_CANNOT_DROP', MDB2_ERROR_CANNOT_DROP);
|
||||
define('DB_ERROR_NOSUCHTABLE', MDB2_ERROR_NOSUCHTABLE);
|
||||
define('DB_ERROR_NOSUCHFIELD', MDB2_ERROR_NOSUCHFIELD);
|
||||
define('DB_ERROR_NEED_MORE_DATA', MDB2_ERROR_NEED_MORE_DATA);
|
||||
define('DB_ERROR_NOT_LOCKED', MDB2_ERROR_NOT_LOCKED);
|
||||
define('DB_ERROR_VALUE_COUNT_ON_ROW', MDB2_ERROR_VALUE_COUNT_ON_ROW);
|
||||
define('DB_ERROR_INVALID_DSN', MDB2_ERROR_INVALID_DSN);
|
||||
define('DB_ERROR_CONNECT_FAILED', MDB2_ERROR_CONNECT_FAILED);
|
||||
define('DB_ERROR_EXTENSION_NOT_FOUND', MDB2_ERROR_EXTENSION_NOT_FOUND);
|
||||
define('DB_ERROR_ACCESS_VIOLATION', MDB2_ERROR_ACCESS_VIOLATION);
|
||||
define('DB_ERROR_NOSUCHDB', MDB2_ERROR_NOSUCHDB);
|
||||
|
||||
define('DB_WARNING', -1000);
|
||||
define('DB_WARNING_READ_ONLY', -1001);
|
||||
|
||||
define('DB_PARAM_SCALAR', 1);
|
||||
define('DB_PARAM_OPAQUE', 2);
|
||||
define('DB_PARAM_MISC', 3);
|
||||
|
||||
define('DB_BINMODE_PASSTHRU', 1);
|
||||
define('DB_BINMODE_RETURN', 2);
|
||||
define('DB_BINMODE_CONVERT', 3);
|
||||
|
||||
define('DB_FETCHMODE_DEFAULT', MDB2_FETCHMODE_DEFAULT);
|
||||
define('DB_FETCHMODE_ORDERED', MDB2_FETCHMODE_ORDERED);
|
||||
define('DB_FETCHMODE_ASSOC', MDB2_FETCHMODE_ASSOC);
|
||||
define('DB_FETCHMODE_OBJECT', MDB2_FETCHMODE_OBJECT);
|
||||
define('DB_FETCHMODE_FLIPPED', MDB2_FETCHMODE_FLIPPED);
|
||||
|
||||
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
|
||||
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
|
||||
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
|
||||
|
||||
require_once 'MDB2/Extended.php';
|
||||
define('DB_AUTOQUERY_INSERT', MDB2_AUTOQUERY_INSERT);
|
||||
define('DB_AUTOQUERY_UPDATE', MDB2_AUTOQUERY_UPDATE);
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
define('DB_TABLEINFO_ORDER', MDB2_TABLEINFO_ORDER);
|
||||
define('DB_TABLEINFO_ORDERTABLE', MDB2_TABLEINFO_ORDERTABLE);
|
||||
define('DB_TABLEINFO_FULL', MDB2_TABLEINFO_FULL);
|
||||
|
||||
define('DB_PORTABILITY_NONE', MDB2_PORTABILITY_NONE);
|
||||
define('DB_PORTABILITY_LOWERCASE', MDB2_PORTABILITY_FIX_CASE);
|
||||
define('DB_PORTABILITY_RTRIM', MDB2_PORTABILITY_RTRIM);
|
||||
define('DB_PORTABILITY_DELETE_COUNT', MDB2_PORTABILITY_DELETE_COUNT);
|
||||
define('DB_PORTABILITY_NUMROWS', MDB2_PORTABILITY_NUMROWS);
|
||||
define('DB_PORTABILITY_ERRORS', MDB2_PORTABILITY_ERRORS);
|
||||
define('DB_PORTABILITY_NULL_TO_EMPTY', MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||
define('DB_PORTABILITY_ALL', MDB2_PORTABILITY_ALL);
|
||||
|
||||
/**
|
||||
* Wrapper that makes MDB2 behave like PEAR DB
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class DB
|
||||
{
|
||||
function &factory($type)
|
||||
{
|
||||
$db =& MDB2::factory($type);
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$obj =& new MDB2_PEARProxy($db);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
function &connect($dsn, $options = false)
|
||||
{
|
||||
if (!is_array($options) && $options) {
|
||||
$options = array('persistent' => true);
|
||||
}
|
||||
$db =& MDB2::connect($dsn, $options);
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$obj =& new MDB2_PEARProxy($db);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
function apiVersion()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
function isError($value)
|
||||
{
|
||||
return PEAR::isError($value);
|
||||
}
|
||||
|
||||
function isManip($query)
|
||||
{
|
||||
return MDB2::isManip($query);
|
||||
}
|
||||
|
||||
function errorMessage($value)
|
||||
{
|
||||
return MDB2::errorMessage($value);
|
||||
}
|
||||
|
||||
function parseDSN($dsn)
|
||||
{
|
||||
return MDB2::parseDSN($dsn);
|
||||
}
|
||||
|
||||
function assertExtension($name)
|
||||
{
|
||||
if (!extension_loaded($name)) {
|
||||
$dlext = OS_WINDOWS ? '.dll' : '.so';
|
||||
@dl($name . $dlext);
|
||||
}
|
||||
return extension_loaded($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MDB2_Error implements a class for reporting portable database error
|
||||
* messages.
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class DB_Error extends PEAR_Error
|
||||
{
|
||||
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
|
||||
$level = E_USER_NOTICE, $debuginfo = null)
|
||||
{
|
||||
if (is_int($code)) {
|
||||
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
|
||||
} else {
|
||||
$this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper that makes MDB2 behave like PEAR DB
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class DB_result extends MDB2_Result_Common
|
||||
{
|
||||
var $result;
|
||||
var $row_counter = null;
|
||||
|
||||
var $limit_from = null;
|
||||
|
||||
var $limit_count = null;
|
||||
|
||||
function DB_result($result)
|
||||
{
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
$arr = $this->result->fetchRow($fetchmode, $rownum);
|
||||
if ($this->result->mdb->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function fetchInto(&$arr, $fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||
{
|
||||
$arr = $this->fetchRow($fetchmode, $rownum);
|
||||
if ($this->result->mdb->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function _convertNullArrayValuesToEmpty(&$array)
|
||||
{
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
$array[$key] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function numCols()
|
||||
{
|
||||
return $this->result->numCols();
|
||||
}
|
||||
|
||||
function numRows()
|
||||
{
|
||||
return $this->result->numRows();
|
||||
}
|
||||
|
||||
function nextResult()
|
||||
{
|
||||
return $this->result->nextResult();
|
||||
}
|
||||
|
||||
function free()
|
||||
{
|
||||
$err = $this->result->free();
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function tableInfo($mode = null)
|
||||
{
|
||||
$this->result->db->loadModule('Reverse');
|
||||
return $this->result->db->reverse->tableInfo($this->result, $mode);
|
||||
}
|
||||
|
||||
function getRowCounter()
|
||||
{
|
||||
return $this->result->rowCount()+1+$this->result->offset;
|
||||
}
|
||||
}
|
||||
|
||||
class DB_row
|
||||
{
|
||||
function DB_row(&$arr)
|
||||
{
|
||||
for (reset($arr); $key = key($arr); next($arr)) {
|
||||
$this->$key = &$arr[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MDB2_PEARProxy extends PEAR
|
||||
{
|
||||
var $db_object;
|
||||
var $phptype;
|
||||
var $connection;
|
||||
var $dsn;
|
||||
|
||||
function MDB2_PEARProxy(&$db_object)
|
||||
{
|
||||
$this->db_object =& $db_object;
|
||||
$this->PEAR('DB_Error');
|
||||
$this->db_object->setOption('seqcol_name', 'id');
|
||||
$this->db_object->setOption('result_wrap_class', 'DB_result');
|
||||
$this->phptype = $this->db_object->phptype;
|
||||
$this->connection = $this->db_object->connection;
|
||||
$this->dsn = $this->db_object->getDSN();
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
$this->options['persistent'] = $presistent;
|
||||
return $this->db_object->connect();
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
return $this->db_object->disconnect();
|
||||
}
|
||||
|
||||
function toString()
|
||||
{
|
||||
return $this->db_object->__toString();
|
||||
}
|
||||
|
||||
function quoteString($string)
|
||||
{
|
||||
$string = $this->quote($string);
|
||||
if ($string{0} == "'") {
|
||||
return substr($string, 1, -1);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
function quote($string)
|
||||
{
|
||||
if (is_null($string)) {
|
||||
return 'NULL';
|
||||
}
|
||||
return $this->db_object->quote($string);
|
||||
}
|
||||
|
||||
function escapeSimple($str)
|
||||
{
|
||||
return $this->db_object->escape($str);
|
||||
}
|
||||
|
||||
function quoteSmart($in)
|
||||
{
|
||||
if (is_int($in) || is_double($in)) {
|
||||
return $in;
|
||||
} elseif (is_bool($in)) {
|
||||
return $in ? 1 : 0;
|
||||
} elseif (is_null($in)) {
|
||||
return 'NULL';
|
||||
} else {
|
||||
return "'" . $this->escapeSimple($in) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
function quoteIdentifier($string)
|
||||
{
|
||||
return $this->db_object->quoteIdentifier($string);
|
||||
}
|
||||
|
||||
// map?
|
||||
function provides($feature)
|
||||
{
|
||||
return $this->db_object->support($feature);
|
||||
}
|
||||
|
||||
// remove?
|
||||
function errorCode($nativecode)
|
||||
{
|
||||
return $this->db_object->errorCode($nativecode);
|
||||
}
|
||||
|
||||
// remove?
|
||||
function errorMessage($dbcode)
|
||||
{
|
||||
return $this->db_object->errorMessage($dbcode);
|
||||
}
|
||||
|
||||
// remove?
|
||||
function &raiseError($code = MDB2_ERROR, $mode = null, $options = null,
|
||||
$userinfo = null, $nativecode = null)
|
||||
{
|
||||
return $this->db_object->raiseError($code, $mode, $options, $userinfo, $nativecode);
|
||||
}
|
||||
|
||||
function setFetchMode($fetchmode, $object_class = 'stdClass')
|
||||
{
|
||||
return $this->db_object->setFetchMode($fetchmode, $object_class);
|
||||
}
|
||||
|
||||
function setOption($option, $value)
|
||||
{
|
||||
return $this->db_object->setOption($option, $value);
|
||||
}
|
||||
|
||||
function getOption($option)
|
||||
{
|
||||
return $this->db_object->getOption($option);
|
||||
}
|
||||
|
||||
function prepare($query)
|
||||
{
|
||||
// parse for ! and &
|
||||
// set types
|
||||
return $this->db_object->prepare($query);
|
||||
}
|
||||
|
||||
function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT, $where = false)
|
||||
{
|
||||
$this->db_object->loadModule('Extended');
|
||||
// types
|
||||
return $this->db_object->extended->autoPrepare($table, $table_fields, $mode, $where);
|
||||
}
|
||||
|
||||
function &autoExecute($table, $fields_values, $mode, $where)
|
||||
{
|
||||
$this->db_object->loadModule('Extended');
|
||||
// types
|
||||
return $this->db_object->extended->autoExecute($table, $fields_values, $mode, $where);
|
||||
}
|
||||
|
||||
function buildManipSQL($table, $table_fields, $mode, $where = false)
|
||||
{
|
||||
$this->db_object->loadModule('Extended');
|
||||
return $this->db_object->extended->buildManipSQL($table, $table_fields, $mode, $where);
|
||||
}
|
||||
|
||||
function &execute($stmt, $data = false)
|
||||
{
|
||||
$stmt->bindParamArray($data);
|
||||
return $stmt->execute();
|
||||
}
|
||||
|
||||
function executeMultiple($stmt, $data)
|
||||
{
|
||||
$this->db_object->loadModule('Extended');
|
||||
return $this->db_object->extended->executeMultiple($stmt, null, $data);
|
||||
}
|
||||
|
||||
function &query($query, $params = array()) {
|
||||
if (sizeof($params) > 0) {
|
||||
$sth = $this->db_object->prepare($query);
|
||||
if (PEAR::isError($sth)) {
|
||||
return $sth;
|
||||
}
|
||||
if (!is_array($params)) {
|
||||
$params = array($params);
|
||||
}
|
||||
$stmt->bindParamArray($params);
|
||||
return $stmt->execute();
|
||||
}
|
||||
return $this->db_object->query($query);
|
||||
}
|
||||
|
||||
function simpleQuery($query) {
|
||||
$result = $this->db_object->query($query);
|
||||
if (PEAR::isError($result) || $result === MDB2_OK) {
|
||||
return $result;
|
||||
} else {
|
||||
return $result->result->getResource();
|
||||
}
|
||||
}
|
||||
|
||||
function limitQuery($query, $from, $count, $params = array())
|
||||
{
|
||||
$result = $this->db_object->setLimit($count, $from);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result =& $this->query($query, $params);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _convertNullArrayValuesToEmpty(&$array)
|
||||
{
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
$array[$key] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function &getOne($query, $params = array())
|
||||
{
|
||||
$result = $this->query($query, $params);
|
||||
$one = $result->result->fetchOne();
|
||||
if (is_null($one)) {
|
||||
$one = '';
|
||||
}
|
||||
return $one;
|
||||
}
|
||||
|
||||
function &getRow($query,
|
||||
$params = array(),
|
||||
$fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
if (!is_array($params)) {
|
||||
if (is_array($fetchmode)) {
|
||||
if (is_null($params)) {
|
||||
$tmp = DB_FETCHMODE_DEFAULT;
|
||||
} else {
|
||||
$tmp = $params;
|
||||
}
|
||||
$params = $fetchmode;
|
||||
$fetchmode = $tmp;
|
||||
} elseif (!is_null($params)) {
|
||||
$fetchmode = $params;
|
||||
$params = array();
|
||||
}
|
||||
}
|
||||
$result =& $this->query($query, $params);
|
||||
return $result->result->fetchRow($fetchmode);
|
||||
}
|
||||
|
||||
function &getCol($query, $col = 0, $params = array())
|
||||
{
|
||||
$result =& $this->query($query, $params);
|
||||
$col = $result->result->fetchCol($col);
|
||||
$this->_convertNullArrayValuesToEmpty($col);
|
||||
return $col;
|
||||
}
|
||||
|
||||
function &getAssoc($query, $force_array = false, $params = array(),
|
||||
$fetchmode = MDB2_FETCHMODE_ORDERED, $group = false)
|
||||
{
|
||||
$result =& $this->query($query, $params);
|
||||
$all = $result->result->fetchAll($fetchmode, true, $force_array, $group);
|
||||
$first = reset($all);
|
||||
if (isset($first) && $this->db_object->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
if (is_array($first)) {
|
||||
foreach ($all as $key => $arr) {
|
||||
$this->_convertNullArrayValuesToEmpty($all[$key]);
|
||||
}
|
||||
} elseif (is_object($first)) {
|
||||
foreach ($all as $key => $arr) {
|
||||
$tmp = get_object_vars($all[$key]);
|
||||
if (is_array($tmp)) {
|
||||
$this->_convertNullArrayValuesToEmpty($tmp);
|
||||
foreach ($tmp as $key2 => $column) {
|
||||
$all[$key]->{$key2} = $column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
function &getAll($query,
|
||||
$params = null,
|
||||
$fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
if (!is_array($params)) {
|
||||
if (is_array($fetchmode)) {
|
||||
if (is_null($params)) {
|
||||
$tmp = DB_FETCHMODE_DEFAULT;
|
||||
} else {
|
||||
$tmp = $params;
|
||||
}
|
||||
$params = $fetchmode;
|
||||
$fetchmode = $tmp;
|
||||
} elseif (!is_null($params)) {
|
||||
$fetchmode = $params;
|
||||
$params = array();
|
||||
}
|
||||
}
|
||||
$result =& $this->query($query, $params);
|
||||
$all = $result->result->fetchAll($fetchmode);
|
||||
$first = reset($all);
|
||||
if (isset($first) && $this->db_object->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
if (is_array($first)) {
|
||||
foreach ($all as $key => $arr) {
|
||||
$this->_convertNullArrayValuesToEmpty($all[$key]);
|
||||
}
|
||||
} elseif (is_object($first)) {
|
||||
foreach ($all as $key => $arr) {
|
||||
$tmp = get_object_vars($all[$key]);
|
||||
if (is_array($tmp)) {
|
||||
$this->_convertNullArrayValuesToEmpty($tmp);
|
||||
foreach ($tmp as $key2 => $column) {
|
||||
$all[$key]->{$key2} = $column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
return $this->db_object->autoCommit($onoff);
|
||||
}
|
||||
|
||||
function commit()
|
||||
{
|
||||
return $this->db_object->commit();
|
||||
}
|
||||
|
||||
function rollback()
|
||||
{
|
||||
return $this->db_object->rollback();
|
||||
}
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
return $this->db_object->affectedRows();
|
||||
}
|
||||
|
||||
// remove?
|
||||
function errorNative()
|
||||
{
|
||||
return $this->db_object->errorNative();
|
||||
}
|
||||
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
return $this->db_object->nextID($seq_name, $ondemand);
|
||||
}
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$this->db_object->loadModule('Manager');
|
||||
return $this->db_object->manager->createSequence($seq_name, 1);
|
||||
}
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$this->db_object->loadModule('Manager');
|
||||
return $this->db_object->manager->dropSequence($seq_name);
|
||||
}
|
||||
|
||||
function &_wrapResource($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
$result_class = $this->db_object->getOption('result_buffering')
|
||||
? $this->db_object->getOption('buffered_result_class') : $$this->db_object->getOption('result_class');
|
||||
$class_name = sprintf($result_class, $this->db_object->phptype);
|
||||
$result =& new $class_name($this->db_object, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
if (!is_null($rownum)) {
|
||||
$result->result->seek($rownum);
|
||||
}
|
||||
$arr = $result->fetchRow($fetchmode);
|
||||
}
|
||||
|
||||
function freePrepared($prepared)
|
||||
{
|
||||
return $this->db_object->freePrepared($prepared);
|
||||
}
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
return $result->free();
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
return $result->numCols();
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
return $result->numRows();
|
||||
}
|
||||
|
||||
function nextResult($result)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
return $result->nextResult();
|
||||
}
|
||||
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$result = $this->_wrapResource($result);
|
||||
if (is_string($result) || MDB2::isResultCommon($result)) {
|
||||
$this->db_object->loadModule('Reverse');
|
||||
return $this->db_object->reverse->tableInfo($result, $mode);
|
||||
}
|
||||
return $result->tableInfo($mode);
|
||||
}
|
||||
|
||||
function getTables()
|
||||
{
|
||||
return $this->getListOf('tables');
|
||||
}
|
||||
|
||||
function getListOf($type)
|
||||
{
|
||||
$this->db_object->loadModule('Manager');
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return $this->db_object->manager->listTables();
|
||||
case 'views':
|
||||
return $this->db_object->manager->listViews();
|
||||
case 'users':
|
||||
return $this->db_object->manager->listUsers();
|
||||
case 'functions':
|
||||
return $this->db_object->manager->listFunctions();
|
||||
case 'databases':
|
||||
return $this->db_object->manager->listDatabases();
|
||||
default:
|
||||
return $this->db_object->raiseError(MDB2_ERROR_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue