port OC_DB to MDB2
This commit is contained in:
parent
cd1ecef75f
commit
ede1c64edd
32 changed files with 25957 additions and 263 deletions
4359
inc/MDB2.php
Executable file
4359
inc/MDB2.php
Executable file
File diff suppressed because it is too large
Load diff
4359
inc/MDB2.php~
Executable file
4359
inc/MDB2.php~
Executable file
File diff suppressed because it is too large
Load diff
183
inc/MDB2/Date.php
Executable file
183
inc/MDB2/Date.php
Executable file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: Date.php,v 1.10 2006/03/01 12:15:32 lsmith Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* @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 convenient 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 int hour of the date
|
||||
* @param int minute of the date
|
||||
* @param int second of the date
|
||||
* @param int month of the date
|
||||
* @param int day of the date
|
||||
* @param int 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 int 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 int 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 int 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;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
1824
inc/MDB2/Driver/Datatype/Common.php
Executable file
1824
inc/MDB2/Driver/Datatype/Common.php
Executable file
File diff suppressed because it is too large
Load diff
553
inc/MDB2/Driver/Datatype/mysql.php
Executable file
553
inc/MDB2/Driver/Datatype/mysql.php
Executable file
|
@ -0,0 +1,553 @@
|
|||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: mysql.php,v 1.65 2008/02/22 19:23:49 quipo Exp $
|
||||
//
|
||||
|
||||
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
|
||||
{
|
||||
// {{{ _getCharsetFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $charset name of the charset
|
||||
* @return string DBMS specific SQL code portion needed to set the CHARACTER SET
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCharsetFieldDeclaration($charset)
|
||||
{
|
||||
return 'CHARACTER SET '.$charset;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCollationFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $collation name of the collation
|
||||
* @return string DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCollationFieldDeclaration($collation)
|
||||
{
|
||||
return 'COLLATE '.$collation;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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':
|
||||
if (empty($field['length']) && array_key_exists('default', $field)) {
|
||||
$field['length'] = $db->varchar_max_length;
|
||||
}
|
||||
$length = !empty($field['length']) ? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYTEXT';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'TEXT';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMTEXT';
|
||||
}
|
||||
}
|
||||
return 'LONGTEXT';
|
||||
case 'blob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYBLOB';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'BLOB';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMBLOB';
|
||||
}
|
||||
}
|
||||
return 'LONGBLOB';
|
||||
case 'integer':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 1) {
|
||||
return 'TINYINT';
|
||||
} elseif ($length == 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3) {
|
||||
return 'MEDIUMINT';
|
||||
} elseif ($length == 4) {
|
||||
return 'INT';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'TINYINT(1)';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME';
|
||||
case 'timestamp':
|
||||
return 'DATETIME';
|
||||
case 'float':
|
||||
return 'DOUBLE';
|
||||
case 'decimal':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'DECIMAL('.$length.','.$scale.')';
|
||||
}
|
||||
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 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 =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = $autoinc = '';
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$autoinc = ' AUTO_INCREMENT PRIMARY KEY';
|
||||
} elseif (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned float if
|
||||
* possible.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
// Since AUTO_INCREMENT can be used for integer or floating-point types,
|
||||
// reuse the INTEGER declaration
|
||||
// @see http://bugs.mysql.com/bug.php?id=31032
|
||||
return $this->_getIntegerDeclaration($name, $field);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* 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 = '';
|
||||
if (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
} elseif (empty($field['notnull'])) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (!is_null($operator)) {
|
||||
$field = is_null($field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE BINARY ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$db_type = strtok($db_type, '(), ');
|
||||
if ($db_type == 'national') {
|
||||
$db_type = strtok('(), ');
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$length = strtok($field['length'], ', ');
|
||||
$decimal = strtok(', ');
|
||||
} else {
|
||||
$length = strtok('(), ');
|
||||
$decimal = strtok('(), ');
|
||||
}
|
||||
$type = array();
|
||||
$unsigned = $fixed = null;
|
||||
switch ($db_type) {
|
||||
case 'tinyint':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 1;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 2;
|
||||
break;
|
||||
case 'mediumint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 3;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 8;
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'string':
|
||||
case 'char':
|
||||
$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';
|
||||
if ($decimal == 'binary') {
|
||||
$type[] = 'blob';
|
||||
}
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'enum':
|
||||
$type[] = 'text';
|
||||
preg_match_all('/\'.+\'/U', $field['type'], $matches);
|
||||
$length = 0;
|
||||
$fixed = false;
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches[0] as $value) {
|
||||
$length = max($length, strlen($value)-2);
|
||||
}
|
||||
if ($length == '1' && count($matches[0]) == 2) {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
$type[] = 'integer';
|
||||
case 'set':
|
||||
$fixed = false;
|
||||
$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';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
break;
|
||||
case 'unknown':
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
if ($decimal !== false) {
|
||||
$length = $length.','.$decimal;
|
||||
}
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'binary':
|
||||
case 'varbinary':
|
||||
$type[] = 'blob';
|
||||
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_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
554
inc/MDB2/Driver/Datatype/pgsql.php
Executable file
554
inc/MDB2/Driver/Datatype/pgsql.php
Executable file
|
@ -0,0 +1,554 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 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: pgsql.php,v 1.93 2008/08/28 20:32:57 afz Exp $
|
||||
|
||||
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
|
||||
{
|
||||
// {{{ _baseConvertResult()
|
||||
|
||||
/**
|
||||
* General type conversion method
|
||||
*
|
||||
* @param mixed $value refernce to a value to be converted
|
||||
* @param string $type specifies which type to convert to
|
||||
* @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
|
||||
* @return object a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _baseConvertResult($value, $type, $rtrim = true)
|
||||
{
|
||||
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 substr($value, 0, strlen('HH:MM:SS'));
|
||||
case 'timestamp':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD HH:MM:SS'));
|
||||
case 'blob':
|
||||
$value = pg_unescape_bytea($value);
|
||||
return parent::_baseConvertResult($value, $type, $rtrim);
|
||||
}
|
||||
return parent::_baseConvertResult($value, $type, $rtrim);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 = !empty($field['length']) ? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
return 'TEXT';
|
||||
case 'blob':
|
||||
return 'BYTEA';
|
||||
case 'integer':
|
||||
if (!empty($field['autoincrement'])) {
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length > 4) {
|
||||
return 'BIGSERIAL PRIMARY KEY';
|
||||
}
|
||||
}
|
||||
return 'SERIAL PRIMARY KEY';
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3 || $length == 4) {
|
||||
return 'INT';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
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':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'NUMERIC('.$length.','.$scale.')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!empty($field['unsigned'])) {
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field);
|
||||
}
|
||||
$default = '';
|
||||
if (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
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 string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteCLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
return $this->_quoteText($value, $quote, $escape_wildcards);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
if (!$quote) {
|
||||
return $value;
|
||||
}
|
||||
if (version_compare(PHP_VERSION, '5.2.0RC6', '>=')) {
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$connection = $db->getConnection();
|
||||
if (PEAR::isError($connection)) {
|
||||
return $connection;
|
||||
}
|
||||
$value = @pg_escape_bytea($connection, $value);
|
||||
} else {
|
||||
$value = @pg_escape_bytea($value);
|
||||
}
|
||||
return "'".$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.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBoolean($value, $quote, $escape_wildcards)
|
||||
{
|
||||
$value = $value ? 't' : 'f';
|
||||
if (!$quote) {
|
||||
return $value;
|
||||
}
|
||||
return "'".$value."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (!is_null($operator)) {
|
||||
$field = is_null($field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'ILIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ patternEscapeString()
|
||||
|
||||
/**
|
||||
* build string to define escape pattern string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*
|
||||
* @return string define escape pattern
|
||||
*/
|
||||
function patternEscapeString()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return ' ESCAPE '.$this->quote($db->string_quoting['escape_pattern']);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$length = $field['length'];
|
||||
$type = array();
|
||||
$unsigned = $fixed = null;
|
||||
switch ($db_type) {
|
||||
case 'smallint':
|
||||
case 'int2':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 2;
|
||||
if ($length == '2') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'int':
|
||||
case 'int4':
|
||||
case 'integer':
|
||||
case 'serial':
|
||||
case 'serial4':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
case 'int8':
|
||||
case 'bigserial':
|
||||
case 'serial8':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 8;
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
$type[] = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'unknown':
|
||||
case 'char':
|
||||
case 'bpchar':
|
||||
$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';
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
case 'timestamptz':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'float4':
|
||||
case 'float8':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
if (isset($field['scale'])) {
|
||||
$length = $length.','.$field['scale'];
|
||||
}
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
case 'bytea':
|
||||
$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_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapPrepareDatatype()
|
||||
|
||||
/**
|
||||
* Maps an mdb2 datatype to native prepare type
|
||||
*
|
||||
* @param string $type
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function mapPrepareDatatype($type)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!empty($db->options['datatype_map'][$type])) {
|
||||
$type = $db->options['datatype_map'][$type];
|
||||
if (!empty($db->options['datatype_map_callback'][$type])) {
|
||||
$parameter = array('type' => $type);
|
||||
return call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__, $parameter));
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
return 'int';
|
||||
case 'boolean':
|
||||
return 'bool';
|
||||
case 'decimal':
|
||||
case 'float':
|
||||
return 'numeric';
|
||||
case 'clob':
|
||||
return 'text';
|
||||
case 'blob':
|
||||
return 'bytea';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
?>
|
409
inc/MDB2/Driver/Datatype/sqlite.php
Executable file
409
inc/MDB2/Driver/Datatype/sqlite.php
Executable file
|
@ -0,0 +1,409 @@
|
|||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 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: sqlite.php,v 1.67 2008/02/22 19:58:06 quipo Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_sqlite extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ _getCollationFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $collation name of the collation
|
||||
*
|
||||
* @return string DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCollationFieldDeclaration($collation)
|
||||
{
|
||||
return 'COLLATE '.$collation;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 = !empty($field['length'])
|
||||
? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYTEXT';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'TEXT';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMTEXT';
|
||||
}
|
||||
}
|
||||
return 'LONGTEXT';
|
||||
case 'blob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYBLOB';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'BLOB';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMBLOB';
|
||||
}
|
||||
}
|
||||
return 'LONGBLOB';
|
||||
case 'integer':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3 || $length == 4) {
|
||||
return 'INTEGER';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
return 'INTEGER';
|
||||
case 'boolean':
|
||||
return 'BOOLEAN';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME';
|
||||
case 'timestamp':
|
||||
return 'DATETIME';
|
||||
case 'float':
|
||||
return 'DOUBLE'.($db->options['fixed_float'] ? '('.
|
||||
($db->options['fixed_float']+2).','.$db->options['fixed_float'].')' : '');
|
||||
case 'decimal':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'DECIMAL('.$length.','.$scale.')';
|
||||
}
|
||||
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 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 =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = $autoinc = '';
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$autoinc = ' PRIMARY KEY';
|
||||
} elseif (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (!is_null($operator)) {
|
||||
$field = is_null($field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _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, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$length = !empty($field['length']) ? $field['length'] : null;
|
||||
$unsigned = !empty($field['unsigned']) ? $field['unsigned'] : null;
|
||||
$fixed = null;
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'boolean':
|
||||
$type[] = 'boolean';
|
||||
break;
|
||||
case 'tinyint':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 1;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 2;
|
||||
break;
|
||||
case 'mediumint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 3;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'serial':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
case 'bigserial':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 8;
|
||||
break;
|
||||
case 'clob':
|
||||
$type[] = 'clob';
|
||||
$fixed = false;
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
case 'varchar2':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
$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';
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
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';
|
||||
$length = $length.','.$field['decimal'];
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$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_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
293
inc/MDB2/Driver/Function/Common.php
Executable file
293
inc/MDB2/Driver/Function/Common.php
Executable file
|
@ -0,0 +1,293 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: Common.php,v 1.21 2008/02/17 18:51:39 quipo Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for the function modules that is extended by each MDB2 driver
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Function');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_Common extends MDB2_Module_Common
|
||||
{
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $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
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
*
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ functionTable()
|
||||
|
||||
/**
|
||||
* return string for internal table used when calling only a function
|
||||
*
|
||||
* @return string for internal table used when calling only a function
|
||||
* @access public
|
||||
*/
|
||||
function functionTable()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ now()
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time:
|
||||
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
|
||||
* - CURRENT_DATE (date, DATE type)
|
||||
* - CURRENT_TIME (time, TIME type)
|
||||
*
|
||||
* @param string $type 'timestamp' | 'time' | 'date'
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @access public
|
||||
*/
|
||||
function now($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
return 'CURRENT_TIME';
|
||||
case 'date':
|
||||
return 'CURRENT_DATE';
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'CURRENT_TIMESTAMP';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (!is_null($length)) {
|
||||
return "SUBSTRING($value FROM $position FOR $length)";
|
||||
}
|
||||
return "SUBSTRING($value FROM $position)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* return string to call a function to get replace inside an SQL statement.
|
||||
*
|
||||
* @return string to call a function to get a replace
|
||||
* @access public
|
||||
*/
|
||||
function replace($str, $from_str, $to_str)
|
||||
{
|
||||
return "REPLACE($str, $from_str , $to_str)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ concat()
|
||||
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
* @param string $value1
|
||||
* @param string $value2
|
||||
* @param string $values...
|
||||
*
|
||||
* @return string to concatenate two strings
|
||||
* @access public
|
||||
*/
|
||||
function concat($value1, $value2)
|
||||
{
|
||||
$args = func_get_args();
|
||||
return "(".implode(' || ', $args).")";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return 'RAND()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ lower()
|
||||
|
||||
/**
|
||||
* return string to call a function to lower the case of an expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to lower case of an expression
|
||||
* @access public
|
||||
*/
|
||||
function lower($expression)
|
||||
{
|
||||
return "LOWER($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ upper()
|
||||
|
||||
/**
|
||||
* return string to call a function to upper the case of an expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to upper case of an expression
|
||||
* @access public
|
||||
*/
|
||||
function upper($expression)
|
||||
{
|
||||
return "UPPER($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ length()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the length of a string expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to get the string expression length
|
||||
* @access public
|
||||
*/
|
||||
function length($expression)
|
||||
{
|
||||
return "LENGTH($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ guid()
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @access public
|
||||
*/
|
||||
function guid()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
136
inc/MDB2/Driver/Function/mysql.php
Executable file
136
inc/MDB2/Driver/Function/mysql.php
Executable file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: mysql.php,v 1.12 2008/02/17 18:54:08 quipo Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_mysql extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $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
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'CALL '.$name;
|
||||
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'UNIX_TIMESTAMP('. $expression.')';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ concat()
|
||||
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
* @param string $value1
|
||||
* @param string $value2
|
||||
* @param string $values...
|
||||
* @return string to concatenate two strings
|
||||
* @access public
|
||||
**/
|
||||
function concat($value1, $value2)
|
||||
{
|
||||
$args = func_get_args();
|
||||
return "CONCAT(".implode(', ', $args).")";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ guid()
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @access public
|
||||
*/
|
||||
function guid()
|
||||
{
|
||||
return 'UUID()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
115
inc/MDB2/Driver/Function/pgsql.php
Executable file
115
inc/MDB2/Driver/Function/pgsql.php
Executable file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: pgsql.php,v 1.11 2008/11/09 19:46:50 quipo Exp $
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_pgsql extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $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
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM '.$name;
|
||||
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'EXTRACT(EPOCH FROM DATE_TRUNC(\'seconds\', CAST ((' . $expression . ') AS TIMESTAMP)))';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return 'RANDOM()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
162
inc/MDB2/Driver/Function/sqlite.php
Executable file
162
inc/MDB2/Driver/Function/sqlite.php
Executable file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: sqlite.php,v 1.10 2008/02/17 18:54:08 quipo Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_sqlite extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($db_index)
|
||||
{
|
||||
parent::__construct($db_index);
|
||||
// create all sorts of UDFs
|
||||
}
|
||||
|
||||
// {{{ now()
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time.
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @access public
|
||||
*/
|
||||
function now($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
return 'time(\'now\')';
|
||||
case 'date':
|
||||
return 'date(\'now\')';
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'datetime(\'now\')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'strftime("%s",'. $expression.', "utc")';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (!is_null($length)) {
|
||||
return "substr($value,$position,$length)";
|
||||
}
|
||||
return "substr($value,$position,length($value))";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return '((RANDOM()+2147483648)/4294967296)';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a replacement inside an SQL statement.
|
||||
*
|
||||
* @return string to call a function to get a replace
|
||||
* @access public
|
||||
*/
|
||||
function replace($str, $from_str, $to_str)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
1014
inc/MDB2/Driver/Manager/Common.php
Executable file
1014
inc/MDB2/Driver/Manager/Common.php
Executable file
File diff suppressed because it is too large
Load diff
1432
inc/MDB2/Driver/Manager/mysql.php
Executable file
1432
inc/MDB2/Driver/Manager/mysql.php
Executable file
File diff suppressed because it is too large
Load diff
948
inc/MDB2/Driver/Manager/pgsql.php
Executable file
948
inc/MDB2/Driver/Manager/pgsql.php
Executable file
|
@ -0,0 +1,948 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: pgsql.php,v 1.87 2008/11/29 14:09:59 afz Exp $
|
||||
|
||||
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
|
||||
* @param array $options array with charset info
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name, $options = array())
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
$query = 'CREATE DATABASE ' . $name;
|
||||
if (!empty($options['charset'])) {
|
||||
$query .= ' WITH ENCODING ' . $db->quote($options['charset'], 'text');
|
||||
}
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterDatabase()
|
||||
|
||||
/**
|
||||
* alter an existing database
|
||||
*
|
||||
* @param string $name name of the database that is intended to be changed
|
||||
* @param array $options array with name, owner info
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function alterDatabase($name, $options = array())
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'ALTER DATABASE '. $db->quoteIdentifier($name, true);
|
||||
if (!empty($options['name'])) {
|
||||
$query .= ' RENAME TO ' . $options['name'];
|
||||
}
|
||||
if (!empty($options['owner'])) {
|
||||
$query .= ' OWNER TO ' . $options['owner'];
|
||||
}
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
$query = "DROP DATABASE $name";
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getAdvancedFKOptions()
|
||||
|
||||
/**
|
||||
* Return the FOREIGN KEY query section dealing with non-standard options
|
||||
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
|
||||
*
|
||||
* @param array $definition
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
function _getAdvancedFKOptions($definition)
|
||||
{
|
||||
$query = '';
|
||||
if (!empty($definition['match'])) {
|
||||
$query .= ' MATCH '.$definition['match'];
|
||||
}
|
||||
if (!empty($definition['onupdate'])) {
|
||||
$query .= ' ON UPDATE '.$definition['onupdate'];
|
||||
}
|
||||
if (!empty($definition['ondelete'])) {
|
||||
$query .= ' ON DELETE '.$definition['ondelete'];
|
||||
}
|
||||
if (!empty($definition['deferrable'])) {
|
||||
$query .= ' DEFERRABLE';
|
||||
} else {
|
||||
$query .= ' NOT DEFERRABLE';
|
||||
}
|
||||
if (!empty($definition['initiallydeferred'])) {
|
||||
$query .= ' INITIALLY DEFERRED';
|
||||
} else {
|
||||
$query .= ' INITIALLY IMMEDIATE';
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ truncateTable()
|
||||
|
||||
/**
|
||||
* Truncate an existing table (if the TRUNCATE TABLE syntax is not supported,
|
||||
* it falls back to a DELETE FROM TABLE query)
|
||||
*
|
||||
* @param string $name name of the table that should be truncated
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function truncateTable($name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $db->exec("TRUNCATE TABLE $name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ vacuum()
|
||||
|
||||
/**
|
||||
* Optimize (vacuum) all the tables in the db (or only the specified table)
|
||||
* and optionally run ANALYZE.
|
||||
*
|
||||
* @param string $table table name (all the tables if empty)
|
||||
* @param array $options an array with driver-specific options:
|
||||
* - timeout [int] (in seconds) [mssql-only]
|
||||
* - analyze [boolean] [pgsql and mysql]
|
||||
* - full [boolean] [pgsql-only]
|
||||
* - freeze [boolean] [pgsql-only]
|
||||
*
|
||||
* @return mixed MDB2_OK success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function vacuum($table = null, $options = array())
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$query = 'VACUUM';
|
||||
|
||||
if (!empty($options['full'])) {
|
||||
$query .= ' FULL';
|
||||
}
|
||||
if (!empty($options['freeze'])) {
|
||||
$query .= ' FREEZE';
|
||||
}
|
||||
if (!empty($options['analyze'])) {
|
||||
$query .= ' ANALYZE';
|
||||
}
|
||||
|
||||
if (!empty($table)) {
|
||||
$query .= ' '.$db->quoteIdentifier($table, true);
|
||||
}
|
||||
return $db->exec($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 MDB2 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 MDB2 parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'name' => array(
|
||||
* 'length' => '20',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 20,
|
||||
* ),
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 1,
|
||||
* 'default' => 'M',
|
||||
* ),
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @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':
|
||||
case 'rename':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'change type "'.$change_name.'\" not yet supported', __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
|
||||
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
$query = 'DROP ' . $field_name;
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['rename']) && is_array($changes['rename'])) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
$result = $db->exec("ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name'], true));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['add']) && is_array($changes['add'])) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$query = 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['change']) && is_array($changes['change'])) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
if (!empty($field['definition']['type'])) {
|
||||
$server_info = $db->getServerVersion();
|
||||
if (PEAR::isError($server_info)) {
|
||||
return $server_info;
|
||||
}
|
||||
if (is_array($server_info) && $server_info['major'] < 8) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'changing column type for "'.$change_name.'\" requires PostgreSQL 8.0 or above', __FUNCTION__);
|
||||
}
|
||||
$db->loadModule('Datatype', null, true);
|
||||
$type = $db->datatype->getTypeDeclaration($field['definition']);
|
||||
$query = "ALTER $field_name TYPE $type USING CAST($field_name AS $type)";
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('default', $field['definition'])) {
|
||||
$query = "ALTER $field_name SET DEFAULT ".$db->quote($field['definition']['default'], $field['definition']['type']);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (!empty($field['definition']['notnull'])) {
|
||||
$query = "ALTER $field_name ".($field['definition']['notnull'] ? 'SET' : 'DROP').' NOT NULL';
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['name'])) {
|
||||
$change_name = $db->quoteIdentifier($changes['name'], true);
|
||||
$result = $db->exec("ALTER TABLE $name RENAME TO ".$change_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed array of database names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT datname FROM pg_database';
|
||||
$result2 = $db->standaloneQuery($query, array('text'), false);
|
||||
if (!MDB2::isResultCommon($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
|
||||
$result = $result2->fetchCol();
|
||||
$result2->free();
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed array of user names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT usename FROM pg_user';
|
||||
$result2 = $db->standaloneQuery($query, array('text'), false);
|
||||
if (!MDB2::isResultCommon($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
|
||||
$result = $result2->fetchCol();
|
||||
$result2->free();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list all views in the current database
|
||||
*
|
||||
* @return mixed array of view names 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
|
||||
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
|
||||
AND viewname !~ '^pg_'";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableViews()
|
||||
|
||||
/**
|
||||
* list the views in the database that reference a given table
|
||||
*
|
||||
* @param string table for which all referenced views should be found
|
||||
* @return mixed array of view names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableViews($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT viewname FROM pg_views NATURAL JOIN pg_tables';
|
||||
$query.= ' WHERE tablename ='.$db->quote($table, 'text');
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listFunctions()
|
||||
|
||||
/**
|
||||
* list all functions in the current database
|
||||
*
|
||||
* @return mixed array of function names 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')";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableTriggers()
|
||||
|
||||
/**
|
||||
* list all triggers in the database that reference a given table
|
||||
*
|
||||
* @param string table for which all referenced triggers should be found
|
||||
* @return mixed array of trigger names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableTriggers($table = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT trg.tgname AS trigger_name
|
||||
FROM pg_trigger trg,
|
||||
pg_class tbl
|
||||
WHERE trg.tgrelid = tbl.oid';
|
||||
if (!is_null($table)) {
|
||||
$table = $db->quote(strtoupper($table), 'text');
|
||||
$query .= " AND tbl.relname = $table";
|
||||
}
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed array of table names 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_'";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a table in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of field names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
if (!empty($schema)) {
|
||||
$table = $db->quoteIdentifier($schema, true) . '.' .$table;
|
||||
}
|
||||
$db->setLimit(1);
|
||||
$result2 = $db->query("SELECT * FROM $table");
|
||||
if (PEAR::isError($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
$result = $result2->getColumnNames();
|
||||
$result2->free();
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return array_flip($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of index names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quote($table, 'text');
|
||||
$subquery = "SELECT indexrelid
|
||||
FROM pg_index
|
||||
LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE pg_class.relname = $table
|
||||
AND indisunique != 't'
|
||||
AND indisprimary != 't'";
|
||||
if (!empty($schema)) {
|
||||
$subquery .= ' AND pg_namespace.nspname = '.$db->quote($schema, 'text');
|
||||
}
|
||||
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
|
||||
$indexes = $db->queryCol($query, 'text');
|
||||
if (PEAR::isError($indexes)) {
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($indexes as $index) {
|
||||
$index = $this->_fixIndexName($index);
|
||||
if (!empty($index)) {
|
||||
$result[$index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_change_key_case($result, $db->options['field_case']);
|
||||
}
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropConstraint()
|
||||
|
||||
/**
|
||||
* drop existing constraint
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the constraint to be dropped
|
||||
* @param string $primary hint if the constraint is primary
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropConstraint($table, $name, $primary = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
// is it an UNIQUE index?
|
||||
$query = 'SELECT relname
|
||||
FROM pg_class
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.relname = '.$db->quote($table, 'text').'
|
||||
AND pg_class.oid = pg_index.indrelid
|
||||
AND indisunique = \'t\')
|
||||
EXCEPT
|
||||
SELECT conname
|
||||
FROM pg_constraint, pg_class
|
||||
WHERE pg_constraint.conrelid = pg_class.oid
|
||||
AND relname = '. $db->quote($table, 'text');
|
||||
$unique = $db->queryCol($query, 'text');
|
||||
if (PEAR::isError($unique) || empty($unique)) {
|
||||
// not an UNIQUE index, maybe a CONSTRAINT
|
||||
return parent::dropConstraint($table, $name, $primary);
|
||||
}
|
||||
|
||||
if (in_array($name, $unique)) {
|
||||
return $db->exec('DROP INDEX '.$db->quoteIdentifier($name, true));
|
||||
}
|
||||
$idxname = $db->getIndexName($name);
|
||||
if (in_array($idxname, $unique)) {
|
||||
return $db->exec('DROP INDEX '.$db->quoteIdentifier($idxname, true));
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$name . ' is not an existing constraint for table ' . $table, __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableConstraints()
|
||||
|
||||
/**
|
||||
* list all constraints in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of constraint names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableConstraints($table)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quote($table, 'text');
|
||||
$query = 'SELECT conname
|
||||
FROM pg_constraint
|
||||
LEFT JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE relname = ' .$table;
|
||||
if (!empty($schema)) {
|
||||
$query .= ' AND pg_namespace.nspname = ' . $db->quote($schema, 'text');
|
||||
}
|
||||
$query .= '
|
||||
UNION DISTINCT
|
||||
SELECT relname
|
||||
FROM pg_class
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index
|
||||
LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE pg_class.relname = '.$table.'
|
||||
AND indisunique = \'t\'';
|
||||
if (!empty($schema)) {
|
||||
$query .= ' AND pg_namespace.nspname = ' . $db->quote($schema, 'text');
|
||||
}
|
||||
$query .= ')';
|
||||
$constraints = $db->queryCol($query);
|
||||
if (PEAR::isError($constraints)) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($constraints as $constraint) {
|
||||
$constraint = $this->_fixIndexName($constraint);
|
||||
if (!empty($constraint)) {
|
||||
$result[$constraint] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$result = array_change_key_case($result, $db->options['field_case']);
|
||||
}
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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->quoteIdentifier($db->getSequenceName($seq_name), true);
|
||||
return $db->exec("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->quoteIdentifier($db->getSequenceName($seq_name), true);
|
||||
return $db->exec("DROP SEQUENCE $sequence_name");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed array of sequence names 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;
|
||||
}
|
||||
$result = array();
|
||||
foreach ($table_names as $table_name) {
|
||||
$result[] = $this->_fixSequenceName($table_name);
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
1362
inc/MDB2/Driver/Manager/sqlite.php
Executable file
1362
inc/MDB2/Driver/Manager/sqlite.php
Executable file
File diff suppressed because it is too large
Load diff
61
inc/MDB2/Driver/Native/Common.php
Executable file
61
inc/MDB2/Driver/Native/Common.php
Executable file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: Common.php,v 1.2 2007/09/09 13:47:36 quipo Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* Base class for the natuve modules that is extended by each MDB2 driver
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Native');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_Common extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
60
inc/MDB2/Driver/Native/mysql.php
Executable file
60
inc/MDB2/Driver/Native/mysql.php
Executable file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: mysql.php,v 1.9 2006/06/18 21:59:05 lsmith Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_mysql extends MDB2_Driver_Native_Common
|
||||
{
|
||||
}
|
||||
?>
|
88
inc/MDB2/Driver/Native/pgsql.php
Executable file
88
inc/MDB2/Driver/Native/pgsql.php
Executable file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: pgsql.php,v 1.12 2006/07/15 13:07:15 lsmith Exp $
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Native_pgsql extends MDB2_Driver_Native_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;
|
||||
}
|
||||
|
||||
$connection = $db->getConnection();
|
||||
if (PEAR::isError($connection)) {
|
||||
return $connection;
|
||||
}
|
||||
|
||||
if (!@pg_lo_unlink($connection, $OID)) {
|
||||
return $db->raiseError(null, null, null,
|
||||
'Unable to unlink OID: '.$OID, __FUNCTION__);
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
60
inc/MDB2/Driver/Native/sqlite.php
Executable file
60
inc/MDB2/Driver/Native/sqlite.php
Executable file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: sqlite.php,v 1.9 2006/06/18 21:59:05 lsmith Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_sqlite extends MDB2_Driver_Native_Common
|
||||
{
|
||||
}
|
||||
?>
|
517
inc/MDB2/Driver/Reverse/Common.php
Executable file
517
inc/MDB2/Driver/Reverse/Common.php
Executable file
|
@ -0,0 +1,517 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 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: Common.php,v 1.43 2009/01/14 15:01:21 quipo Exp $
|
||||
//
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Reverse');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_Common extends MDB2_Module_Common
|
||||
{
|
||||
// {{{ splitTableSchema()
|
||||
|
||||
/**
|
||||
* Split the "[owner|schema].table" notation into an array
|
||||
*
|
||||
* @param string $table [schema and] table name
|
||||
*
|
||||
* @return array array(schema, table)
|
||||
* @access private
|
||||
*/
|
||||
function splitTableSchema($table)
|
||||
{
|
||||
$ret = array();
|
||||
if (strpos($table, '.') !== false) {
|
||||
return explode('.', $table);
|
||||
}
|
||||
return array(null, $table);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure.
|
||||
* The returned array contains an array for each field definition,
|
||||
* with all or some of these indices, depending on the field data type:
|
||||
* [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure 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
|
||||
* The returned array has this structure:
|
||||
* </pre>
|
||||
* array (
|
||||
* [fields] => array (
|
||||
* [field1name] => array() // one entry per each field covered
|
||||
* [field2name] => array() // by the index
|
||||
* [field3name] => array(
|
||||
* [sorting] => ascending
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
* </pre>
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an constraints 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
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [primary] => 0
|
||||
* [unique] => 0
|
||||
* [foreign] => 1
|
||||
* [check] => 0
|
||||
* [fields] => array (
|
||||
* [field1name] => array() // one entry per each field covered
|
||||
* [field2name] => array() // by the index
|
||||
* [field3name] => array(
|
||||
* [sorting] => ascending
|
||||
* [position] => 3
|
||||
* )
|
||||
* )
|
||||
* [references] => array(
|
||||
* [table] => name
|
||||
* [fields] => array(
|
||||
* [field1name] => array( //one entry per each referenced field
|
||||
* [position] => 1
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* [deferrable] => 0
|
||||
* [initiallydeferred] => 0
|
||||
* [onupdate] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
|
||||
* [ondelete] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
|
||||
* [match] => SIMPLE|PARTIAL|FULL
|
||||
* );
|
||||
* </pre>
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table, $index)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSequenceDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure 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
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [start] => n
|
||||
* );
|
||||
* </pre>
|
||||
* @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;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [trigger_name] => 'trigger name',
|
||||
* [table_name] => 'table name',
|
||||
* [trigger_body] => 'trigger body definition',
|
||||
* [trigger_type] => 'BEFORE' | 'AFTER',
|
||||
* [trigger_event] => 'INSERT' | 'UPDATE' | 'DELETE'
|
||||
* //or comma separated list of multiple events, when supported
|
||||
* [trigger_enabled] => true|false
|
||||
* [trigger_comment] => 'trigger comment',
|
||||
* );
|
||||
* </pre>
|
||||
* The oci8 driver also returns a [when_clause] index.
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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;
|
||||
}
|
||||
|
||||
if (!is_string($result)) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
$db->loadModule('Manager', null, true);
|
||||
$fields = $db->manager->listTableFields($result);
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$flags = array();
|
||||
|
||||
$idxname_format = $db->getOption('idxname_format');
|
||||
$db->setOption('idxname_format', '%s');
|
||||
|
||||
$indexes = $db->manager->listTableIndexes($result);
|
||||
if (PEAR::isError($indexes)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
$definition = $this->getTableIndexDefinition($result, $index);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
if (count($definition['fields']) > 1) {
|
||||
foreach ($definition['fields'] as $field => $sort) {
|
||||
$flags[$field] = 'multiple_key';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$constraints = $db->manager->listTableConstraints($result);
|
||||
if (PEAR::isError($constraints)) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
foreach ($constraints as $constraint) {
|
||||
$definition = $this->getTableConstraintDefinition($result, $constraint);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
$flag = !empty($definition['primary'])
|
||||
? 'primary_key' : (!empty($definition['unique'])
|
||||
? 'unique_key' : false);
|
||||
if ($flag) {
|
||||
foreach ($definition['fields'] as $field => $sort) {
|
||||
if (empty($flags[$field]) || $flags[$field] != 'primary_key') {
|
||||
$flags[$field] = $flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = count($fields);
|
||||
}
|
||||
|
||||
foreach ($fields as $i => $field) {
|
||||
$definition = $this->getTableFieldDefinition($result, $field);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
$res[$i] = $definition[0];
|
||||
$res[$i]['name'] = $field;
|
||||
$res[$i]['table'] = $result;
|
||||
$res[$i]['type'] = preg_replace('/^([a-z]+).*$/i', '\\1', trim($definition[0]['nativetype']));
|
||||
// 'primary_key', 'unique_key', 'multiple_key'
|
||||
$res[$i]['flags'] = empty($flags[$field]) ? '' : $flags[$field];
|
||||
// not_null', 'unsigned', 'auto_increment', 'default_[rawencodedvalue]'
|
||||
if (!empty($res[$i]['notnull'])) {
|
||||
$res[$i]['flags'].= ' not_null';
|
||||
}
|
||||
if (!empty($res[$i]['unsigned'])) {
|
||||
$res[$i]['flags'].= ' unsigned';
|
||||
}
|
||||
if (!empty($res[$i]['auto_increment'])) {
|
||||
$res[$i]['flags'].= ' autoincrement';
|
||||
}
|
||||
if (!empty($res[$i]['default'])) {
|
||||
$res[$i]['flags'].= ' default_'.rawurlencode($res[$i]['default']);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
536
inc/MDB2/Driver/Reverse/mysql.php
Executable file
536
inc/MDB2/Driver/Reverse/mysql.php
Executable file
|
@ -0,0 +1,536 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 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: mysql.php,v 1.80 2008/03/26 21:15:37 quipo Exp $
|
||||
//
|
||||
|
||||
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>
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table_name 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_name, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW FULL COLUMNS FROM $table LIKE ".$db->quote($field_name);
|
||||
$columns = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
foreach ($columns as $column) {
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
$column['name'] = $column['field'];
|
||||
unset($column['field']);
|
||||
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']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['name']) {
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (empty($column['null']) || $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 (!empty($column['extra']) && $column['extra'] == 'auto_increment') {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$collate = null;
|
||||
if (!empty($column['collation'])) {
|
||||
$collate = $column['collation'];
|
||||
$charset = preg_replace('/(.+?)(_.+)?/', '$1', $collate);
|
||||
}
|
||||
|
||||
$definition[0] = array(
|
||||
'notnull' => $notnull,
|
||||
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||
);
|
||||
if (!is_null($length)) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (!is_null($unsigned)) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (!is_null($fixed)) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
if (!is_null($collate)) {
|
||||
$definition[0]['collate'] = $collate;
|
||||
$definition[0]['charset'] = $charset;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
} elseif ($type == 'timestamp' && $notnull && empty($definition[$key]['default'])) {
|
||||
$definition[$key]['default'] = '0000-00-00 00:00:00';
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table_name 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_name, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
$result = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2)));
|
||||
if (!PEAR::isError($result) && !is_null($result)) {
|
||||
// apply 'idxname_format' only if the query succeeded, otherwise
|
||||
// fallback to the given $index_name, without transformation
|
||||
$index_name = $index_name_mdb2;
|
||||
}
|
||||
$result = $db->query(sprintf($query, $db->quote($index_name)));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$colpos = 1;
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
$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['non_unique']) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name . ' is not an existing table index', __FUNCTION__);
|
||||
}
|
||||
$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(
|
||||
'position' => $colpos++
|
||||
);
|
||||
if (!empty($row['collation'])) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name . ' is not an existing table index', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
$constraint_name_original = $constraint_name;
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
|
||||
if (strtolower($constraint_name) != 'primary') {
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$result = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2)));
|
||||
if (!PEAR::isError($result) && !is_null($result)) {
|
||||
// apply 'idxname_format' only if the query succeeded, otherwise
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name = $constraint_name_mdb2;
|
||||
}
|
||||
}
|
||||
$result = $db->query(sprintf($query, $db->quote($constraint_name)));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$colpos = 1;
|
||||
//default values, eventually overridden
|
||||
$definition = array(
|
||||
'primary' => false,
|
||||
'unique' => false,
|
||||
'foreign' => false,
|
||||
'check' => false,
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => '',
|
||||
'fields' => array(),
|
||||
),
|
||||
'onupdate' => '',
|
||||
'ondelete' => '',
|
||||
'match' => '',
|
||||
'deferrable' => false,
|
||||
'initiallydeferred' => false,
|
||||
);
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
$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 ($constraint_name == $key_name) {
|
||||
if ($row['non_unique']) {
|
||||
//FOREIGN KEY?
|
||||
return $this->_getTableFKConstraintDefinition($table, $constraint_name_original, $definition);
|
||||
}
|
||||
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(
|
||||
'position' => $colpos++
|
||||
);
|
||||
if (!empty($row['collation'])) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $this->_getTableFKConstraintDefinition($table, $constraint_name_original, $definition);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTableFKConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the FK definition from the CREATE TABLE statement
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param string $constraint_name constraint name
|
||||
* @param array $definition default values for constraint definition
|
||||
*
|
||||
* @return array|PEAR_Error
|
||||
* @access private
|
||||
*/
|
||||
function _getTableFKConstraintDefinition($table, $constraint_name, $definition)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$query = 'SHOW CREATE TABLE '. $db->escape($table);
|
||||
$constraint = $db->queryOne($query, 'text', 1);
|
||||
if (!PEAR::isError($constraint) && !empty($constraint)) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$constraint = strtolower($constraint);
|
||||
} else {
|
||||
$constraint = strtoupper($constraint);
|
||||
}
|
||||
}
|
||||
$constraint_name_original = $constraint_name;
|
||||
$constraint_name = $db->getIndexName($constraint_name);
|
||||
$pattern = '/\bCONSTRAINT\s+'.$constraint_name.'\s+FOREIGN KEY\s+\(([^\)]+)\) \bREFERENCES\b ([^ ]+) \(([^\)]+)\)/i';
|
||||
if (!preg_match($pattern, str_replace('`', '', $constraint), $matches)) {
|
||||
//fallback to original constraint name
|
||||
$pattern = '/\bCONSTRAINT\s+'.$constraint_name_original.'\s+FOREIGN KEY\s+\(([^\)]+)\) \bREFERENCES\b ([^ ]+) \(([^\)]+)\)/i';
|
||||
}
|
||||
if (preg_match($pattern, str_replace('`', '', $constraint), $matches)) {
|
||||
$definition['foreign'] = true;
|
||||
$column_names = explode(',', $matches[1]);
|
||||
$referenced_cols = explode(',', $matches[3]);
|
||||
$definition['references'] = array(
|
||||
'table' => $matches[2],
|
||||
'fields' => array(),
|
||||
);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($referenced_cols as $column_name) {
|
||||
$definition['references']['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$definition['onupdate'] = 'NO ACTION';
|
||||
$definition['ondelete'] = 'NO ACTION';
|
||||
$definition['match'] = 'SIMPLE';
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT trigger_name,
|
||||
event_object_table AS table_name,
|
||||
action_statement AS trigger_body,
|
||||
action_timing AS trigger_type,
|
||||
event_manipulation AS trigger_event
|
||||
FROM information_schema.triggers
|
||||
WHERE trigger_name = '. $db->quote($trigger, 'text');
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
);
|
||||
$def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($def)) {
|
||||
return $def;
|
||||
}
|
||||
$def['trigger_comment'] = '';
|
||||
$def['trigger_enabled'] = true;
|
||||
return $def;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
|
||||
if (!is_resource($resource)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Could not generate result resource', __FUNCTION__);
|
||||
}
|
||||
|
||||
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($resource);
|
||||
$res = array();
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
$db->loadModule('Datatype', null, true);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func(@mysql_field_table($resource, $i)),
|
||||
'name' => $case_func(@mysql_field_name($resource, $i)),
|
||||
'type' => @mysql_field_type($resource, $i),
|
||||
'length' => @mysql_field_len($resource, $i),
|
||||
'flags' => @mysql_field_flags($resource, $i),
|
||||
);
|
||||
if ($res[$i]['type'] == 'string') {
|
||||
$res[$i]['type'] = 'char';
|
||||
} elseif ($res[$i]['type'] == 'unknown') {
|
||||
$res[$i]['type'] = 'decimal';
|
||||
}
|
||||
$mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
|
||||
if (PEAR::isError($mdb2type_info)) {
|
||||
return $mdb2type_info;
|
||||
}
|
||||
$res[$i]['mdb2type'] = $mdb2type_info[0][0];
|
||||
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;
|
||||
}
|
||||
}
|
||||
?>
|
573
inc/MDB2/Driver/Reverse/pgsql.php
Executable file
573
inc/MDB2/Driver/Reverse/pgsql.php
Executable file
|
@ -0,0 +1,573 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 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: Paul Cooper <pgc@ucecom.com> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: pgsql.php,v 1.75 2008/08/22 16:36:20 quipo Exp $
|
||||
|
||||
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>
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_pgsql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table_name 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_name, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT a.attname AS name,
|
||||
t.typname AS type,
|
||||
CASE a.attlen
|
||||
WHEN -1 THEN
|
||||
CASE t.typname
|
||||
WHEN 'numeric' THEN (a.atttypmod / 65536)
|
||||
WHEN 'decimal' THEN (a.atttypmod / 65536)
|
||||
WHEN 'money' THEN (a.atttypmod / 65536)
|
||||
ELSE CASE a.atttypmod
|
||||
WHEN -1 THEN NULL
|
||||
ELSE a.atttypmod - 4
|
||||
END
|
||||
END
|
||||
ELSE a.attlen
|
||||
END AS length,
|
||||
CASE t.typname
|
||||
WHEN 'numeric' THEN (a.atttypmod % 65536) - 4
|
||||
WHEN 'decimal' THEN (a.atttypmod % 65536) - 4
|
||||
WHEN 'money' THEN (a.atttypmod % 65536) - 4
|
||||
ELSE 0
|
||||
END AS scale,
|
||||
a.attnotnull,
|
||||
a.atttypmod,
|
||||
a.atthasdef,
|
||||
(SELECT substring(pg_get_expr(d.adbin, d.adrelid) for 128)
|
||||
FROM pg_attrdef d
|
||||
WHERE d.adrelid = a.attrelid
|
||||
AND d.adnum = a.attnum
|
||||
AND a.atthasdef
|
||||
) as default
|
||||
FROM pg_attribute a,
|
||||
pg_class c,
|
||||
pg_type t
|
||||
WHERE c.relname = ".$db->quote($table, 'text')."
|
||||
AND a.atttypid = t.oid
|
||||
AND c.oid = a.attrelid
|
||||
AND NOT a.attisdropped
|
||||
AND a.attnum > 0
|
||||
AND a.attname = ".$db->quote($field_name, 'text')."
|
||||
ORDER BY a.attnum";
|
||||
$column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($column)) {
|
||||
return $column;
|
||||
}
|
||||
|
||||
if (empty($column)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (!empty($column['attnotnull']) && $column['attnotnull'] == 't') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = null;
|
||||
if ($column['atthasdef'] === 't'
|
||||
&& !preg_match("/nextval\('([^']+)'/", $column['default'])
|
||||
) {
|
||||
$pattern = '/^\'(.*)\'::[\w ]+$/i';
|
||||
$default = $column['default'];#substr($column['adsrc'], 1, -1);
|
||||
if (is_null($default) && $notnull) {
|
||||
$default = '';
|
||||
} elseif (!empty($default) && preg_match($pattern, $default)) {
|
||||
//remove data type cast
|
||||
$default = preg_replace ($pattern, '\\1', $default);
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (preg_match("/nextval\('([^']+)'/", $column['default'], $nextvals)) {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
|
||||
if (!is_null($length)) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (!is_null($unsigned)) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (!is_null($fixed)) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table_name 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_name, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = 'SELECT relname, indkey FROM pg_index, pg_class';
|
||||
$query.= ' WHERE pg_class.oid = pg_index.indexrelid';
|
||||
$query.= " AND indisunique != 't' AND indisprimary != 't'";
|
||||
$query.= ' AND pg_class.relname = %s';
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($index_name, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
if (empty($row)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
|
||||
$db->loadModule('Manager', null, true);
|
||||
$columns = $db->manager->listTableFields($table_name);
|
||||
|
||||
$definition = array();
|
||||
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
|
||||
$colpos = 1;
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT c.oid,
|
||||
c.conname AS constraint_name,
|
||||
CASE WHEN c.contype = 'c' THEN 1 ELSE 0 END AS \"check\",
|
||||
CASE WHEN c.contype = 'f' THEN 1 ELSE 0 END AS \"foreign\",
|
||||
CASE WHEN c.contype = 'p' THEN 1 ELSE 0 END AS \"primary\",
|
||||
CASE WHEN c.contype = 'u' THEN 1 ELSE 0 END AS \"unique\",
|
||||
CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS deferrable,
|
||||
CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS initiallydeferred,
|
||||
--array_to_string(c.conkey, ' ') AS constraint_key,
|
||||
t.relname AS table_name,
|
||||
t2.relname AS references_table,
|
||||
CASE confupdtype
|
||||
WHEN 'a' THEN 'NO ACTION'
|
||||
WHEN 'r' THEN 'RESTRICT'
|
||||
WHEN 'c' THEN 'CASCADE'
|
||||
WHEN 'n' THEN 'SET NULL'
|
||||
WHEN 'd' THEN 'SET DEFAULT'
|
||||
END AS onupdate,
|
||||
CASE confdeltype
|
||||
WHEN 'a' THEN 'NO ACTION'
|
||||
WHEN 'r' THEN 'RESTRICT'
|
||||
WHEN 'c' THEN 'CASCADE'
|
||||
WHEN 'n' THEN 'SET NULL'
|
||||
WHEN 'd' THEN 'SET DEFAULT'
|
||||
END AS ondelete,
|
||||
CASE confmatchtype
|
||||
WHEN 'u' THEN 'UNSPECIFIED'
|
||||
WHEN 'f' THEN 'FULL'
|
||||
WHEN 'p' THEN 'PARTIAL'
|
||||
END AS match,
|
||||
--array_to_string(c.confkey, ' ') AS fk_constraint_key,
|
||||
consrc
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.conrelid = t.oid
|
||||
LEFT JOIN pg_class t2 ON c.confrelid = t2.oid
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = " . $db->quote($table, 'text');
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name_mdb2 = $constraint_name;
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
$uniqueIndex = false;
|
||||
if (empty($row)) {
|
||||
// We might be looking for a UNIQUE index that was not created
|
||||
// as a constraint but should be treated as such.
|
||||
$query = 'SELECT relname AS constraint_name,
|
||||
indkey,
|
||||
0 AS "check",
|
||||
0 AS "foreign",
|
||||
0 AS "primary",
|
||||
1 AS "unique",
|
||||
0 AS deferrable,
|
||||
0 AS initiallydeferred,
|
||||
NULL AS references_table,
|
||||
NULL AS onupdate,
|
||||
NULL AS ondelete,
|
||||
NULL AS match
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.oid = pg_index.indexrelid
|
||||
AND indisunique = \'t\'
|
||||
AND pg_class.relname = %s';
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name_mdb2 = $constraint_name;
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (empty($row)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
$uniqueIndex = true;
|
||||
}
|
||||
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
|
||||
$definition = array(
|
||||
'primary' => (boolean)$row['primary'],
|
||||
'unique' => (boolean)$row['unique'],
|
||||
'foreign' => (boolean)$row['foreign'],
|
||||
'check' => (boolean)$row['check'],
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => $row['references_table'],
|
||||
'fields' => array(),
|
||||
),
|
||||
'deferrable' => (boolean)$row['deferrable'],
|
||||
'initiallydeferred' => (boolean)$row['initiallydeferred'],
|
||||
'onupdate' => $row['onupdate'],
|
||||
'ondelete' => $row['ondelete'],
|
||||
'match' => $row['match'],
|
||||
);
|
||||
|
||||
if ($uniqueIndex) {
|
||||
$db->loadModule('Manager', null, true);
|
||||
$columns = $db->manager->listTableFields($table_name);
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
$colpos = 1;
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
$query = 'SELECT a.attname
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.conrelid = t.oid
|
||||
LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(c.conkey)
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = ' . $db->quote($table, 'text');
|
||||
$fields = $db->queryCol(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null);
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($fields as $field) {
|
||||
$definition['fields'][$field] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
|
||||
if ($definition['foreign']) {
|
||||
$query = 'SELECT a.attname
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.confrelid = t.oid
|
||||
LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(c.confkey)
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = ' . $db->quote($definition['references']['table'], 'text');
|
||||
$foreign_fields = $db->queryCol(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null);
|
||||
if (PEAR::isError($foreign_fields)) {
|
||||
return $foreign_fields;
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($foreign_fields as $foreign_field) {
|
||||
$definition['references']['fields'][$foreign_field] = array(
|
||||
'position' => $colpos++,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($definition['check']) {
|
||||
$check_def = $db->queryOne("SELECT pg_get_constraintdef(" . $row['oid'] . ", 't')");
|
||||
// ...
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*
|
||||
* @TODO: add support for plsql functions and functions with args
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT trg.tgname AS trigger_name,
|
||||
tbl.relname AS table_name,
|
||||
CASE
|
||||
WHEN p.proname IS NOT NULL THEN 'EXECUTE PROCEDURE ' || p.proname || '();'
|
||||
ELSE ''
|
||||
END AS trigger_body,
|
||||
CASE trg.tgtype & cast(2 as int2)
|
||||
WHEN 0 THEN 'AFTER'
|
||||
ELSE 'BEFORE'
|
||||
END AS trigger_type,
|
||||
CASE trg.tgtype & cast(28 as int2)
|
||||
WHEN 16 THEN 'UPDATE'
|
||||
WHEN 8 THEN 'DELETE'
|
||||
WHEN 4 THEN 'INSERT'
|
||||
WHEN 20 THEN 'INSERT, UPDATE'
|
||||
WHEN 28 THEN 'INSERT, UPDATE, DELETE'
|
||||
WHEN 24 THEN 'UPDATE, DELETE'
|
||||
WHEN 12 THEN 'INSERT, DELETE'
|
||||
END AS trigger_event,
|
||||
CASE trg.tgenabled
|
||||
WHEN 'O' THEN 't'
|
||||
ELSE trg.tgenabled
|
||||
END AS trigger_enabled,
|
||||
obj_description(trg.oid, 'pg_trigger') AS trigger_comment
|
||||
FROM pg_trigger trg,
|
||||
pg_class tbl,
|
||||
pg_proc p
|
||||
WHERE trg.tgrelid = tbl.oid
|
||||
AND trg.tgfoid = p.oid
|
||||
AND trg.tgname = ". $db->quote($trigger, 'text');
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
'trigger_comment' => 'text',
|
||||
'trigger_enabled' => 'boolean',
|
||||
);
|
||||
return $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
|
||||
if (!is_resource($resource)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Could not generate result resource', __FUNCTION__);
|
||||
}
|
||||
|
||||
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($resource);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
$db->loadModule('Datatype', null, true);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => function_exists('pg_field_table') ? @pg_field_table($resource, $i) : '',
|
||||
'name' => $case_func(@pg_field_name($resource, $i)),
|
||||
'type' => @pg_field_type($resource, $i),
|
||||
'length' => @pg_field_size($resource, $i),
|
||||
'flags' => '',
|
||||
);
|
||||
$mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
|
||||
if (PEAR::isError($mdb2type_info)) {
|
||||
return $mdb2type_info;
|
||||
}
|
||||
$res[$i]['mdb2type'] = $mdb2type_info[0][0];
|
||||
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;
|
||||
}
|
||||
}
|
||||
?>
|
609
inc/MDB2/Driver/Reverse/sqlite.php
Executable file
609
inc/MDB2/Driver/Reverse/sqlite.php
Executable file
|
@ -0,0 +1,609 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Lorenzo Alberton |
|
||||
// | 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> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: sqlite.php,v 1.80 2008/05/03 10:30:14 quipo Exp $
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQlite driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_sqlite extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
/**
|
||||
* Remove SQL comments from the field definition
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _removeComments($sql) {
|
||||
$lines = split("\n", $sql);
|
||||
foreach ($lines as $k => $line) {
|
||||
$pieces = explode('--', $line);
|
||||
if (count($pieces) > 1 && (substr_count($pieces[0], '\'') % 2) == 0) {
|
||||
$lines[$k] = substr($line, 0, strpos($line, '--'));
|
||||
}
|
||||
}
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function _getTableColumns($sql)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_def = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
// replace the decimal length-places-separator with a colon
|
||||
$column_def = preg_replace('/(\d),(\d)/', '\1:\2', $column_def);
|
||||
$column_def = $this->_removeComments($column_def);
|
||||
$column_sql = split(',', $column_def);
|
||||
$columns = array();
|
||||
$count = count($column_sql);
|
||||
if ($count == 0) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unexpected empty table column definition list', __FUNCTION__);
|
||||
}
|
||||
$regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i';
|
||||
$regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i';
|
||||
for ($i=0, $j=0; $i<$count; ++$i) {
|
||||
if (!preg_match($regexp, trim($column_sql[$i]), $matches)) {
|
||||
if (!preg_match($regexp2, trim($column_sql[$i]))) {
|
||||
continue;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unexpected table column SQL definition: "'.$column_sql[$i].'"', __FUNCTION__);
|
||||
}
|
||||
$columns[$j]['name'] = trim($matches[1], implode('', $db->identifier_quoting));
|
||||
$columns[$j]['type'] = strtolower($matches[2]);
|
||||
if (isset($matches[4]) && strlen($matches[4])) {
|
||||
$columns[$j]['length'] = $matches[4];
|
||||
}
|
||||
if (isset($matches[6]) && strlen($matches[6])) {
|
||||
$columns[$j]['decimal'] = $matches[6];
|
||||
}
|
||||
if (isset($matches[8]) && strlen($matches[8])) {
|
||||
$columns[$j]['unsigned'] = true;
|
||||
}
|
||||
if (isset($matches[9]) && strlen($matches[9])) {
|
||||
$columns[$j]['autoincrement'] = true;
|
||||
}
|
||||
if (isset($matches[12]) && strlen($matches[12])) {
|
||||
$default = $matches[12];
|
||||
if (strlen($default) && $default[0]=="'") {
|
||||
$default = str_replace("''", "'", substr($default, 1, strlen($default)-2));
|
||||
}
|
||||
if ($default === 'NULL') {
|
||||
$default = null;
|
||||
}
|
||||
$columns[$j]['default'] = $default;
|
||||
}
|
||||
if (isset($matches[7]) && strlen($matches[7])) {
|
||||
$columns[$j]['notnull'] = ($matches[7] === ' NOT NULL');
|
||||
} else if (isset($matches[9]) && strlen($matches[9])) {
|
||||
$columns[$j]['notnull'] = ($matches[9] === ' NOT NULL');
|
||||
} else if (isset($matches[13]) && strlen($matches[13])) {
|
||||
$columns[$j]['notnull'] = ($matches[13] === ' NOT NULL');
|
||||
}
|
||||
++$j;
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table_name 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.
|
||||
* The returned array contains an array for each field definition,
|
||||
* with (some of) these indices:
|
||||
* [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table_name, $field_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name='.$db->quote($table, 'text');
|
||||
}
|
||||
$sql = $db->queryOne($query);
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
$columns = $this->_getTableColumns($sql);
|
||||
foreach ($columns as $column) {
|
||||
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']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['name']) {
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (!empty($column['notnull'])) {
|
||||
$notnull = $column['notnull'];
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if (is_null($default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (!empty($column['autoincrement'])) {
|
||||
$autoincrement = true;
|
||||
}
|
||||
|
||||
$definition[0] = array(
|
||||
'notnull' => $notnull,
|
||||
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||
);
|
||||
if (!is_null($length)) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (!is_null($unsigned)) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (!is_null($fixed)) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table_name 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_name, $index_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text');
|
||||
}
|
||||
$query.= ' AND sql NOT NULL ORDER BY name';
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($index_name_mdb2), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($index_name_mdb2, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
if (PEAR::isError($sql) || empty($sql)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($index_name), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($index_name, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
}
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
if (!$sql) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$sql = strtolower($sql);
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_names = split(',', $column_names);
|
||||
|
||||
if (preg_match("/^create unique/", $sql)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
$count = count($column_names);
|
||||
for ($i=0; $i<$count; ++$i) {
|
||||
$column_name = strtok($column_names[$i], ' ');
|
||||
$collation = strtok(' ');
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => $i+1
|
||||
);
|
||||
if (!empty($collation)) {
|
||||
$definition['fields'][$column_name]['sorting'] =
|
||||
($collation=='ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text');
|
||||
}
|
||||
$query.= ' AND sql NOT NULL ORDER BY name';
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($constraint_name_mdb2), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($constraint_name_mdb2, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
if (PEAR::isError($sql) || empty($sql)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($constraint_name), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($constraint_name, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
}
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
//default values, eventually overridden
|
||||
$definition = array(
|
||||
'primary' => false,
|
||||
'unique' => false,
|
||||
'foreign' => false,
|
||||
'check' => false,
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => '',
|
||||
'fields' => array(),
|
||||
),
|
||||
'onupdate' => '',
|
||||
'ondelete' => '',
|
||||
'match' => '',
|
||||
'deferrable' => false,
|
||||
'initiallydeferred' => false,
|
||||
);
|
||||
if (!$sql) {
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name='.$db->quote($table, 'text');
|
||||
}
|
||||
$query.= " AND sql NOT NULL ORDER BY name";
|
||||
$sql = $db->queryOne($query, 'text');
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
if ($constraint_name == 'primary') {
|
||||
// search in table definition for PRIMARY KEYs
|
||||
if (preg_match("/\bPRIMARY\s+KEY\b\s*\(([^)]+)/i", $sql, $tmp)) {
|
||||
$definition['primary'] = true;
|
||||
$definition['fields'] = array();
|
||||
$column_names = split(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
if (preg_match("/\"([^\"]+)\"[^\,\"]+\bPRIMARY\s+KEY\b[^\,\)]*/i", $sql, $tmp)) {
|
||||
$definition['primary'] = true;
|
||||
$definition['fields'] = array();
|
||||
$column_names = split(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
} else {
|
||||
// search in table definition for FOREIGN KEYs
|
||||
$pattern = "/\bCONSTRAINT\b\s+%s\s+
|
||||
\bFOREIGN\s+KEY\b\s*\(([^\)]+)\)\s*
|
||||
\bREFERENCES\b\s+([^\s]+)\s*\(([^\)]+)\)\s*
|
||||
(?:\bMATCH\s*([^\s]+))?\s*
|
||||
(?:\bON\s+UPDATE\s+([^\s,\)]+))?\s*
|
||||
(?:\bON\s+DELETE\s+([^\s,\)]+))?\s*
|
||||
/imsx";
|
||||
$found_fk = false;
|
||||
if (preg_match(sprintf($pattern, $constraint_name_mdb2), $sql, $tmp)) {
|
||||
$found_fk = true;
|
||||
} elseif (preg_match(sprintf($pattern, $constraint_name), $sql, $tmp)) {
|
||||
$found_fk = true;
|
||||
}
|
||||
if ($found_fk) {
|
||||
$definition['foreign'] = true;
|
||||
$definition['match'] = 'SIMPLE';
|
||||
$definition['onupdate'] = 'NO ACTION';
|
||||
$definition['ondelete'] = 'NO ACTION';
|
||||
$definition['references']['table'] = $tmp[2];
|
||||
$column_names = split(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$referenced_cols = split(',', $tmp[3]);
|
||||
$colpos = 1;
|
||||
foreach ($referenced_cols as $column_name) {
|
||||
$definition['references']['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
if (isset($tmp[4])) {
|
||||
$definition['match'] = $tmp[4];
|
||||
}
|
||||
if (isset($tmp[5])) {
|
||||
$definition['onupdate'] = $tmp[5];
|
||||
}
|
||||
if (isset($tmp[6])) {
|
||||
$definition['ondelete'] = $tmp[6];
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
$sql = false;
|
||||
}
|
||||
if (!$sql) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
$sql = strtolower($sql);
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_names = split(',', $column_names);
|
||||
|
||||
if (!preg_match("/^create unique/", $sql)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
$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(
|
||||
'position' => $i+1
|
||||
);
|
||||
if (!empty($collation)) {
|
||||
$definition['fields'][$column_name]['sorting'] =
|
||||
($collation=='ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT name as trigger_name,
|
||||
tbl_name AS table_name,
|
||||
sql AS trigger_body,
|
||||
NULL AS trigger_type,
|
||||
NULL AS trigger_event,
|
||||
NULL AS trigger_comment,
|
||||
1 AS trigger_enabled
|
||||
FROM sqlite_master
|
||||
WHERE type='trigger'";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= ' AND LOWER(name)='.$db->quote(strtolower($trigger), 'text');
|
||||
} else {
|
||||
$query.= ' AND name='.$db->quote($trigger, 'text');
|
||||
}
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
'trigger_comment' => 'text',
|
||||
'trigger_enabled' => 'boolean',
|
||||
);
|
||||
$def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($def)) {
|
||||
return $def;
|
||||
}
|
||||
if (empty($def)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing trigger', __FUNCTION__);
|
||||
}
|
||||
if (preg_match("/^create\s+(?:temp|temporary)?trigger\s+(?:if\s+not\s+exists\s+)?.*(before|after)?\s+(insert|update|delete)/Uims", $def['trigger_body'], $tmp)) {
|
||||
$def['trigger_type'] = strtoupper($tmp[1]);
|
||||
$def['trigger_event'] = strtoupper($tmp[2]);
|
||||
}
|
||||
return $def;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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_Driver_Common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE, null, null,
|
||||
'This DBMS can not obtain tableInfo from result sets', __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
1700
inc/MDB2/Driver/mysql.php
Executable file
1700
inc/MDB2/Driver/mysql.php
Executable file
File diff suppressed because it is too large
Load diff
1519
inc/MDB2/Driver/pgsql.php
Executable file
1519
inc/MDB2/Driver/pgsql.php
Executable file
File diff suppressed because it is too large
Load diff
1082
inc/MDB2/Driver/sqlite.php
Executable file
1082
inc/MDB2/Driver/sqlite.php
Executable file
File diff suppressed because it is too large
Load diff
721
inc/MDB2/Extended.php
Executable file
721
inc/MDB2/Extended.php
Executable file
|
@ -0,0 +1,721 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: Extended.php,v 1.60 2007/11/28 19:49:34 quipo Exp $
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used by autoPrepare()
|
||||
*/
|
||||
define('MDB2_AUTOQUERY_INSERT', 1);
|
||||
define('MDB2_AUTOQUERY_UPDATE', 2);
|
||||
define('MDB2_AUTOQUERY_DELETE', 3);
|
||||
define('MDB2_AUTOQUERY_SELECT', 4);
|
||||
|
||||
/**
|
||||
* 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()
|
||||
|
||||
/**
|
||||
* Generate an insert, update or delete query and call prepare() on it
|
||||
*
|
||||
* @param string table
|
||||
* @param array the fields names
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete queries, this string will be put after the sql WHERE statement)
|
||||
* @param array that contains the types of the placeholders
|
||||
* @param mixed array that contains the types of the columns in
|
||||
* the result set or MDB2_PREPARE_RESULT, if set to
|
||||
* MDB2_PREPARE_MANIP the query is handled as a manipulation query
|
||||
*
|
||||
* @return resource handle for the query
|
||||
* @see buildManipSQL
|
||||
* @access public
|
||||
*/
|
||||
function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_types = MDB2_PREPARE_MANIP)
|
||||
{
|
||||
$query = $this->buildManipSQL($table, $table_fields, $mode, $where);
|
||||
if (PEAR::isError($query)) {
|
||||
return $query;
|
||||
}
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$lobs = array();
|
||||
foreach ((array)$types as $param => $type) {
|
||||
if (($type == 'clob') || ($type == 'blob')) {
|
||||
$lobs[$param] = $table_fields[$param];
|
||||
}
|
||||
}
|
||||
return $db->prepare($query, $types, $result_types, $lobs);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoExecute()
|
||||
|
||||
/**
|
||||
* Generate an insert, update or delete query and call prepare() and execute() on it
|
||||
*
|
||||
* @param string name of the table
|
||||
* @param array assoc ($key=>$value) where $key is a field name and $value its value
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete queries, this string will be put after the sql WHERE statement)
|
||||
* @param array that contains the types of the placeholders
|
||||
* @param string which specifies which result class to use
|
||||
* @param mixed array that contains the types of the columns in
|
||||
* the result set or MDB2_PREPARE_RESULT, if set to
|
||||
* MDB2_PREPARE_MANIP the query is handled as a manipulation query
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, a MDB2 error on failure
|
||||
* @see buildManipSQL
|
||||
* @see autoPrepare
|
||||
* @access public
|
||||
*/
|
||||
function &autoExecute($table, $fields_values, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_class = true, $result_types = MDB2_PREPARE_MANIP)
|
||||
{
|
||||
$fields_values = (array)$fields_values;
|
||||
if ($mode == MDB2_AUTOQUERY_SELECT) {
|
||||
if (is_array($result_types)) {
|
||||
$keys = array_keys($result_types);
|
||||
} elseif (!empty($fields_values)) {
|
||||
$keys = $fields_values;
|
||||
} else {
|
||||
$keys = array();
|
||||
}
|
||||
} else {
|
||||
$keys = array_keys($fields_values);
|
||||
}
|
||||
$params = array_values($fields_values);
|
||||
if (empty($params)) {
|
||||
$query = $this->buildManipSQL($table, $keys, $mode, $where);
|
||||
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if ($mode == MDB2_AUTOQUERY_SELECT) {
|
||||
$result =& $db->query($query, $result_types, $result_class);
|
||||
} else {
|
||||
$result = $db->exec($query);
|
||||
}
|
||||
} else {
|
||||
$stmt = $this->autoPrepare($table, $keys, $mode, $where, $types, $result_types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$result =& $stmt->execute($params, $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/DELETE query, all
|
||||
* the records of the table will be updated/deleted !
|
||||
*
|
||||
* @param string name of the table
|
||||
* @param ordered array containing the fields names
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete 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 ($db->options['quote_identifier']) {
|
||||
$table = $db->quoteIdentifier($table);
|
||||
}
|
||||
|
||||
if (!empty($table_fields) && $db->options['quote_identifier']) {
|
||||
foreach ($table_fields as $key => $field) {
|
||||
$table_fields[$key] = $db->quoteIdentifier($field);
|
||||
}
|
||||
}
|
||||
|
||||
if ($where !== false && !is_null($where)) {
|
||||
if (is_array($where)) {
|
||||
$where = implode(' AND ', $where);
|
||||
}
|
||||
$where = ' WHERE '.$where;
|
||||
}
|
||||
|
||||
switch ($mode) {
|
||||
case MDB2_AUTOQUERY_INSERT:
|
||||
if (empty($table_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Insert requires table fields', __FUNCTION__);
|
||||
}
|
||||
$cols = implode(', ', $table_fields);
|
||||
$values = '?'.str_repeat(', ?', (count($table_fields) - 1));
|
||||
return 'INSERT INTO '.$table.' ('.$cols.') VALUES ('.$values.')';
|
||||
break;
|
||||
case MDB2_AUTOQUERY_UPDATE:
|
||||
if (empty($table_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Update requires table fields', __FUNCTION__);
|
||||
}
|
||||
$set = implode(' = ?, ', $table_fields).' = ?';
|
||||
$sql = 'UPDATE '.$table.' SET '.$set.$where;
|
||||
return $sql;
|
||||
break;
|
||||
case MDB2_AUTOQUERY_DELETE:
|
||||
$sql = 'DELETE FROM '.$table.$where;
|
||||
return $sql;
|
||||
break;
|
||||
case MDB2_AUTOQUERY_SELECT:
|
||||
$cols = !empty($table_fields) ? implode(', ', $table_fields) : '*';
|
||||
$sql = 'SELECT '.$cols.' FROM '.$table.$where;
|
||||
return $sql;
|
||||
break;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_SYNTAX, null, null,
|
||||
'Non existant mode', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ limitQuery()
|
||||
|
||||
/**
|
||||
* Generates a limited query
|
||||
*
|
||||
* @param string query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param integer the numbers of rows to fetch
|
||||
* @param integer the row to start to fetching
|
||||
* @param string which specifies which result class to use
|
||||
* @param mixed string which specifies which class to wrap results in
|
||||
*
|
||||
* @return MDB2_Result|MDB2_Error result set on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function &limitQuery($query, $types, $limit, $offset = 0, $result_class = true,
|
||||
$result_wrap_class = false)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->setLimit($limit, $offset);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result =& $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execParam()
|
||||
|
||||
/**
|
||||
* Execute a parameterized DML statement.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
*
|
||||
* @return int|MDB2_Error affected rows on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function execParam($query, $params = array(), $param_types = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->exec($query);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, MDB2_PREPARE_MANIP);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$stmt->free();
|
||||
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 the SQL query
|
||||
* @param string that contains the type of the column in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int|string which column to return
|
||||
*
|
||||
* @return scalar|MDB2_Error 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 (empty($params)) {
|
||||
return $db->queryOne($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
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 the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int the fetch mode to use
|
||||
*
|
||||
* @return array|MDB2_Error data 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 (empty($params)) {
|
||||
return $db->queryRow($query, $types, $fetchmode);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
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 the SQL query
|
||||
* @param string that contains the type of the column in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int|string which column to return
|
||||
*
|
||||
* @return array|MDB2_Error data 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 (empty($params)) {
|
||||
return $db->queryCol($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
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 the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int the fetch mode to use
|
||||
* @param bool if set to true, the $all will have the first
|
||||
* column as its first dimension
|
||||
* @param bool $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 bool $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|MDB2_Error data 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 (empty($params)) {
|
||||
return $db->queryAll($query, $types, $fetchmode, $rekey, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
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 MDB2 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:
|
||||
* <pre>
|
||||
* ID TEXT DATE
|
||||
* --------------------------------
|
||||
* 1 'one' 944679408
|
||||
* 2 'two' 944679408
|
||||
* 3 'three' 944679408
|
||||
* </pre>
|
||||
* Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
||||
* <pre>
|
||||
* array(
|
||||
* '1' => 'one',
|
||||
* '2' => 'two',
|
||||
* '3' => 'three',
|
||||
* )
|
||||
* </pre>
|
||||
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
||||
* <pre>
|
||||
* array(
|
||||
* '1' => array('one', '944679408'),
|
||||
* '2' => array('two', '944679408'),
|
||||
* '3' => array('three', '944679408')
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* 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:
|
||||
* <pre>
|
||||
* 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')
|
||||
* )
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* Keep in mind that database functions in PHP usually return string
|
||||
* values for results regardless of the database's internal type.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param bool $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 bool $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|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @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 (empty($params)) {
|
||||
return $db->queryAll($query, $types, $fetchmode, true, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
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 query handle from prepare()
|
||||
* @param array numeric array containing the data to insert into the query
|
||||
*
|
||||
* @return bool|MDB2_Error true 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++) {
|
||||
$result = $stmt->execute($params[$i]);
|
||||
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 name of the table into which a new row was inserted
|
||||
* @param string name of the field into which a new row was inserted
|
||||
* @param bool when true the sequence is automatic created, if it not exists
|
||||
* @param bool if the returned value should be quoted
|
||||
*
|
||||
* @return int|MDB2_Error id on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getBeforeID($table, $field = null, $ondemand = true, $quote = 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 (!$quote || PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
return $db->quote($id, 'integer');
|
||||
} elseif (!$quote) {
|
||||
return null;
|
||||
}
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAfterID()
|
||||
|
||||
/**
|
||||
* Returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed value as returned by getBeforeId()
|
||||
* @param string name of the table into which a new row was inserted
|
||||
* @param string name of the field into which a new row was inserted
|
||||
*
|
||||
* @return int|MDB2_Error id on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getAfterID($id, $table, $field = null)
|
||||
{
|
||||
$db =& $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->supports('auto_increment') !== true) {
|
||||
return $id;
|
||||
}
|
||||
return $db->lastInsertID($table, $field);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
259
inc/MDB2/Iterator.php
Executable file
259
inc/MDB2/Iterator.php
Executable file
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: Iterator.php,v 1.22 2006/05/06 14:03:41 lsmith Exp $
|
||||
|
||||
/**
|
||||
* PHP5 Iterator
|
||||
*
|
||||
* @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 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 bool true/false, false is also returned on failure
|
||||
* @access public
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return (bool)$this->current();
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function free()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->free();
|
||||
}
|
||||
$this->result = false;
|
||||
$this->row = null;
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ key()
|
||||
|
||||
/**
|
||||
* Returns the row number
|
||||
*
|
||||
* @return int|bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @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();
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP5 buffered Iterator
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_BufferedIterator extends MDB2_Iterator implements SeekableIterator
|
||||
{
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* Check if the end of the result set has been reached
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @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 int|MDB2_Error number of rows, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->numRows();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ rewind()
|
||||
|
||||
/**
|
||||
* Seek to the first row in a result set
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
264
inc/MDB2/LOB.php
Executable file
264
inc/MDB2/LOB.php
Executable file
|
@ -0,0 +1,264 @@
|
|||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 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: LOB.php,v 1.34 2006/10/25 11:52:21 lsmith Exp $
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
require_once 'MDB2.php';
|
||||
|
||||
/**
|
||||
* MDB2_LOB: user land stream wrapper implementation for LOB support
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_LOB
|
||||
{
|
||||
/**
|
||||
* contains the key to the global MDB2 instance array of the associated
|
||||
* MDB2 instance
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
var $db_index;
|
||||
|
||||
/**
|
||||
* contains the key to the global MDB2_LOB instance array of the associated
|
||||
* MDB2_LOB instance
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
var $lob_index;
|
||||
|
||||
// {{{ stream_open()
|
||||
|
||||
/**
|
||||
* open stream
|
||||
*
|
||||
* @param string specifies the URL that was passed to fopen()
|
||||
* @param string the mode used to open the file
|
||||
* @param int holds additional flags set by the streams API
|
||||
* @param string not used
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
if (!preg_match('/^rb?\+?$/', $mode)) {
|
||||
return false;
|
||||
}
|
||||
$url = parse_url($path);
|
||||
if (empty($url['host'])) {
|
||||
return false;
|
||||
}
|
||||
$this->db_index = (int)$url['host'];
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return false;
|
||||
}
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$this->lob_index = (int)$url['user'];
|
||||
if (!isset($db->datatype->lobs[$this->lob_index])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_read()
|
||||
|
||||
/**
|
||||
* read stream
|
||||
*
|
||||
* @param int number of bytes to read
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function stream_read($count)
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$db->datatype->_retrieveLOB($db->datatype->lobs[$this->lob_index]);
|
||||
|
||||
$data = $db->datatype->_readLOB($db->datatype->lobs[$this->lob_index], $count);
|
||||
$length = strlen($data);
|
||||
if ($length == 0) {
|
||||
$db->datatype->lobs[$this->lob_index]['endOfLOB'] = true;
|
||||
}
|
||||
$db->datatype->lobs[$this->lob_index]['position'] += $length;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_write()
|
||||
|
||||
/**
|
||||
* write stream, note implemented
|
||||
*
|
||||
* @param string data
|
||||
*
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function stream_write($data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_tell()
|
||||
|
||||
/**
|
||||
* return the current position
|
||||
*
|
||||
* @return int current position
|
||||
* @access public
|
||||
*/
|
||||
function stream_tell()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->datatype->lobs[$this->lob_index]['position'];
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_eof()
|
||||
|
||||
/**
|
||||
* Check if stream reaches EOF
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_eof()
|
||||
{
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$result = $db->datatype->_endOfLOB($db->datatype->lobs[$this->lob_index]);
|
||||
if (version_compare(phpversion(), "5.0", ">=")
|
||||
&& version_compare(phpversion(), "5.1", "<")
|
||||
) {
|
||||
return !$result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_seek()
|
||||
|
||||
/**
|
||||
* Seek stream, not implemented
|
||||
*
|
||||
* @param int offset
|
||||
* @param int whence
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_seek($offset, $whence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_stat()
|
||||
|
||||
/**
|
||||
* return information about stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function stream_stat()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return array(
|
||||
'db_index' => $this->db_index,
|
||||
'lob_index' => $this->lob_index,
|
||||
);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_close()
|
||||
|
||||
/**
|
||||
* close stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
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($db->datatype->lobs[$this->lob_index]);
|
||||
unset($db->datatype->lobs[$this->lob_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
// register streams wrapper
|
||||
if (!stream_wrapper_register("MDB2LOB", "MDB2_LOB")) {
|
||||
MDB2::raiseError();
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
402
inc/lib_base.php
402
inc/lib_base.php
|
@ -24,7 +24,8 @@
|
|||
|
||||
// set some stuff
|
||||
ob_start();
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
// error_reporting(E_ALL | E_STRICT);
|
||||
error_reporting(E_ALL); // MDB2 gives loads of strict error, disabling for now
|
||||
date_default_timezone_set('Europe/Berlin');
|
||||
ini_set('arg_separator.output','&');
|
||||
ini_set('session.cookie_httponly','1;');
|
||||
|
@ -54,6 +55,8 @@ $CONFIG_DBTYPE='sqlite';
|
|||
// include the generated configfile
|
||||
@include_once($SERVERROOT.'/config/config.php');
|
||||
|
||||
|
||||
$CONFIG_DATADIRECTORY_ROOT=$CONFIG_DATADIRECTORY;// store this in a seperate variable so we can change the data directory to jail users.
|
||||
// redirect to https site if configured
|
||||
if(isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL){
|
||||
if(!isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] != 'on') {
|
||||
|
@ -69,9 +72,10 @@ oc_require_once('lib_log.php');
|
|||
oc_require_once('lib_config.php');
|
||||
oc_require_once('lib_user.php');
|
||||
oc_require_once('lib_ocs.php');
|
||||
@oc_require_once('MDB2.php');
|
||||
// @oc_require_once('MDB2/Driver/Manager/common.php');
|
||||
|
||||
|
||||
$CONFIG_DATADIRECTORY_ROOT=$CONFIG_DATADIRECTORY;// store this in a seperate variable so we can change the data directory to jail users.
|
||||
if(!is_dir($CONFIG_DATADIRECTORY_ROOT)){
|
||||
mkdir($CONFIG_DATADIRECTORY_ROOT);
|
||||
}
|
||||
|
@ -219,48 +223,71 @@ class OC_UTIL {
|
|||
*
|
||||
*/
|
||||
class OC_DB {
|
||||
|
||||
/**
|
||||
* executes a query on the database
|
||||
*
|
||||
* @param string $cmd
|
||||
* @return result-set
|
||||
*/
|
||||
static function query($cmd) {
|
||||
global $DOCUMENTROOT;
|
||||
global $SERVERROOT;
|
||||
global $DBConnection;
|
||||
global $CONFIG_DBNAME;
|
||||
global $CONFIG_DBHOST;
|
||||
global $CONFIG_DBUSER;
|
||||
global $CONFIG_DBPASSWORD;
|
||||
global $CONFIG_DBTYPE;
|
||||
if(!isset($DBConnection)) {
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$DBConnection = @new SQLiteDatabase($SERVERROOT.'/'.$CONFIG_DBNAME);
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$DBConnection = @new mysqli($CONFIG_DBHOST, $CONFIG_DBUSER, $CONFIG_DBPASSWORD,$CONFIG_DBNAME);
|
||||
}
|
||||
if (!$DBConnection) {
|
||||
@ob_end_clean();
|
||||
echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'.</center>');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$result = @$DBConnection->query($cmd);
|
||||
if (!$result) {
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$error=sqlite_error_string($DBConnection->lastError());
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
print_r($DBConnection);
|
||||
$error=$DBConnection->error;
|
||||
}
|
||||
$entry='DB Error: "'.$error.'"<br />';
|
||||
$entry.='Offending command was: '.$cmd.'<br />';
|
||||
echo($entry);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
static private $DBConnection=false;
|
||||
/**
|
||||
* connect to the datbase if not already connected
|
||||
*/
|
||||
public static function connect(){
|
||||
global $CONFIG_DBNAME;
|
||||
global $CONFIG_DBHOST;
|
||||
global $CONFIG_DBUSER;
|
||||
global $CONFIG_DBPASSWORD;
|
||||
global $CONFIG_DBTYPE;
|
||||
global $DOCUMENTROOT;
|
||||
global $SERVERROOT;
|
||||
if(!self::$DBConnection){
|
||||
$options = array(
|
||||
'debug' => 0,
|
||||
'portability' => MDB2_PORTABILITY_ALL,
|
||||
);
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$dsn = array(
|
||||
'phptype' => 'sqlite',
|
||||
'database' => $SERVERROOT.'/'.$CONFIG_DBNAME,
|
||||
'mode' => '0644',
|
||||
);
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$dsn = array(
|
||||
'phptype' => 'mysql',
|
||||
'username' => $CONFIG_DBUSER,
|
||||
'password' => $CONFIG_DBPASSWORD,
|
||||
'hostspec' => $CONFIG_DBHOST,
|
||||
'database' => $CONFIG_DBNAME,
|
||||
);
|
||||
}
|
||||
self::$DBConnection=MDB2::connect($dsn,$options);
|
||||
if (@PEAR::isError(self::$DBConnection)) {
|
||||
echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
|
||||
die(self::$DBConnection->getMessage());
|
||||
}
|
||||
self::$DBConnection->setFetchMode(MDB2_FETCHMODE_ASSOC);
|
||||
// self::$DBConnection->loadModule('Manager');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* executes a query on the database
|
||||
*
|
||||
* @param string $cmd
|
||||
* @return result-set
|
||||
*/
|
||||
static function query($cmd){
|
||||
global $CONFIG_DBTYPE;
|
||||
if(!trim($cmd)){
|
||||
return false;
|
||||
}
|
||||
OC_DB::connect();
|
||||
if($CONFIG_DBTYPE=='sqlite'){//fix differences between sql versions
|
||||
$cmd=str_replace('`','',$cmd);
|
||||
}
|
||||
$result=self::$DBConnection->query($cmd);
|
||||
if (PEAR::isError($result)) {
|
||||
$entry='DB Error: "'.$result->getMessage().'"<br />';
|
||||
$entry.='Offending command was: '.$cmd.'<br />';
|
||||
die($entry);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* executes a query on the database and returns the result in an array
|
||||
|
@ -268,193 +295,96 @@ class OC_DB {
|
|||
* @param string $cmd
|
||||
* @return result-set
|
||||
*/
|
||||
static function select($cmd) {
|
||||
global $CONFIG_DBTYPE;
|
||||
$result=OC_DB::query($cmd);
|
||||
if($result){
|
||||
$data=array();
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
while($row=$result->fetch(SQLITE_ASSOC)){
|
||||
$data[]=$row;
|
||||
}
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
while($row=$result->fetch_array(MYSQLI_ASSOC)){
|
||||
$data[]=$row;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
static function select($cmd){
|
||||
OC_DB::connect();
|
||||
return self::$DBConnection->queryAll($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* executes multiply queries on the database
|
||||
*
|
||||
* @param string $cmd
|
||||
* @return result-set
|
||||
*/
|
||||
static function multiquery($cmd) {
|
||||
global $DOCUMENTROOT;
|
||||
global $SERVERROOT;
|
||||
global $DBConnection;
|
||||
global $CONFIG_DBNAME;
|
||||
global $CONFIG_DBTYPE;
|
||||
global $CONFIG_DBHOST;
|
||||
global $CONFIG_DBUSER;
|
||||
global $CONFIG_DBPASSWORD;
|
||||
if(!isset($DBConnection)) {
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$DBConnection = new SQLiteDatabase($SERVERROOT.'/'.$CONFIG_DBNAME);
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$DBConnection = @new mysqli($CONFIG_DBHOST, $CONFIG_DBUSER, $CONFIG_DBPASSWORD,$CONFIG_DBNAME);
|
||||
}
|
||||
if (!$DBConnection) {
|
||||
@ob_end_clean();
|
||||
echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'.</center>');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$result = @$DBConnection->queryExec($cmd);
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$result = @$DBConnection->multi_query($cmd);
|
||||
}
|
||||
if (!$result) {
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$error=sqlite_error_string($DBConnection->lastError());
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$error=$DBConnection->error;
|
||||
}
|
||||
$entry='DB Error: "'.$error.'"<br />';
|
||||
$entry.='Offending command was: '.$cmd.'<br />';
|
||||
echo($entry);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* executes multiply queries on the database
|
||||
*
|
||||
* @param string $cmd
|
||||
* @return result-set
|
||||
*/
|
||||
static function multiquery($cmd) {
|
||||
$queries=explode(';',$cmd);
|
||||
foreach($queries as $query){
|
||||
OC_DB::query($query);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* closing a db connection
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function close() {
|
||||
global $CONFIG_DBTYPE;
|
||||
global $DBConnection;
|
||||
if(isset($DBConnection)) {
|
||||
return $DBConnection->close();
|
||||
} else {
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* closing a db connection
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function close() {
|
||||
self::$DBConnection->disconnect();
|
||||
self::$DBConnection=false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returning primarykey if last statement was an insert.
|
||||
*
|
||||
* @return primarykey
|
||||
*/
|
||||
static function insertid() {
|
||||
global $DBConnection;
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
return $DBConnection->lastInsertRowid();
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
return(mysqli_insert_id($DBConnection));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returning primarykey if last statement was an insert.
|
||||
*
|
||||
* @return primarykey
|
||||
*/
|
||||
static function insertid() {
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
return self::$DBConnection->lastInsertRowid();
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
return(mysqli_insert_id(self::$DBConnection));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning number of rows in a result
|
||||
*
|
||||
* @param resultset $result
|
||||
* @return int
|
||||
*/
|
||||
static function numrows($result) {
|
||||
if(!isset($result) or ($result == false)) return 0;
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$num= $result->numRows();
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$num= mysqli_num_rows($result);
|
||||
}
|
||||
return($num);
|
||||
}
|
||||
/**
|
||||
* Returning number of rows in a result
|
||||
*
|
||||
* @param resultset $result
|
||||
* @return int
|
||||
*/
|
||||
static function numrows($result) {
|
||||
$result->numRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning number of affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
static function affected_rows() {
|
||||
global $DBConnection;
|
||||
global $CONFIG_DBTYPE;
|
||||
if(!isset($DBConnection) or ($DBConnection==false)) return 0;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$num= $DBConnection->changes();
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$num= mysqli_affected_rows($DBConnection);
|
||||
}
|
||||
return($num);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a field from the resultset
|
||||
*
|
||||
* @param resultset $result
|
||||
* @param int $i
|
||||
* @param int $field
|
||||
* @return unknown
|
||||
*/
|
||||
static function result($result, $i, $field) {
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$result->seek($i);
|
||||
$tmp=$result->fetch();
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
mysqli_data_seek($result,$i);
|
||||
if (is_string($field))
|
||||
$tmp=mysqli_fetch_array($result,MYSQLI_BOTH);
|
||||
else
|
||||
$tmp=mysqli_fetch_array($result,MYSQLI_NUM);
|
||||
}
|
||||
$tmp=$tmp[$field];
|
||||
return($tmp);
|
||||
return($tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* get data-array from resultset
|
||||
*
|
||||
* @param resultset $result
|
||||
* @return data
|
||||
*/
|
||||
static function fetch_assoc($result) {
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
return $result->fetch(SQLITE_ASSOC);
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
return mysqli_fetch_assoc($result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Freeing resultset (performance)
|
||||
*
|
||||
* @param unknown_type $result
|
||||
* @return bool
|
||||
*/
|
||||
static function free_result($result) {
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$result = null; //No native way to do this
|
||||
return true;
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
return @mysqli_free_result($result);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returning number of affected rows
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
static function affected_rows() {
|
||||
self::$DBConnection->affectedRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Freeing resultset (performance)
|
||||
*
|
||||
* @param unknown_type $result
|
||||
* @return bool
|
||||
*/
|
||||
static function free_result($result) {
|
||||
$result->free();
|
||||
}
|
||||
|
||||
static public function disconnect(){
|
||||
if(self::$DBConnection){
|
||||
self::$DBConnection->disconnect();
|
||||
self::$DBConnection=false;
|
||||
}
|
||||
}
|
||||
|
||||
static public function createTable($name,$definition){
|
||||
self::connect();
|
||||
self::$DBConnection->createTable($name,$definition);
|
||||
}
|
||||
|
||||
static public function createConstraint($table,$name,$definition){
|
||||
self::connect();
|
||||
self::$DBConnection->createConstraint($table,$name,$definition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -474,11 +404,11 @@ function oc_require($file){
|
|||
global $CONFIG_DATEFORMAT;
|
||||
global $CONFIG_INSTALLED;
|
||||
if(is_file($file)){
|
||||
require($file);
|
||||
return require($file);
|
||||
}elseif(is_file($SERVERROOT.'/'.$file)){
|
||||
require($SERVERROOT.'/'.$file);
|
||||
return require($SERVERROOT.'/'.$file);
|
||||
}elseif(is_file($SERVERROOT.'/inc/'.$file)){
|
||||
require($SERVERROOT.'/inc/'.$file);
|
||||
return require($SERVERROOT.'/inc/'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,11 +426,11 @@ function oc_require_once($file){
|
|||
global $CONFIG_DATEFORMAT;
|
||||
global $CONFIG_INSTALLED;
|
||||
if(is_file($file)){
|
||||
require_once($file);
|
||||
return require_once($file);
|
||||
}elseif(is_file($SERVERROOT.'/'.$file)){
|
||||
require_once($SERVERROOT.'/'.$file);
|
||||
return require_once($SERVERROOT.'/'.$file);
|
||||
}elseif(is_file($SERVERROOT.'/inc/'.$file)){
|
||||
require_once($SERVERROOT.'/inc/'.$file);
|
||||
return require_once($SERVERROOT.'/inc/'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,11 +448,11 @@ function oc_include($file){
|
|||
global $CONFIG_DATEFORMAT;
|
||||
global $CONFIG_INSTALLED;
|
||||
if(is_file($file)){
|
||||
include($file);
|
||||
return include($file);
|
||||
}elseif(is_file($SERVERROOT.'/'.$file)){
|
||||
include($SERVERROOT.'/'.$file);
|
||||
return include($SERVERROOT.'/'.$file);
|
||||
}elseif(is_file($SERVERROOT.'/inc/'.$file)){
|
||||
include($SERVERROOT.'/inc/'.$file);
|
||||
return include($SERVERROOT.'/inc/'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,11 +470,11 @@ function oc_include_once($file){
|
|||
global $CONFIG_DATEFORMAT;
|
||||
global $CONFIG_INSTALLED;
|
||||
if(is_file($file)){
|
||||
include_once($file);
|
||||
return include_once($file);
|
||||
}elseif(is_file($SERVERROOT.'/'.$file)){
|
||||
include_once($SERVERROOT.'/'.$file);
|
||||
return include_once($SERVERROOT.'/'.$file);
|
||||
}elseif(is_file($SERVERROOT.'/inc/'.$file)){
|
||||
include_once($SERVERROOT.'/inc/'.$file);
|
||||
return include_once($SERVERROOT.'/inc/'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,6 +196,8 @@ class OC_CONFIG{
|
|||
if(!$f){
|
||||
$error.='path of sqlite database not writable by server<br/>';
|
||||
}
|
||||
OC_DB::disconnect();
|
||||
unlink($SERVERROOT.'/'.$CONFIG_DBNAME);
|
||||
}
|
||||
try{
|
||||
if(isset($_POST['filldb'])){
|
||||
|
@ -205,24 +207,22 @@ class OC_CONFIG{
|
|||
echo 'testin';
|
||||
$error.='error while trying to fill the database<br/>';
|
||||
}
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
OC_DB::disconnect();
|
||||
}
|
||||
if(!OC_USER::createuser($_POST['adminlogin'],$_POST['adminpassword']) && !OC_USER::login($_POST['adminlogin'],$_POST['adminpassword'])){
|
||||
$error.='error while trying to create the admin user<br/>';
|
||||
}
|
||||
|
||||
if(OC_USER::getgroupid('admin')==0){
|
||||
if(!OC_USER::creategroup('admin')){
|
||||
$error.='error while trying to create the admin group<br/>';
|
||||
}
|
||||
}
|
||||
|
||||
if(!OC_USER::addtogroup($_POST['adminlogin'],'admin')){
|
||||
$error.='error while trying to add the admin user to the admin group<br/>';
|
||||
}
|
||||
|
||||
//storedata
|
||||
$config='<?php '."\n";
|
||||
// $config.='$CONFIG_ADMINLOGIN=\''.$_POST['adminlogin']."';\n";
|
||||
// $config.='$CONFIG_ADMINPASSWORD=\''.$_POST['adminpassword']."';\n";
|
||||
$config.='$CONFIG_INSTALLED=true;'."\n";
|
||||
$config.='$CONFIG_DATADIRECTORY=\''.$_POST['datadirectory']."';\n";
|
||||
if(isset($_POST['forcessl'])) $config.='$CONFIG_HTTPFORCESSL=true'.";\n"; else $config.='$CONFIG_HTTPFORCESSL=false'.";\n";
|
||||
|
@ -263,7 +263,7 @@ class OC_CONFIG{
|
|||
* "rowid"
|
||||
*/
|
||||
private static function filldatabase(){
|
||||
global $CONFIG_DBTYPE;
|
||||
global $CONFIG_DBTYPE;
|
||||
if($CONFIG_DBTYPE=='sqlite'){
|
||||
$query="CREATE TABLE 'locks' (
|
||||
'token' VARCHAR(255) NOT NULL DEFAULT '',
|
||||
|
@ -296,18 +296,30 @@ CREATE TABLE 'properties' (
|
|||
);
|
||||
|
||||
CREATE TABLE 'users' (
|
||||
'user_id' int(11) NOT NULL,
|
||||
'user_id' INTEGER ASC DEFAULT '',
|
||||
'user_name' varchar(64) NOT NULL DEFAULT '',
|
||||
'user_name_clean' varchar(64) NOT NULL DEFAULT '',
|
||||
'user_password' varchar(40) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY ('user_id'),
|
||||
UNIQUE ('user_name' ,'user_name_clean')
|
||||
);
|
||||
|
||||
CREATE TABLE 'groups' (
|
||||
'group_id' INTEGER ASC DEFAULT '',
|
||||
'group_name' VARCHAR( 64 ) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY ('group_id'),
|
||||
UNIQUE ('group_name')
|
||||
);
|
||||
|
||||
CREATE TABLE 'user_group' (
|
||||
'user_group_id' INTEGER ASC DEFAULT '',
|
||||
'user_id' VARCHAR( 64 ) NOT NULL DEFAULT '',
|
||||
'group_id' VARCHAR( 64 ) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY ('user_group_id')
|
||||
)
|
||||
";
|
||||
}elseif($CONFIG_DBTYPE=='mysql'){
|
||||
$query="SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `locks` (
|
||||
$query="CREATE TABLE IF NOT EXISTS `locks` (
|
||||
`token` varchar(255) NOT NULL DEFAULT '',
|
||||
`path` varchar(200) NOT NULL DEFAULT '',
|
||||
`created` int(11) NOT NULL DEFAULT '0',
|
||||
|
@ -323,7 +335,7 @@ CREATE TABLE IF NOT EXISTS `locks` (
|
|||
KEY `path_2` (`path`),
|
||||
KEY `path_3` (`path`,`token`),
|
||||
KEY `expires` (`expires`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
|
@ -332,7 +344,7 @@ CREATE TABLE IF NOT EXISTS `log` (
|
|||
`type` int(11) NOT NULL,
|
||||
`message` varchar(250) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `properties` (
|
||||
|
@ -342,7 +354,7 @@ CREATE TABLE IF NOT EXISTS `properties` (
|
|||
`value` text,
|
||||
PRIMARY KEY (`path`,`name`,`ns`),
|
||||
KEY `path` (`path`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
||||
|
@ -353,7 +365,7 @@ UNIQUE (
|
|||
`user_name` ,
|
||||
`user_name_clean`
|
||||
)
|
||||
) ENGINE = MYISAM ;
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `groups` (
|
||||
`group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
||||
|
@ -361,13 +373,13 @@ CREATE TABLE IF NOT EXISTS `groups` (
|
|||
UNIQUE (
|
||||
`group_name`
|
||||
)
|
||||
) ENGINE = MYISAM ;
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `user_group` (
|
||||
`user_group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
||||
`user_id` VARCHAR( 64 ) NOT NULL ,
|
||||
`group_id` VARCHAR( 64 ) NOT NULL
|
||||
) ENGINE = MYISAM ;
|
||||
)
|
||||
";
|
||||
}
|
||||
OC_DB::multiquery($query);
|
||||
|
|
|
@ -62,7 +62,7 @@ class OC_USER {
|
|||
$usernameclean=strtolower($username);
|
||||
$username=mysql_escape_string($username);
|
||||
$usernameclean=mysql_escape_string($usernameclean);
|
||||
$query="INSERT INTO `users` (`user_id` ,`user_name` ,`user_name_clean` ,`user_password`)VALUES (NULL , '$username', '$usernameclean', '$password')";
|
||||
$query="INSERT INTO `users` (`user_id` ,`user_name` ,`user_name_clean` ,`user_password`) VALUES (NULL , '$username', '$usernameclean', '$password')";
|
||||
$result=OC_DB::query($query);
|
||||
return ($result)?true:false;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ class OC_USER {
|
|||
$usernameclean=strtolower($username);
|
||||
$username=mysql_escape_string($username);
|
||||
$usernameclean=mysql_escape_string($usernameclean);
|
||||
$query="SELECT user_id FROM `users` WHERE `user_name_clean` = '$usernameclean' AND `user_password` = '$password' LIMIT 1";
|
||||
$query="SELECT user_id FROM users WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['user_id'])){
|
||||
$_SESSION['user_id']=$result[0]['user_id'];
|
||||
|
@ -118,7 +118,7 @@ class OC_USER {
|
|||
public static function creategroup($groupname){
|
||||
if(OC_USER::getgroupid($groupname)==0){
|
||||
$groupname=mysql_escape_string($groupname);
|
||||
$query="INSERT INTO `groups` (`group_id` ,`group_name`) VALUES (NULL , '$groupname');";
|
||||
$query="INSERT INTO `groups` (`group_id` ,`group_name`) VALUES (NULL , '$groupname')";
|
||||
$result=OC_DB::query($query);
|
||||
return ($result)?true:false;
|
||||
}else{
|
||||
|
@ -134,7 +134,7 @@ class OC_USER {
|
|||
$usernameclean=strtolower($username);
|
||||
$username=mysql_escape_string($username);
|
||||
$usernameclean=mysql_escape_string($usernameclean);
|
||||
$query="SELECT user_id FROM `users` WHERE `user_name_clean` = '$usernameclean' LIMIT 1";
|
||||
$query="SELECT user_id FROM users WHERE user_name_clean = '$usernameclean'";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['user_id'])){
|
||||
return $result[0]['user_id'];
|
||||
|
@ -149,7 +149,7 @@ class OC_USER {
|
|||
*/
|
||||
public static function getgroupid($groupname){
|
||||
$groupname=mysql_escape_string($groupname);
|
||||
$query="SELECT group_id FROM `groups` WHERE `group_name` = '$groupname' LIMIT 1";
|
||||
$query="SELECT group_id FROM groups WHERE group_name = '$groupname'";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['group_id'])){
|
||||
return $result[0]['group_id'];
|
||||
|
@ -164,7 +164,7 @@ class OC_USER {
|
|||
*/
|
||||
public static function getgroupname($groupid){
|
||||
$groupid=(integer)$groupid;
|
||||
$query="SELECT group_name FROM `groups` WHERE `group_id` = '$groupid' LIMIT 1";
|
||||
$query="SELECT group_name FROM groups WHERE group_id = '$groupid' LIMIT 1";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['group_name'])){
|
||||
return $result[0]['group_name'];
|
||||
|
@ -181,7 +181,7 @@ class OC_USER {
|
|||
$userid=OC_USER::getuserid($username);
|
||||
$groupid=OC_USER::getgroupid($groupname);
|
||||
if($groupid>0 and $userid>0){
|
||||
$query="SELECT user_group_id FROM `user_group` WHERE `group_id` = '$groupid ' AND `user_id` = '$userid 'LIMIT 1";
|
||||
$query="SELECT user_group_id FROM user_group WHERE group_id = $groupid AND user_id = $userid LIMIT 1";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['user_group_id'])){
|
||||
return true;
|
||||
|
@ -202,7 +202,7 @@ class OC_USER {
|
|||
$userid=OC_USER::getuserid($username);
|
||||
$groupid=OC_USER::getgroupid($groupname);
|
||||
if($groupid!=0 and $userid!=0){
|
||||
$query="INSERT INTO `user_group` (`user_group_id` ,`user_id` ,`group_id`) VALUES (NULL , '$userid', '$groupid');";
|
||||
$query="INSERT INTO `user_group` (`user_group_id` ,`user_id` ,`group_id`) VALUES (NULL , '$userid', '$groupid');";
|
||||
$result=OC_DB::query($query);
|
||||
if($result){
|
||||
return true;
|
||||
|
@ -227,7 +227,7 @@ class OC_USER {
|
|||
*/
|
||||
public static function getusergroups($username){
|
||||
$userid=OC_USER::getuserid($username);
|
||||
$query="SELECT group_id FROM `user_group` WHERE `user_id` = '$userid'";
|
||||
$query="SELECT group_id FROM user_group WHERE user_id = '$userid'";
|
||||
$result=OC_DB::select($query);
|
||||
$groups=array();
|
||||
if(is_array($result)){
|
||||
|
@ -246,7 +246,7 @@ class OC_USER {
|
|||
public static function setpassword($username,$password){
|
||||
$password=sha1($password);
|
||||
$userid=OC_USER::getuserid($username);
|
||||
$query="UPDATE `users` SET `user_password` = '$password' WHERE `user_id` =$userid LIMIT 1 ;";
|
||||
$query="UPDATE users SET user_password = '$password' WHERE user_id =$userid LIMIT 1 ;";
|
||||
$result=OC_DB::query($query);
|
||||
if($result){
|
||||
return true;
|
||||
|
@ -264,7 +264,7 @@ class OC_USER {
|
|||
$usernameclean=strtolower($username);
|
||||
$username=mysql_escape_string($username);
|
||||
$usernameclean=mysql_escape_string($usernameclean);
|
||||
$query="SELECT user_id FROM `users` WHERE `user_name_clean` = '$usernameclean' AND `user_password` = '$password' LIMIT 1";
|
||||
$query="SELECT user_id FROM 'users' WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
|
||||
$result=OC_DB::select($query);
|
||||
if(isset($result[0]) && isset($result[0]['user_id']) && $result[0]['user_id']>0){
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue