First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
4357
sites/all/modules/civicrm/packages/DB/DataObject.php
Normal file
4357
sites/all/modules/civicrm/packages/DB/DataObject.php
Normal file
File diff suppressed because it is too large
Load diff
549
sites/all/modules/civicrm/packages/DB/DataObject/Cast.php
Normal file
549
sites/all/modules/civicrm/packages/DB/DataObject/Cast.php
Normal file
|
@ -0,0 +1,549 @@
|
|||
<?php
|
||||
/**
|
||||
* Prototype Castable Object.. for DataObject queries
|
||||
*
|
||||
* Storage for Data that may be cast into a variety of formats.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_DataObject
|
||||
* @author Alan Knowles <alan@akbkhome.com>
|
||||
* @copyright 1997-2008 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Cast.php 287158 2009-08-12 13:58:31Z alan_k $
|
||||
* @link http://pear.php.net/package/DB_DataObject
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Common usages:
|
||||
* // blobs
|
||||
* $data = DB_DataObject_Cast::blob($somefile);
|
||||
* $data = DB_DataObject_Cast::string($somefile);
|
||||
* $dataObject->someblobfield = $data
|
||||
*
|
||||
* // dates?
|
||||
* $d1 = new DB_DataObject_Cast::date('12/12/2000');
|
||||
* $d2 = new DB_DataObject_Cast::date(2000,12,30);
|
||||
* $d3 = new DB_DataObject_Cast::date($d1->year, $d1->month+30, $d1->day+30);
|
||||
*
|
||||
* // time, datetime.. ?????????
|
||||
*
|
||||
* // raw sql????
|
||||
* $data = DB_DataObject_Cast::sql('cast("123123",datetime)');
|
||||
* $data = DB_DataObject_Cast::sql('NULL');
|
||||
*
|
||||
* // int's/string etc. are proably pretty pointless..!!!!
|
||||
*
|
||||
*
|
||||
* inside DB_DataObject,
|
||||
* if (is_a($v,'db_dataobject_class')) {
|
||||
* $value .= $v->toString(DB_DATAOBJECT_INT,'mysql');
|
||||
* }
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
|
||||
*/
|
||||
class DB_DataObject_Cast {
|
||||
|
||||
/**
|
||||
* Type of data Stored in the object..
|
||||
*
|
||||
* @var string (date|blob|.....?)
|
||||
* @access public
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* Data For date representation
|
||||
*
|
||||
* @var int day/month/year
|
||||
* @access public
|
||||
*/
|
||||
var $day;
|
||||
var $month;
|
||||
var $year;
|
||||
|
||||
|
||||
/**
|
||||
* Generic Data..
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
|
||||
var $value;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Blob consructor
|
||||
*
|
||||
* create a Cast object from some raw data.. (binary)
|
||||
*
|
||||
*
|
||||
* @param string (with binary data!)
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function blob($value) {
|
||||
$r = new DB_DataObject_Cast;
|
||||
$r->type = 'blob';
|
||||
$r->value = $value;
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* String consructor (actually use if for ints and everything else!!!
|
||||
*
|
||||
* create a Cast object from some string (not binary)
|
||||
*
|
||||
*
|
||||
* @param string (with binary data!)
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function string($value) {
|
||||
$r = new DB_DataObject_Cast;
|
||||
$r->type = 'string';
|
||||
$r->value = $value;
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL constructor (for raw SQL insert)
|
||||
*
|
||||
* create a Cast object from some sql
|
||||
*
|
||||
* @param string (with binary data!)
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function sql($value)
|
||||
{
|
||||
$r = new DB_DataObject_Cast;
|
||||
$r->type = 'sql';
|
||||
$r->value = $value;
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Date Constructor
|
||||
*
|
||||
* create a Cast object from some string (not binary)
|
||||
* NO VALIDATION DONE, although some crappy re-calcing done!
|
||||
*
|
||||
* @param vargs... accepts
|
||||
* dd/mm
|
||||
* dd/mm/yyyy
|
||||
* yyyy-mm
|
||||
* yyyy-mm-dd
|
||||
* array(yyyy,dd)
|
||||
* array(yyyy,dd,mm)
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function date()
|
||||
{
|
||||
$args = func_get_args();
|
||||
switch(count($args)) {
|
||||
case 0: // no args = today!
|
||||
$bits = explode('-',date('Y-m-d'));
|
||||
break;
|
||||
case 1: // one arg = a string
|
||||
|
||||
if (strpos($args[0],'/') !== false) {
|
||||
$bits = array_reverse(explode('/',$args[0]));
|
||||
} else {
|
||||
$bits = explode('-',$args[0]);
|
||||
}
|
||||
break;
|
||||
default: // 2 or more..
|
||||
$bits = $args;
|
||||
}
|
||||
if (count($bits) == 1) { // if YYYY set day = 1st..
|
||||
$bits[] = 1;
|
||||
}
|
||||
|
||||
if (count($bits) == 2) { // if YYYY-DD set day = 1st..
|
||||
$bits[] = 1;
|
||||
}
|
||||
|
||||
// if year < 1970 we cant use system tools to check it...
|
||||
// so we make a few best gueses....
|
||||
// basically do date calculations for the year 2000!!!
|
||||
// fix me if anyone has more time...
|
||||
if (($bits[0] < 1975) || ($bits[0] > 2030)) {
|
||||
$oldyear = $bits[0];
|
||||
$bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],2000)));
|
||||
$bits[0] = ($bits[0] - 2000) + $oldyear;
|
||||
} else {
|
||||
// now mktime
|
||||
$bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],$bits[0])));
|
||||
}
|
||||
$r = new DB_DataObject_Cast;
|
||||
$r->type = 'date';
|
||||
list($r->year,$r->month,$r->day) = $bits;
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data For time representation ** does not handle timezones!!
|
||||
*
|
||||
* @var int hour/minute/second
|
||||
* @access public
|
||||
*/
|
||||
var $hour;
|
||||
var $minute;
|
||||
var $second;
|
||||
|
||||
|
||||
/**
|
||||
* DateTime Constructor
|
||||
*
|
||||
* create a Cast object from a Date/Time
|
||||
* Maybe should accept a Date object.!
|
||||
* NO VALIDATION DONE, although some crappy re-calcing done!
|
||||
*
|
||||
* @param vargs... accepts
|
||||
* noargs (now)
|
||||
* yyyy-mm-dd HH:MM:SS (Iso)
|
||||
* array(yyyy,mm,dd,HH,MM,SS)
|
||||
*
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
* @author therion 5 at hotmail
|
||||
*/
|
||||
|
||||
function dateTime()
|
||||
{
|
||||
$args = func_get_args();
|
||||
switch(count($args)) {
|
||||
case 0: // no args = now!
|
||||
$datetime = date('Y-m-d G:i:s', mktime());
|
||||
|
||||
case 1:
|
||||
// continue on from 0 args.
|
||||
if (!isset($datetime)) {
|
||||
$datetime = $args[0];
|
||||
}
|
||||
|
||||
$parts = explode(' ', $datetime);
|
||||
$bits = explode('-', $parts[0]);
|
||||
$bits = array_merge($bits, explode(':', $parts[1]));
|
||||
break;
|
||||
|
||||
default: // 2 or more..
|
||||
$bits = $args;
|
||||
|
||||
}
|
||||
|
||||
if (count($bits) != 6) {
|
||||
// PEAR ERROR?
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = DB_DataObject_Cast::date($bits[0], $bits[1], $bits[2]);
|
||||
if (!$r) {
|
||||
return $r; // pass thru error (False) - doesnt happen at present!
|
||||
}
|
||||
// change the type!
|
||||
$r->type = 'datetime';
|
||||
|
||||
// should we mathematically sort this out..
|
||||
// (or just assume that no-one's dumb enough to enter 26:90:90 as a time!
|
||||
$r->hour = $bits[3];
|
||||
$r->minute = $bits[4];
|
||||
$r->second = $bits[5];
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* time Constructor
|
||||
*
|
||||
* create a Cast object from a Date/Time
|
||||
* Maybe should accept a Date object.!
|
||||
* NO VALIDATION DONE, and no-recalcing done!
|
||||
*
|
||||
* @param vargs... accepts
|
||||
* noargs (now)
|
||||
* HH:MM:SS (Iso)
|
||||
* array(HH,MM,SS)
|
||||
*
|
||||
*
|
||||
* @return object DB_DataObject_Cast
|
||||
* @access public
|
||||
* @author therion 5 at hotmail
|
||||
*/
|
||||
function time()
|
||||
{
|
||||
$args = func_get_args();
|
||||
switch (count($args)) {
|
||||
case 0: // no args = now!
|
||||
$time = date('G:i:s', mktime());
|
||||
|
||||
case 1:
|
||||
// continue on from 0 args.
|
||||
if (!isset($time)) {
|
||||
$time = $args[0];
|
||||
}
|
||||
$bits = explode(':', $time);
|
||||
break;
|
||||
|
||||
default: // 2 or more..
|
||||
$bits = $args;
|
||||
|
||||
}
|
||||
|
||||
if (count($bits) != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// now take data from bits into object fields
|
||||
$r = new DB_DataObject_Cast;
|
||||
$r->type = 'time';
|
||||
$r->hour = $bits[0];
|
||||
$r->minute = $bits[1];
|
||||
$r->second = $bits[2];
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for this...
|
||||
*
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function toString($to=false,$db)
|
||||
{
|
||||
// if $this->type is not set, we are in serious trouble!!!!
|
||||
// values for to:
|
||||
$method = 'toStringFrom'.$this->type;
|
||||
return $this->$method($to,$db);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement from a blob of binary data
|
||||
* ** Suppots only blob->postgres::bytea
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function toStringFromBlob($to,$db)
|
||||
{
|
||||
// first weed out invalid casts..
|
||||
// in blobs can only be cast to blobs.!
|
||||
|
||||
// perhaps we should support TEXT fields???
|
||||
|
||||
if (!($to & DB_DATAOBJECT_BLOB)) {
|
||||
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::blob to something other than a blob!');
|
||||
}
|
||||
|
||||
switch ($db->dsn["phptype"]) {
|
||||
case 'pgsql':
|
||||
return "'".pg_escape_bytea($this->value)."'::bytea";
|
||||
|
||||
case 'mysql':
|
||||
return "'".mysql_real_escape_string($this->value,$db->connection)."'";
|
||||
|
||||
case 'mysqli':
|
||||
// this is funny - the parameter order is reversed ;)
|
||||
return "'".mysqli_real_escape_string($db->connection, $this->value)."'";
|
||||
|
||||
case 'sqlite':
|
||||
// this is funny - the parameter order is reversed ;)
|
||||
return "'".sqlite_escape_string($this->value)."'";
|
||||
|
||||
|
||||
default:
|
||||
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for a blob from a string!
|
||||
* ** Suppots only string->postgres::bytea
|
||||
*
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function toStringFromString($to,$db)
|
||||
{
|
||||
// first weed out invalid casts..
|
||||
// in blobs can only be cast to blobs.!
|
||||
|
||||
// perhaps we should support TEXT fields???
|
||||
//
|
||||
|
||||
if (!($to & DB_DATAOBJECT_BLOB)) {
|
||||
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a blob!'.
|
||||
' (why not just use native features)');
|
||||
}
|
||||
|
||||
switch ($db->dsn['phptype']) {
|
||||
case 'pgsql':
|
||||
return "'".pg_escape_string($this->value)."'::bytea";
|
||||
|
||||
case 'mysql':
|
||||
return "'".mysql_real_escape_string($this->value,$db->connection)."'";
|
||||
|
||||
|
||||
case 'mysqli':
|
||||
return "'".mysqli_real_escape_string($db->connection, $this->value)."'";
|
||||
|
||||
|
||||
default:
|
||||
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for a date
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function toStringFromDate($to,$db)
|
||||
{
|
||||
// first weed out invalid casts..
|
||||
// in blobs can only be cast to blobs.!
|
||||
// perhaps we should support TEXT fields???
|
||||
//
|
||||
|
||||
if (($to !== false) && !($to & DB_DATAOBJECT_DATE)) {
|
||||
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a date!'.
|
||||
' (why not just use native features)');
|
||||
}
|
||||
return "'{$this->year}-{$this->month}-{$this->day}'";
|
||||
}
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for a datetime
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
* @author therion 5 at hotmail
|
||||
*/
|
||||
|
||||
function toStringFromDateTime($to,$db)
|
||||
{
|
||||
// first weed out invalid casts..
|
||||
// in blobs can only be cast to blobs.!
|
||||
// perhaps we should support TEXT fields???
|
||||
if (($to !== false) &&
|
||||
!($to & (DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME))) {
|
||||
return PEAR::raiseError('Invalid Cast from a ' .
|
||||
' DB_DataObject_Cast::dateTime to something other than a datetime!' .
|
||||
' (try using native features)');
|
||||
}
|
||||
return "'{$this->year}-{$this->month}-{$this->day} {$this->hour}:{$this->minute}:{$this->second}'";
|
||||
}
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for a time
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
* @author therion 5 at hotmail
|
||||
*/
|
||||
|
||||
function toStringFromTime($to,$db)
|
||||
{
|
||||
// first weed out invalid casts..
|
||||
// in blobs can only be cast to blobs.!
|
||||
// perhaps we should support TEXT fields???
|
||||
if (($to !== false) && !($to & DB_DATAOBJECT_TIME)) {
|
||||
return PEAR::raiseError('Invalid Cast from a' .
|
||||
' DB_DataObject_Cast::time to something other than a time!'.
|
||||
' (try using native features)');
|
||||
}
|
||||
return "'{$this->hour}:{$this->minute}:{$this->second}'";
|
||||
}
|
||||
|
||||
/**
|
||||
* get the string to use in the SQL statement for a raw sql statement.
|
||||
*
|
||||
* @param int $to Type (DB_DATAOBJECT_*
|
||||
* @param object $db DB Connection Object
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function toStringFromSql($to,$db)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
53
sites/all/modules/civicrm/packages/DB/DataObject/Error.php
Normal file
53
sites/all/modules/civicrm/packages/DB/DataObject/Error.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/**
|
||||
* DataObjects error handler, loaded on demand...
|
||||
*
|
||||
* DB_DataObject_Error is a quick wrapper around pear error, so you can distinguish the
|
||||
* error code source.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_DataObject
|
||||
* @author Alan Knowles <alan@akbkhome.com>
|
||||
* @copyright 1997-2006 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Error.php 287158 2009-08-12 13:58:31Z alan_k $
|
||||
* @link http://pear.php.net/package/DB_DataObject
|
||||
*/
|
||||
|
||||
|
||||
class DB_DataObject_Error extends PEAR_Error
|
||||
{
|
||||
|
||||
/**
|
||||
* DB_DataObject_Error constructor.
|
||||
*
|
||||
* @param mixed $code DB error code, or string with error message.
|
||||
* @param integer $mode what "error mode" to operate in
|
||||
* @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER
|
||||
* @param mixed $debuginfo additional debug info, such as the last query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @see PEAR_Error
|
||||
*/
|
||||
function __construct($message = '', $code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
|
||||
$level = E_USER_NOTICE)
|
||||
{
|
||||
parent::__construct('DB_DataObject Error: ' . $message, $code, $mode, $level);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// todo : - support code -> message handling, and translated error messages...
|
||||
|
||||
|
||||
|
||||
}
|
1571
sites/all/modules/civicrm/packages/DB/DataObject/Generator.php
Normal file
1571
sites/all/modules/civicrm/packages/DB/DataObject/Generator.php
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/php -q
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Alan Knowles <alan@akbkhome.com>
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: createTables.php 277015 2009-03-12 05:51:03Z alan_k $
|
||||
//
|
||||
|
||||
// since this version doesnt use overload,
|
||||
// and I assume anyone using custom generators should add this..
|
||||
|
||||
define('DB_DATAOBJECT_NO_OVERLOAD',1);
|
||||
|
||||
//require_once 'DB/DataObject/Generator.php';
|
||||
require_once 'DB/DataObject/Generator.php';
|
||||
|
||||
if (!ini_get('register_argc_argv')) {
|
||||
PEAR::raiseError("\nERROR: You must turn register_argc_argv On in you php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n", null, PEAR_ERROR_DIE);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!@$_SERVER['argv'][1]) {
|
||||
PEAR::raiseError("\nERROR: createTable.php usage:\n\nC:\php\pear\DB\DataObjects\createTable.php example.ini\n\n", null, PEAR_ERROR_DIE);
|
||||
exit;
|
||||
}
|
||||
|
||||
$config = parse_ini_file($_SERVER['argv'][1], true);
|
||||
foreach($config as $class=>$values) {
|
||||
$options = PEAR::getStaticProperty($class,'options');
|
||||
$options = $values;
|
||||
}
|
||||
|
||||
|
||||
$options = PEAR::getStaticProperty('DB_DataObject','options');
|
||||
if (empty($options)) {
|
||||
PEAR::raiseError("\nERROR: could not read ini file\n\n", null, PEAR_ERROR_DIE);
|
||||
exit;
|
||||
}
|
||||
set_time_limit(0);
|
||||
|
||||
// use debug level from file if set..
|
||||
DB_DataObject::debugLevel(isset($options['debug']) ? $options['debug'] : 1);
|
||||
|
||||
$generator = new DB_DataObject_Generator;
|
||||
$generator->start();
|
||||
|
2334
sites/all/modules/civicrm/packages/DB/Table.php
Normal file
2334
sites/all/modules/civicrm/packages/DB/Table.php
Normal file
File diff suppressed because it is too large
Load diff
755
sites/all/modules/civicrm/packages/DB/Table/Base.php
Normal file
755
sites/all/modules/civicrm/packages/DB/Table/Base.php
Normal file
|
@ -0,0 +1,755 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* DB_Table_Base Base class for DB_Table and DB_Table_Database
|
||||
*
|
||||
* This utility class contains properties and methods that are common
|
||||
* to DB_Table and DB_Table database. These are all related to one of:
|
||||
* - DB/MDB2 connection object [ $db and $backend properties ]
|
||||
* - Error handling [ throwError() method, $error and $_primary_subclass ]
|
||||
* - SELECT queries [ select*() methods, $sql & $fetchmode* properties]
|
||||
* - buildSQL() and quote() SQL utilities
|
||||
* - _swapModes() method
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul M. Jones <pmjones@php.net>
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Base.php,v 1.4 2007/12/13 16:52:14 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
// {{{ DB_Table_Base
|
||||
|
||||
/**
|
||||
* Base class for DB_Table and DB_Table_Database
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul M. Jones <pmjones@php.net>
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
class DB_Table_Base
|
||||
{
|
||||
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The PEAR DB/MDB2 object that connects to the database.
|
||||
*
|
||||
* @var object
|
||||
* @access public
|
||||
*/
|
||||
var $db = null;
|
||||
|
||||
/**
|
||||
* The backend type, which must be 'db' or 'mdb2'
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $backend = null;
|
||||
|
||||
/**
|
||||
* If there is an error on instantiation, this captures that error.
|
||||
*
|
||||
* This property is used only for errors encountered in the constructor
|
||||
* at instantiation time. To check if there was an instantiation error...
|
||||
*
|
||||
* <code>
|
||||
* $obj = new DB_Table_*();
|
||||
* if ($obj->error) {
|
||||
* // ... error handling code here ...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @var object PEAR_Error
|
||||
* @access public
|
||||
*/
|
||||
var $error = null;
|
||||
|
||||
/**
|
||||
* Baseline SELECT maps for buildSQL() and select*() methods.
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $sql = array();
|
||||
|
||||
/**
|
||||
* Format of rows in sets returned by the select() method
|
||||
*
|
||||
* This should be one of the DB/MDB2_FETCHMODE_* constant values, such as
|
||||
* MDB2_FETCHMODE_ASSOC, MDB2_FETCHMODE_ORDERED, or MDB2_FETCHMODE_OBJECT.
|
||||
* It determines whether select() returns represents individual rows as
|
||||
* associative arrays with column name keys, ordered/sequential arrays,
|
||||
* or objects with column names mapped to properties. Use corresponding
|
||||
* DB_FETCHMODE_* constants for use with the DB backend. It has no effect
|
||||
* upon the return value of selectResult().
|
||||
*
|
||||
* If a 'fetchmode' element is set for a specific query array, the query
|
||||
* fetchmode will override this DB_Table or DB_Table_Database property.
|
||||
* If no value is set for the query or the DB_Table_Base object, the value
|
||||
* or default set in the underlying DB/MDB2 object will be used.
|
||||
*
|
||||
* @var int
|
||||
* @access public
|
||||
*/
|
||||
var $fetchmode = null;
|
||||
|
||||
/**
|
||||
* Class of objects to use for rows returned as objects by select()
|
||||
*
|
||||
* When fetchmode is DB/MDB2_FETCHMODE_OBJECT, use this class for each
|
||||
* returned row in rsults of select(). May be overridden by value of
|
||||
* 'fetchmode_object_class'. If no class name is set in the query or
|
||||
* the DB_Table_Base, defaults to that set in the DB/MDB2 object, or
|
||||
* to default of StdObject.
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $fetchmode_object_class = null;
|
||||
|
||||
/**
|
||||
* Upper case name of primary subclass, 'DB_TABLE' or 'DB_TABLE_DATABASE'
|
||||
*
|
||||
* This should be set in the constructor of the child class, and is
|
||||
* used in the DB_Table_Base::throwError() method to determine the
|
||||
* location of the relevant error codes and messages. Error codes and
|
||||
* error code messages are defined in class $this->_primary_subclass.
|
||||
* Messages are stored in $GLOBALS['_' . $this->_primary_subclass]['error']
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_primary_subclass = null;
|
||||
|
||||
// }}}
|
||||
// {{{ Methods
|
||||
|
||||
/**
|
||||
* Specialized version of throwError() modeled on PEAR_Error.
|
||||
*
|
||||
* Throws a PEAR_Error with an error message based on an error code
|
||||
* and corresponding error message defined in $this->_primary_subclass
|
||||
*
|
||||
* @param string $code An error code constant
|
||||
* @param string $extra Extra text for the error (in addition to the
|
||||
* regular error message).
|
||||
* @return object PEAR_Error
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &throwError($code, $extra = null)
|
||||
{
|
||||
// get the error message text based on the error code
|
||||
$index = '_' . $this->_primary_subclass;
|
||||
$text = $this->_primary_subclass . " Error - \n"
|
||||
. $GLOBALS[$index]['error'][$code];
|
||||
|
||||
// add any additional error text
|
||||
if ($extra) {
|
||||
$text .= ' ' . $extra;
|
||||
}
|
||||
|
||||
// done!
|
||||
$error = PEAR::throwError($text, $code);
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites one or more error messages, e.g., to internationalize them.
|
||||
*
|
||||
* May be used to change messages stored in global array $GLOBALS[$class_key]
|
||||
* @param mixed $code If string, the error message with code $code will be
|
||||
* overwritten by $message. If array, each key is a code
|
||||
* and each value is a new message.
|
||||
*
|
||||
* @param string $message Only used if $key is not an array.
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setErrorMessage($code, $message = null) {
|
||||
$index = '_' . $this->_primary_subclass;
|
||||
if (is_array($code)) {
|
||||
foreach ($code as $single_code => $single_message) {
|
||||
$GLOBALS[$index]['error'][$single_code] = $single_message;
|
||||
}
|
||||
} else {
|
||||
$GLOBALS[$index]['error'][$code] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns SQL SELECT string constructed from sql query array
|
||||
*
|
||||
* @param mixed $query SELECT query array, or key string of $this->sql
|
||||
* @param string $filter SQL snippet to AND with default WHERE clause
|
||||
* @param string $order SQL snippet to override default ORDER BY clause
|
||||
* @param int $start The row number from which to start result set
|
||||
* @param int $count The number of rows to list in the result set.
|
||||
*
|
||||
* @return string SQL SELECT command string (or PEAR_Error on failure)
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function buildSQL($query, $filter = null, $order = null,
|
||||
$start = null, $count = null)
|
||||
{
|
||||
|
||||
// Is $query a query array or a key of $this->sql ?
|
||||
if (!is_array($query)) {
|
||||
if (is_string($query)) {
|
||||
if (isset($this->sql[$query])) {
|
||||
$query = $this->sql[$query];
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_UNDEF'),
|
||||
$query);
|
||||
}
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_NOT_STRING'));
|
||||
}
|
||||
}
|
||||
|
||||
// Construct SQL command from parts
|
||||
$s = array();
|
||||
if (isset($query['select'])) {
|
||||
$s[] = 'SELECT ' . $query['select'];
|
||||
} else {
|
||||
$s[] = 'SELECT *';
|
||||
}
|
||||
if (isset($query['from'])) {
|
||||
$s[] = 'FROM ' . $query['from'];
|
||||
} elseif ($this->_primary_subclass == 'DB_TABLE') {
|
||||
$s[] = 'FROM ' . $this->table;
|
||||
}
|
||||
if (isset($query['join'])) {
|
||||
$s[] = $query['join'];
|
||||
}
|
||||
if (isset($query['where'])) {
|
||||
if ($filter) {
|
||||
$s[] = 'WHERE ( ' . $query['where'] . ' )';
|
||||
$s[] = ' AND ( '. $filter . ' )';
|
||||
} else {
|
||||
$s[] = 'WHERE ' . $query['where'];
|
||||
}
|
||||
} elseif ($filter) {
|
||||
$s[] = 'WHERE ' . $filter;
|
||||
}
|
||||
if (isset($query['group'])) {
|
||||
$s[] = 'GROUP BY ' . $query['group'];
|
||||
}
|
||||
if (isset($query['having'])) {
|
||||
$s[] = 'HAVING '. $query['having'];
|
||||
}
|
||||
// If $order parameter is set, override 'order' element
|
||||
if (!is_null($order)) {
|
||||
$s[] = 'ORDER BY '. $order;
|
||||
} elseif (isset($query['order'])) {
|
||||
$s[] = 'ORDER BY ' . $query['order'];
|
||||
}
|
||||
$cmd = implode("\n", $s);
|
||||
|
||||
// add LIMIT if requested
|
||||
if (!is_null($start) && !is_null($count)) {
|
||||
$db =& $this->db;
|
||||
if ($this->backend == 'mdb2') {
|
||||
$db->setLimit($count, $start);
|
||||
} else {
|
||||
$cmd = $db->modifyLimitQuery(
|
||||
$cmd, $start, $count);
|
||||
}
|
||||
}
|
||||
|
||||
// Return command string
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Selects rows using one of the DB/MDB2 get*() methods.
|
||||
*
|
||||
* @param string $query SQL SELECT query array, or a key of the
|
||||
* $this->sql property array.
|
||||
* @param string $filter SQL snippet to AND with default WHERE clause
|
||||
* @param string $order SQL snippet to override default ORDER BY clause
|
||||
* @param int $start The row number from which to start result set
|
||||
* @param int $count The number of rows to list in the result set.
|
||||
* @param array $params Parameters for placeholder substitutions, if any
|
||||
* @return mixed An array of records from the table if anything but
|
||||
* ('getOne'), a single value (if 'getOne'), or a PEAR_Error
|
||||
* @see DB::getAll()
|
||||
* @see MDB2::getAll()
|
||||
* @see DB::getAssoc()
|
||||
* @see MDB2::getAssoc()
|
||||
* @see DB::getCol()
|
||||
* @see MDB2::getCol()
|
||||
* @see DB::getOne()
|
||||
* @see MDB2::getOne()
|
||||
* @see DB::getRow()
|
||||
* @see MDB2::getRow()
|
||||
* @see DB_Table_Base::_swapModes()
|
||||
* @access public
|
||||
*/
|
||||
function select($query, $filter = null, $order = null,
|
||||
$start = null, $count = null, $params = array())
|
||||
{
|
||||
|
||||
// Is $query a query array or a key of $this->sql ?
|
||||
// On output from this block, $query is an array
|
||||
if (!is_array($query)) {
|
||||
if (is_string($query)) {
|
||||
if (isset($this->sql[$query])) {
|
||||
$query = $this->sql[$query];
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_UNDEF'),
|
||||
$query);
|
||||
}
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_NOT_STRING'));
|
||||
}
|
||||
}
|
||||
|
||||
// build the base command
|
||||
$sql = $this->buildSQL($query, $filter, $order, $start, $count);
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// set the get*() method name
|
||||
if (isset($query['get'])) {
|
||||
$method = ucwords(strtolower(trim($query['get'])));
|
||||
$method = "get$method";
|
||||
} else {
|
||||
$method = 'getAll';
|
||||
}
|
||||
|
||||
// DB_Table assumes you are using a shared PEAR DB/MDB2 object.
|
||||
// Record fetchmode settings, to be restored before returning.
|
||||
$db =& $this->db;
|
||||
$restore_mode = $db->fetchmode;
|
||||
if ($this->backend == 'mdb2') {
|
||||
$restore_class = $db->getOption('fetch_class');
|
||||
} else {
|
||||
$restore_class = $db->fetchmode_object_class;
|
||||
}
|
||||
|
||||
// swap modes
|
||||
$fetchmode = $this->fetchmode;
|
||||
$fetchmode_object_class = $this->fetchmode_object_class;
|
||||
if (isset($query['fetchmode'])) {
|
||||
$fetchmode = $query['fetchmode'];
|
||||
}
|
||||
if (isset($query['fetchmode_object_class'])) {
|
||||
$fetchmode_object_class = $query['fetchmode_object_class'];
|
||||
}
|
||||
$this->_swapModes($fetchmode, $fetchmode_object_class);
|
||||
|
||||
// make sure params is an array
|
||||
if (!is_null($params)) {
|
||||
$params = (array) $params;
|
||||
}
|
||||
|
||||
// get the result
|
||||
if ($this->backend == 'mdb2') {
|
||||
$result = $db->extended->$method($sql, null, $params);
|
||||
} else {
|
||||
switch ($method) {
|
||||
|
||||
case 'getCol':
|
||||
$result = $db->$method($sql, 0, $params);
|
||||
break;
|
||||
|
||||
case 'getAssoc':
|
||||
$result = $db->$method($sql, false, $params);
|
||||
break;
|
||||
|
||||
default:
|
||||
$result = $db->$method($sql, $params);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// restore old fetch_mode and fetch_object_class back
|
||||
$this->_swapModes($restore_mode, $restore_class);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Selects rows as a DB_Result/MDB2_Result_* object.
|
||||
*
|
||||
* @param string $query The name of the SQL SELECT to use from the
|
||||
* $this->sql property array.
|
||||
* @param string $filter SQL snippet to AND to the default WHERE clause
|
||||
* @param string $order SQL snippet to override default ORDER BY clause
|
||||
* @param int $start The record number from which to start result set
|
||||
* @param int $count The number of records to list in result set.
|
||||
* @param array $params Parameters for placeholder substitutions, if any.
|
||||
* @return object DB_Result/MDB2_Result_* object on success
|
||||
* (PEAR_Error on failure)
|
||||
* @see DB_Table::_swapModes()
|
||||
* @access public
|
||||
*/
|
||||
function selectResult($query, $filter = null, $order = null,
|
||||
$start = null, $count = null, $params = array())
|
||||
{
|
||||
// Is $query a query array or a key of $this->sql ?
|
||||
// On output from this block, $query is an array
|
||||
if (!is_array($query)) {
|
||||
if (is_string($query)) {
|
||||
if (isset($this->sql[$query])) {
|
||||
$query = $this->sql[$query];
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_UNDEF'),
|
||||
$query);
|
||||
}
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_NOT_STRING'));
|
||||
}
|
||||
}
|
||||
|
||||
// build the base command
|
||||
$sql = $this->buildSQL($query, $filter, $order, $start, $count);
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// DB_Table assumes you are using a shared PEAR DB/MDB2 object.
|
||||
// Record fetchmode settings, to be restored afterwards.
|
||||
$db =& $this->db;
|
||||
$restore_mode = $db->fetchmode;
|
||||
if ($this->backend == 'mdb2') {
|
||||
$restore_class = $db->getOption('fetch_class');
|
||||
} else {
|
||||
$restore_class = $db->fetchmode_object_class;
|
||||
}
|
||||
|
||||
// swap modes
|
||||
$fetchmode = $this->fetchmode;
|
||||
$fetchmode_object_class = $this->fetchmode_object_class;
|
||||
if (isset($query['fetchmode'])) {
|
||||
$fetchmode = $query['fetchmode'];
|
||||
}
|
||||
if (isset($query['fetchmode_object_class'])) {
|
||||
$fetchmode_object_class = $query['fetchmode_object_class'];
|
||||
}
|
||||
$this->_swapModes($fetchmode, $fetchmode_object_class);
|
||||
|
||||
// make sure params is an array
|
||||
if (!is_null($params)) {
|
||||
$params = (array) $params;
|
||||
}
|
||||
|
||||
// get the result
|
||||
if ($this->backend == 'mdb2') {
|
||||
$stmt =& $db->prepare($sql);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$result =& $stmt->execute($params);
|
||||
} else {
|
||||
$result =& $db->query($sql, $params);
|
||||
}
|
||||
|
||||
// swap modes back
|
||||
$this->_swapModes($restore_mode, $restore_class);
|
||||
|
||||
// return the result
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of rows which will be returned by a query.
|
||||
*
|
||||
* This function works identically to {@link select()}, but it
|
||||
* returns the number of rows returned by a query instead of the
|
||||
* query results themselves.
|
||||
*
|
||||
* @author Ian Eure <ian@php.net>
|
||||
* @param string $query The name of the SQL SELECT to use from the
|
||||
* $this->sql property array.
|
||||
* @param string $filter Ad-hoc SQL snippet to AND with the default
|
||||
* SELECT WHERE clause.
|
||||
* @param string $order Ad-hoc SQL snippet to override the default
|
||||
* SELECT ORDER BY clause.
|
||||
* @param int $start Row number from which to start listing in result
|
||||
* @param int $count Number of rows to list in result set
|
||||
* @param array $params Parameters to use in placeholder substitutions
|
||||
* (if any).
|
||||
* @return int Number of records from the table (or PEAR_Error on failure)
|
||||
*
|
||||
* @see DB_Table::select()
|
||||
* @access public
|
||||
*/
|
||||
function selectCount($query, $filter = null, $order = null,
|
||||
$start = null, $count = null, $params = array())
|
||||
{
|
||||
|
||||
// Is $query a query array or a key of $this->sql ?
|
||||
if (is_array($query)) {
|
||||
$sql_key = null;
|
||||
$count_query = $query;
|
||||
} else {
|
||||
if (is_string($query)) {
|
||||
if (isset($this->sql[$query])) {
|
||||
$sql_key = $query;
|
||||
$count_query = $this->sql[$query];
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_UNDEF'),
|
||||
$query);
|
||||
}
|
||||
} else {
|
||||
return $this->throwError(
|
||||
constant($this->_primary_subclass . '_ERR_SQL_NOT_STRING'));
|
||||
}
|
||||
}
|
||||
|
||||
// Use Table name as default 'from' if child class is DB_TABLE
|
||||
if ($this->_primary_subclass == 'DB_TABLE') {
|
||||
if (!isset($query['from'])) {
|
||||
$count_query['from'] = $this->table;
|
||||
}
|
||||
}
|
||||
|
||||
// If the query is a stored query in $this->sql, then create a corresponding
|
||||
// key for the count query, or check if the count-query already exists
|
||||
$ready = false;
|
||||
if ($sql_key) {
|
||||
// Create an sql key name for this count-query
|
||||
$count_key = '__count_' . $sql_key;
|
||||
// Check if a this count query alread exists in $this->sql
|
||||
if (isset($this->sql[$count_key])) {
|
||||
$ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If a count-query does not already exist, create $count_query array
|
||||
if ($ready) {
|
||||
|
||||
$count_query = $this->sql[$count_key];
|
||||
|
||||
} else {
|
||||
|
||||
// Is a count-field set for the query?
|
||||
if (!isset($count_query['count']) ||
|
||||
trim($count_query['count']) == '') {
|
||||
$count_query['count'] = '*';
|
||||
}
|
||||
|
||||
// Replace the SELECT fields with a COUNT() command
|
||||
$count_query['select'] = "COUNT({$count_query['count']})";
|
||||
|
||||
// Replace the 'get' key so we only get one result item
|
||||
$count_query['get'] = 'one';
|
||||
|
||||
// Create a new count-query in $this->sql
|
||||
if ($sql_key) {
|
||||
$this->sql[$count_key] = $count_query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Retrieve the count results
|
||||
return $this->select($count_query, $filter, $order,
|
||||
$start, $count, $params);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the $this->db PEAR DB/MDB2 object fetchmode and
|
||||
* fetchmode_object_class.
|
||||
*
|
||||
* @param string $new_mode A DB/MDB2_FETCHMODE_* constant. If null,
|
||||
* defaults to whatever the DB/MDB2 object is currently using.
|
||||
*
|
||||
* @param string $new_class The object class to use for results when
|
||||
* the $db object is in DB/MDB2_FETCHMODE_OBJECT fetch mode. If null,
|
||||
* defaults to whatever the the DB/MDB2 object is currently using.
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _swapModes($new_mode, $new_class)
|
||||
{
|
||||
// get the old (current) mode and class
|
||||
$db =& $this->db;
|
||||
$old_mode = $db->fetchmode;
|
||||
if ($this->backend == 'mdb2') {
|
||||
$old_class = $db->getOption('fetch_class');
|
||||
} else {
|
||||
$old_class = $db->fetchmode_object_class;
|
||||
}
|
||||
|
||||
// don't need to swap anything if the new modes are both
|
||||
// null or if the old and new modes already match.
|
||||
if ((is_null($new_mode) && is_null($new_class)) ||
|
||||
($old_mode == $new_mode && $old_class == $new_class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the default new mode
|
||||
if (is_null($new_mode)) {
|
||||
$new_mode = $old_mode;
|
||||
}
|
||||
|
||||
// set the default new class
|
||||
if (is_null($new_class)) {
|
||||
$new_class = $old_class;
|
||||
}
|
||||
|
||||
// swap modes
|
||||
$db->setFetchMode($new_mode, $new_class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns SQL condition equating columns to literal values.
|
||||
*
|
||||
* The parameter $data is an associative array in which keys are
|
||||
* column names and values are corresponding values. The method
|
||||
* returns an SQL string that is true if the value of every
|
||||
* specified database columns is equal to the corresponding
|
||||
* value in $data.
|
||||
*
|
||||
* For example, if:
|
||||
* <code>
|
||||
* $data = array( 'c1' => 'thing', 'c2' => 23, 'c3' => 0.32 )
|
||||
* </code>
|
||||
* then buildFilter($data) returns a string
|
||||
* <code>
|
||||
* c1 => 'thing' AND c2 => 23 AND c3 = 0.32
|
||||
* </code>
|
||||
* in which string values are replaced by SQL literal values,
|
||||
* quoted and escaped as necessary.
|
||||
*
|
||||
* Values are quoted and escaped as appropriate for each data
|
||||
* type and the backend RDBMS, using the MDB2::quote() or
|
||||
* DB::smartQuote() method. The behavior depends on the PHP type
|
||||
* of the value: string values are quoted and escaped, while
|
||||
* integer and float numerical values are not. Boolean values
|
||||
* in $data are represented as 0 or 1, consistent with the way
|
||||
* booleans are stored by DB_Table.
|
||||
*
|
||||
* Null values: The treatment of null values in $data depends upon
|
||||
* the value of the $match parameter . If $match == 'simple', an
|
||||
* empty string is returned if any $value of $data with a key in
|
||||
* $data_key is null. If $match == 'partial', the returned SQL
|
||||
* expression equates only the relevant non-null values of $data
|
||||
* to the values of corresponding database columns. If
|
||||
* $match == 'full', the function returns an empty string if all
|
||||
* of the relevant values of data are null, and returns a
|
||||
* PEAR_Error if some of the selected values are null and others
|
||||
* are not null.
|
||||
*
|
||||
* @param array $data associative array, keys are column names
|
||||
* @return string SQL expression equating values in $data to
|
||||
* values of columns named by keys.
|
||||
* @access public
|
||||
*/
|
||||
function buildFilter($data, $match = 'simple')
|
||||
{
|
||||
// Check $match type value
|
||||
if (!in_array($match, array('simple', 'partial', 'full'))) {
|
||||
return $this->throwError(
|
||||
DB_TABLE_DATABASE_ERR_MATCH_TYPE);
|
||||
}
|
||||
|
||||
if (count($data) == 0) {
|
||||
return '';
|
||||
}
|
||||
$filter = array();
|
||||
foreach ($data as $key => $value) {
|
||||
if (!is_null($value)) {
|
||||
if ($match == 'full' && isset($found_null)) {
|
||||
return $this->throwError(
|
||||
DB_TABLE_DATABASE_ERR_FULL_KEY);
|
||||
}
|
||||
if (is_bool($value)) {
|
||||
$value = $value ? '1' : '0';
|
||||
} else {
|
||||
if ($this->backend == 'mdb2') {
|
||||
$value = $this->db->quote($value);
|
||||
} else {
|
||||
$value = $this->db->quoteSmart($value);
|
||||
}
|
||||
}
|
||||
$filter[] = "$key = $value";
|
||||
} else {
|
||||
if ($match == 'simple') {
|
||||
return ''; // if any value in $data is null
|
||||
} elseif ($match == 'full') {
|
||||
$found_null = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return implode(' AND ', $filter);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* c-hanging-comment-ender-p: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
3495
sites/all/modules/civicrm/packages/DB/Table/Database.php
Normal file
3495
sites/all/modules/civicrm/packages/DB/Table/Database.php
Normal file
File diff suppressed because it is too large
Load diff
195
sites/all/modules/civicrm/packages/DB/Table/Date.php
Normal file
195
sites/all/modules/civicrm/packages/DB/Table/Date.php
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Generic date handling class for DB_Table.
|
||||
*
|
||||
* Stripped down to two essential methods specially for DB_Table from the
|
||||
* PEAR Date package by Paul M. Jones <pmjones@php.net>.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Baba Buehler <baba@babaz.com>
|
||||
* @author Pierre-Alain Joye <pajoye@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Date.php,v 1.3 2007/12/13 16:52:14 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic date handling class for DB_Table.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Baba Buehler <baba@babaz.com>
|
||||
* @author Pierre-Alain Joye <pajoye@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
class DB_Table_Date {
|
||||
|
||||
/**
|
||||
* the year
|
||||
* @var int
|
||||
*/
|
||||
var $year;
|
||||
/**
|
||||
* the month
|
||||
* @var int
|
||||
*/
|
||||
var $month;
|
||||
/**
|
||||
* the day
|
||||
* @var int
|
||||
*/
|
||||
var $day;
|
||||
/**
|
||||
* the hour
|
||||
* @var int
|
||||
*/
|
||||
var $hour;
|
||||
/**
|
||||
* the minute
|
||||
* @var int
|
||||
*/
|
||||
var $minute;
|
||||
/**
|
||||
* the second
|
||||
* @var int
|
||||
*/
|
||||
var $second;
|
||||
/**
|
||||
* the parts of a second
|
||||
* @var float
|
||||
*/
|
||||
var $partsecond;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creates a new DB_Table_Date Object. The date should be near to
|
||||
* ISO 8601 format.
|
||||
*
|
||||
* @access public
|
||||
* @param string $date A date in ISO 8601 format.
|
||||
*/
|
||||
function __construct($date)
|
||||
{
|
||||
// This regex is very loose and accepts almost any butchered
|
||||
// format you could throw at it. e.g. 2003-10-07 19:45:15 and
|
||||
// 2003-10071945:15 are the same thing in the eyes of this
|
||||
// regex, even though the latter is not a valid ISO 8601 date.
|
||||
preg_match('/^(\d{4})-?(\d{2})-?(\d{2})([T\s]?(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?(Z|[\+\-]\d{2}:?\d{2})?)?$/i', $date, $regs);
|
||||
$this->year = $regs[1];
|
||||
$this->month = $regs[2];
|
||||
$this->day = $regs[3];
|
||||
$this->hour = isset($regs[5])?$regs[5]:0;
|
||||
$this->minute = isset($regs[6])?$regs[6]:0;
|
||||
$this->second = isset($regs[7])?$regs[7]:0;
|
||||
$this->partsecond = isset($regs[8])?(float)$regs[8]:(float)0;
|
||||
|
||||
// if an offset is defined, convert time to UTC
|
||||
// Date currently can't set a timezone only by offset,
|
||||
// so it has to store it as UTC
|
||||
if (isset($regs[9])) {
|
||||
$this->toUTCbyOffset($regs[9]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Date pretty printing, similar to strftime()
|
||||
*
|
||||
* Formats the date in the given format, much like
|
||||
* strftime(). Most strftime() options are supported.<br><br>
|
||||
*
|
||||
* formatting options:<br><br>
|
||||
*
|
||||
* <code>%Y </code> year as decimal including century (range 0000 to 9999) <br>
|
||||
* <code>%m </code> month as decimal number (range 01 to 12) <br>
|
||||
* <code>%d </code> day of month (range 00 to 31) <br>
|
||||
* <code>%H </code> hour as decimal number (00 to 23) <br>
|
||||
* <code>%M </code> minute as a decimal number (00 to 59) <br>
|
||||
* <code>%S </code> seconds as a decimal number (00 to 59) <br>
|
||||
* <code>%% </code> literal '%' <br>
|
||||
* <br>
|
||||
*
|
||||
* @access public
|
||||
* @param string format the format string for returned date/time
|
||||
* @return string date/time in given format
|
||||
*/
|
||||
function format($format)
|
||||
{
|
||||
$output = "";
|
||||
|
||||
for($strpos = 0; $strpos < strlen($format); $strpos++) {
|
||||
$char = substr($format,$strpos,1);
|
||||
if ($char == "%") {
|
||||
$nextchar = substr($format,$strpos + 1,1);
|
||||
switch ($nextchar) {
|
||||
case "Y":
|
||||
$output .= $this->year;
|
||||
break;
|
||||
case "m":
|
||||
$output .= sprintf("%02d",$this->month);
|
||||
break;
|
||||
case "d":
|
||||
$output .= sprintf("%02d",$this->day);
|
||||
break;
|
||||
case "H":
|
||||
$output .= sprintf("%02d", $this->hour);
|
||||
break;
|
||||
case "M":
|
||||
$output .= sprintf("%02d",$this->minute);
|
||||
break;
|
||||
case "S":
|
||||
$output .= sprintf("%02d", $this->second);
|
||||
break;
|
||||
default:
|
||||
$output .= $char.$nextchar;
|
||||
}
|
||||
$strpos++;
|
||||
} else {
|
||||
$output .= $char;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
1332
sites/all/modules/civicrm/packages/DB/Table/Generator.php
Normal file
1332
sites/all/modules/civicrm/packages/DB/Table/Generator.php
Normal file
File diff suppressed because it is too large
Load diff
2349
sites/all/modules/civicrm/packages/DB/Table/Manager.php
Normal file
2349
sites/all/modules/civicrm/packages/DB/Table/Manager.php
Normal file
File diff suppressed because it is too large
Load diff
443
sites/all/modules/civicrm/packages/DB/Table/Manager/mysql.php
Normal file
443
sites/all/modules/civicrm/packages/DB/Table/Manager/mysql.php
Normal file
|
@ -0,0 +1,443 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Lukas Smith <smith@pooteeweet.org>
|
||||
* Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: mysql.php,v 1.5 2007/12/13 16:52:15 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* require DB_Table class
|
||||
*/
|
||||
require_once 'DB/Table.php';
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
class DB_Table_Manager_mysql {
|
||||
|
||||
/**
|
||||
*
|
||||
* The PEAR DB object that connects to the database.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var object
|
||||
*
|
||||
*/
|
||||
|
||||
var $_db = null;
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$key_name = 'Key_name';
|
||||
$non_unique = 'Non_unique';
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes = $this->_db->getAll($query, null, DB_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($indexes)) {
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($indexes as $index_data) {
|
||||
if ($index_data[$non_unique]) {
|
||||
$result[$index_data[$key_name]] = true;
|
||||
}
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableConstraints($table)
|
||||
{
|
||||
$key_name = 'Key_name';
|
||||
$non_unique = 'Non_unique';
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes = $this->_db->getAll($query, null, DB_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 = $index_data[$key_name];
|
||||
} else {
|
||||
$index = 'PRIMARY';
|
||||
}
|
||||
$result[$index] = true;
|
||||
}
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$result = $this->_db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(DB_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
$key_name = strtolower($key_name);
|
||||
|
||||
if ($index_name == $key_name) {
|
||||
$column_name = $row['column_name'];
|
||||
$column_name = strtolower($column_name);
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result->free();
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table, $index_name)
|
||||
{
|
||||
$result = $this->_db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(DB_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
$key_name = strtolower($key_name);
|
||||
|
||||
if ($index_name == $key_name) {
|
||||
if ($row['key_name'] == 'PRIMARY') {
|
||||
$definition['primary'] = true;
|
||||
} else {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
$column_name = strtolower($column_name);
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result->free();
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("DROP INDEX $name ON $table");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropConstraint($table, $name)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
if (strtolower($name) == 'primary') {
|
||||
$query = "ALTER TABLE $table DROP PRIMARY KEY";
|
||||
} else {
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
$query = "ALTER TABLE $table DROP INDEX $name";
|
||||
}
|
||||
return $this->_db->query($query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 (ignored in DB_Table)
|
||||
* @access public
|
||||
*
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
return DB_Table::throwError(DB_TABLE_ERR_ALTER_TABLE_IMPOS);
|
||||
}
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if (array_key_exists('name', $changes)) {
|
||||
$change_name = $this->_db->quoteIdentifier($changes['name']);
|
||||
$query .= 'RENAME TO ' . $change_name;
|
||||
}
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $field_name . ' ' . $field;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$field_name = $this->_db->quoteIdentifier($field_name);
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$rename[$field['name']] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$field_name])) {
|
||||
$old_field_name = $rename[$field_name];
|
||||
unset($rename[$field_name]);
|
||||
} else {
|
||||
$old_field_name = $field_name;
|
||||
}
|
||||
$old_field_name = $this->_db->quoteIdentifier($old_field_name);
|
||||
$query.= "CHANGE $old_field_name " . $field_name . ' ' . $field['definition'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rename)) {
|
||||
foreach ($rename as $rename_name => $renamed_field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$field = $changes['rename'][$renamed_field];
|
||||
$renamed_field = $this->_db->quoteIdentifier($renamed_field);
|
||||
$query.= 'CHANGE ' . $renamed_field . ' ' . $field['name'] . ' ' . $renamed_field['definition'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
440
sites/all/modules/civicrm/packages/DB/Table/Manager/mysqli.php
Normal file
440
sites/all/modules/civicrm/packages/DB/Table/Manager/mysqli.php
Normal file
|
@ -0,0 +1,440 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Lukas Smith <smith@pooteeweet.org>
|
||||
* Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: mysqli.php,v 1.6 2007/12/13 16:52:15 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* require DB_Table class
|
||||
*/
|
||||
require_once 'DB/Table.php';
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
class DB_Table_Manager_mysqli {
|
||||
|
||||
/**
|
||||
*
|
||||
* The PEAR DB object that connects to the database.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var object
|
||||
*
|
||||
*/
|
||||
|
||||
var $_db = null;
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$key_name = 'Key_name';
|
||||
$non_unique = 'Non_unique';
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes = $this->_db->getAll($query, null, DB_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($indexes)) {
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($indexes as $index_data) {
|
||||
if ($index_data[$non_unique]) {
|
||||
$result[$index_data[$key_name]] = true;
|
||||
}
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableConstraints($table)
|
||||
{
|
||||
$key_name = 'Key_name';
|
||||
$non_unique = 'Non_unique';
|
||||
|
||||
$query = "SHOW INDEX FROM $table";
|
||||
$indexes = $this->_db->getAll($query, null, DB_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 = $index_data[$key_name];
|
||||
} else {
|
||||
$index = 'PRIMARY';
|
||||
}
|
||||
$result[$index] = true;
|
||||
}
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$result = $this->_db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(DB_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
$key_name = strtolower($key_name);
|
||||
if ($index_name == $key_name) {
|
||||
$column_name = $row['column_name'];
|
||||
$column_name = strtolower($column_name);
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result->free();
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table, $index_name)
|
||||
{
|
||||
$result = $this->_db->query("SHOW INDEX FROM $table");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(DB_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
$key_name = strtolower($key_name);
|
||||
if ($index_name == $key_name) {
|
||||
if ($row['key_name'] == 'PRIMARY') {
|
||||
$definition['primary'] = true;
|
||||
} else {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
$column_name = strtolower($column_name);
|
||||
$definition['fields'][$column_name] = array();
|
||||
if (array_key_exists('collation', $row)) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result->free();
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("DROP INDEX $name ON $table");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropConstraint($table, $name)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
if (strtolower($name) == 'primary') {
|
||||
$query = "ALTER TABLE $table DROP PRIMARY KEY";
|
||||
} else {
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
$query = "ALTER TABLE $table DROP INDEX $name";
|
||||
}
|
||||
return $this->_db->query($query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 (ignored in DB_Table)
|
||||
* @access public
|
||||
*
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
return DB_Table::throwError(DB_TABLE_ERR_ALTER_TABLE_IMPOS);
|
||||
}
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if (array_key_exists('name', $changes)) {
|
||||
$change_name = $this->_db->quoteIdentifier($changes['name']);
|
||||
$query .= 'RENAME TO ' . $change_name;
|
||||
}
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $field_name . ' ' . $field;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$field_name = $db->quoteIdentifier($field_name);
|
||||
$query.= 'DROP ' . $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$rename[$field['name']] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$field_name])) {
|
||||
$old_field_name = $rename[$field_name];
|
||||
unset($rename[$field_name]);
|
||||
} else {
|
||||
$old_field_name = $field_name;
|
||||
}
|
||||
$old_field_name = $this->_db->quoteIdentifier($old_field_name);
|
||||
$query.= "CHANGE $old_field_name " . $field_name . ' ' . $field['definition'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rename)) {
|
||||
foreach ($rename as $rename_name => $renamed_field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$field = $changes['rename'][$renamed_field];
|
||||
$renamed_field = $this->_db->quoteIdentifier($renamed_field);
|
||||
$query.= 'CHANGE ' . $renamed_field . ' ' . $field['name'] . ' ' . $renamed_field['definition'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("ALTER TABLE $name $query");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
440
sites/all/modules/civicrm/packages/DB/Table/Manager/pgsql.php
Normal file
440
sites/all/modules/civicrm/packages/DB/Table/Manager/pgsql.php
Normal file
|
@ -0,0 +1,440 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Paul Cooper <pgc@ucecom.com>
|
||||
* Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: pgsql.php,v 1.5 2007/12/13 16:52:15 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* require DB_Table class
|
||||
*/
|
||||
require_once 'DB/Table.php';
|
||||
|
||||
/**
|
||||
* Index, constraint and alter methods for DB_Table usage with
|
||||
* PEAR::DB as backend.
|
||||
*
|
||||
* The code in this class was adopted from the MDB2 PEAR package.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
class DB_Table_Manager_pgsql {
|
||||
|
||||
/**
|
||||
*
|
||||
* The PEAR DB object that connects to the database.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var object
|
||||
*
|
||||
*/
|
||||
|
||||
var $_db = null;
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$subquery = "SELECT indexrelid FROM pg_index, pg_class";
|
||||
$subquery.= " WHERE pg_class.relname='$table' AND pg_class.oid=pg_index.indrelid AND indisunique != 't' AND indisprimary != 't'";
|
||||
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
|
||||
$indexes = $this->_db->getCol($query);
|
||||
if (PEAR::isError($indexes)) {
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($indexes as $index) {
|
||||
$result[$index] = true;
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableConstraints($table)
|
||||
{
|
||||
$subquery = "SELECT indexrelid FROM pg_index, pg_class";
|
||||
$subquery.= " WHERE pg_class.relname='$table' AND pg_class.oid=pg_index.indrelid AND (indisunique = 't' OR indisprimary = 't')";
|
||||
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
|
||||
$constraints = $this->_db->getCol($query);
|
||||
if (PEAR::isError($constraints)) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($constraints as $constraint) {
|
||||
$result[$constraint] = true;
|
||||
}
|
||||
$result = array_change_key_case($result, CASE_LOWER);
|
||||
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index_name)
|
||||
{
|
||||
$query = "SELECT relname, indkey FROM pg_index, pg_class
|
||||
WHERE pg_class.relname = ".$this->_db->quoteSmart($index_name)." AND pg_class.oid = pg_index.indexrelid
|
||||
AND indisunique != 't' AND indisprimary != 't'";
|
||||
$row = $this->_db->getRow($query, null, DB_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
$columns = $this->_listTableFields($table);
|
||||
|
||||
$definition = array();
|
||||
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array('sorting' => 'ascending');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the structure 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 PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table, $index_name)
|
||||
{
|
||||
$query = "SELECT relname, indisunique, indisprimary, indkey FROM pg_index, pg_class
|
||||
WHERE pg_class.relname = ".$this->_db->quoteSmart($index_name)." AND pg_class.oid = pg_index.indexrelid
|
||||
AND (indisunique = 't' OR indisprimary = 't')";
|
||||
$row = $this->_db->getRow($query, null, DB_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
$columns = $this->_listTableFields($table);
|
||||
|
||||
$definition = array();
|
||||
if ($row['indisprimary'] == 't') {
|
||||
$definition['primary'] = true;
|
||||
} elseif ($row['indisunique'] == 't') {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array('sorting' => 'ascending');
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 PEAR error on failure
|
||||
* @access private
|
||||
*/
|
||||
function _listTableFields($table)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
$result2 = $this->_db->query("SELECT * FROM $table");
|
||||
if (PEAR::isError($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
$columns = array();
|
||||
$numcols = $result2->numCols();
|
||||
for ($column = 0; $column < $numcols; $column++) {
|
||||
$column_name = @pg_field_name($result2->result, $column);
|
||||
$columns[$column_name] = $column;
|
||||
}
|
||||
$result2->free();
|
||||
return array_flip($columns);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropIndex($table, $name)
|
||||
{
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("DROP INDEX $name");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropConstraint($table, $name)
|
||||
{
|
||||
$table = $this->_db->quoteIdentifier($table);
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
return $this->_db->query("ALTER TABLE $table DROP CONSTRAINT $name");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 (ignored in DB_Table)
|
||||
* @access public
|
||||
*
|
||||
* @return mixed DB_OK on success, a PEAR error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'name':
|
||||
case 'rename':
|
||||
break;
|
||||
default:
|
||||
return DB_Table::throwError(DB_TABLE_ERR_ALTER_TABLE_IMPOS);
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('add', $changes)) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$query = 'ADD ' . $field_name . ' ' . $field;
|
||||
$result = $this->_db->query("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('remove', $changes)) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
$field_name = $this->_db->quoteIdentifier($field_name);
|
||||
$query = 'DROP ' . $field_name;
|
||||
$result = $this->_db->query("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('change', $changes)) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
$field_name = $this->_db->quoteIdentifier($field_name);
|
||||
if (array_key_exists('type', $field)) {
|
||||
$query = "ALTER $field_name TYPE " . $field['definition'];
|
||||
$result = $this->_db->query("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
/* default / notnull changes not (yet) supported in DB_Table
|
||||
if (array_key_exists('default', $field)) {
|
||||
$query = "ALTER $field_name SET DEFAULT ".$db->quote($field['definition']['default'], $field['definition']['type']);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('notnull', $field)) {
|
||||
$query.= "ALTER $field_name ".($field['definition']['notnull'] ? "SET" : "DROP").' NOT NULL';
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('rename', $changes)) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$field_name = $this->_db->quoteIdentifier($field_name);
|
||||
$result = $this->_db->query("ALTER TABLE $name RENAME COLUMN $field_name TO ".$this->_db->quoteIdentifier($field['name']));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$name = $this->_db->quoteIdentifier($name);
|
||||
if (array_key_exists('name', $changes)) {
|
||||
$change_name = $this->_db->quoteIdentifier($changes['name']);
|
||||
$result = $this->_db->query("ALTER TABLE $name RENAME TO ".$change_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
1173
sites/all/modules/civicrm/packages/DB/Table/QuickForm.php
Normal file
1173
sites/all/modules/civicrm/packages/DB/Table/QuickForm.php
Normal file
File diff suppressed because it is too large
Load diff
454
sites/all/modules/civicrm/packages/DB/Table/Valid.php
Normal file
454
sites/all/modules/civicrm/packages/DB/Table/Valid.php
Normal file
|
@ -0,0 +1,454 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* DB_Table_Valid validates values against DB_Table column types.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul M. Jones <pmjones@php.net>
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Valid.php,v 1.10 2007/12/13 16:52:15 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* DB_Table class for constants and other globals.
|
||||
*/
|
||||
require_once 'DB/Table.php';
|
||||
|
||||
|
||||
/**
|
||||
* validation ranges for integers
|
||||
*/
|
||||
if (! isset($GLOBALS['_DB_TABLE']['valid'])) {
|
||||
$GLOBALS['_DB_TABLE']['valid'] = array(
|
||||
'smallint' => array(pow(-2, 15), pow(+2, 15) - 1),
|
||||
'integer' => array(pow(-2, 31), pow(+2, 31) - 1),
|
||||
'bigint' => array(pow(-2, 63), pow(+2, 63) - 1)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DB_Table_Valid validates values against DB_Table column types.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author Paul M. Jones <pmjones@php.net>
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @author Mark Wiesemann <wiesemann@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
class DB_Table_Valid {
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'boolean' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isBoolean($value)
|
||||
{
|
||||
if ($value === true || $value === false) {
|
||||
return true;
|
||||
} elseif (is_numeric($value) && ($value == 0 || $value == 1)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'char' and 'varchar' data type.
|
||||
*
|
||||
* We allow most anything here, only checking that the length is in range.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isChar($value, $colsize)
|
||||
{
|
||||
$is_scalar = (! is_array($value) && ! is_object($value));
|
||||
$in_range = (strlen($value) <= $colsize);
|
||||
return $is_scalar && $in_range;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'smallint' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isSmallint($value)
|
||||
{
|
||||
return is_integer($value) &&
|
||||
($value >= $GLOBALS['_DB_TABLE']['valid']['smallint'][0]) &&
|
||||
($value <= $GLOBALS['_DB_TABLE']['valid']['smallint'][1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'integer' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isInteger($value)
|
||||
{
|
||||
return is_integer($value) &&
|
||||
($value >= $GLOBALS['_DB_TABLE']['valid']['integer'][0]) &&
|
||||
($value <= $GLOBALS['_DB_TABLE']['valid']['integer'][1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'bigint' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isBigint($value)
|
||||
{
|
||||
return is_integer($value) &&
|
||||
($value >= $GLOBALS['_DB_TABLE']['valid']['bigint'][0]) &&
|
||||
($value <= $GLOBALS['_DB_TABLE']['valid']['bigint'][1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'decimal' data type.
|
||||
*
|
||||
* For the column defined "DECIMAL(5,2)" standard SQL requires that
|
||||
* the column be able to store any value with 5 digits and 2
|
||||
* decimals. In this case, therefore, the range of values that can be
|
||||
* stored in the column is from -999.99 to 999.99. DB_Table attempts
|
||||
* to enforce this behavior regardless of the RDBMS backend behavior.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @param string $colsize The 'size' to use for validation (to make
|
||||
* sure of min/max and decimal places).
|
||||
*
|
||||
* @param string $colscope The 'scope' to use for validation (to make
|
||||
* sure of min/max and decimal places).
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isDecimal($value, $colsize, $colscope)
|
||||
{
|
||||
if (! is_numeric($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// maximum number of digits allowed to the left
|
||||
// and right of the decimal point.
|
||||
$right_max = $colscope;
|
||||
$left_max = $colsize - $colscope;
|
||||
|
||||
// ignore negative signs in all validation
|
||||
$value = str_replace('-', '', $value);
|
||||
|
||||
// find the decimal point, then get the left
|
||||
// and right portions.
|
||||
$pos = strpos($value, '.');
|
||||
if ($pos === false) {
|
||||
$left = $value;
|
||||
$right = '';
|
||||
} else {
|
||||
$left = substr($value, 0, $pos);
|
||||
$right = substr($value, $pos+1);
|
||||
}
|
||||
|
||||
// how long are the left and right portions?
|
||||
$left_len = strlen($left);
|
||||
$right_len = strlen($right);
|
||||
|
||||
// do the portions exceed their maxes?
|
||||
if ($left_len > $left_max ||
|
||||
$right_len > $right_max) {
|
||||
// one or the other exceeds the max lengths
|
||||
return false;
|
||||
} else {
|
||||
// both are within parameters
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'single' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isSingle($value)
|
||||
{
|
||||
return is_float($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'double' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isDouble($value)
|
||||
{
|
||||
return is_float($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'time' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isTime($value)
|
||||
{
|
||||
// hh:ii:ss
|
||||
// 01234567
|
||||
$h = substr($value, 0, 2);
|
||||
$s1 = substr($value, 2, 1);
|
||||
$i = substr($value, 3, 2);
|
||||
$s2 = substr($value, 5, 1);
|
||||
$s = substr($value, 6, 2);
|
||||
|
||||
// time check
|
||||
if (strlen($value) != 8 ||
|
||||
! is_numeric($h) || $h < 0 || $h > 23 ||
|
||||
$s1 != ':' ||
|
||||
! is_numeric($i) || $i < 0 || $i > 59 ||
|
||||
$s2 != ':' ||
|
||||
! is_numeric($s) || $s < 0 || $s > 59) {
|
||||
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'date' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isDate($value)
|
||||
{
|
||||
// yyyy-mm-dd
|
||||
// 0123456789
|
||||
$y = substr($value, 0, 4);
|
||||
$s1 = substr($value, 4, 1);
|
||||
$m = substr($value, 5, 2);
|
||||
$s2 = substr($value, 7, 1);
|
||||
$d = substr($value, 8, 2);
|
||||
|
||||
// date check
|
||||
if (strlen($value) != 10 || $s1 != '-' || $s2 != '-' ||
|
||||
! checkdate($m, $d, $y)) {
|
||||
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'timestamp' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isTimestamp($value)
|
||||
{
|
||||
// yyyy-mm-dd hh:ii:ss
|
||||
// 0123456789012345678
|
||||
$date = substr($value, 0, 10);
|
||||
$sep = substr($value, 10, 1);
|
||||
$time = substr($value, 11, 8);
|
||||
|
||||
if (strlen($value) != 19 || $sep != ' ' ||
|
||||
! DB_Table_Valid::isDate($date) ||
|
||||
! DB_Table_Valid::isTime($time)) {
|
||||
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a value validates against the 'clob' data type.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $value The value to validate.
|
||||
*
|
||||
* @return boolean True if the value is valid for the data type, false
|
||||
* if not.
|
||||
*
|
||||
*/
|
||||
|
||||
function isClob($value)
|
||||
{
|
||||
return is_string($value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
111
sites/all/modules/civicrm/packages/DB/Table/XML.php
Normal file
111
sites/all/modules/civicrm/packages/DB/Table/XML.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* A few simple static methods for writing XML
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 1997-2007, Paul M. Jones <pmjones@php.net>
|
||||
* David C. Morse <morse@php.net>
|
||||
* Mark Wiesemann <wiesemann@php.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* * The names of the authors may not 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 COPYRIGHT OWNER 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.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: XML.php,v 1.2 2007/12/13 16:52:15 wiesemann Exp $
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class DB_Table_XML contains a few simple static methods for writing XML
|
||||
*
|
||||
* @category Database
|
||||
* @package DB_Table
|
||||
* @author David C. Morse <morse@php.net>
|
||||
* @version Release: 1.5.6
|
||||
* @link http://pear.php.net/package/DB_Table
|
||||
*/
|
||||
|
||||
class DB_Table_XML
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns XML closing tag <tag>, increases $indent by 3 spaces
|
||||
*
|
||||
* @static
|
||||
* @param string $tag XML element tag name
|
||||
* @param string $indent current indentation, string of spaces
|
||||
* @return string XML opening tag
|
||||
* @access public
|
||||
*/
|
||||
function openTag($tag, &$indent)
|
||||
{
|
||||
$old_indent = $indent;
|
||||
$indent = $indent . ' ';
|
||||
return $old_indent . "<$tag>";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns XML closing tag </tag>, decreases $indent by 3 spaces
|
||||
*
|
||||
* @static
|
||||
* @param string $tag XML element tag name
|
||||
* @param string $indent current indentation, string of spaces
|
||||
* @return string XML closing tag
|
||||
* @access public
|
||||
*/
|
||||
function closeTag($tag, &$indent)
|
||||
{
|
||||
$indent = substr($indent, 0, -3);
|
||||
return $indent . "</$tag>";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns string single line XML element <tag>text</tag>
|
||||
*
|
||||
* @static
|
||||
* @param string $tag XML element tag name
|
||||
* @param string $text element contents
|
||||
* @param string $indent current indentation, string of spaces
|
||||
* @return string single-line XML element
|
||||
* @access public
|
||||
*/
|
||||
function lineElement($tag, $text, $indent)
|
||||
{
|
||||
return $indent . "<$tag>$text</$tag>";
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
2262
sites/all/modules/civicrm/packages/DB/common.php
Normal file
2262
sites/all/modules/civicrm/packages/DB/common.php
Normal file
File diff suppressed because it is too large
Load diff
510
sites/all/modules/civicrm/packages/DB/dbase.php
Normal file
510
sites/all/modules/civicrm/packages/DB/dbase.php
Normal file
|
@ -0,0 +1,510 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's dbase extension
|
||||
* for interacting with dBase databases
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: dbase.php,v 1.45 2007/09/21 13:40:41 aharvey Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's dbase extension
|
||||
* for interacting with dBase databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 1.7.13
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_dbase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'dbase';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'dbase';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => false,
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => false,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* A means of emulating result resources
|
||||
* @var array
|
||||
*/
|
||||
var $res_row = array();
|
||||
|
||||
/**
|
||||
* The quantity of results so far
|
||||
*
|
||||
* For emulating result resources.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $result = 0;
|
||||
|
||||
/**
|
||||
* Maps dbase data type id's to human readable strings
|
||||
*
|
||||
* The human readable values are based on the output of PHP's
|
||||
* dbase_get_header_info() function.
|
||||
*
|
||||
* @var array
|
||||
* @since Property available since Release 1.7.0
|
||||
*/
|
||||
var $types = array(
|
||||
'C' => 'character',
|
||||
'D' => 'date',
|
||||
'L' => 'boolean',
|
||||
'M' => 'memo',
|
||||
'N' => 'number',
|
||||
);
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database and create it if it doesn't exist
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's dbase driver supports the following extra DSN options:
|
||||
* + mode An integer specifying the read/write mode to use
|
||||
* (0 = read only, 1 = write only, 2 = read/write).
|
||||
* Available since PEAR DB 1.7.0.
|
||||
* + fields An array of arrays that PHP's dbase_create() function needs
|
||||
* to create a new database. This information is used if the
|
||||
* dBase file specified in the "database" segment of the DSN
|
||||
* does not exist. For more info, see the PHP manual's
|
||||
* {@link http://php.net/dbase_create dbase_create()} page.
|
||||
* Available since PEAR DB 1.7.0.
|
||||
*
|
||||
* Example of how to connect and establish a new dBase file if necessary:
|
||||
* <code>
|
||||
* require_once 'DB.php';
|
||||
*
|
||||
* $dsn = array(
|
||||
* 'phptype' => 'dbase',
|
||||
* 'database' => '/path/and/name/of/dbase/file',
|
||||
* 'mode' => 2,
|
||||
* 'fields' => array(
|
||||
* array('a', 'N', 5, 0),
|
||||
* array('b', 'C', 40),
|
||||
* array('c', 'C', 255),
|
||||
* array('d', 'C', 20),
|
||||
* ),
|
||||
* );
|
||||
* $options = array(
|
||||
* 'debug' => 2,
|
||||
* 'portability' => DB_PORTABILITY_ALL,
|
||||
* );
|
||||
*
|
||||
* $db = DB::connect($dsn, $options);
|
||||
* if (PEAR::isError($db)) {
|
||||
* die($db->getMessage());
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('dbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn track_errors on for entire script since $php_errormsg
|
||||
* is the only way to find errors from the dbase extension.
|
||||
*/
|
||||
@ini_set('track_errors', 1);
|
||||
$php_errormsg = '';
|
||||
|
||||
if (!file_exists($dsn['database'])) {
|
||||
$this->dsn['mode'] = 2;
|
||||
if (empty($dsn['fields']) || !is_array($dsn['fields'])) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
'the dbase file does not exist and '
|
||||
. 'it could not be created because '
|
||||
. 'the "fields" element of the DSN '
|
||||
. 'is not properly set');
|
||||
}
|
||||
$this->connection = @dbase_create($dsn['database'],
|
||||
$dsn['fields']);
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
'the dbase file does not exist and '
|
||||
. 'the attempt to create it failed: '
|
||||
. $php_errormsg);
|
||||
}
|
||||
} else {
|
||||
if (!isset($this->dsn['mode'])) {
|
||||
$this->dsn['mode'] = 0;
|
||||
}
|
||||
$this->connection = @dbase_open($dsn['database'],
|
||||
$this->dsn['mode']);
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @dbase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &query()
|
||||
|
||||
function &query($query = null)
|
||||
{
|
||||
// emulate result resources
|
||||
$this->res_row[(int)$this->result] = 0;
|
||||
$tmp = new DB_result($this, $this->result++);
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum === null) {
|
||||
$rownum = $this->res_row[(int)$result]++;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @dbase_get_record_with_names($this->connection, $rownum);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @dbase_get_record($this->connection, $rownum);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set.
|
||||
*
|
||||
* This method is a no-op for dbase, as there aren't result resources in
|
||||
* the same sense as most other database backends.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($foo)
|
||||
{
|
||||
return @dbase_numfields($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($foo)
|
||||
{
|
||||
return @dbase_numrecords($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteBoolean()
|
||||
|
||||
/**
|
||||
* Formats a boolean value for use within a query in a locale-independent
|
||||
* manner.
|
||||
*
|
||||
* @param boolean the boolean value to be quoted.
|
||||
* @return string the quoted string.
|
||||
* @see DB_common::quoteSmart()
|
||||
* @since Method available since release 1.7.8.
|
||||
*/
|
||||
function quoteBoolean($boolean) {
|
||||
return $boolean ? 'T' : 'F';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about the current database
|
||||
*
|
||||
* @param mixed $result THIS IS UNUSED IN DBASE. The current database
|
||||
* is examined regardless of what is provided here.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result = null, $mode = null)
|
||||
{
|
||||
if (function_exists('dbase_get_header_info')) {
|
||||
$id = @dbase_get_header_info($this->connection);
|
||||
if (!$id && $php_errormsg) {
|
||||
return $this->raiseError(DB_ERROR,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This segment for PHP 4 is loosely based on code by
|
||||
* Hadi Rusiah <deegos@yahoo.com> in the comments on
|
||||
* the dBase reference page in the PHP manual.
|
||||
*/
|
||||
$db = @fopen($this->dsn['database'], 'r');
|
||||
if (!$db) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$php_errormsg);
|
||||
}
|
||||
|
||||
$id = array();
|
||||
$i = 0;
|
||||
|
||||
$line = fread($db, 32);
|
||||
while (!feof($db)) {
|
||||
$line = fread($db, 32);
|
||||
if (substr($line, 0, 1) == chr(13)) {
|
||||
break;
|
||||
} else {
|
||||
$pos = strpos(substr($line, 0, 10), chr(0));
|
||||
$pos = ($pos == 0 ? 10 : $pos);
|
||||
$id[$i] = array(
|
||||
'name' => substr($line, 0, $pos),
|
||||
'type' => $this->types[substr($line, 11, 1)],
|
||||
'length' => ord(substr($line, 16, 1)),
|
||||
'precision' => ord(substr($line, 17, 1)),
|
||||
);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
fclose($db);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$res = array();
|
||||
$count = count($id);
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $this->dsn['database'],
|
||||
'name' => $case_func($id[$i]['name']),
|
||||
'type' => $id[$i]['type'],
|
||||
'len' => $id[$i]['length'],
|
||||
'flags' => ''
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
963
sites/all/modules/civicrm/packages/DB/mssql.php
Normal file
963
sites/all/modules/civicrm/packages/DB/mssql.php
Normal file
|
@ -0,0 +1,963 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's mssql extension
|
||||
* for interacting with Microsoft SQL Server databases
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: mssql.php,v 1.92 2007/09/21 13:40:41 aharvey Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's mssql extension
|
||||
* for interacting with Microsoft SQL Server databases
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* DB's mssql driver is only for Microsfoft SQL Server databases.
|
||||
*
|
||||
* If you're connecting to a Sybase database, you MUST specify "sybase"
|
||||
* as the "phptype" in the DSN.
|
||||
*
|
||||
* This class only works correctly if you have compiled PHP using
|
||||
* --with-mssql=[dir_to_FreeTDS].
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 1.7.13
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_mssql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'mssql';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'mssql';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
|
||||
var $errorcode_map = array(
|
||||
102 => DB_ERROR_SYNTAX,
|
||||
110 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
155 => DB_ERROR_NOSUCHFIELD,
|
||||
156 => DB_ERROR_SYNTAX,
|
||||
170 => DB_ERROR_SYNTAX,
|
||||
207 => DB_ERROR_NOSUCHFIELD,
|
||||
208 => DB_ERROR_NOSUCHTABLE,
|
||||
245 => DB_ERROR_INVALID_NUMBER,
|
||||
319 => DB_ERROR_SYNTAX,
|
||||
321 => DB_ERROR_NOSUCHFIELD,
|
||||
325 => DB_ERROR_SYNTAX,
|
||||
336 => DB_ERROR_SYNTAX,
|
||||
515 => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
547 => DB_ERROR_CONSTRAINT,
|
||||
1018 => DB_ERROR_SYNTAX,
|
||||
1035 => DB_ERROR_SYNTAX,
|
||||
1913 => DB_ERROR_ALREADY_EXISTS,
|
||||
2209 => DB_ERROR_SYNTAX,
|
||||
2223 => DB_ERROR_SYNTAX,
|
||||
2248 => DB_ERROR_SYNTAX,
|
||||
2256 => DB_ERROR_SYNTAX,
|
||||
2257 => DB_ERROR_SYNTAX,
|
||||
2627 => DB_ERROR_CONSTRAINT,
|
||||
2714 => DB_ERROR_ALREADY_EXISTS,
|
||||
3607 => DB_ERROR_DIVZERO,
|
||||
3701 => DB_ERROR_NOSUCHTABLE,
|
||||
7630 => DB_ERROR_SYNTAX,
|
||||
8134 => DB_ERROR_DIVZERO,
|
||||
9303 => DB_ERROR_SYNTAX,
|
||||
9317 => DB_ERROR_SYNTAX,
|
||||
9318 => DB_ERROR_SYNTAX,
|
||||
9331 => DB_ERROR_SYNTAX,
|
||||
9332 => DB_ERROR_SYNTAX,
|
||||
15253 => DB_ERROR_SYNTAX,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* Should data manipulation queries be committed automatically?
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $autocommit = true;
|
||||
|
||||
/**
|
||||
* The quantity of transactions begun
|
||||
*
|
||||
* {@internal While this is private, it can't actually be designated
|
||||
* private in PHP 5 because it is directly accessed in the test suite.}}
|
||||
*
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $transaction_opcount = 0;
|
||||
|
||||
/**
|
||||
* The database specified in the DSN
|
||||
*
|
||||
* It's a fix to allow calls to different databases in the same script.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_db = null;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('mssql') && !PEAR::loadExtension('sybase')
|
||||
&& !PEAR::loadExtension('sybase_ct'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
|
||||
$params = array(
|
||||
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost',
|
||||
$dsn['username'] ? $dsn['username'] : null,
|
||||
$dsn['password'] ? $dsn['password'] : null,
|
||||
);
|
||||
if ($dsn['port']) {
|
||||
$params[0] .= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':')
|
||||
. $dsn['port'];
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
$this->connection = @call_user_func_array($connect_function, $params);
|
||||
|
||||
if (!$this->connection) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
@mssql_get_last_message());
|
||||
}
|
||||
if ($dsn['database']) {
|
||||
if (!@mssql_select_db($dsn['database'], $this->connection)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED,
|
||||
null, null, null,
|
||||
@mssql_get_last_message());
|
||||
}
|
||||
$this->_db = $dsn['database'];
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @mssql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = $this->_checkManip($query);
|
||||
$this->last_query = $query;
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$query = $this->modifyQuery($query);
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @mssql_query('BEGIN TRAN', $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @mssql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return $ismanip ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal mssql result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return @mssql_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@mssql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @mssql_fetch_assoc($result);
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$arr = @mssql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
return null;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return is_resource($result) ? mssql_free_result($result) : false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mssql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mssql_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
// XXX if $this->transaction_opcount > 0, we should probably
|
||||
// issue a warning here.
|
||||
$this->autocommit = $onoff ? true : false;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mssql_query('COMMIT TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mssql_query('ROLLBACK TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if ($this->_last_query_manip) {
|
||||
$res = @mssql_query('select @@rowcount', $this->connection);
|
||||
if (!$res) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
$ar = @mssql_fetch_row($res);
|
||||
if (!$ar) {
|
||||
$result = 0;
|
||||
} else {
|
||||
@mssql_free_result($res);
|
||||
$result = $ar[0];
|
||||
}
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_mssql::createSequence(), DB_mssql::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
|
||||
{
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} elseif (!DB::isError($result)) {
|
||||
$result = $this->query("SELECT IDENT_CURRENT('$seqname')");
|
||||
if (DB::isError($result)) {
|
||||
/* Fallback code for MS SQL Server 7.0, which doesn't have
|
||||
* IDENT_CURRENT. This is *not* safe for concurrent
|
||||
* requests, and really, if you're using it, you're in a
|
||||
* world of hurt. Nevertheless, it's here to ensure BC. See
|
||||
* bug #181 for the gory details.*/
|
||||
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
|
||||
}
|
||||
$repeat = 0;
|
||||
} else {
|
||||
$repeat = false;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_mssql::nextID(), DB_mssql::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
return $this->query('CREATE TABLE '
|
||||
. $this->getSequenceName($seq_name)
|
||||
. ' ([id] [int] IDENTITY (1, 1) NOT NULL,'
|
||||
. ' [vapor] [int] NULL)');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_mssql::nextID(), DB_mssql::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used as a table or column name
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @see DB_common::quoteIdentifier()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
return '[' . str_replace(']', ']]', $str) . ']';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mssqlRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_mssql::errorNative(), DB_mssql::errorCode()
|
||||
*/
|
||||
function mssqlRaiseError($code = null)
|
||||
{
|
||||
$message = @mssql_get_last_message();
|
||||
if (!$code) {
|
||||
$code = $this->errorNative();
|
||||
}
|
||||
return $this->raiseError($this->errorCode($code, $message),
|
||||
null, null, null, "$code - $message");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code produced by the last query
|
||||
*
|
||||
* @return int the DBMS' error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
|
||||
if (!$res) {
|
||||
return DB_ERROR;
|
||||
}
|
||||
$row = @mssql_fetch_row($res);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Determines PEAR::DB error code from mssql's native codes.
|
||||
*
|
||||
* If <var>$nativecode</var> isn't known yet, it will be looked up.
|
||||
*
|
||||
* @param mixed $nativecode mssql error code, if known
|
||||
* @return integer an error number from a DB error constant
|
||||
* @see errorNative()
|
||||
*/
|
||||
function errorCode($nativecode = null, $msg = '')
|
||||
{
|
||||
if (!$nativecode) {
|
||||
$nativecode = $this->errorNative();
|
||||
}
|
||||
if (isset($this->errorcode_map[$nativecode])) {
|
||||
if ($nativecode == 3701
|
||||
&& preg_match('/Cannot drop the index/i', $msg))
|
||||
{
|
||||
return DB_ERROR_NOT_FOUND;
|
||||
}
|
||||
return $this->errorcode_map[$nativecode];
|
||||
} else {
|
||||
return DB_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ 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 DB_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 DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
if (!@mssql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$id = @mssql_query("SELECT * FROM $result WHERE 1=0",
|
||||
$this->connection);
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$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 $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mssql_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if ($got_string) {
|
||||
$flags = $this->_mssql_field_flags($result,
|
||||
@mssql_field_name($id, $i));
|
||||
if (DB::isError($flags)) {
|
||||
return $flags;
|
||||
}
|
||||
} else {
|
||||
$flags = '';
|
||||
}
|
||||
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@mssql_field_name($id, $i)),
|
||||
'type' => @mssql_field_type($id, $i),
|
||||
'len' => @mssql_field_length($id, $i),
|
||||
'flags' => $flags,
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_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 private
|
||||
* @author Joern Barthel <j_barthel@web.de>
|
||||
*/
|
||||
function _mssql_field_flags($table, $column)
|
||||
{
|
||||
static $tableName = null;
|
||||
static $flags = array();
|
||||
|
||||
if ($table != $tableName) {
|
||||
|
||||
$flags = array();
|
||||
$tableName = $table;
|
||||
|
||||
// get unique and primary keys
|
||||
$res = $this->getAll("EXEC SP_HELPINDEX $table", DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
foreach ($res as $val) {
|
||||
$keys = explode(', ', $val['index_keys']);
|
||||
|
||||
if (sizeof($keys) > 1) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'multiple_key');
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($val['index_description'], 'primary key')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'primary_key');
|
||||
}
|
||||
} elseif (strpos($val['index_description'], 'unique')) {
|
||||
foreach ($keys as $key) {
|
||||
$this->_add_flag($flags[$key], 'unique_key');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get auto_increment, not_null and timestamp
|
||||
$res = $this->getAll("EXEC SP_COLUMNS $table", DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
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 (array_key_exists($column, $flags)) {
|
||||
return(implode(' ', $flags[$column]));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _add_flag()
|
||||
|
||||
/**
|
||||
* Adds a string to the flags array if the flag is not yet in there
|
||||
* - if there is no flag present the array is created
|
||||
*
|
||||
* @param array &$array the reference to the flag-array
|
||||
* @param string $value the flag value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the SQL query string or null if the driver doesn't
|
||||
* support the object type requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'U'"
|
||||
. ' ORDER BY name';
|
||||
case 'views':
|
||||
return "SELECT name FROM sysobjects WHERE type = 'V'";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
1046
sites/all/modules/civicrm/packages/DB/mysql.php
Normal file
1046
sites/all/modules/civicrm/packages/DB/mysql.php
Normal file
File diff suppressed because it is too large
Load diff
1101
sites/all/modules/civicrm/packages/DB/mysqli.php
Normal file
1101
sites/all/modules/civicrm/packages/DB/mysqli.php
Normal file
File diff suppressed because it is too large
Load diff
883
sites/all/modules/civicrm/packages/DB/odbc.php
Normal file
883
sites/all/modules/civicrm/packages/DB/odbc.php
Normal file
|
@ -0,0 +1,883 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The PEAR DB driver for PHP's odbc extension
|
||||
* for interacting with databases via ODBC connections
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: odbc.php,v 1.81 2007/07/06 05:19:21 aharvey Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB_common class so it can be extended from
|
||||
*/
|
||||
require_once 'DB/common.php';
|
||||
|
||||
/**
|
||||
* The methods PEAR DB uses to interact with PHP's odbc extension
|
||||
* for interacting with databases via ODBC connections
|
||||
*
|
||||
* These methods overload the ones declared in DB_common.
|
||||
*
|
||||
* More info on ODBC errors could be found here:
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Daniel Convissor <danielc@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 1.7.13
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_odbc extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* The DB driver type (mysql, oci8, odbc, etc.)
|
||||
* @var string
|
||||
*/
|
||||
var $phptype = 'odbc';
|
||||
|
||||
/**
|
||||
* The database syntax variant to be used (db2, access, etc.), if any
|
||||
* @var string
|
||||
*/
|
||||
var $dbsyntax = 'sql92';
|
||||
|
||||
/**
|
||||
* The capabilities of this DB implementation
|
||||
*
|
||||
* The 'new_link' element contains the PHP version that first provided
|
||||
* new_link support for this DBMS. Contains false if it's unsupported.
|
||||
*
|
||||
* Meaning of the 'limit' element:
|
||||
* + 'emulate' = emulate with fetch row by number
|
||||
* + 'alter' = alter the query
|
||||
* + false = skip rows
|
||||
*
|
||||
* NOTE: The feature set of the following drivers are different than
|
||||
* the default:
|
||||
* + solid: 'transactions' = true
|
||||
* + navision: 'limit' = false
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $features = array(
|
||||
'limit' => 'emulate',
|
||||
'new_link' => false,
|
||||
'numrows' => true,
|
||||
'pconnect' => true,
|
||||
'prepare' => false,
|
||||
'ssl' => false,
|
||||
'transactions' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping of native error codes to DB error codes
|
||||
* @var array
|
||||
*/
|
||||
var $errorcode_map = array(
|
||||
'01004' => DB_ERROR_TRUNCATED,
|
||||
'07001' => DB_ERROR_MISMATCH,
|
||||
'21S01' => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
'21S02' => DB_ERROR_MISMATCH,
|
||||
'22001' => DB_ERROR_INVALID,
|
||||
'22003' => DB_ERROR_INVALID_NUMBER,
|
||||
'22005' => DB_ERROR_INVALID_NUMBER,
|
||||
'22008' => DB_ERROR_INVALID_DATE,
|
||||
'22012' => DB_ERROR_DIVZERO,
|
||||
'23000' => DB_ERROR_CONSTRAINT,
|
||||
'23502' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
'23503' => DB_ERROR_CONSTRAINT,
|
||||
'23504' => DB_ERROR_CONSTRAINT,
|
||||
'23505' => DB_ERROR_CONSTRAINT,
|
||||
'24000' => DB_ERROR_INVALID,
|
||||
'34000' => DB_ERROR_INVALID,
|
||||
'37000' => DB_ERROR_SYNTAX,
|
||||
'42000' => DB_ERROR_SYNTAX,
|
||||
'42601' => DB_ERROR_SYNTAX,
|
||||
'IM001' => DB_ERROR_UNSUPPORTED,
|
||||
'S0000' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0001' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0002' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0011' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0012' => DB_ERROR_NOT_FOUND,
|
||||
'S0021' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0022' => DB_ERROR_NOSUCHFIELD,
|
||||
'S1009' => DB_ERROR_INVALID,
|
||||
'S1090' => DB_ERROR_INVALID,
|
||||
'S1C00' => DB_ERROR_NOT_CAPABLE,
|
||||
);
|
||||
|
||||
/**
|
||||
* The raw database connection created by PHP
|
||||
* @var resource
|
||||
*/
|
||||
var $connection;
|
||||
|
||||
/**
|
||||
* The DSN information for connecting to a database
|
||||
* @var array
|
||||
*/
|
||||
var $dsn = array();
|
||||
|
||||
|
||||
/**
|
||||
* The number of rows affected by a data manipulation query
|
||||
* @var integer
|
||||
* @access private
|
||||
*/
|
||||
var $affected = 0;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* This constructor calls <kbd>$this->DB_common()</kbd>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to the database server, log in and open the database
|
||||
*
|
||||
* Don't call this method directly. Use DB::connect() instead.
|
||||
*
|
||||
* PEAR DB's odbc driver supports the following extra DSN options:
|
||||
* + cursor The type of cursor to be used for this connection.
|
||||
*
|
||||
* @param array $dsn the data source name
|
||||
* @param bool $persistent should the connection be persistent?
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function connect($dsn, $persistent = false)
|
||||
{
|
||||
if (!PEAR::loadExtension('odbc')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->dsn = $dsn;
|
||||
if ($dsn['dbsyntax']) {
|
||||
$this->dbsyntax = $dsn['dbsyntax'];
|
||||
}
|
||||
switch ($this->dbsyntax) {
|
||||
case 'access':
|
||||
case 'db2':
|
||||
case 'solid':
|
||||
$this->features['transactions'] = true;
|
||||
break;
|
||||
case 'navision':
|
||||
$this->features['limit'] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is hear for backwards compatibility. Should have been using
|
||||
* 'database' all along, but prior to 1.6.0RC3 'hostspec' was used.
|
||||
*/
|
||||
if ($dsn['database']) {
|
||||
$odbcdsn = $dsn['database'];
|
||||
} elseif ($dsn['hostspec']) {
|
||||
$odbcdsn = $dsn['hostspec'];
|
||||
} else {
|
||||
$odbcdsn = 'localhost';
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
|
||||
if (empty($dsn['cursor'])) {
|
||||
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
|
||||
$dsn['password']);
|
||||
} else {
|
||||
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
|
||||
$dsn['password'],
|
||||
$dsn['cursor']);
|
||||
}
|
||||
|
||||
if (!is_resource($this->connection)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
|
||||
null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Disconnects from the database server
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$err = @odbc_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $err;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Sends a query to the database server
|
||||
*
|
||||
* @param string the SQL query string
|
||||
*
|
||||
* @return mixed + a PHP result resrouce for successful SELECT queries
|
||||
* + the DB_OK constant for other successful queries
|
||||
* + a DB_Error object on failure
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @odbc_exec($this->connection, $query);
|
||||
if (!$result) {
|
||||
return $this->odbcRaiseError(); // XXX ERRORMSG
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if ($this->_checkManip($query)) {
|
||||
$this->affected = $result; // For affectedRows()
|
||||
return DB_OK;
|
||||
}
|
||||
$this->affected = 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal odbc result pointer to the next available result
|
||||
*
|
||||
* @param a valid fbsql result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return @odbc_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Places a row from the result set into the given array
|
||||
*
|
||||
* Formating of the array and the data therein are configurable.
|
||||
* See DB_result::fetchInto() for more information.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::fetchInto() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result the query result resource
|
||||
* @param array $arr the referenced array to put the data in
|
||||
* @param int $fetchmode how the resulting array should be indexed
|
||||
* @param int $rownum the row number to fetch (0 = first row)
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL when the end of a result set is
|
||||
* reached or on failure
|
||||
*
|
||||
* @see DB_result::fetchInto()
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
|
||||
{
|
||||
$arr = array();
|
||||
if ($rownum !== null) {
|
||||
$rownum++; // ODBC first row is 1
|
||||
if (version_compare(phpversion(), '4.2.0', 'ge')) {
|
||||
$cols = @odbc_fetch_into($result, $arr, $rownum);
|
||||
} else {
|
||||
$cols = @odbc_fetch_into($result, $rownum, $arr);
|
||||
}
|
||||
} else {
|
||||
$cols = @odbc_fetch_into($result, $arr);
|
||||
}
|
||||
if (!$cols) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
|
||||
for ($i = 0; $i < count($arr); $i++) {
|
||||
$colName = @odbc_field_name($result, $i+1);
|
||||
$a[$colName] = $arr[$i];
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$a = array_change_key_case($a, CASE_LOWER);
|
||||
}
|
||||
$arr = $a;
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
|
||||
$this->_rtrimArrayValues($arr);
|
||||
}
|
||||
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
|
||||
$this->_convertNullArrayValuesToEmpty($arr);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Deletes the result set and frees the memory occupied by the result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::free() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*
|
||||
* @see DB_result::free()
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
return is_resource($result) ? odbc_free_result($result) : false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Gets the number of columns in a result set
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numCols() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of columns. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numCols()
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @odbc_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Determines the number of rows affected by a data maniuplation query
|
||||
*
|
||||
* 0 is returned for queries that don't manipulate data.
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (empty($this->affected)) { // In case of SELECT stms
|
||||
return 0;
|
||||
}
|
||||
$nrows = @odbc_num_rows($this->affected);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows in a result set
|
||||
*
|
||||
* Not all ODBC drivers support this functionality. If they don't
|
||||
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
|
||||
*
|
||||
* This method is not meant to be called directly. Use
|
||||
* DB_result::numRows() instead. It can't be declared "protected"
|
||||
* because DB_result is a separate object.
|
||||
*
|
||||
* @param resource $result PHP's query result resource
|
||||
*
|
||||
* @return int the number of rows. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_result::numRows()
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$nrows = @odbc_num_rows($result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
|
||||
}
|
||||
if ($nrows === false) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quoteIdentifier()
|
||||
|
||||
/**
|
||||
* Quotes a string so it can be safely used as a table or column name
|
||||
*
|
||||
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
|
||||
* "Use ANSI quoted identifiers" when setting up the ODBC data source.
|
||||
*
|
||||
* @param string $str identifier name to be quoted
|
||||
*
|
||||
* @return string quoted identifier string
|
||||
*
|
||||
* @see DB_common::quoteIdentifier()
|
||||
* @since Method available since Release 1.6.0
|
||||
*/
|
||||
function quoteIdentifier($str)
|
||||
{
|
||||
switch ($this->dsn['dbsyntax']) {
|
||||
case 'access':
|
||||
return '[' . $str . ']';
|
||||
case 'mssql':
|
||||
case 'sybase':
|
||||
return '[' . str_replace(']', ']]', $str) . ']';
|
||||
case 'mysql':
|
||||
case 'mysqli':
|
||||
return '`' . $str . '`';
|
||||
default:
|
||||
return '"' . str_replace('"', '""', $str) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quote()
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in release 1.6.0
|
||||
* @internal
|
||||
*/
|
||||
function quote($str)
|
||||
{
|
||||
return $this->quoteSmart($str);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Returns the next free id in a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence
|
||||
* @param boolean $ondemand when true, the seqence is automatically
|
||||
* created if it does not exist
|
||||
*
|
||||
* @return int the next id number in the sequence.
|
||||
* A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::nextID(), DB_common::getSequenceName(),
|
||||
* DB_odbc::createSequence(), DB_odbc::dropSequence()
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("update ${seqname} set id = id + 1");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->createSequence($seq_name);
|
||||
$this->popErrorHandling();
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $this->query("insert into ${seqname} (id) values(0)");
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
$result = $this->query("select id from ${seqname}");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetchRow(DB_FETCHMODE_ORDERED);
|
||||
if (DB::isError($row || !$row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new sequence
|
||||
*
|
||||
* @param string $seq_name name of the new sequence
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::createSequence(), DB_common::getSequenceName(),
|
||||
* DB_odbc::nextID(), DB_odbc::dropSequence()
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
return $this->query('CREATE TABLE '
|
||||
. $this->getSequenceName($seq_name)
|
||||
. ' (id integer NOT NULL,'
|
||||
. ' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Deletes a sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be deleted
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
|
||||
* DB_odbc::nextID(), DB_odbc::createSequence()
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enables or disables automatic commits
|
||||
*
|
||||
* @param bool $onoff true turns it on, false turns it off
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object if the driver
|
||||
* doesn't support auto-committing transactions.
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
if (!@odbc_autocommit($this->connection, $onoff)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commits the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if (!@odbc_commit($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Reverts the current transaction
|
||||
*
|
||||
* @return int DB_OK on success. A DB_Error object on failure.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if (!@odbc_rollback($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ odbcRaiseError()
|
||||
|
||||
/**
|
||||
* Produces a DB_Error object regarding the current problem
|
||||
*
|
||||
* @param int $errno if the error is being manually raised pass a
|
||||
* DB_ERROR* constant here. If this isn't passed
|
||||
* the error information gathered from the DBMS.
|
||||
*
|
||||
* @return object the DB_Error object
|
||||
*
|
||||
* @see DB_common::raiseError(),
|
||||
* DB_odbc::errorNative(), DB_common::errorCode()
|
||||
*/
|
||||
function odbcRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
switch ($this->dbsyntax) {
|
||||
case 'access':
|
||||
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
|
||||
$this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD;
|
||||
} else {
|
||||
// Doing this in case mode changes during runtime.
|
||||
$this->errorcode_map['07001'] = DB_ERROR_MISMATCH;
|
||||
}
|
||||
|
||||
$native_code = odbc_error($this->connection);
|
||||
|
||||
// S1000 is for "General Error." Let's be more specific.
|
||||
if ($native_code == 'S1000') {
|
||||
$errormsg = odbc_errormsg($this->connection);
|
||||
static $error_regexps;
|
||||
if (!isset($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/includes related records.$/i' => DB_ERROR_CONSTRAINT,
|
||||
'/cannot contain a Null value/i' => DB_ERROR_CONSTRAINT_NOT_NULL,
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $this->raiseError($code,
|
||||
null, null, null,
|
||||
$native_code . ' ' . $errormsg);
|
||||
}
|
||||
}
|
||||
$errno = DB_ERROR;
|
||||
} else {
|
||||
$errno = $this->errorCode($native_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$errno = $this->errorCode(odbc_error($this->connection));
|
||||
}
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Gets the DBMS' native error code and message produced by the last query
|
||||
*
|
||||
* @return string the DBMS' error code and message
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
if (!is_resource($this->connection)) {
|
||||
return @odbc_error() . ' ' . @odbc_errormsg();
|
||||
}
|
||||
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result DB_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 DB_Error object on failure.
|
||||
*
|
||||
* @see DB_common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
/*
|
||||
* Probably received a table name.
|
||||
* Create a result resource identifier.
|
||||
*/
|
||||
$id = @odbc_exec($this->connection, "SELECT * FROM $result");
|
||||
if (!$id) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
$got_string = true;
|
||||
} elseif (isset($result->result)) {
|
||||
/*
|
||||
* Probably received a result object.
|
||||
* Extract the result resource identifier.
|
||||
*/
|
||||
$id = $result->result;
|
||||
$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 $this->odbcRaiseError(DB_ERROR_NEED_MORE_DATA);
|
||||
}
|
||||
|
||||
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @odbc_num_fields($id);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$col = $i + 1;
|
||||
$res[$i] = array(
|
||||
'table' => $got_string ? $case_func($result) : '',
|
||||
'name' => $case_func(@odbc_field_name($id, $col)),
|
||||
'type' => @odbc_field_type($id, $col),
|
||||
'len' => @odbc_field_len($id, $col),
|
||||
'flags' => '',
|
||||
);
|
||||
if ($mode & DB_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & DB_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) {
|
||||
@odbc_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Obtains the query string needed for listing a given type of objects
|
||||
*
|
||||
* Thanks to symbol1@gmail.com and Philippe.Jausions@11abacus.com.
|
||||
*
|
||||
* @param string $type the kind of objects you want to retrieve
|
||||
*
|
||||
* @return string the list of objects requested
|
||||
*
|
||||
* @access protected
|
||||
* @see DB_common::getListOf()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'databases':
|
||||
if (!function_exists('odbc_data_source')) {
|
||||
return null;
|
||||
}
|
||||
$res = @odbc_data_source($this->connection, SQL_FETCH_FIRST);
|
||||
if (is_array($res)) {
|
||||
$out = array($res['server']);
|
||||
while($res = @odbc_data_source($this->connection,
|
||||
SQL_FETCH_NEXT))
|
||||
{
|
||||
$out[] = $res['server'];
|
||||
}
|
||||
return $out;
|
||||
} else {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
break;
|
||||
case 'tables':
|
||||
case 'schema.tables':
|
||||
$keep = 'TABLE';
|
||||
break;
|
||||
case 'views':
|
||||
$keep = 'VIEW';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removing non-conforming items in the while loop rather than
|
||||
* in the odbc_tables() call because some backends choke on this:
|
||||
* odbc_tables($this->connection, '', '', '', 'TABLE')
|
||||
*/
|
||||
$res = @odbc_tables($this->connection);
|
||||
if (!$res) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
$out = array();
|
||||
while ($row = odbc_fetch_array($res)) {
|
||||
if ($row['TABLE_TYPE'] != $keep) {
|
||||
continue;
|
||||
}
|
||||
if ($type == 'schema.tables') {
|
||||
$out[] = $row['TABLE_SCHEM'] . '.' . $row['TABLE_NAME'];
|
||||
} else {
|
||||
$out[] = $row['TABLE_NAME'];
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
1116
sites/all/modules/civicrm/packages/DB/pgsql.php
Normal file
1116
sites/all/modules/civicrm/packages/DB/pgsql.php
Normal file
File diff suppressed because it is too large
Load diff
15
sites/all/modules/civicrm/packages/DB/scripts/DB_DataObject_createTables.bat
Executable file
15
sites/all/modules/civicrm/packages/DB/scripts/DB_DataObject_createTables.bat
Executable file
|
@ -0,0 +1,15 @@
|
|||
@ECHO OFF
|
||||
REM $Id: DB_DataObject_createTables.bat,v 1.1 2003/09/08 20:43:31 arnaud Exp $
|
||||
REM BATCH FILE TO EXECUTE PEAR::DB_DATAOBJECT createTables.php script
|
||||
|
||||
IF '%1' == '' (
|
||||
ECHO **************************************************
|
||||
ECHO * Please pass the name of the ini file
|
||||
ECHO * to process at the only parameter
|
||||
ECHO *
|
||||
ECHO * e.g.: DB_DataObject_createTables my_ini_file.ini
|
||||
ECHO **************************************************
|
||||
GOTO :EOF
|
||||
)
|
||||
|
||||
%PHP_PEAR_PHP_BIN% %PHP_PEAR_INSTALL_DIR%\DB\DataObject\createTables.php %1
|
506
sites/all/modules/civicrm/packages/DB/storage.php
Normal file
506
sites/all/modules/civicrm/packages/DB/storage.php
Normal file
|
@ -0,0 +1,506 @@
|
|||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Provides an object interface to a table row
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: storage.php,v 1.24 2007/08/12 05:27:25 aharvey Exp $
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtain the DB class so it can be extended from
|
||||
*/
|
||||
require_once 'DB.php';
|
||||
|
||||
/**
|
||||
* Provides an object interface to a table row
|
||||
*
|
||||
* It lets you add, delete and change rows using objects rather than SQL
|
||||
* statements.
|
||||
*
|
||||
* @category Database
|
||||
* @package DB
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
* @copyright 1997-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 1.7.13
|
||||
* @link http://pear.php.net/package/DB
|
||||
*/
|
||||
class DB_storage extends PEAR
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/** the name of the table (or view, if the backend database supports
|
||||
updates in views) we hold data from */
|
||||
var $_table = null;
|
||||
|
||||
/** which column(s) in the table contains primary keys, can be a
|
||||
string for single-column primary keys, or an array of strings
|
||||
for multiple-column primary keys */
|
||||
var $_keycolumn = null;
|
||||
|
||||
/** DB connection handle used for all transactions */
|
||||
var $_dbh = null;
|
||||
|
||||
/** an assoc with the names of database fields stored as properties
|
||||
in this object */
|
||||
var $_properties = array();
|
||||
|
||||
/** an assoc with the names of the properties in this object that
|
||||
have been changed since they were fetched from the database */
|
||||
var $_changes = array();
|
||||
|
||||
/** flag that decides if data in this object can be changed.
|
||||
objects that don't have their table's key column in their
|
||||
property lists will be flagged as read-only. */
|
||||
var $_readonly = false;
|
||||
|
||||
/** function or method that implements a validator for fields that
|
||||
are set, this validator function returns true if the field is
|
||||
valid, false if not */
|
||||
var $_validator = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param $table string the name of the database table
|
||||
*
|
||||
* @param $keycolumn mixed string with name of key column, or array of
|
||||
* strings if the table has a primary key of more than one column
|
||||
*
|
||||
* @param $dbh object database connection object
|
||||
*
|
||||
* @param $validator mixed function or method used to validate
|
||||
* each new value, called with three parameters: the name of the
|
||||
* field/column that is changing, a reference to the new value and
|
||||
* a reference to this object
|
||||
*
|
||||
*/
|
||||
function __construct($table, $keycolumn, &$dbh, $validator = null)
|
||||
{
|
||||
parent::__construct('DB_Error');
|
||||
$this->_table = $table;
|
||||
$this->_keycolumn = $keycolumn;
|
||||
$this->_dbh = $dbh;
|
||||
$this->_readonly = false;
|
||||
$this->_validator = $validator;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _makeWhere()
|
||||
|
||||
/**
|
||||
* Utility method to build a "WHERE" clause to locate ourselves in
|
||||
* the table.
|
||||
*
|
||||
* XXX future improvement: use rowids?
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _makeWhere($keyval = null)
|
||||
{
|
||||
if (is_array($this->_keycolumn)) {
|
||||
if ($keyval === null) {
|
||||
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
|
||||
$keyval[] = $this->{$this->_keycolumn[$i]};
|
||||
}
|
||||
}
|
||||
$whereclause = '';
|
||||
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
|
||||
if ($i > 0) {
|
||||
$whereclause .= ' AND ';
|
||||
}
|
||||
$whereclause .= $this->_keycolumn[$i];
|
||||
if (is_null($keyval[$i])) {
|
||||
// there's not much point in having a NULL key,
|
||||
// but we support it anyway
|
||||
$whereclause .= ' IS NULL';
|
||||
} else {
|
||||
$whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($keyval === null) {
|
||||
$keyval = @$this->{$this->_keycolumn};
|
||||
}
|
||||
$whereclause = $this->_keycolumn;
|
||||
if (is_null($keyval)) {
|
||||
// there's not much point in having a NULL key,
|
||||
// but we support it anyway
|
||||
$whereclause .= ' IS NULL';
|
||||
} else {
|
||||
$whereclause .= ' = ' . $this->_dbh->quote($keyval);
|
||||
}
|
||||
}
|
||||
return $whereclause;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setup()
|
||||
|
||||
/**
|
||||
* Method used to initialize a DB_storage object from the
|
||||
* configured table.
|
||||
*
|
||||
* @param $keyval mixed the key[s] of the row to fetch (string or array)
|
||||
*
|
||||
* @return int DB_OK on success, a DB error if not
|
||||
*/
|
||||
function setup($keyval)
|
||||
{
|
||||
$whereclause = $this->_makeWhere($keyval);
|
||||
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
|
||||
$sth = $this->_dbh->query($query);
|
||||
if (DB::isError($sth)) {
|
||||
return $sth;
|
||||
}
|
||||
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (!$row) {
|
||||
return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null,
|
||||
$query, null, true);
|
||||
}
|
||||
foreach ($row as $key => $value) {
|
||||
$this->_properties[$key] = true;
|
||||
$this->$key = $value;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ insert()
|
||||
|
||||
/**
|
||||
* Create a new (empty) row in the configured table for this
|
||||
* object.
|
||||
*/
|
||||
function insert($newpk)
|
||||
{
|
||||
if (is_array($this->_keycolumn)) {
|
||||
$primarykey = $this->_keycolumn;
|
||||
} else {
|
||||
$primarykey = array($this->_keycolumn);
|
||||
}
|
||||
settype($newpk, "array");
|
||||
for ($i = 0; $i < sizeof($primarykey); $i++) {
|
||||
$pkvals[] = $this->_dbh->quote($newpk[$i]);
|
||||
}
|
||||
|
||||
$sth = $this->_dbh->query("INSERT INTO $this->_table (" .
|
||||
implode(",", $primarykey) . ") VALUES(" .
|
||||
implode(",", $pkvals) . ")");
|
||||
if (DB::isError($sth)) {
|
||||
return $sth;
|
||||
}
|
||||
if (sizeof($newpk) == 1) {
|
||||
$newpk = $newpk[0];
|
||||
}
|
||||
$this->setup($newpk);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ toString()
|
||||
|
||||
/**
|
||||
* Output a simple description of this DB_storage object.
|
||||
* @return string object description
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$info = strtolower(get_class($this));
|
||||
$info .= " (table=";
|
||||
$info .= $this->_table;
|
||||
$info .= ", keycolumn=";
|
||||
if (is_array($this->_keycolumn)) {
|
||||
$info .= "(" . implode(",", $this->_keycolumn) . ")";
|
||||
} else {
|
||||
$info .= $this->_keycolumn;
|
||||
}
|
||||
$info .= ", dbh=";
|
||||
if (is_object($this->_dbh)) {
|
||||
$info .= $this->_dbh->toString();
|
||||
} else {
|
||||
$info .= "null";
|
||||
}
|
||||
$info .= ")";
|
||||
if (sizeof($this->_properties)) {
|
||||
$info .= " [loaded, key=";
|
||||
$keyname = $this->_keycolumn;
|
||||
if (is_array($keyname)) {
|
||||
$info .= "(";
|
||||
for ($i = 0; $i < sizeof($keyname); $i++) {
|
||||
if ($i > 0) {
|
||||
$info .= ",";
|
||||
}
|
||||
$info .= $this->$keyname[$i];
|
||||
}
|
||||
$info .= ")";
|
||||
} else {
|
||||
$info .= $this->$keyname;
|
||||
}
|
||||
$info .= "]";
|
||||
}
|
||||
if (sizeof($this->_changes)) {
|
||||
$info .= " [modified]";
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dump()
|
||||
|
||||
/**
|
||||
* Dump the contents of this object to "standard output".
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
foreach ($this->_properties as $prop => $foo) {
|
||||
print "$prop = ";
|
||||
print htmlentities($this->$prop);
|
||||
print "<br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &create()
|
||||
|
||||
/**
|
||||
* Static method used to create new DB storage objects.
|
||||
* @param $data assoc. array where the keys are the names
|
||||
* of properties/columns
|
||||
* @return object a new instance of DB_storage or a subclass of it
|
||||
*/
|
||||
function &create($table, &$data)
|
||||
{
|
||||
$classname = strtolower(get_class($this));
|
||||
$obj = new $classname($table);
|
||||
foreach ($data as $name => $value) {
|
||||
$obj->_properties[$name] = true;
|
||||
$obj->$name = &$value;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ loadFromQuery()
|
||||
|
||||
/**
|
||||
* Loads data into this object from the given query. If this
|
||||
* object already contains table data, changes will be saved and
|
||||
* the object re-initialized first.
|
||||
*
|
||||
* @param $query SQL query
|
||||
*
|
||||
* @param $params parameter list in case you want to use
|
||||
* prepare/execute mode
|
||||
*
|
||||
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the
|
||||
* returned object is read-only (because the object's specified
|
||||
* key column was not found among the columns returned by $query),
|
||||
* or another DB error code in case of errors.
|
||||
*/
|
||||
// XXX commented out for now
|
||||
/*
|
||||
function loadFromQuery($query, $params = null)
|
||||
{
|
||||
if (sizeof($this->_properties)) {
|
||||
if (sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
$this->_changes = array();
|
||||
}
|
||||
$this->_properties = array();
|
||||
}
|
||||
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
|
||||
if (DB::isError($rowdata)) {
|
||||
return $rowdata;
|
||||
}
|
||||
reset($rowdata);
|
||||
$found_keycolumn = false;
|
||||
while (list($key, $value) = each($rowdata)) {
|
||||
if ($key == $this->_keycolumn) {
|
||||
$found_keycolumn = true;
|
||||
}
|
||||
$this->_properties[$key] = true;
|
||||
$this->$key = &$value;
|
||||
unset($value); // have to unset, or all properties will
|
||||
// refer to the same value
|
||||
}
|
||||
if (!$found_keycolumn) {
|
||||
$this->_readonly = true;
|
||||
return DB_WARNING_READ_ONLY;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
// }}}
|
||||
// {{{ set()
|
||||
|
||||
/**
|
||||
* Modify an attriute value.
|
||||
*/
|
||||
function set($property, $newvalue)
|
||||
{
|
||||
// only change if $property is known and object is not
|
||||
// read-only
|
||||
if ($this->_readonly) {
|
||||
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
|
||||
null, null, null, true);
|
||||
}
|
||||
if (@isset($this->_properties[$property])) {
|
||||
if (empty($this->_validator)) {
|
||||
$valid = true;
|
||||
} else {
|
||||
$valid = @call_user_func($this->_validator,
|
||||
$this->_table,
|
||||
$property,
|
||||
$newvalue,
|
||||
$this->$property,
|
||||
$this);
|
||||
}
|
||||
if ($valid) {
|
||||
$this->$property = $newvalue;
|
||||
if (empty($this->_changes[$property])) {
|
||||
$this->_changes[$property] = 0;
|
||||
} else {
|
||||
$this->_changes[$property]++;
|
||||
}
|
||||
} else {
|
||||
return $this->raiseError(null, DB_ERROR_INVALID, null,
|
||||
null, "invalid field: $property",
|
||||
null, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null,
|
||||
null, "unknown field: $property",
|
||||
null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ &get()
|
||||
|
||||
/**
|
||||
* Fetch an attribute value.
|
||||
*
|
||||
* @param string attribute name
|
||||
*
|
||||
* @return attribute contents, or null if the attribute name is
|
||||
* unknown
|
||||
*/
|
||||
function &get($property)
|
||||
{
|
||||
// only return if $property is known
|
||||
if (isset($this->_properties[$property])) {
|
||||
return $this->$property;
|
||||
}
|
||||
$tmp = null;
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _DB_storage()
|
||||
|
||||
/**
|
||||
* Destructor, calls DB_storage::store() if there are changes
|
||||
* that are to be kept.
|
||||
*/
|
||||
function _DB_storage()
|
||||
{
|
||||
if (sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
$this->_table = null;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ store()
|
||||
|
||||
/**
|
||||
* Stores changes to this object in the database.
|
||||
*
|
||||
* @return DB_OK or a DB error
|
||||
*/
|
||||
function store()
|
||||
{
|
||||
$params = array();
|
||||
$vars = array();
|
||||
foreach ($this->_changes as $name => $foo) {
|
||||
$params[] = &$this->$name;
|
||||
$vars[] = $name . ' = ?';
|
||||
}
|
||||
if ($vars) {
|
||||
$query = 'UPDATE ' . $this->_table . ' SET ' .
|
||||
implode(', ', $vars) . ' WHERE ' .
|
||||
$this->_makeWhere();
|
||||
$stmt = $this->_dbh->prepare($query);
|
||||
$res = $this->_dbh->execute($stmt, $params);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
$this->_changes = array();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ remove()
|
||||
|
||||
/**
|
||||
* Remove the row represented by this object from the database.
|
||||
*
|
||||
* @return mixed DB_OK or a DB error
|
||||
*/
|
||||
function remove()
|
||||
{
|
||||
if ($this->_readonly) {
|
||||
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
|
||||
null, null, null, true);
|
||||
}
|
||||
$query = 'DELETE FROM ' . $this->_table .' WHERE '.
|
||||
$this->_makeWhere();
|
||||
$res = $this->_dbh->query($query);
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
foreach ($this->_properties as $prop => $foo) {
|
||||
unset($this->$prop);
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
Loading…
Add table
Add a link
Reference in a new issue