forked from Wavyzz/dolibarr
Ajout du package Pear MDB2 qui sera le successeur du package DB
This commit is contained in:
4255
htdocs/includes/pear/MDB2.php
Normal file
4255
htdocs/includes/pear/MDB2.php
Normal file
File diff suppressed because it is too large
Load Diff
183
htdocs/includes/pear/MDB2/Date.php
Normal file
183
htdocs/includes/pear/MDB2/Date.php
Normal 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$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
1716
htdocs/includes/pear/MDB2/Driver/Datatype/Common.php
Normal file
1716
htdocs/includes/pear/MDB2/Driver/Datatype/Common.php
Normal file
File diff suppressed because it is too large
Load Diff
266
htdocs/includes/pear/MDB2/Driver/Datatype/mssql.php
Normal file
266
htdocs/includes/pear/MDB2/Driver/Datatype/mssql.php
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
<?php
|
||||||
|
// vim: set et ts=4 sw=4 fdm=marker:
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | 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. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Authors: Lukas Smith <smith@pooteeweet.org> |
|
||||||
|
// | Daniel Convissor <danielc@php.net> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MS SQL driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Datatype_mssql extends MDB2_Driver_Datatype_Common
|
||||||
|
{
|
||||||
|
// {{{ convertResult()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a value to a RDBMS indepdenant MDB2 type
|
||||||
|
*
|
||||||
|
* @param mixed $value value to be converted
|
||||||
|
* @param int $type constant that specifies which type to convert to
|
||||||
|
* @return mixed converted value
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function convertResult($value, $type)
|
||||||
|
{
|
||||||
|
if (is_null($value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch ($type) {
|
||||||
|
case 'boolean':
|
||||||
|
return $value == '1';
|
||||||
|
case 'date':
|
||||||
|
if (strlen($value) > 10) {
|
||||||
|
$value = substr($value,0,10);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
case 'time':
|
||||||
|
if (strlen($value) > 8) {
|
||||||
|
$value = substr($value,11,8);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
default:
|
||||||
|
return $this->_baseConvertResult($value,$type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ 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 <= 8000) {
|
||||||
|
return 'VARCHAR('.$length.')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'TEXT';
|
||||||
|
case 'blob':
|
||||||
|
if (!empty($field['length'])) {
|
||||||
|
$length = $field['length'];
|
||||||
|
if ($length <= 8000) {
|
||||||
|
return "VARBINARY($length)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'IMAGE';
|
||||||
|
case 'integer':
|
||||||
|
return 'INT';
|
||||||
|
case 'boolean':
|
||||||
|
return 'BIT';
|
||||||
|
case 'date':
|
||||||
|
return 'CHAR ('.strlen('YYYY-MM-DD').')';
|
||||||
|
case 'time':
|
||||||
|
return 'CHAR ('.strlen('HH:MM:SS').')';
|
||||||
|
case 'timestamp':
|
||||||
|
return 'CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')';
|
||||||
|
case 'float':
|
||||||
|
return 'FLOAT';
|
||||||
|
case 'decimal':
|
||||||
|
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||||
|
return 'DECIMAL('.$length.','.$db->options['decimal_places'].')';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _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
|
||||||
|
* @return string text string that represents the given argument value in
|
||||||
|
* a DBMS specific format.
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _quoteBLOB($value, $quote)
|
||||||
|
{
|
||||||
|
if (!$quote) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
$value = bin2hex("0x".$this->_readFile($value));
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ mapNativeDatatype()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a native array description of a field to a MDB2 datatype and length
|
||||||
|
*
|
||||||
|
* @param array $field native field description
|
||||||
|
* @return array containing the various possible types, length, sign, fixed
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function mapNativeDatatype($field)
|
||||||
|
{
|
||||||
|
$db_type = preg_replace('/\d/','', strtolower($field['type']) );
|
||||||
|
$length = $field['length'];
|
||||||
|
if ((int)$length <= 0) {
|
||||||
|
$length = null;
|
||||||
|
}
|
||||||
|
$type = array();
|
||||||
|
// todo: unsigned handling seems to be missing
|
||||||
|
$unsigned = $fixed = null;
|
||||||
|
switch ($db_type) {
|
||||||
|
case 'bit':
|
||||||
|
$type[0] = 'boolean';
|
||||||
|
break;
|
||||||
|
case 'int':
|
||||||
|
$type[0] = 'integer';
|
||||||
|
break;
|
||||||
|
case 'datetime':
|
||||||
|
$type[0] = 'timestamp';
|
||||||
|
break;
|
||||||
|
case 'float':
|
||||||
|
case 'real':
|
||||||
|
case 'numeric':
|
||||||
|
$type[0] = 'float';
|
||||||
|
break;
|
||||||
|
case 'decimal':
|
||||||
|
case 'money':
|
||||||
|
$type[0] = 'decimal';
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
case 'varchar':
|
||||||
|
$fixed = false;
|
||||||
|
case 'char':
|
||||||
|
$type[0] = '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 ($fixed !== false) {
|
||||||
|
$fixed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'image':
|
||||||
|
case 'varbinary':
|
||||||
|
$type[] = 'blob';
|
||||||
|
$length = null;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'mapNativeDatatype: unknown database attribute type: '.$db_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($type, $length, $unsigned, $fixed);
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
460
htdocs/includes/pear/MDB2/Driver/Datatype/mysql.php
Normal file
460
htdocs/includes/pear/MDB2/Driver/Datatype/mysql.php
Normal file
@@ -0,0 +1,460 @@
|
|||||||
|
<?php
|
||||||
|
// vim: set et ts=4 sw=4 fdm=marker:
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | 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$
|
||||||
|
//
|
||||||
|
|
||||||
|
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');
|
||||||
|
} 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.$autoinc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ matchPattern()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build a pattern matching string
|
||||||
|
*
|
||||||
|
* EXPERIMENTAL
|
||||||
|
*
|
||||||
|
* WARNING: this function is experimental and may change signature at
|
||||||
|
* any time until labelled as non-experimental
|
||||||
|
*
|
||||||
|
* @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 = $field['length'];
|
||||||
|
$decimal = '';
|
||||||
|
} 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 '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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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']);
|
||||||
|
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__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($type, $length, $unsigned, $fixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
498
htdocs/includes/pear/MDB2/Driver/Datatype/mysqli.php
Normal file
498
htdocs/includes/pear/MDB2/Driver/Datatype/mysqli.php
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
<?php
|
||||||
|
// vim: set et ts=4 sw=4 fdm=marker:
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | 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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQLi driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Datatype_mysqli 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');
|
||||||
|
} 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.$autoinc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ matchPattern()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build a pattern matching string
|
||||||
|
*
|
||||||
|
* EXPERIMENTAL
|
||||||
|
*
|
||||||
|
* WARNING: this function is experimental and may change signature at
|
||||||
|
* any time until labelled as non-experimental
|
||||||
|
*
|
||||||
|
* @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 = $field['length'];
|
||||||
|
$decimal = '';
|
||||||
|
} 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 '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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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']);
|
||||||
|
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__);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 'i';
|
||||||
|
case 'float':
|
||||||
|
return 'd';
|
||||||
|
case 'blob':
|
||||||
|
return 'b';
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
210
htdocs/includes/pear/MDB2/Driver/Function/Common.php
Normal file
210
htdocs/includes/pear/MDB2/Driver/Function/Common.php
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for the function modules that is extended by each MDB2 driver
|
||||||
|
*
|
||||||
|
* @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)
|
||||||
|
*
|
||||||
|
* @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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
?>
|
||||||
149
htdocs/includes/pear/MDB2/Driver/Function/mssql.php
Normal file
149
htdocs/includes/pear/MDB2/Driver/Function/mssql.php
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
<?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: Frank M. Kromann <frank@kromann.info> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Function/Common.php';
|
||||||
|
|
||||||
|
// {{{ class MDB2_Driver_Function_mssql
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL driver for the function modules
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Function_mssql 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 = 'EXECUTE '.$name;
|
||||||
|
$query .= $params ? ' '.implode(', ', $params) : '';
|
||||||
|
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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)
|
||||||
|
*
|
||||||
|
* @return string to call a variable with the current timestamp
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function now($type = 'timestamp')
|
||||||
|
{
|
||||||
|
switch ($type) {
|
||||||
|
case 'time':
|
||||||
|
case 'date':
|
||||||
|
case 'timestamp':
|
||||||
|
default:
|
||||||
|
return 'GETDATE()';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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, $position, $length)";
|
||||||
|
}
|
||||||
|
return "SUBSTRING($value, $position, LEN($value) - $position + 1)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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).")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
?>
|
||||||
104
htdocs/includes/pear/MDB2/Driver/Function/mysql.php
Normal file
104
htdocs/includes/pear/MDB2/Driver/Function/mysql.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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).")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
112
htdocs/includes/pear/MDB2/Driver/Function/mysqli.php
Normal file
112
htdocs/includes/pear/MDB2/Driver/Function/mysqli.php
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Function/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQLi driver for the function modules
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Function_mysqli 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$multi_query = $db->getOption('multi_query');
|
||||||
|
if (!$multi_query) {
|
||||||
|
$db->setOption('multi_query', true);
|
||||||
|
}
|
||||||
|
$query = 'CALL '.$name;
|
||||||
|
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||||
|
$result =& $db->query($query, $types, $result_class, $result_wrap_class);
|
||||||
|
if (!$multi_query) {
|
||||||
|
$db->setOption('multi_query', false);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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).")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
828
htdocs/includes/pear/MDB2/Driver/Manager/Common.php
Normal file
828
htdocs/includes/pear/MDB2/Driver/Manager/Common.php
Normal file
@@ -0,0 +1,828 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for the management modules that is extended by each MDB2 driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Manager_Common extends MDB2_Module_Common
|
||||||
|
{
|
||||||
|
// }}}
|
||||||
|
// {{{ getFieldDeclarationList()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get declaration of a number of field in bulk
|
||||||
|
*
|
||||||
|
* @param string $fields a multidimensional associative array.
|
||||||
|
* The first dimension determines the field name, while the second
|
||||||
|
* dimension is keyed with the name of the properties
|
||||||
|
* of the field being declared as array indexes. Currently, the types
|
||||||
|
* of supported field properties are as follows:
|
||||||
|
*
|
||||||
|
* default
|
||||||
|
* Boolean value to be used as default for this field.
|
||||||
|
*
|
||||||
|
* notnull
|
||||||
|
* Boolean flag that indicates whether this field is constrained
|
||||||
|
* to not be set to null.
|
||||||
|
*
|
||||||
|
* @return mixed string on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getFieldDeclarationList($fields)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($fields) || empty($fields)) {
|
||||||
|
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'missing any fields', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($fields as $field_name => $field) {
|
||||||
|
$query = $db->getDeclaration($field['type'], $field_name, $field);
|
||||||
|
if (PEAR::isError($query)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
$query_fields[] = $query;
|
||||||
|
}
|
||||||
|
return implode(', ', $query_fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _fixSequenceName()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any formatting in an sequence name using the 'seqname_format' option
|
||||||
|
*
|
||||||
|
* @param string $sqn string that containts name of a potential sequence
|
||||||
|
* @param bool $check if only formatted sequences should be returned
|
||||||
|
* @return string name of the sequence with possible formatting removed
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _fixSequenceName($sqn, $check = false)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$seq_pattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $db->options['seqname_format']).'$/i';
|
||||||
|
$seq_name = preg_replace($seq_pattern, '\\1', $sqn);
|
||||||
|
if ($seq_name && !strcasecmp($sqn, $db->getSequenceName($seq_name))) {
|
||||||
|
return $seq_name;
|
||||||
|
}
|
||||||
|
if ($check) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $sqn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _fixIndexName()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any formatting in an index name using the 'idxname_format' option
|
||||||
|
*
|
||||||
|
* @param string $idx string that containts name of anl index
|
||||||
|
* @return string name of the index with possible formatting removed
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _fixIndexName($idx)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$idx_pattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $db->options['idxname_format']).'$/i';
|
||||||
|
$idx_name = preg_replace($idx_pattern, '\\1', $idx);
|
||||||
|
if ($idx_name && !strcasecmp($idx, $db->getIndexName($idx_name))) {
|
||||||
|
return $idx_name;
|
||||||
|
}
|
||||||
|
return $idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be created
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createDatabase($database)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop an existing database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropDatabase($database)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a basic SQL query for a new table creation
|
||||||
|
* @param string $name Name of the database that should be created
|
||||||
|
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||||
|
* @param array $options An associative array of table options
|
||||||
|
* @return mixed string (the SQL query) on success, a MDB2 error on failure
|
||||||
|
* @see createTable()
|
||||||
|
*/
|
||||||
|
function _getCreateTableQuery($name, $fields, $options = array())
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$name) {
|
||||||
|
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||||
|
'no valid table name specified', __FUNCTION__);
|
||||||
|
}
|
||||||
|
if (empty($fields)) {
|
||||||
|
return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null,
|
||||||
|
'no fields specified for table "'.$name.'"', __FUNCTION__);
|
||||||
|
}
|
||||||
|
$query_fields = $this->getFieldDeclarationList($fields);
|
||||||
|
if (PEAR::isError($query_fields)) {
|
||||||
|
return $query_fields;
|
||||||
|
}
|
||||||
|
if (!empty($options['primary'])) {
|
||||||
|
$query_fields.= ', PRIMARY KEY ('.implode(', ', array_keys($options['primary'])).')';
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
return "CREATE TABLE $name ($query_fields)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new table
|
||||||
|
*
|
||||||
|
* @param string $name Name of the database that should be created
|
||||||
|
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||||
|
* The indexes of the array entries are the names of the fields of the table an
|
||||||
|
* the array entry values are associative arrays like those that are meant to be
|
||||||
|
* passed with the field definitions to get[Type]Declaration() functions.
|
||||||
|
* array(
|
||||||
|
* 'id' => array(
|
||||||
|
* 'type' => 'integer',
|
||||||
|
* 'unsigned' => 1
|
||||||
|
* 'notnull' => 1
|
||||||
|
* 'default' => 0
|
||||||
|
* ),
|
||||||
|
* 'name' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* ),
|
||||||
|
* 'password' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* )
|
||||||
|
* );
|
||||||
|
* @param array $options An associative array of table options:
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createTable($name, $fields, $options = array())
|
||||||
|
{
|
||||||
|
$query = $this->_getCreateTableQuery($name, $fields, $options);
|
||||||
|
if (PEAR::isError($query)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop an existing table
|
||||||
|
*
|
||||||
|
* @param string $name name of the table that should be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropTable($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
return $db->exec("DROP TABLE $name");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ alterTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alter an existing table
|
||||||
|
*
|
||||||
|
* @param string $name name of the table that is intended to be changed.
|
||||||
|
* @param array $changes associative array that contains the details of each type
|
||||||
|
* of change that is intended to be performed. The types of
|
||||||
|
* changes that are currently supported are defined as follows:
|
||||||
|
*
|
||||||
|
* name
|
||||||
|
*
|
||||||
|
* New name for the table.
|
||||||
|
*
|
||||||
|
* add
|
||||||
|
*
|
||||||
|
* Associative array with the names of fields to be added as
|
||||||
|
* indexes of the array. The value of each entry of the array
|
||||||
|
* should be set to another associative array with the properties
|
||||||
|
* of the fields to be added. The properties of the fields should
|
||||||
|
* be the same as defined by the 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listDatabases()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all databases
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listDatabases()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implementedd', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listUsers()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all users
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listUsers()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listViews()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all views in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listViews($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableViews()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list the views in the database that reference a given table
|
||||||
|
*
|
||||||
|
* @param string table for which all references views should be found
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
**/
|
||||||
|
function listTableViews($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableTriggers()
|
||||||
|
/**
|
||||||
|
* This function will be called to get all triggers of the
|
||||||
|
* current database ($db->getDatabase())
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $table The name of the table from the
|
||||||
|
* previous database to query against.
|
||||||
|
* @return mixed Array on success or MDB2 error on failure
|
||||||
|
*/
|
||||||
|
function listTableTriggers($table = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ listFunctions()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all functions in the current database
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listFunctions()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ listTables()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all tables in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTables($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableFields()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all fields in a tables in the current database
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableFields($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @param string $table name of the table on which the index is to be created
|
||||||
|
* @param string $name name of the index to be created
|
||||||
|
* @param array $definition associative array that defines properties of the index to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the index fields as array
|
||||||
|
* indexes. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the index that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Currently, only the sorting property is supported. It should be used
|
||||||
|
* to define the sorting direction of the index. It may be set to either
|
||||||
|
* ascending or descending.
|
||||||
|
*
|
||||||
|
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||||
|
* drivers of those that do not support it ignore this property. Use the
|
||||||
|
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(
|
||||||
|
* 'sorting' => 'ascending'
|
||||||
|
* ),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createIndex($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "CREATE INDEX $name ON $table";
|
||||||
|
$fields = array();
|
||||||
|
foreach (array_keys($definition['fields']) as $field) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop existing index
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $name name of the index to be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropIndex($table, $name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
return $db->exec("DROP INDEX $name");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableIndexes()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all indexes in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableIndexes($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createConstraint()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a constraint on a table
|
||||||
|
*
|
||||||
|
* @param string $table name of the table on which the constraint is to be created
|
||||||
|
* @param string $name name of the constraint to be created
|
||||||
|
* @param array $definition associative array that defines properties of the constraint to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the constraint fields as array
|
||||||
|
* constraints. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the constraint that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createConstraint($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "ALTER TABLE $table ADD CONSTRAINT $name";
|
||||||
|
if (!empty($definition['primary'])) {
|
||||||
|
$query.= ' PRIMARY KEY';
|
||||||
|
} elseif (!empty($definition['unique'])) {
|
||||||
|
$query.= ' UNIQUE';
|
||||||
|
}
|
||||||
|
$fields = array();
|
||||||
|
foreach (array_keys($definition['fields']) as $field) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
return $db->exec("ALTER TABLE $table DROP CONSTRAINT $name");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableConstraints()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all constraints in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableConstraints($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createSequence()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create sequence
|
||||||
|
*
|
||||||
|
* @param string $seq_name name of the sequence to be created
|
||||||
|
* @param string $start start value of the sequence; default is 1
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createSequence($seq_name, $start = 1)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropSequence()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop existing sequence
|
||||||
|
*
|
||||||
|
* @param string $seq_name name of the sequence to be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropSequence($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listSequences()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all sequences in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listSequences($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
543
htdocs/includes/pear/MDB2/Driver/Manager/mssql.php
Normal file
543
htdocs/includes/pear/MDB2/Driver/Manager/mssql.php
Normal file
@@ -0,0 +1,543 @@
|
|||||||
|
<?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: Frank M. Kromann <frank@kromann.info> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Manager/Common.php';
|
||||||
|
|
||||||
|
// {{{ class MDB2_Driver_Manager_mssql
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL driver for the management modules
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Frank M. Kromann <frank@kromann.info>
|
||||||
|
* @author David Coallier <davidc@php.net>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Manager_mssql extends MDB2_Driver_Manager_Common
|
||||||
|
{
|
||||||
|
// {{{ createDatabase()
|
||||||
|
/**
|
||||||
|
* create a new database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be created
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createDatabase($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
$query = "CREATE DATABASE $name";
|
||||||
|
if ($db->options['database_device']) {
|
||||||
|
$query.= ' ON '.$db->options['database_device'];
|
||||||
|
$query.= $db->options['database_size'] ? '=' .
|
||||||
|
$db->options['database_size'] : '';
|
||||||
|
}
|
||||||
|
return $db->standaloneQuery($query, 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);
|
||||||
|
return $db->standaloneQuery("DROP DATABASE $name", null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ alterTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alter an existing table
|
||||||
|
*
|
||||||
|
* @param string $name name of the table that is intended to be changed.
|
||||||
|
* @param array $changes associative array that contains the details of each type
|
||||||
|
* of change that is intended to be performed. The types of
|
||||||
|
* changes that are currently supported are defined as follows:
|
||||||
|
*
|
||||||
|
* name
|
||||||
|
*
|
||||||
|
* New name for the table.
|
||||||
|
*
|
||||||
|
* add
|
||||||
|
*
|
||||||
|
* Associative array with the names of fields to be added as
|
||||||
|
* indexes of the array. The value of each entry of the array
|
||||||
|
* should be set to another associative array with the properties
|
||||||
|
* of the fields to be added. The properties of the fields should
|
||||||
|
* be the same as defined by the Metabase parser.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* remove
|
||||||
|
*
|
||||||
|
* Associative array with the names of fields to be removed as indexes
|
||||||
|
* of the array. Currently the values assigned to each entry are ignored.
|
||||||
|
* An empty array should be used for future compatibility.
|
||||||
|
*
|
||||||
|
* rename
|
||||||
|
*
|
||||||
|
* Associative array with the names of fields to be renamed as indexes
|
||||||
|
* of the array. The value of each entry of the array should be set to
|
||||||
|
* another associative array with the entry named name with the new
|
||||||
|
* field name and the entry named Declaration that is expected to contain
|
||||||
|
* the portion of the field declaration already in DBMS specific SQL code
|
||||||
|
* as it is used in the CREATE TABLE statement.
|
||||||
|
*
|
||||||
|
* change
|
||||||
|
*
|
||||||
|
* Associative array with the names of the fields to be changed as indexes
|
||||||
|
* of the array. Keep in mind that if it is intended to change either the
|
||||||
|
* name of a field and any other properties, the change array entries
|
||||||
|
* should have the new names of the fields as array indexes.
|
||||||
|
*
|
||||||
|
* The value of each entry of the array should be set to another associative
|
||||||
|
* array with the properties of the fields to that are meant to be changed as
|
||||||
|
* array entries. These entries should be assigned to the new values of the
|
||||||
|
* respective properties. The properties of the fields should be the same
|
||||||
|
* as defined by the Metabase parser.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'name' => 'userlist',
|
||||||
|
* 'add' => array(
|
||||||
|
* 'quota' => array(
|
||||||
|
* 'type' => 'integer',
|
||||||
|
* 'unsigned' => 1
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* 'remove' => array(
|
||||||
|
* 'file_limit' => array(),
|
||||||
|
* 'time_limit' => array()
|
||||||
|
* ),
|
||||||
|
* 'change' => array(
|
||||||
|
* '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':
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
break;
|
||||||
|
case 'name':
|
||||||
|
case 'rename':
|
||||||
|
case 'change':
|
||||||
|
default:
|
||||||
|
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||||
|
'alterTable: change type "'.$change_name.'" not yet supported');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($check) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = '';
|
||||||
|
if (!empty($changes['add']) && is_array($changes['add'])) {
|
||||||
|
foreach ($changes['add'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$query.= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||||
|
foreach ($changes['remove'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$field_name = $db->quoteIdentifier($field_name, true);
|
||||||
|
$query.= 'DROP COLUMN ' . $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$query) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
return $db->exec("ALTER TABLE $name $query");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ listTables()
|
||||||
|
/**
|
||||||
|
* list all tables in the current database
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTables()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = 'EXEC sp_tables @table_type = "\'TABLE\'"';
|
||||||
|
$table_names = $db->queryCol($query, null, 2);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table_name) {
|
||||||
|
if (!$this->_fixSequenceName($table_name, true)) {
|
||||||
|
$result[] = $table_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 tables in the current database
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableFields($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$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 data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableIndexes($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key_name = 'INDEX_NAME';
|
||||||
|
$pk_name = 'PK_NAME';
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$key_name = strtolower($key_name);
|
||||||
|
$pk_name = strtolower($pk_name);
|
||||||
|
} else {
|
||||||
|
$key_name = strtoupper($key_name);
|
||||||
|
$pk_name = strtoupper($pk_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$table = $db->quote($table, 'text');
|
||||||
|
$query = "EXEC sp_statistics @table_name=$table";
|
||||||
|
$indexes = $db->queryCol($query, 'text', $key_name);
|
||||||
|
if (PEAR::isError($indexes)) {
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
$query = "EXEC sp_pkeys @table_name=$table";
|
||||||
|
$pk_all = $db->queryCol($query, 'text', $pk_name);
|
||||||
|
$result = array();
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
if (!in_array($index, $pk_all) && $index != null) {
|
||||||
|
$result[$this->_fixIndexName($index)] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_change_key_case($result, $db->options['field_case']);
|
||||||
|
}
|
||||||
|
return array_keys($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableTriggers()
|
||||||
|
/**
|
||||||
|
* This function will be called to
|
||||||
|
* display all the triggers from the current
|
||||||
|
* database ($db->getDatabase()).
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $table The name of the table from the
|
||||||
|
* previous database to query against.
|
||||||
|
* @return mixed Array of the triggers if the query
|
||||||
|
* is successful, otherwise, false which
|
||||||
|
* could be a db error if the db is not
|
||||||
|
* instantiated or could be the results
|
||||||
|
* of the error that occured during the
|
||||||
|
* query'ing of the sysobject module.
|
||||||
|
*/
|
||||||
|
function listTableTriggers($table = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quote($table, 'text');
|
||||||
|
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR'";
|
||||||
|
if (!is_null($table)) {
|
||||||
|
$query .= "AND object_name(parent_obj) = $table";
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->queryCol($query);
|
||||||
|
if (PEAR::isError($results)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE &&
|
||||||
|
$db->options['field_case'] == CASE_LOWER)
|
||||||
|
{
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
|
||||||
|
'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ listViews()
|
||||||
|
/**
|
||||||
|
* This function is a simple method that lists
|
||||||
|
* all the views that are set on a db instance
|
||||||
|
* (The db connected to it)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return mixed Error on failure or array of views for a database.
|
||||||
|
*/
|
||||||
|
function listViews()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SELECT name
|
||||||
|
FROM sysobjects
|
||||||
|
WHERE xtype = 'V'";
|
||||||
|
|
||||||
|
$result = $db->queryCol($query);
|
||||||
|
if (PEAR::isError($results)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE &&
|
||||||
|
$db->options['field_case'] == CASE_LOWER)
|
||||||
|
{
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
|
||||||
|
'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $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);
|
||||||
|
$seqcol_name = $db->quoteIdentifier($db->options['seqcol_name'], true);
|
||||||
|
$query = "CREATE TABLE $sequence_name ($seqcol_name " .
|
||||||
|
"INT PRIMARY KEY CLUSTERED IDENTITY($start,1) NOT NULL)";
|
||||||
|
|
||||||
|
$res = $db->exec($query);
|
||||||
|
if (PEAR::isError($res)) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($start == 1) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$query = "SET IDENTITY_INSERT $sequence_name ON ".
|
||||||
|
"INSERT INTO $sequence_name ($seqcol_name) VALUES ($start)";
|
||||||
|
$res = $db->exec($query);
|
||||||
|
|
||||||
|
if (!PEAR::isError($res)) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->exec("DROP TABLE $sequence_name");
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $db->raiseError($result, null, null,
|
||||||
|
'createSequence: could not drop inconsistent sequence table');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError($res, null, null,
|
||||||
|
'createSequence: could not create sequence table');
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ dropSequence()
|
||||||
|
/**
|
||||||
|
* This function drops an 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 TABLE $sequence_name");
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ listSequences()
|
||||||
|
/**
|
||||||
|
* list all sequences in the current database
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listSequences()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SELECT name FROM sysobjects WHERE xtype = 'U'";
|
||||||
|
$table_names = $db->queryCol($query);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table_name) {
|
||||||
|
if ($sqn = $this->_fixSequenceName($table_name, true)) {
|
||||||
|
$result[] = $sqn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
|
||||||
|
'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
?>
|
||||||
901
htdocs/includes/pear/MDB2/Driver/Manager/mysql.php
Normal file
901
htdocs/includes/pear/MDB2/Driver/Manager/mysql.php
Normal file
@@ -0,0 +1,901 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Manager/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQL driver for the management modules
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Manager_mysql extends MDB2_Driver_Manager_Common
|
||||||
|
{
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be created
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createDatabase($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
$query = "CREATE DATABASE $name";
|
||||||
|
$result = $db->exec($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop an existing database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropDatabase($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
$query = "DROP DATABASE $name";
|
||||||
|
$result = $db->exec($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new table
|
||||||
|
*
|
||||||
|
* @param string $name Name of the database that should be created
|
||||||
|
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||||
|
* The indexes of the array entries are the names of the fields of the table an
|
||||||
|
* the array entry values are associative arrays like those that are meant to be
|
||||||
|
* passed with the field definitions to get[Type]Declaration() functions.
|
||||||
|
* array(
|
||||||
|
* 'id' => array(
|
||||||
|
* 'type' => 'integer',
|
||||||
|
* 'unsigned' => 1
|
||||||
|
* 'notnull' => 1
|
||||||
|
* 'default' => 0
|
||||||
|
* ),
|
||||||
|
* 'name' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* ),
|
||||||
|
* 'password' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* )
|
||||||
|
* );
|
||||||
|
* @param array $options An associative array of table options:
|
||||||
|
* array(
|
||||||
|
* 'comment' => 'Foo',
|
||||||
|
* 'character_set' => 'utf8',
|
||||||
|
* 'collate' => 'utf8_unicode_ci',
|
||||||
|
* 'collate' => 'utf8_unicode_ci',
|
||||||
|
* 'type' => 'innodb',
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createTable($name, $fields, $options = array())
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
$query = $this->_getCreateTableQuery($name, $fields, $options);
|
||||||
|
if (PEAR::isError($query)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
$options_strings = array();
|
||||||
|
|
||||||
|
if (!empty($options['comment'])) {
|
||||||
|
$options_strings['comment'] = 'COMMENT = '.$db->quote($options['comment'], 'text');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options['charset'])) {
|
||||||
|
$options_strings['charset'] = 'DEFAULT CHARACTER SET '.$options['charset'];
|
||||||
|
if (!empty($options['collate'])) {
|
||||||
|
$options_strings['charset'].= ' COLLATE '.$options['collate'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = false;
|
||||||
|
if (!empty($options['type'])) {
|
||||||
|
$type = $options['type'];
|
||||||
|
} elseif ($db->options['default_table_type']) {
|
||||||
|
$type = $db->options['default_table_type'];
|
||||||
|
}
|
||||||
|
if ($type) {
|
||||||
|
$options_strings[] = "ENGINE = $type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options_strings)) {
|
||||||
|
$query.= ' '.implode(' ', $options_strings);
|
||||||
|
}
|
||||||
|
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 'rename':
|
||||||
|
case 'name':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||||
|
'change type "'.$change_name.'" not yet supported', __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($check) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = '';
|
||||||
|
if (!empty($changes['name'])) {
|
||||||
|
$change_name = $db->quoteIdentifier($changes['name'], true);
|
||||||
|
$query .= 'RENAME TO ' . $change_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['add']) && is_array($changes['add'])) {
|
||||||
|
foreach ($changes['add'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$query.= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||||
|
foreach ($changes['remove'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$field_name = $db->quoteIdentifier($field_name, true);
|
||||||
|
$query.= 'DROP ' . $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rename = array();
|
||||||
|
if (!empty($changes['rename']) && is_array($changes['rename'])) {
|
||||||
|
foreach ($changes['rename'] as $field_name => $field) {
|
||||||
|
$rename[$field['name']] = $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['change']) && is_array($changes['change'])) {
|
||||||
|
foreach ($changes['change'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
if (isset($rename[$field_name])) {
|
||||||
|
$old_field_name = $rename[$field_name];
|
||||||
|
unset($rename[$field_name]);
|
||||||
|
} else {
|
||||||
|
$old_field_name = $field_name;
|
||||||
|
}
|
||||||
|
$old_field_name = $db->quoteIdentifier($old_field_name, true);
|
||||||
|
$query.= "CHANGE $old_field_name " . $db->getDeclaration($field['definition']['type'], $field_name, $field['definition']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($rename) && is_array($rename)) {
|
||||||
|
foreach ($rename as $rename_name => $renamed_field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$field = $changes['rename'][$renamed_field];
|
||||||
|
$renamed_field = $db->quoteIdentifier($renamed_field, true);
|
||||||
|
$query.= 'CHANGE ' . $renamed_field . ' ' . $db->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$query) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
return $db->exec("ALTER TABLE $name $query");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listDatabases()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all databases
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listDatabases()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->queryCol('SHOW DATABASES');
|
||||||
|
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 data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listUsers()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->queryCol('SELECT DISTINCT USER FROM USER');
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTables()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all tables in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTables($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SHOW /*!50002 FULL*/ TABLES";
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query .= " FROM $database";
|
||||||
|
}
|
||||||
|
$query.= "/*!50002 WHERE Table_type = 'BASE TABLE'*/";
|
||||||
|
|
||||||
|
$table_names = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table) {
|
||||||
|
if (!$this->_fixSequenceName($table[0], true)) {
|
||||||
|
$result[] = $table[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listViews()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list the views in the database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
**/
|
||||||
|
function listViews($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = 'SHOW FULL TABLES';
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query.= " FROM $database";
|
||||||
|
}
|
||||||
|
$query.= " WHERE Table_type = 'VIEW'";
|
||||||
|
|
||||||
|
$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 tables in the current database
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableFields($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$result = $db->queryCol("SHOW COLUMNS FROM $table");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @author Leoncx
|
||||||
|
* @param string $table name of the table on which the index is to be created
|
||||||
|
* @param string $name name of the index to be created
|
||||||
|
* @param array $definition associative array that defines properties of the index to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the index fields as array
|
||||||
|
* indexes. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the index that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Currently, only the sorting property is supported. It should be used
|
||||||
|
* to define the sorting direction of the index. It may be set to either
|
||||||
|
* ascending or descending.
|
||||||
|
*
|
||||||
|
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||||
|
* drivers of those that do not support it ignore this property. Use the
|
||||||
|
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(
|
||||||
|
* 'sorting' => 'ascending'
|
||||||
|
* 'length' => 10
|
||||||
|
* ),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createIndex($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "CREATE INDEX $name ON $table";
|
||||||
|
$fields = array();
|
||||||
|
foreach ($definition['fields'] as $field => $fieldinfo) {
|
||||||
|
if (!empty($fieldinfo['length'])) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true) . '(' . $fieldinfo['length'] . ')';
|
||||||
|
} else {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop existing index
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $name name of the index to be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropIndex($table, $name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
return $db->exec("DROP INDEX $name ON $table");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableIndexes()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all indexes in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableIndexes($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key_name = 'Key_name';
|
||||||
|
$non_unique = 'Non_unique';
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$key_name = strtolower($key_name);
|
||||||
|
$non_unique = strtolower($non_unique);
|
||||||
|
} else {
|
||||||
|
$key_name = strtoupper($key_name);
|
||||||
|
$non_unique = strtoupper($non_unique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table";
|
||||||
|
$indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
if (PEAR::isError($indexes)) {
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($indexes as $index_data) {
|
||||||
|
if ($index_data[$non_unique] && ($index = $this->_fixIndexName($index_data[$key_name]))) {
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createConstraint()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a constraint on a table
|
||||||
|
*
|
||||||
|
* @param string $table name of the table on which the constraint is to be created
|
||||||
|
* @param string $name name of the constraint to be created
|
||||||
|
* @param array $definition associative array that defines properties of the constraint to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the constraint fields as array
|
||||||
|
* constraints. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the constraint that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createConstraint($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = '';
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
if (!empty($definition['primary'])) {
|
||||||
|
$type = 'PRIMARY';
|
||||||
|
$name = 'KEY';
|
||||||
|
} elseif (!empty($definition['unique'])) {
|
||||||
|
$type = 'UNIQUE';
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "ALTER TABLE $table ADD $type $name";
|
||||||
|
$fields = array();
|
||||||
|
foreach (array_keys($definition['fields']) as $field) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
if ($primary || strtolower($name) == 'primary') {
|
||||||
|
$query = "ALTER TABLE $table DROP PRIMARY KEY";
|
||||||
|
} else {
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "ALTER TABLE $table DROP INDEX $name";
|
||||||
|
}
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableConstraints()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all constraints in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableConstraints($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key_name = 'Key_name';
|
||||||
|
$non_unique = 'Non_unique';
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$key_name = strtolower($key_name);
|
||||||
|
$non_unique = strtolower($non_unique);
|
||||||
|
} else {
|
||||||
|
$key_name = strtoupper($key_name);
|
||||||
|
$non_unique = strtoupper($non_unique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table";
|
||||||
|
$indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
if (PEAR::isError($indexes)) {
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($indexes as $index_data) {
|
||||||
|
if (!$index_data[$non_unique]) {
|
||||||
|
if ($index_data[$key_name] !== 'PRIMARY') {
|
||||||
|
$index = $this->_fixIndexName($index_data[$key_name]);
|
||||||
|
} else {
|
||||||
|
$index = 'PRIMARY';
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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);
|
||||||
|
$seqcol_name = $db->quoteIdentifier($db->options['seqcol_name'], true);
|
||||||
|
|
||||||
|
$query = "CREATE TABLE $sequence_name ($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))";
|
||||||
|
$query.= strlen($db->options['default_table_type']) ? ' TYPE='.$db->options['default_table_type'] : '';
|
||||||
|
$res = $db->exec($query);
|
||||||
|
|
||||||
|
if (PEAR::isError($res)) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($start == 1) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')';
|
||||||
|
$res = $db->exec($query);
|
||||||
|
if (!PEAR::isError($res)) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
$result = $db->exec("DROP TABLE $sequence_name");
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $db->raiseError($result, null, null,
|
||||||
|
'could not drop inconsistent sequence table', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError($res, null, null,
|
||||||
|
'could not create sequence table', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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 TABLE $sequence_name");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listSequences()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all sequences in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listSequences($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SHOW TABLES";
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query .= " FROM $database";
|
||||||
|
}
|
||||||
|
$table_names = $db->queryCol($query);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table_name) {
|
||||||
|
if ($sqn = $this->_fixSequenceName($table_name, true)) {
|
||||||
|
$result[] = $sqn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
?>
|
||||||
902
htdocs/includes/pear/MDB2/Driver/Manager/mysqli.php
Normal file
902
htdocs/includes/pear/MDB2/Driver/Manager/mysqli.php
Normal file
@@ -0,0 +1,902 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Manager/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQLi driver for the management modules
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Manager_mysqli extends MDB2_Driver_Manager_Common
|
||||||
|
{
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be created
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createDatabase($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
$query = "CREATE DATABASE $name";
|
||||||
|
$result = $db->exec($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropDatabase()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop an existing database
|
||||||
|
*
|
||||||
|
* @param string $name name of the database that should be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropDatabase($name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
$query = "DROP DATABASE $name";
|
||||||
|
$result = $db->exec($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createTable()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new table
|
||||||
|
*
|
||||||
|
* @param string $name Name of the database that should be created
|
||||||
|
* @param array $fields Associative array that contains the definition of each field of the new table
|
||||||
|
* The indexes of the array entries are the names of the fields of the table an
|
||||||
|
* the array entry values are associative arrays like those that are meant to be
|
||||||
|
* passed with the field definitions to get[Type]Declaration() functions.
|
||||||
|
* array(
|
||||||
|
* 'id' => array(
|
||||||
|
* 'type' => 'integer',
|
||||||
|
* 'unsigned' => 1
|
||||||
|
* 'notnull' => 1
|
||||||
|
* 'default' => 0
|
||||||
|
* ),
|
||||||
|
* 'name' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* ),
|
||||||
|
* 'password' => array(
|
||||||
|
* 'type' => 'text',
|
||||||
|
* 'length' => 12
|
||||||
|
* )
|
||||||
|
* );
|
||||||
|
* @param array $options An associative array of table options:
|
||||||
|
* array(
|
||||||
|
* 'comment' => 'Foo',
|
||||||
|
* 'character_set' => 'utf8',
|
||||||
|
* 'collate' => 'utf8_unicode_ci',
|
||||||
|
* 'collate' => 'utf8_unicode_ci',
|
||||||
|
* 'type' => 'innodb',
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createTable($name, $fields, $options = array())
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $this->_getCreateTableQuery($name, $fields, $options);
|
||||||
|
if (PEAR::isError($query)) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
$options_strings = array();
|
||||||
|
|
||||||
|
if (!empty($options['comment'])) {
|
||||||
|
$options_strings['comment'] = 'COMMENT = '.$db->quote($options['comment'], 'text');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options['charset'])) {
|
||||||
|
$options_strings['charset'] = 'DEFAULT CHARACTER SET '.$options['charset'];
|
||||||
|
if (!empty($options['collate'])) {
|
||||||
|
$options_strings['charset'].= ' COLLATE '.$options['collate'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = false;
|
||||||
|
if (!empty($options['type'])) {
|
||||||
|
$type = $options['type'];
|
||||||
|
} elseif ($db->options['default_table_type']) {
|
||||||
|
$type = $db->options['default_table_type'];
|
||||||
|
}
|
||||||
|
if ($type) {
|
||||||
|
$options_strings[] = "ENGINE = $type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options_strings)) {
|
||||||
|
$query.= ' '.implode(' ', $options_strings);
|
||||||
|
}
|
||||||
|
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 'rename':
|
||||||
|
case 'name':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||||
|
'change type "'.$change_name.'" not yet supported', __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($check) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = '';
|
||||||
|
if (!empty($changes['name'])) {
|
||||||
|
$change_name = $db->quoteIdentifier($changes['name'], true);
|
||||||
|
$query .= 'RENAME TO ' . $change_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['add']) && is_array($changes['add'])) {
|
||||||
|
foreach ($changes['add'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$query.= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||||
|
foreach ($changes['remove'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$field_name = $db->quoteIdentifier($field_name, true);
|
||||||
|
$query.= 'DROP ' . $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rename = array();
|
||||||
|
if (!empty($changes['rename']) && is_array($changes['rename'])) {
|
||||||
|
foreach ($changes['rename'] as $field_name => $field) {
|
||||||
|
$rename[$field['name']] = $field_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($changes['change']) && is_array($changes['change'])) {
|
||||||
|
foreach ($changes['change'] as $field_name => $field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
if (isset($rename[$field_name])) {
|
||||||
|
$old_field_name = $rename[$field_name];
|
||||||
|
unset($rename[$field_name]);
|
||||||
|
} else {
|
||||||
|
$old_field_name = $field_name;
|
||||||
|
}
|
||||||
|
$old_field_name = $db->quoteIdentifier($old_field_name, true);
|
||||||
|
$query.= "CHANGE $old_field_name " . $db->getDeclaration($field['definition']['type'], $field_name, $field['definition']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($rename) && is_array($rename)) {
|
||||||
|
foreach ($rename as $rename_name => $renamed_field) {
|
||||||
|
if ($query) {
|
||||||
|
$query.= ', ';
|
||||||
|
}
|
||||||
|
$field = $changes['rename'][$renamed_field];
|
||||||
|
$renamed_field = $db->quoteIdentifier($renamed_field, true);
|
||||||
|
$query.= 'CHANGE ' . $renamed_field . ' ' . $db->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$query) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $db->quoteIdentifier($name, true);
|
||||||
|
return $db->exec("ALTER TABLE $name $query");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listDatabases()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all databases
|
||||||
|
*
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listDatabases()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->queryCol('SHOW DATABASES');
|
||||||
|
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 data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listUsers()
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->queryCol('SELECT DISTINCT USER FROM USER');
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTables()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all tables in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTables($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SHOW /*!50002 FULL*/ TABLES";
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query .= " FROM $database";
|
||||||
|
}
|
||||||
|
$query.= "/*!50002 WHERE Table_type = 'BASE TABLE'*/";
|
||||||
|
|
||||||
|
$table_names = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table) {
|
||||||
|
if (!$this->_fixSequenceName($table[0], true)) {
|
||||||
|
$result[] = $table[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listViews()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list the views in the database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
**/
|
||||||
|
function listViews($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = 'SHOW FULL TABLES';
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query.= " FROM $database";
|
||||||
|
}
|
||||||
|
$query.= " WHERE Table_type = 'VIEW'";
|
||||||
|
|
||||||
|
$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 tables in the current database
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableFields($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$result = $db->queryCol("SHOW COLUMNS FROM $table");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @author Leoncx
|
||||||
|
* @param string $table name of the table on which the index is to be created
|
||||||
|
* @param string $name name of the index to be created
|
||||||
|
* @param array $definition associative array that defines properties of the index to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the index fields as array
|
||||||
|
* indexes. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the index that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Currently, only the sorting property is supported. It should be used
|
||||||
|
* to define the sorting direction of the index. It may be set to either
|
||||||
|
* ascending or descending.
|
||||||
|
*
|
||||||
|
* Not all DBMS support index sorting direction configuration. The DBMS
|
||||||
|
* drivers of those that do not support it ignore this property. Use the
|
||||||
|
* function supports() to determine whether the DBMS driver can manage indexes.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(
|
||||||
|
* 'sorting' => 'ascending'
|
||||||
|
* 'length' => 10
|
||||||
|
* ),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createIndex($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "CREATE INDEX $name ON $table";
|
||||||
|
$fields = array();
|
||||||
|
foreach ($definition['fields'] as $field => $fieldinfo) {
|
||||||
|
if (!empty($fieldinfo['length'])) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true) . '(' . $fieldinfo['length'] . ')';
|
||||||
|
} else {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ dropIndex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop existing index
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $name name of the index to be dropped
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function dropIndex($table, $name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
return $db->exec("DROP INDEX $name ON $table");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableIndexes()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all indexes in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableIndexes($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key_name = 'Key_name';
|
||||||
|
$non_unique = 'Non_unique';
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$key_name = strtolower($key_name);
|
||||||
|
$non_unique = strtolower($non_unique);
|
||||||
|
} else {
|
||||||
|
$key_name = strtoupper($key_name);
|
||||||
|
$non_unique = strtoupper($non_unique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table";
|
||||||
|
$indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
if (PEAR::isError($indexes)) {
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($indexes as $index_data) {
|
||||||
|
if ($index_data[$non_unique] && ($index = $this->_fixIndexName($index_data[$key_name]))) {
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ createConstraint()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a constraint on a table
|
||||||
|
*
|
||||||
|
* @param string $table name of the table on which the constraint is to be created
|
||||||
|
* @param string $name name of the constraint to be created
|
||||||
|
* @param array $definition associative array that defines properties of the constraint to be created.
|
||||||
|
* Currently, only one property named FIELDS is supported. This property
|
||||||
|
* is also an associative with the names of the constraint fields as array
|
||||||
|
* constraints. Each entry of this array is set to another type of associative
|
||||||
|
* array that specifies properties of the constraint that are specific to
|
||||||
|
* each field.
|
||||||
|
*
|
||||||
|
* Example
|
||||||
|
* array(
|
||||||
|
* 'fields' => array(
|
||||||
|
* 'user_name' => array(),
|
||||||
|
* 'last_login' => array()
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function createConstraint($table, $name, $definition)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = '';
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
if (!empty($definition['primary'])) {
|
||||||
|
$type = 'PRIMARY';
|
||||||
|
$name = 'KEY';
|
||||||
|
} elseif (!empty($definition['unique'])) {
|
||||||
|
$type = 'UNIQUE';
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "ALTER TABLE $table ADD $type $name";
|
||||||
|
$fields = array();
|
||||||
|
foreach (array_keys($definition['fields']) as $field) {
|
||||||
|
$fields[] = $db->quoteIdentifier($field, true);
|
||||||
|
}
|
||||||
|
$query .= ' ('. implode(', ', $fields) . ')';
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
if ($primary || strtolower($name) == 'primary') {
|
||||||
|
$query = "ALTER TABLE $table DROP PRIMARY KEY";
|
||||||
|
} else {
|
||||||
|
$name = $db->quoteIdentifier($db->getIndexName($name), true);
|
||||||
|
$query = "ALTER TABLE $table DROP INDEX $name";
|
||||||
|
}
|
||||||
|
return $db->exec($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listTableConstraints()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all constraints in a table
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listTableConstraints($table)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key_name = 'Key_name';
|
||||||
|
$non_unique = 'Non_unique';
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$key_name = strtolower($key_name);
|
||||||
|
$non_unique = strtolower($non_unique);
|
||||||
|
} else {
|
||||||
|
$key_name = strtoupper($key_name);
|
||||||
|
$non_unique = strtoupper($non_unique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table";
|
||||||
|
$indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
if (PEAR::isError($indexes)) {
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($indexes as $index_data) {
|
||||||
|
if (!$index_data[$non_unique]) {
|
||||||
|
if ($index_data[$key_name] !== 'PRIMARY') {
|
||||||
|
$index = $this->_fixIndexName($index_data[$key_name]);
|
||||||
|
} else {
|
||||||
|
$index = 'PRIMARY';
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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);
|
||||||
|
$seqcol_name = $db->quoteIdentifier($db->options['seqcol_name'], true);
|
||||||
|
|
||||||
|
$query = "CREATE TABLE $sequence_name ($seqcol_name INT NOT NULL AUTO_INCREMENT, PRIMARY KEY ($seqcol_name))";
|
||||||
|
$query.= strlen($db->options['default_table_type']) ? ' TYPE='.$db->options['default_table_type'] : '';
|
||||||
|
$res = $db->exec($query);
|
||||||
|
|
||||||
|
if (PEAR::isError($res)) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($start == 1) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')';
|
||||||
|
$res = $db->exec($query);
|
||||||
|
if (!PEAR::isError($res)) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
$result = $db->exec("DROP TABLE $sequence_name");
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $db->raiseError($result, null, null,
|
||||||
|
'could not drop inconsistent sequence table', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError($res, null, null,
|
||||||
|
'could not create sequence table', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ 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 TABLE $sequence_name");
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ listSequences()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all sequences in the current database
|
||||||
|
*
|
||||||
|
* @param string database, the current is default
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function listSequences($database = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SHOW TABLES";
|
||||||
|
if (!is_null($database)) {
|
||||||
|
$query .= " FROM $database";
|
||||||
|
}
|
||||||
|
$table_names = $db->queryCol($query);
|
||||||
|
if (PEAR::isError($table_names)) {
|
||||||
|
return $table_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($table_names as $table_name) {
|
||||||
|
if ($sqn = $this->_fixSequenceName($table_name, true)) {
|
||||||
|
$result[] = $sqn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
?>
|
||||||
58
htdocs/includes/pear/MDB2/Driver/Native/Common.php
Normal file
58
htdocs/includes/pear/MDB2/Driver/Native/Common.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for the natuve modules that is extended by each MDB2 driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Native_Common extends MDB2_Module_Common
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
||||||
58
htdocs/includes/pear/MDB2/Driver/Native/mssql.php
Normal file
58
htdocs/includes/pear/MDB2/Driver/Native/mssql.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP versions 4 and 5 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||||
|
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||||
|
// | All rights reserved. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||||
|
// | API as well as database abstraction for PHP applications. |
|
||||||
|
// | This LICENSE is in the BSD license style. |
|
||||||
|
// | |
|
||||||
|
// | Redistribution and use in source and binary forms, with or without |
|
||||||
|
// | modification, are permitted provided that the following conditions |
|
||||||
|
// | are met: |
|
||||||
|
// | |
|
||||||
|
// | Redistributions of source code must retain the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer. |
|
||||||
|
// | |
|
||||||
|
// | Redistributions in binary form must reproduce the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer in the |
|
||||||
|
// | documentation and/or other materials provided with the distribution. |
|
||||||
|
// | |
|
||||||
|
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||||
|
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||||
|
// | or promote products derived from this software without specific prior|
|
||||||
|
// | written permission. |
|
||||||
|
// | |
|
||||||
|
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
|
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||||
|
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||||
|
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||||
|
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||||
|
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||||
|
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||||
|
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||||
|
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||||
|
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||||
|
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||||
|
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL driver for the native module
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@dybnet.de>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Native_mssql extends MDB2_Module_Common
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
||||||
60
htdocs/includes/pear/MDB2/Driver/Native/mysql.php
Normal file
60
htdocs/includes/pear/MDB2/Driver/Native/mysql.php
Normal 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$
|
||||||
|
//
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
||||||
60
htdocs/includes/pear/MDB2/Driver/Native/mysqli.php
Normal file
60
htdocs/includes/pear/MDB2/Driver/Native/mysqli.php
Normal 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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Native/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQLi driver for the native module
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Native_mysqli extends MDB2_Driver_Native_Common
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
||||||
423
htdocs/includes/pear/MDB2/Driver/Reverse/Common.php
Normal file
423
htdocs/includes/pear/MDB2/Driver/Reverse/Common.php
Normal file
@@ -0,0 +1,423 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are constants for the tableInfo-function
|
||||||
|
* they are bitwised or'ed. so if there are more constants to be defined
|
||||||
|
* in the future, adjust MDB2_TABLEINFO_FULL accordingly
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('MDB2_TABLEINFO_ORDER', 1);
|
||||||
|
define('MDB2_TABLEINFO_ORDERTABLE', 2);
|
||||||
|
define('MDB2_TABLEINFO_FULL', 3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for the schema reverse engineering module that is extended by each MDB2 driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Reverse_Common extends MDB2_Module_Common
|
||||||
|
{
|
||||||
|
// }}}
|
||||||
|
// {{{ getTableFieldDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $fields name of field that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableFieldDefinition($table, $field)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getTableIndexDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of an index into an array
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $index name of index that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableIndexDefinition($table, $index)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||||
|
'method not implemented', __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getTableConstraintDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture 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
|
||||||
|
* @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 stucture of a sequence into an array
|
||||||
|
*
|
||||||
|
* @param string $sequence name of sequence that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getSequenceDefinition($sequence)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = $db->currId($sequence);
|
||||||
|
if (PEAR::isError($start)) {
|
||||||
|
return $start;
|
||||||
|
}
|
||||||
|
if ($db->supports('current_id')) {
|
||||||
|
$start++;
|
||||||
|
} else {
|
||||||
|
$db->warnings[] = 'database does not support getting current
|
||||||
|
sequence value, the sequence value was incremented';
|
||||||
|
}
|
||||||
|
$definition = array();
|
||||||
|
if ($start != 1) {
|
||||||
|
$definition = array('start' => $start);
|
||||||
|
}
|
||||||
|
return $definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getTriggerDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of an trigger into an array
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
277
htdocs/includes/pear/MDB2/Driver/Reverse/mssql.php
Normal file
277
htdocs/includes/pear/MDB2/Driver/Reverse/mssql.php
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP versions 4 and 5 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||||
|
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||||
|
// | All rights reserved. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||||
|
// | API as well as database abstraction for PHP applications. |
|
||||||
|
// | This LICENSE is in the BSD license style. |
|
||||||
|
// | |
|
||||||
|
// | Redistribution and use in source and binary forms, with or without |
|
||||||
|
// | modification, are permitted provided that the following conditions |
|
||||||
|
// | are met: |
|
||||||
|
// | |
|
||||||
|
// | Redistributions of source code must retain the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer. |
|
||||||
|
// | |
|
||||||
|
// | Redistributions in binary form must reproduce the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer in the |
|
||||||
|
// | documentation and/or other materials provided with the distribution. |
|
||||||
|
// | |
|
||||||
|
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||||
|
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||||
|
// | or promote products derived from this software without specific prior|
|
||||||
|
// | written permission. |
|
||||||
|
// | |
|
||||||
|
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
|
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||||
|
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||||
|
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||||
|
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||||
|
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||||
|
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||||
|
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||||
|
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||||
|
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||||
|
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||||
|
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL driver for the schema reverse engineering module
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@dybnet.de>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Reverse_mssql extends MDB2_Driver_Reverse_Common
|
||||||
|
{
|
||||||
|
// }}}
|
||||||
|
// {{{ tableInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about a table or a result set
|
||||||
|
*
|
||||||
|
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||||
|
* is a table name.
|
||||||
|
*
|
||||||
|
* @param object|string $result MDB2_result object from a query or a
|
||||||
|
* string containing the name of a table.
|
||||||
|
* While this also accepts a query result
|
||||||
|
* resource identifier, this behavior is
|
||||||
|
* deprecated.
|
||||||
|
* @param int $mode a valid tableInfo mode
|
||||||
|
*
|
||||||
|
* @return array an associative array with the information requested.
|
||||||
|
* A MDB2_Error object on failure.
|
||||||
|
*
|
||||||
|
* @see MDB2_Driver_Common::tableInfo()
|
||||||
|
*/
|
||||||
|
function tableInfo($result, $mode = null)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($result)) {
|
||||||
|
/*
|
||||||
|
* Probably received a table name.
|
||||||
|
* Create a result resource identifier.
|
||||||
|
*/
|
||||||
|
$query = 'SELECT TOP 0 * FROM '.$db->quoteIdentifier($result);
|
||||||
|
$id =& $db->_doQuery($query, false);
|
||||||
|
if (PEAR::isError($id)) {
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$got_string = true;
|
||||||
|
} elseif (MDB2::isResultCommon($result)) {
|
||||||
|
/*
|
||||||
|
* Probably received a result object.
|
||||||
|
* Extract the result resource identifier.
|
||||||
|
*/
|
||||||
|
$id = $result->getResource();
|
||||||
|
$got_string = false;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Probably received a result resource identifier.
|
||||||
|
* Copy it.
|
||||||
|
* Deprecated. Here for compatibility only.
|
||||||
|
*/
|
||||||
|
$id = $result;
|
||||||
|
$got_string = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_resource($id)) {
|
||||||
|
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$case_func = 'strtolower';
|
||||||
|
} else {
|
||||||
|
$case_func = 'strtoupper';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$case_func = 'strval';
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = @mssql_num_fields($id);
|
||||||
|
$res = array();
|
||||||
|
|
||||||
|
if ($mode) {
|
||||||
|
$res['num_fields'] = $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->loadModule('Datatype', null, true);
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
$res[$i] = array(
|
||||||
|
'table' => $got_string ? $case_func($result) : '',
|
||||||
|
'name' => $case_func(@mssql_field_name($id, $i)),
|
||||||
|
'type' => @mssql_field_type($id, $i),
|
||||||
|
'length' => @mssql_field_length($id, $i),
|
||||||
|
// We only support flags for table
|
||||||
|
'flags' => $got_string
|
||||||
|
? $this->_mssql_field_flags($result, @mssql_field_name($id, $i)) : '',
|
||||||
|
);
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the result only if we were called on a table
|
||||||
|
if ($got_string) {
|
||||||
|
@mssql_free_result($id);
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _mssql_field_flags()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a column's flags
|
||||||
|
*
|
||||||
|
* Supports "not_null", "primary_key",
|
||||||
|
* "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
|
||||||
|
* "unique_key" (mssql unique index, unique check or primary_key) and
|
||||||
|
* "multiple_key" (multikey index)
|
||||||
|
*
|
||||||
|
* mssql timestamp is NOT similar to the mysql timestamp so this is maybe
|
||||||
|
* not useful at all - is the behaviour of mysql_field_flags that primary
|
||||||
|
* keys are alway unique? is the interpretation of multiple_key correct?
|
||||||
|
*
|
||||||
|
* @param string $table the table name
|
||||||
|
* @param string $column the field name
|
||||||
|
*
|
||||||
|
* @return string the flags
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @author Joern Barthel <j_barthel@web.de>
|
||||||
|
*/
|
||||||
|
function _mssql_field_flags($table, $column)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
static $tableName = null;
|
||||||
|
static $flags = array();
|
||||||
|
|
||||||
|
if ($table != $tableName) {
|
||||||
|
|
||||||
|
$flags = array();
|
||||||
|
$tableName = $table;
|
||||||
|
|
||||||
|
// get unique and primary keys
|
||||||
|
$res = $db->queryAll("EXEC SP_HELPINDEX[$table]", null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
|
||||||
|
foreach ($res as $val) {
|
||||||
|
$val = array_change_key_case($val, CASE_LOWER);
|
||||||
|
$keys = explode(', ', $val['index_keys']);
|
||||||
|
|
||||||
|
if (sizeof($keys) > 1) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->_add_flag($flags[$key], 'multiple_key');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($val['index_description'], 'primary key')) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->_add_flag($flags[$key], 'primary_key');
|
||||||
|
}
|
||||||
|
} elseif (strpos($val['index_description'], 'unique')) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->_add_flag($flags[$key], 'unique_key');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get auto_increment, not_null and timestamp
|
||||||
|
$res = $db->queryAll("EXEC SP_COLUMNS[$table]", null, MDB2_FETCHMODE_ASSOC);
|
||||||
|
|
||||||
|
foreach ($res as $val) {
|
||||||
|
$val = array_change_key_case($val, CASE_LOWER);
|
||||||
|
if ($val['nullable'] == '0') {
|
||||||
|
$this->_add_flag($flags[$val['column_name']], 'not_null');
|
||||||
|
}
|
||||||
|
if (strpos($val['type_name'], 'identity')) {
|
||||||
|
$this->_add_flag($flags[$val['column_name']], 'auto_increment');
|
||||||
|
}
|
||||||
|
if (strpos($val['type_name'], 'timestamp')) {
|
||||||
|
$this->_add_flag($flags[$val['column_name']], 'timestamp');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($flags[$column])) {
|
||||||
|
return(implode(' ', $flags[$column]));
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _add_flag()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a string to the flags array if the flag is not yet in there
|
||||||
|
* - if there is no flag present the array is created
|
||||||
|
*
|
||||||
|
* @param array &$array the reference to the flag-array
|
||||||
|
* @param string $value the flag value
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @author Joern Barthel <j_barthel@web.de>
|
||||||
|
*/
|
||||||
|
function _add_flag(&$array, $value)
|
||||||
|
{
|
||||||
|
if (!is_array($array)) {
|
||||||
|
$array = array($value);
|
||||||
|
} elseif (!in_array($value, $array)) {
|
||||||
|
array_push($array, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
369
htdocs/includes/pear/MDB2/Driver/Reverse/mysql.php
Normal file
369
htdocs/includes/pear/MDB2/Driver/Reverse/mysql.php
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQL driver for the schema reverse engineering module
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
|
||||||
|
{
|
||||||
|
// {{{ getTableFieldDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $field_name name of field that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableFieldDefinition($table, $field_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->loadModule('Datatype', null, true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW 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']) {
|
||||||
|
list($types, $length, $unsigned, $fixed) = $db->datatype->mapNativeDatatype($column);
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$definition[0] = array(
|
||||||
|
'notnull' => $notnull,
|
||||||
|
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||||
|
);
|
||||||
|
if ($length > 0) {
|
||||||
|
$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 of table that should be used in method
|
||||||
|
* @param string $index_name name of index that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableIndexDefinition($table, $index_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$index_name = $db->getIndexName($index_name);
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = ".$db->quote($index_name)." */";
|
||||||
|
$result = $db->query($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$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,
|
||||||
|
'it was not specified 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();
|
||||||
|
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,
|
||||||
|
'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 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 getTableConstraintDefinition($table, $index_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strtolower($index_name) != 'primary') {
|
||||||
|
$index_name = $db->getIndexName($index_name);
|
||||||
|
}
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = ".$db->quote($index_name)." */";
|
||||||
|
$result = $db->query($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$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,
|
||||||
|
'it was not specified an existing table constraint', __FUNCTION__);
|
||||||
|
}
|
||||||
|
if ($row['key_name'] == 'PRIMARY') {
|
||||||
|
$definition['primary'] = true;
|
||||||
|
} else {
|
||||||
|
$definition['unique'] = true;
|
||||||
|
}
|
||||||
|
$column_name = $row['column_name'];
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$column_name = strtolower($column_name);
|
||||||
|
} else {
|
||||||
|
$column_name = strtoupper($column_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$definition['fields'][$column_name] = array();
|
||||||
|
if (!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,
|
||||||
|
'it was not specified an existing table constraint', __FUNCTION__);
|
||||||
|
}
|
||||||
|
return $definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ tableInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about a table or a result set
|
||||||
|
*
|
||||||
|
* @param object|string $result MDB2_result object from a query or a
|
||||||
|
* string containing the name of a table.
|
||||||
|
* While this also accepts a query result
|
||||||
|
* resource identifier, this behavior is
|
||||||
|
* deprecated.
|
||||||
|
* @param int $mode a valid tableInfo mode
|
||||||
|
*
|
||||||
|
* @return array an associative array with the information requested.
|
||||||
|
* A MDB2_Error object on failure.
|
||||||
|
*
|
||||||
|
* @see MDB2_Driver_Common::setOption()
|
||||||
|
*/
|
||||||
|
function tableInfo($result, $mode = null)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
432
htdocs/includes/pear/MDB2/Driver/Reverse/mysqli.php
Normal file
432
htdocs/includes/pear/MDB2/Driver/Reverse/mysqli.php
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
<?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$
|
||||||
|
//
|
||||||
|
|
||||||
|
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MySQLi driver for the schema reverse engineering module
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Lukas Smith <smith@pooteeweet.org>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_Reverse_mysqli extends MDB2_Driver_Reverse_Common
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Array for converting MYSQLI_*_FLAG constants to text values
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $flags = array(
|
||||||
|
MYSQLI_NOT_NULL_FLAG => 'not_null',
|
||||||
|
MYSQLI_PRI_KEY_FLAG => 'primary_key',
|
||||||
|
MYSQLI_UNIQUE_KEY_FLAG => 'unique_key',
|
||||||
|
MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key',
|
||||||
|
MYSQLI_BLOB_FLAG => 'blob',
|
||||||
|
MYSQLI_UNSIGNED_FLAG => 'unsigned',
|
||||||
|
MYSQLI_ZEROFILL_FLAG => 'zerofill',
|
||||||
|
MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment',
|
||||||
|
MYSQLI_TIMESTAMP_FLAG => 'timestamp',
|
||||||
|
MYSQLI_SET_FLAG => 'set',
|
||||||
|
// MYSQLI_NUM_FLAG => 'numeric', // unnecessary
|
||||||
|
// MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie
|
||||||
|
MYSQLI_GROUP_FLAG => 'group_by'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array for converting MYSQLI_TYPE_* constants to text values
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $types = array(
|
||||||
|
MYSQLI_TYPE_DECIMAL => 'decimal',
|
||||||
|
246 => 'decimal',
|
||||||
|
MYSQLI_TYPE_TINY => 'tinyint',
|
||||||
|
MYSQLI_TYPE_SHORT => 'int',
|
||||||
|
MYSQLI_TYPE_LONG => 'int',
|
||||||
|
MYSQLI_TYPE_FLOAT => 'float',
|
||||||
|
MYSQLI_TYPE_DOUBLE => 'double',
|
||||||
|
// MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it
|
||||||
|
MYSQLI_TYPE_TIMESTAMP => 'timestamp',
|
||||||
|
MYSQLI_TYPE_LONGLONG => 'bigint',
|
||||||
|
MYSQLI_TYPE_INT24 => 'mediumint',
|
||||||
|
MYSQLI_TYPE_DATE => 'date',
|
||||||
|
MYSQLI_TYPE_TIME => 'time',
|
||||||
|
MYSQLI_TYPE_DATETIME => 'datetime',
|
||||||
|
MYSQLI_TYPE_YEAR => 'year',
|
||||||
|
MYSQLI_TYPE_NEWDATE => 'date',
|
||||||
|
MYSQLI_TYPE_ENUM => 'enum',
|
||||||
|
MYSQLI_TYPE_SET => 'set',
|
||||||
|
MYSQLI_TYPE_TINY_BLOB => 'tinyblob',
|
||||||
|
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
|
||||||
|
MYSQLI_TYPE_LONG_BLOB => 'longblob',
|
||||||
|
MYSQLI_TYPE_BLOB => 'blob',
|
||||||
|
MYSQLI_TYPE_VAR_STRING => 'varchar',
|
||||||
|
MYSQLI_TYPE_STRING => 'char',
|
||||||
|
MYSQLI_TYPE_GEOMETRY => 'geometry',
|
||||||
|
);
|
||||||
|
|
||||||
|
// {{{ getTableFieldDefinition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stucture of a field into an array
|
||||||
|
*
|
||||||
|
* @param string $table name of table that should be used in method
|
||||||
|
* @param string $field_name name of field that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableFieldDefinition($table, $field_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $db->loadModule('Datatype', null, true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW 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']) {
|
||||||
|
list($types, $length, $unsigned, $fixed) = $db->datatype->mapNativeDatatype($column);
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$definition[0] = array(
|
||||||
|
'notnull' => $notnull,
|
||||||
|
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||||
|
);
|
||||||
|
if ($length > 0) {
|
||||||
|
$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 of table that should be used in method
|
||||||
|
* @param string $index_name name of index that should be used in method
|
||||||
|
* @return mixed data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getTableIndexDefinition($table, $index_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
$index_name = $db->getIndexName($index_name);
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = ".$db->quote($index_name)." */";
|
||||||
|
$result = $db->query($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$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,
|
||||||
|
'it was not specified 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();
|
||||||
|
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,
|
||||||
|
'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 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 getTableConstraintDefinition($table, $index_name)
|
||||||
|
{
|
||||||
|
$db =& $this->getDBInstance();
|
||||||
|
if (PEAR::isError($db)) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strtolower($index_name) != 'primary') {
|
||||||
|
$index_name = $db->getIndexName($index_name);
|
||||||
|
}
|
||||||
|
$table = $db->quoteIdentifier($table, true);
|
||||||
|
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = ".$db->quote($index_name)." */";
|
||||||
|
$result = $db->query($query);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$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,
|
||||||
|
'it was not specified an existing table constraint', __FUNCTION__);
|
||||||
|
}
|
||||||
|
if ($row['key_name'] == 'PRIMARY') {
|
||||||
|
$definition['primary'] = true;
|
||||||
|
} else {
|
||||||
|
$definition['unique'] = true;
|
||||||
|
}
|
||||||
|
$column_name = $row['column_name'];
|
||||||
|
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
if ($db->options['field_case'] == CASE_LOWER) {
|
||||||
|
$column_name = strtolower($column_name);
|
||||||
|
} else {
|
||||||
|
$column_name = strtoupper($column_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$definition['fields'][$column_name] = array();
|
||||||
|
if (!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,
|
||||||
|
'it was not specified an existing table constraint', __FUNCTION__);
|
||||||
|
}
|
||||||
|
return $definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ tableInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about a table or a result set
|
||||||
|
*
|
||||||
|
* @param object|string $result MDB2_result object from a query or a
|
||||||
|
* string containing the name of a table.
|
||||||
|
* While this also accepts a query result
|
||||||
|
* resource identifier, this behavior is
|
||||||
|
* deprecated.
|
||||||
|
* @param int $mode a valid tableInfo mode
|
||||||
|
*
|
||||||
|
* @return array an associative array with the information requested.
|
||||||
|
* A MDB2_Error object on failure.
|
||||||
|
*
|
||||||
|
* @see MDB2_Driver_Common::setOption()
|
||||||
|
*/
|
||||||
|
function tableInfo($result, $mode = null)
|
||||||
|
{
|
||||||
|
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_object($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 = @mysqli_num_fields($resource);
|
||||||
|
$res = array();
|
||||||
|
if ($mode) {
|
||||||
|
$res['num_fields'] = $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->loadModule('Datatype', null, true);
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
|
$tmp = @mysqli_fetch_field($resource);
|
||||||
|
|
||||||
|
$flags = '';
|
||||||
|
foreach ($this->flags as $const => $means) {
|
||||||
|
if ($tmp->flags & $const) {
|
||||||
|
$flags.= $means . ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($tmp->def) {
|
||||||
|
$flags.= 'default_' . rawurlencode($tmp->def);
|
||||||
|
}
|
||||||
|
$flags = trim($flags);
|
||||||
|
|
||||||
|
$res[$i] = array(
|
||||||
|
'table' => $case_func($tmp->table),
|
||||||
|
'name' => $case_func($tmp->name),
|
||||||
|
'type' => isset($this->types[$tmp->type])
|
||||||
|
? $this->types[$tmp->type] : 'unknown',
|
||||||
|
// http://bugs.php.net/?id=36579
|
||||||
|
'length' => $tmp->length,
|
||||||
|
'flags' => $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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
892
htdocs/includes/pear/MDB2/Driver/mssql.php
Normal file
892
htdocs/includes/pear/MDB2/Driver/mssql.php
Normal file
@@ -0,0 +1,892 @@
|
|||||||
|
<?php
|
||||||
|
// vim: set et ts=4 sw=4 fdm=marker:
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP versions 4 and 5 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||||
|
// | Stig. S. Bakken, Lukas Smith, Frank M. Kromann |
|
||||||
|
// | All rights reserved. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||||
|
// | API as well as database abstraction for PHP applications. |
|
||||||
|
// | This LICENSE is in the BSD license style. |
|
||||||
|
// | |
|
||||||
|
// | Redistribution and use in source and binary forms, with or without |
|
||||||
|
// | modification, are permitted provided that the following conditions |
|
||||||
|
// | are met: |
|
||||||
|
// | |
|
||||||
|
// | Redistributions of source code must retain the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer. |
|
||||||
|
// | |
|
||||||
|
// | Redistributions in binary form must reproduce the above copyright |
|
||||||
|
// | notice, this list of conditions and the following disclaimer in the |
|
||||||
|
// | documentation and/or other materials provided with the distribution. |
|
||||||
|
// | |
|
||||||
|
// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||||
|
// | Lukas Smith nor the names of his contributors may be used to endorse |
|
||||||
|
// | or promote products derived from this software without specific prior|
|
||||||
|
// | written permission. |
|
||||||
|
// | |
|
||||||
|
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
|
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||||
|
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||||
|
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||||
|
// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||||
|
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||||
|
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
|
||||||
|
// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||||
|
// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||||
|
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
|
||||||
|
// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||||
|
// | POSSIBILITY OF SUCH DAMAGE. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Frank M. Kromann <frank@kromann.info> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// {{{ Class MDB2_Driver_mssql
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL Server driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Frank M. Kromann <frank@kromann.info>
|
||||||
|
*/
|
||||||
|
class MDB2_Driver_mssql extends MDB2_Driver_Common
|
||||||
|
{
|
||||||
|
// {{{ properties
|
||||||
|
var $escape_quotes = "'";
|
||||||
|
|
||||||
|
var $escape_identifier = '';
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ constructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->phptype = 'mssql';
|
||||||
|
$this->dbsyntax = 'mssql';
|
||||||
|
|
||||||
|
$this->supported['sequences'] = 'emulated';
|
||||||
|
$this->supported['indexes'] = true;
|
||||||
|
$this->supported['affected_rows'] = true;
|
||||||
|
$this->supported['transactions'] = true;
|
||||||
|
$this->supported['summary_functions'] = true;
|
||||||
|
$this->supported['order_by_text'] = true;
|
||||||
|
$this->supported['current_id'] = 'emulated';
|
||||||
|
$this->supported['limit_queries'] = 'emulated';
|
||||||
|
$this->supported['LOBs'] = true;
|
||||||
|
$this->supported['replace'] = 'emulated';
|
||||||
|
$this->supported['sub_selects'] = true;
|
||||||
|
$this->supported['auto_increment'] = true;
|
||||||
|
$this->supported['primary_key'] = true;
|
||||||
|
$this->supported['result_introspection'] = true;
|
||||||
|
$this->supported['prepared_statements'] = 'emulated';
|
||||||
|
|
||||||
|
$this->options['database_device'] = false;
|
||||||
|
$this->options['database_size'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ errorInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to collect information about an error
|
||||||
|
*
|
||||||
|
* @param integer $error
|
||||||
|
* @return array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function errorInfo($error = null)
|
||||||
|
{
|
||||||
|
$native_code = null;
|
||||||
|
if ($this->connection) {
|
||||||
|
$result = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
|
||||||
|
if ($result) {
|
||||||
|
$native_code = @mssql_result($result, 0, 0);
|
||||||
|
@mssql_free_result($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$native_msg = @mssql_get_last_message();
|
||||||
|
if (is_null($error)) {
|
||||||
|
static $ecode_map;
|
||||||
|
if (empty($ecode_map)) {
|
||||||
|
$ecode_map = array(
|
||||||
|
110 => MDB2_ERROR_VALUE_COUNT_ON_ROW,
|
||||||
|
155 => MDB2_ERROR_NOSUCHFIELD,
|
||||||
|
170 => MDB2_ERROR_SYNTAX,
|
||||||
|
207 => MDB2_ERROR_NOSUCHFIELD,
|
||||||
|
208 => MDB2_ERROR_NOSUCHTABLE,
|
||||||
|
245 => MDB2_ERROR_INVALID_NUMBER,
|
||||||
|
515 => MDB2_ERROR_CONSTRAINT_NOT_NULL,
|
||||||
|
547 => MDB2_ERROR_CONSTRAINT,
|
||||||
|
1913 => MDB2_ERROR_ALREADY_EXISTS,
|
||||||
|
2627 => MDB2_ERROR_CONSTRAINT,
|
||||||
|
2714 => MDB2_ERROR_ALREADY_EXISTS,
|
||||||
|
3701 => MDB2_ERROR_NOSUCHTABLE,
|
||||||
|
8134 => MDB2_ERROR_DIVZERO,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isset($ecode_map[$native_code])) {
|
||||||
|
if ($native_code == 3701
|
||||||
|
&& preg_match('/Cannot drop the index/i', $native_msg)
|
||||||
|
) {
|
||||||
|
$error = MDB2_ERROR_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
$error = $ecode_map[$native_code];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array($error, $native_code, $native_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ quoteIdentifier()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quote a string so it can be safely used as a table / column name
|
||||||
|
*
|
||||||
|
* Quoting style depends on which database driver is being used.
|
||||||
|
*
|
||||||
|
* @param string $str identifier name to be quoted
|
||||||
|
* @param bool $check_option check the 'quote_identifier' option
|
||||||
|
*
|
||||||
|
* @return string quoted identifier string
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function quoteIdentifier($str, $check_option = false)
|
||||||
|
{
|
||||||
|
if ($check_option && !$this->options['quote_identifier']) {
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
return '[' . str_replace(']', ']]', $str) . ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ beginTransaction()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a transaction.
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function beginTransaction()
|
||||||
|
{
|
||||||
|
$this->debug('starting transaction', 'beginTransaction', false);
|
||||||
|
if ($this->in_transaction) {
|
||||||
|
return MDB2_OK; //nothing to do
|
||||||
|
}
|
||||||
|
if (!$this->destructor_registered && $this->opened_persistent) {
|
||||||
|
$this->destructor_registered = true;
|
||||||
|
register_shutdown_function('MDB2_closeOpenTransactions');
|
||||||
|
}
|
||||||
|
$result =& $this->_doQuery('BEGIN TRANSACTION', true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$this->in_transaction = true;
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ commit()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit the database changes done during a transaction that is in
|
||||||
|
* progress.
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function commit()
|
||||||
|
{
|
||||||
|
$this->debug('commit transaction', 'commit', false);
|
||||||
|
if (!$this->in_transaction) {
|
||||||
|
return $this->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||||
|
'commit: transaction changes are being auto committed');
|
||||||
|
}
|
||||||
|
$result =& $this->_doQuery('COMMIT TRANSACTION', true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$this->in_transaction = false;
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ rollback()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel any database changes done during a transaction that is in
|
||||||
|
* progress.
|
||||||
|
*
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function rollback()
|
||||||
|
{
|
||||||
|
$this->debug('rolling back transaction', 'rollback', false);
|
||||||
|
if (!$this->in_transaction) {
|
||||||
|
return $this->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||||
|
'rollback: transactions can not be rolled back when changes are auto committed');
|
||||||
|
}
|
||||||
|
$result =& $this->_doQuery('ROLLBACK TRANSACTION', true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$this->in_transaction = false;
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ connect()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the database
|
||||||
|
*
|
||||||
|
* @return true on success, MDB2 Error Object on failure
|
||||||
|
*/
|
||||||
|
function connect()
|
||||||
|
{
|
||||||
|
if (is_resource($this->connection)) {
|
||||||
|
if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
|
||||||
|
&& $this->opened_persistent == $this->options['persistent']
|
||||||
|
) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
$this->disconnect(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PEAR::loadExtension($this->phptype)) {
|
||||||
|
return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||||
|
'connect: extension '.$this->phptype.' is not compiled into PHP');
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
$this->dsn['hostspec'] ? $this->dsn['hostspec'] : 'localhost',
|
||||||
|
$this->dsn['username'] ? $this->dsn['username'] : null,
|
||||||
|
$this->dsn['password'] ? $this->dsn['password'] : null,
|
||||||
|
);
|
||||||
|
if ($this->dsn['port']) {
|
||||||
|
$params[0].= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':').$this->dsn['port'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$connect_function = $this->options['persistent'] ? 'mssql_pconnect' : 'mssql_connect';
|
||||||
|
|
||||||
|
$connection = @call_user_func_array($connect_function, $params);
|
||||||
|
if ($connection <= 0) {
|
||||||
|
return $this->raiseError(MDB2_ERROR_CONNECT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->dsn['charset'])) {
|
||||||
|
$result = $this->setCharset($this->dsn['charset'], $connection);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->connected_dsn = $this->dsn;
|
||||||
|
$this->connected_database_name = '';
|
||||||
|
$this->opened_persistent = $this->options['persistent'];
|
||||||
|
$this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype;
|
||||||
|
|
||||||
|
if ((bool) ini_get('mssql.datetimeconvert')) {
|
||||||
|
@ini_set('mssql.datetimeconvert', '0');
|
||||||
|
}
|
||||||
|
@mssql_query('SET DATEFORMAT ymd', $connection);
|
||||||
|
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ disconnect()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log out and disconnect from the database.
|
||||||
|
*
|
||||||
|
* @param boolean $force if the disconnect should be forced even if the
|
||||||
|
* connection is opened persistently
|
||||||
|
* @return mixed true on success, false if not connected and error
|
||||||
|
* object on error
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function disconnect($force = true)
|
||||||
|
{
|
||||||
|
if (is_resource($this->connection)) {
|
||||||
|
if ($this->in_transaction) {
|
||||||
|
$this->rollback();
|
||||||
|
}
|
||||||
|
if (!$this->opened_persistent || $force) {
|
||||||
|
@mssql_close($this->connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parent::disconnect($force);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _doQuery()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query
|
||||||
|
* @param string $query query
|
||||||
|
* @param boolean $is_manip if the query is a manipulation query
|
||||||
|
* @param resource $connection
|
||||||
|
* @param string $database_name
|
||||||
|
* @return result or error object
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function &_doQuery($query, $is_manip = false, $connection = null, $database_name = null)
|
||||||
|
{
|
||||||
|
$this->last_query = $query;
|
||||||
|
$result = $this->debug($query, 'query', $is_manip);
|
||||||
|
if ($result) {
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$query = $result;
|
||||||
|
}
|
||||||
|
if ($this->getOption('disable_query')) {
|
||||||
|
if ($is_manip) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($connection)) {
|
||||||
|
$connection = $this->getConnection();
|
||||||
|
if (PEAR::isError($connection)) {
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_null($database_name)) {
|
||||||
|
$database_name = $this->database_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($database_name) {
|
||||||
|
if ($database_name != $this->connected_database_name) {
|
||||||
|
if (!@mssql_select_db($database_name, $connection)) {
|
||||||
|
$err = $this->raiseError(null, null, null,
|
||||||
|
'_doQuery: Could not select the database: '.$database_name);
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
$this->connected_database_name = $database_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = @mssql_query($query, $connection);
|
||||||
|
if (!$result) {
|
||||||
|
$err = $this->raiseError(null, null, null,
|
||||||
|
'_doQuery: Could not execute statement');
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _affectedRows()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows affected
|
||||||
|
*
|
||||||
|
* @param resource $result
|
||||||
|
* @param resource $connection
|
||||||
|
* @return mixed MDB2 Error Object or the number of rows affected
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _affectedRows($connection, $result = null)
|
||||||
|
{
|
||||||
|
if (is_null($connection)) {
|
||||||
|
$connection = $this->getConnection();
|
||||||
|
if (PEAR::isError($connection)) {
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return @mssql_rows_affected($connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _modifyQuery()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes a query string for various DBMS specific reasons
|
||||||
|
*
|
||||||
|
* @param string $query query to modify
|
||||||
|
* @param boolean $is_manip if it is a DML query
|
||||||
|
* @param integer $limit limit the number of rows
|
||||||
|
* @param integer $offset start reading from given offset
|
||||||
|
* @return string modified query
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _modifyQuery($query, $is_manip, $limit, $offset)
|
||||||
|
{
|
||||||
|
if ($limit > 0) {
|
||||||
|
$fetch = $offset + $limit;
|
||||||
|
if (!$is_manip) {
|
||||||
|
return preg_replace('/^([\s(])*SELECT(?!\s*TOP\s*\()/i',
|
||||||
|
"\\1SELECT TOP $fetch", $query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ getServerVersion()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return version information about the server
|
||||||
|
*
|
||||||
|
* @param string $native determines if the raw version string should be returned
|
||||||
|
* @return mixed array/string with version information or MDB2 error object
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getServerVersion($native = false)
|
||||||
|
{
|
||||||
|
if ($this->connected_server_info) {
|
||||||
|
$server_info = $this->connected_server_info;
|
||||||
|
} else {
|
||||||
|
$query = 'SELECT @@VERSION';
|
||||||
|
$server_info = $this->queryOne($query, 'text');
|
||||||
|
if (PEAR::isError($server_info)) {
|
||||||
|
return $server_info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cache server_info
|
||||||
|
$this->connected_server_info = $server_info;
|
||||||
|
if (!$native && !PEAR::isError($server_info)) {
|
||||||
|
if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $server_info, $tmp)) {
|
||||||
|
$server_info = array(
|
||||||
|
'major' => $tmp[1],
|
||||||
|
'minor' => $tmp[2],
|
||||||
|
'patch' => $tmp[3],
|
||||||
|
'extra' => null,
|
||||||
|
'native' => $server_info,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$server_info = array(
|
||||||
|
'major' => null,
|
||||||
|
'minor' => null,
|
||||||
|
'patch' => null,
|
||||||
|
'extra' => null,
|
||||||
|
'native' => $server_info,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $server_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _checkSequence
|
||||||
|
/**
|
||||||
|
* Checks if there's a sequence that exists.
|
||||||
|
*
|
||||||
|
* @param string $seq_name The sequence name to verify.
|
||||||
|
* @return bool $tableExists The value if the table exists or not
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _checkSequence($seq_name)
|
||||||
|
{
|
||||||
|
$query = "SELECT * FROM $seq_name";
|
||||||
|
$tableExists =& $this->_doQuery($query, true);
|
||||||
|
if (PEAR::isError($tableExists)) {
|
||||||
|
if ($tableExists->getCode() == MDB2_ERROR_NOSUCHTABLE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//return $tableExists;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ nextID()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next free id of a sequence
|
||||||
|
*
|
||||||
|
* @param string $seq_name name of the sequence
|
||||||
|
* @param boolean $ondemand when true the sequence is
|
||||||
|
* automatic created, if it
|
||||||
|
* not exists
|
||||||
|
*
|
||||||
|
* @return mixed MDB2 Error Object or id
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function nextID($seq_name, $ondemand = true)
|
||||||
|
{
|
||||||
|
$sequence_name = $this->quoteIdentifier($this->getSequenceName($seq_name), true);
|
||||||
|
$seqcol_name = $this->quoteIdentifier($this->options['seqcol_name'], true);
|
||||||
|
$this->expectError(MDB2_ERROR_NOSUCHTABLE);
|
||||||
|
if ($this->_checkSequence($sequence_name)) {
|
||||||
|
$query = "SET IDENTITY_INSERT $sequence_name ON ".
|
||||||
|
"INSERT INTO $sequence_name ($seqcol_name) VALUES (0)";
|
||||||
|
} else {
|
||||||
|
$query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (0)";
|
||||||
|
}
|
||||||
|
$result =& $this->_doQuery($query, true);
|
||||||
|
$this->popExpect();
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
if ($ondemand && !$this->_checkSequence($sequence_name)) {
|
||||||
|
$this->loadModule('Manager', null, true);
|
||||||
|
// Since we are creating the sequence on demand
|
||||||
|
// we know the first id = 1 so initialize the
|
||||||
|
// sequence at 2
|
||||||
|
$result = $this->manager->createSequence($seq_name, 2);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $this->raiseError($result, null, null,
|
||||||
|
'nextID: on demand sequence '.$seq_name.' could not be created');
|
||||||
|
} else {
|
||||||
|
// First ID of a newly created sequence is 1
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
$value = $this->lastInsertID($sequence_name);
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
$query = "DELETE FROM $sequence_name WHERE $seqcol_name < $value";
|
||||||
|
$result =& $this->_doQuery($query, true);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
$this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ lastInsertID()
|
||||||
|
/**
|
||||||
|
* Returns the autoincrement ID if supported or $id or fetches the current
|
||||||
|
* ID in a sequence called: $table.(empty($field) ? '' : '_'.$field)
|
||||||
|
*
|
||||||
|
* @param string $table name of the table into which a new row was inserted
|
||||||
|
* @param string $field name of the field into which a new row was inserted
|
||||||
|
* @return mixed MDB2 Error Object or id
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function lastInsertID($table = null, $field = null)
|
||||||
|
{
|
||||||
|
$server_info = $this->getServerVersion();
|
||||||
|
if (is_array($server_info)
|
||||||
|
&& !is_null($server_info['major'])
|
||||||
|
&& $server_info['major'] >= 8) {
|
||||||
|
$query = "SELECT SCOPE_IDENTITY()";
|
||||||
|
} else {
|
||||||
|
$query = "SELECT @@IDENTITY";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->queryOne($query, 'integer');
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ Class MDB2_Result_mssql
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL Server result driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Frank M. Kromann <frank@kromann.info>
|
||||||
|
*/
|
||||||
|
class MDB2_Result_mssql extends MDB2_Result_Common
|
||||||
|
{
|
||||||
|
// {{{ _skipLimitOffset()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip the first row of a result set.
|
||||||
|
*
|
||||||
|
* @param resource $result
|
||||||
|
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _skipLimitOffset()
|
||||||
|
{
|
||||||
|
if ($this->limit) {
|
||||||
|
if ($this->rownum >= $this->limit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->offset) {
|
||||||
|
while ($this->offset_count < $this->offset) {
|
||||||
|
++$this->offset_count;
|
||||||
|
if (!is_array(@mssql_fetch_row($this->result))) {
|
||||||
|
$this->offset_count = $this->limit;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ fetchRow()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a row and insert the data into an existing array.
|
||||||
|
*
|
||||||
|
* @param int $fetchmode how the array data should be indexed
|
||||||
|
* @param int $rownum number of the row where the data can be found
|
||||||
|
* @return int data array on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
|
||||||
|
{
|
||||||
|
if (!$this->_skipLimitOffset()) {
|
||||||
|
$null = null;
|
||||||
|
return $null;
|
||||||
|
}
|
||||||
|
if (!is_null($rownum)) {
|
||||||
|
$seek = $this->seek($rownum);
|
||||||
|
if (PEAR::isError($seek)) {
|
||||||
|
return $seek;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($fetchmode == MDB2_FETCHMODE_DEFAULT) {
|
||||||
|
$fetchmode = $this->db->fetchmode;
|
||||||
|
}
|
||||||
|
if ($fetchmode & MDB2_FETCHMODE_ASSOC) {
|
||||||
|
$row = @mssql_fetch_assoc($this->result);
|
||||||
|
if (is_array($row)
|
||||||
|
&& $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||||
|
) {
|
||||||
|
$row = array_change_key_case($row, $this->db->options['field_case']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$row = @mssql_fetch_row($this->result);
|
||||||
|
}
|
||||||
|
if (!$row) {
|
||||||
|
if ($this->result === false) {
|
||||||
|
$err =& $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'fetchRow: resultset has already been freed');
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
$null = null;
|
||||||
|
return $null;
|
||||||
|
}
|
||||||
|
if ($this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL) {
|
||||||
|
$this->db->_fixResultArrayValues($row, MDB2_PORTABILITY_EMPTY_TO_NULL);
|
||||||
|
}
|
||||||
|
if (!empty($this->values)) {
|
||||||
|
$this->_assignBindColumns($row);
|
||||||
|
}
|
||||||
|
if (!empty($this->types)) {
|
||||||
|
$row = $this->db->datatype->convertResultRow($this->types, $row);
|
||||||
|
}
|
||||||
|
if ($fetchmode === MDB2_FETCHMODE_OBJECT) {
|
||||||
|
$object_class = $this->db->options['fetch_class'];
|
||||||
|
if ($object_class == 'stdClass') {
|
||||||
|
$row = (object) $row;
|
||||||
|
} else {
|
||||||
|
$row = &new $object_class($row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++$this->rownum;
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _getColumnNames()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the names of columns returned by the DBMS in a query result.
|
||||||
|
*
|
||||||
|
* @return mixed Array variable that holds the names of columns as keys
|
||||||
|
* or an MDB2 error on failure.
|
||||||
|
* Some DBMS may not return any columns when the result set
|
||||||
|
* does not contain any rows.
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _getColumnNames()
|
||||||
|
{
|
||||||
|
$columns = array();
|
||||||
|
$numcols = $this->numCols();
|
||||||
|
if (PEAR::isError($numcols)) {
|
||||||
|
return $numcols;
|
||||||
|
}
|
||||||
|
for ($column = 0; $column < $numcols; $column++) {
|
||||||
|
$column_name = @mssql_field_name($this->result, $column);
|
||||||
|
$columns[$column_name] = $column;
|
||||||
|
}
|
||||||
|
if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||||
|
$columns = array_change_key_case($columns, $this->db->options['field_case']);
|
||||||
|
}
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ numCols()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of columns returned by the DBMS in a query result.
|
||||||
|
*
|
||||||
|
* @return mixed integer value with the number of columns, a MDB2 error
|
||||||
|
* on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function numCols()
|
||||||
|
{
|
||||||
|
$cols = @mssql_num_fields($this->result);
|
||||||
|
if (is_null($cols)) {
|
||||||
|
if ($this->result === false) {
|
||||||
|
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'numCols: resultset has already been freed');
|
||||||
|
} elseif (is_null($this->result)) {
|
||||||
|
return count($this->types);
|
||||||
|
}
|
||||||
|
return $this->db->raiseError(null, null, null,
|
||||||
|
'numCols: Could not get column count');
|
||||||
|
}
|
||||||
|
return $cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ nextResult()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the internal result pointer to the next available result
|
||||||
|
*
|
||||||
|
* @return true on success, false if there is no more result set or an error object on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function nextResult()
|
||||||
|
{
|
||||||
|
if ($this->result === false) {
|
||||||
|
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'nextResult: resultset has already been freed');
|
||||||
|
} elseif (is_null($this->result)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return @mssql_next_result($this->result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ free()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the internal resources associated with $result.
|
||||||
|
*
|
||||||
|
* @return boolean true on success, false if $result is invalid
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function free()
|
||||||
|
{
|
||||||
|
if (is_resource($this->result) && $this->db->connection) {
|
||||||
|
$free = @mssql_free_result($this->result);
|
||||||
|
if ($free === false) {
|
||||||
|
return $this->db->raiseError(null, null, null,
|
||||||
|
'free: Could not free result');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->result = false;
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL Server buffered result driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Frank M. Kromann <frank@kromann.info>
|
||||||
|
*/
|
||||||
|
class MDB2_BufferedResult_mssql extends MDB2_Result_mssql
|
||||||
|
{
|
||||||
|
// }}}
|
||||||
|
// {{{ seek()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seek to a specific row in a result set
|
||||||
|
*
|
||||||
|
* @param int $rownum number of the row where the data can be found
|
||||||
|
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function seek($rownum = 0)
|
||||||
|
{
|
||||||
|
if ($this->rownum != ($rownum - 1) && !@mssql_data_seek($this->result, $rownum)) {
|
||||||
|
if ($this->result === false) {
|
||||||
|
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'seek: resultset has already been freed');
|
||||||
|
} elseif (is_null($this->result)) {
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
return $this->db->raiseError(MDB2_ERROR_INVALID, null, null,
|
||||||
|
'seek: tried to seek to an invalid row number ('.$rownum.')');
|
||||||
|
}
|
||||||
|
$this->rownum = $rownum - 1;
|
||||||
|
return MDB2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{{ valid()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the end of the result set has been reached
|
||||||
|
*
|
||||||
|
* @return mixed true or false on sucess, a MDB2 error on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function valid()
|
||||||
|
{
|
||||||
|
$numrows = $this->numRows();
|
||||||
|
if (PEAR::isError($numrows)) {
|
||||||
|
return $numrows;
|
||||||
|
}
|
||||||
|
return $this->rownum < ($numrows - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ numRows()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows in a result object
|
||||||
|
*
|
||||||
|
* @return mixed MDB2 Error Object or the number of rows
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function numRows()
|
||||||
|
{
|
||||||
|
$rows = @mssql_num_rows($this->result);
|
||||||
|
if (is_null($rows)) {
|
||||||
|
if ($this->result === false) {
|
||||||
|
return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||||
|
'numRows: resultset has already been freed');
|
||||||
|
} elseif (is_null($this->result)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return $this->db->raiseError(null, null, null,
|
||||||
|
'numRows: Could not get row count');
|
||||||
|
}
|
||||||
|
if ($this->limit) {
|
||||||
|
$rows -= $this->limit;
|
||||||
|
if ($rows < 0) {
|
||||||
|
$rows = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// {{{ MDB2_Statement_mssql
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDB2 MSSQL Server statement driver
|
||||||
|
*
|
||||||
|
* @package MDB2
|
||||||
|
* @category Database
|
||||||
|
* @author Frank M. Kromann <frank@kromann.info>
|
||||||
|
*/
|
||||||
|
class MDB2_Statement_mssql extends MDB2_Statement_Common
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
?>
|
||||||
1406
htdocs/includes/pear/MDB2/Driver/mysql.php
Normal file
1406
htdocs/includes/pear/MDB2/Driver/mysql.php
Normal file
File diff suppressed because it is too large
Load Diff
1565
htdocs/includes/pear/MDB2/Driver/mysqli.php
Normal file
1565
htdocs/includes/pear/MDB2/Driver/mysqli.php
Normal file
File diff suppressed because it is too large
Load Diff
706
htdocs/includes/pear/MDB2/Extended.php
Normal file
706
htdocs/includes/pear/MDB2/Extended.php
Normal file
@@ -0,0 +1,706 @@
|
|||||||
|
<?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$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
return $db->prepare($query, $types, $result_types);
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// {{{ 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 (!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:
|
||||||
|
*
|
||||||
|
* ID TEXT DATE
|
||||||
|
* --------------------------------
|
||||||
|
* 1 'one' 944679408
|
||||||
|
* 2 'two' 944679408
|
||||||
|
* 3 'three' 944679408
|
||||||
|
*
|
||||||
|
* Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
||||||
|
* array(
|
||||||
|
* '1' => 'one',
|
||||||
|
* '2' => 'two',
|
||||||
|
* '3' => 'three',
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
||||||
|
* array(
|
||||||
|
* '1' => array('one', '944679408'),
|
||||||
|
* '2' => array('two', '944679408'),
|
||||||
|
* '3' => array('three', '944679408')
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* If the more than one row occurs with the same value in the
|
||||||
|
* first column, the last row overwrites all previous ones by
|
||||||
|
* default. Use the $group parameter if you don't want to
|
||||||
|
* overwrite like this. Example:
|
||||||
|
*
|
||||||
|
* getAssoc('SELECT category,id,name FROM mytable', null, null
|
||||||
|
* MDB2_FETCHMODE_ASSOC, false, true) returns:
|
||||||
|
* array(
|
||||||
|
* '1' => array(array('id' => '4', 'name' => 'number four'),
|
||||||
|
* array('id' => '6', 'name' => 'number six')
|
||||||
|
* ),
|
||||||
|
* '9' => array(array('id' => '4', 'name' => 'number four'),
|
||||||
|
* array('id' => '6', 'name' => 'number six')
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* Keep in mind that database functions in PHP usually return string
|
||||||
|
* values for results regardless of the database's internal type.
|
||||||
|
*
|
||||||
|
* @param string 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
htdocs/includes/pear/MDB2/Iterator.php
Normal file
259
htdocs/includes/pear/MDB2/Iterator.php
Normal 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$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
htdocs/includes/pear/MDB2/LOB.php
Normal file
264
htdocs/includes/pear/MDB2/LOB.php
Normal 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$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
Reference in New Issue
Block a user