1. Import
This commit is contained in:
874
html/service/include/DB.php
Normal file
874
html/service/include/DB.php
Normal file
@@ -0,0 +1,874 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Stig Bakken <ssb@fast.no> |
|
||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: DB.php,v 1.86.2.2 2002/04/09 19:04:02 ssb Exp $
|
||||
//
|
||||
// Database independent query interface.
|
||||
//
|
||||
|
||||
require_once "PEAR.php";
|
||||
|
||||
/*
|
||||
* The method mapErrorCode in each DB_dbtype implementation maps
|
||||
* native error codes to one of these.
|
||||
*
|
||||
* If you add an error code here, make sure you also add a textual
|
||||
* version of it in DB::errorMessage().
|
||||
*/
|
||||
|
||||
define("DB_OK", 1);
|
||||
define("DB_ERROR", -1);
|
||||
define("DB_ERROR_SYNTAX", -2);
|
||||
define("DB_ERROR_CONSTRAINT", -3);
|
||||
define("DB_ERROR_NOT_FOUND", -4);
|
||||
define("DB_ERROR_ALREADY_EXISTS", -5);
|
||||
define("DB_ERROR_UNSUPPORTED", -6);
|
||||
define("DB_ERROR_MISMATCH", -7);
|
||||
define("DB_ERROR_INVALID", -8);
|
||||
define("DB_ERROR_NOT_CAPABLE", -9);
|
||||
define("DB_ERROR_TRUNCATED", -10);
|
||||
define("DB_ERROR_INVALID_NUMBER", -11);
|
||||
define("DB_ERROR_INVALID_DATE", -12);
|
||||
define("DB_ERROR_DIVZERO", -13);
|
||||
define("DB_ERROR_NODBSELECTED", -14);
|
||||
define("DB_ERROR_CANNOT_CREATE", -15);
|
||||
define("DB_ERROR_CANNOT_DELETE", -16);
|
||||
define("DB_ERROR_CANNOT_DROP", -17);
|
||||
define("DB_ERROR_NOSUCHTABLE", -18);
|
||||
define("DB_ERROR_NOSUCHFIELD", -19);
|
||||
define("DB_ERROR_NEED_MORE_DATA", -20);
|
||||
define("DB_ERROR_NOT_LOCKED", -21);
|
||||
define("DB_ERROR_VALUE_COUNT_ON_ROW", -22);
|
||||
define("DB_ERROR_INVALID_DSN", -23);
|
||||
define("DB_ERROR_CONNECT_FAILED", -24);
|
||||
define("DB_ERROR_EXTENSION_NOT_FOUND",-25);
|
||||
define("DB_ERROR_NOSUCHDB", -25);
|
||||
define("DB_ERROR_ACCESS_VIOLATION", -26);
|
||||
|
||||
/*
|
||||
* Warnings are not detected as errors by DB::isError(), and are not
|
||||
* fatal. You can detect whether an error is in fact a warning with
|
||||
* DB::isWarning().
|
||||
*/
|
||||
|
||||
define('DB_WARNING', -1000);
|
||||
define('DB_WARNING_READ_ONLY', -1001);
|
||||
|
||||
/*
|
||||
* These constants are used when storing information about prepared
|
||||
* statements (using the "prepare" method in DB_dbtype).
|
||||
*
|
||||
* The prepare/execute model in DB is mostly borrowed from the ODBC
|
||||
* extension, in a query the "?" character means a scalar parameter.
|
||||
* There are two extensions though, a "&" character means an opaque
|
||||
* parameter. An opaque parameter is simply a file name, the real
|
||||
* data are in that file (useful for putting uploaded files into your
|
||||
* database and such). The "!" char means a parameter that must be
|
||||
* left as it is.
|
||||
* They modify the quote behavoir:
|
||||
* DB_PARAM_SCALAR (?) => 'original string quoted'
|
||||
* DB_PARAM_OPAQUE (&) => 'string from file quoted'
|
||||
* DB_PARAM_MISC (!) => original string
|
||||
*/
|
||||
|
||||
define('DB_PARAM_SCALAR', 1);
|
||||
define('DB_PARAM_OPAQUE', 2);
|
||||
define('DB_PARAM_MISC', 3);
|
||||
|
||||
/*
|
||||
* These constants define different ways of returning binary data
|
||||
* from queries. Again, this model has been borrowed from the ODBC
|
||||
* extension.
|
||||
*
|
||||
* DB_BINMODE_PASSTHRU sends the data directly through to the browser
|
||||
* when data is fetched from the database.
|
||||
* DB_BINMODE_RETURN lets you return data as usual.
|
||||
* DB_BINMODE_CONVERT returns data as well, only it is converted to
|
||||
* hex format, for example the string "123" would become "313233".
|
||||
*/
|
||||
|
||||
define('DB_BINMODE_PASSTHRU', 1);
|
||||
define('DB_BINMODE_RETURN', 2);
|
||||
define('DB_BINMODE_CONVERT', 3);
|
||||
|
||||
/**
|
||||
* This is a special constant that tells DB the user hasn't specified
|
||||
* any particular get mode, so the default should be used.
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_DEFAULT', 0);
|
||||
|
||||
/**
|
||||
* Column data indexed by numbers, ordered from 0 and up
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_ORDERED', 1);
|
||||
|
||||
/**
|
||||
* Column data indexed by column names
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_ASSOC', 2);
|
||||
|
||||
/**
|
||||
* Column data as object properties
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_OBJECT', 3);
|
||||
|
||||
/**
|
||||
* For multi-dimensional results: normally the first level of arrays
|
||||
* is the row number, and the second level indexed by column number or name.
|
||||
* DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays
|
||||
* is the column name, and the second level the row number.
|
||||
*/
|
||||
|
||||
define('DB_FETCHMODE_FLIPPED', 4);
|
||||
|
||||
/* for compatibility */
|
||||
|
||||
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
|
||||
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
|
||||
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
|
||||
|
||||
/**
|
||||
* these are constants for the tableInfo-function
|
||||
* they are bitwised or'ed. so if there are more constants to be defined
|
||||
* in the future, adjust DB_TABLEINFO_FULL accordingly
|
||||
*/
|
||||
|
||||
define('DB_TABLEINFO_ORDER', 1);
|
||||
define('DB_TABLEINFO_ORDERTABLE', 2);
|
||||
define('DB_TABLEINFO_FULL', 3);
|
||||
|
||||
|
||||
/**
|
||||
* The main "DB" class is simply a container class with some static
|
||||
* methods for creating DB objects as well as some utility functions
|
||||
* common to all parts of DB.
|
||||
*
|
||||
* The object model of DB is as follows (indentation means inheritance):
|
||||
*
|
||||
* DB The main DB class. This is simply a utility class
|
||||
* with some "static" methods for creating DB objects as
|
||||
* well as common utility functions for other DB classes.
|
||||
*
|
||||
* DB_common The base for each DB implementation. Provides default
|
||||
* | implementations (in OO lingo virtual methods) for
|
||||
* | the actual DB implementations as well as a bunch of
|
||||
* | query utility functions.
|
||||
* |
|
||||
* +-DB_mysql The DB implementation for MySQL. Inherits DB_common.
|
||||
* When calling DB::factory or DB::connect for MySQL
|
||||
* connections, the object returned is an instance of this
|
||||
* class.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @since PHP 4.0
|
||||
*/
|
||||
|
||||
class DB
|
||||
{
|
||||
/**
|
||||
* Create a new DB connection object for the specified database
|
||||
* type
|
||||
*
|
||||
* @param string $type database type, for example "mysql"
|
||||
*
|
||||
* @return mixed a newly created DB object, or a DB error code on
|
||||
* error
|
||||
*
|
||||
* access public
|
||||
*/
|
||||
|
||||
function &factory($type)
|
||||
{
|
||||
@include_once("DB/${type}.php");
|
||||
|
||||
$classname = "DB_${type}";
|
||||
|
||||
if (!class_exists($classname)) {
|
||||
return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
|
||||
null, null, null, 'DB_Error', true);
|
||||
}
|
||||
|
||||
@$obj =& new $classname;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DB connection object and connect to the specified
|
||||
* database
|
||||
*
|
||||
* @param mixed $dsn "data source name", see the DB::parseDSN
|
||||
* method for a description of the dsn format. Can also be
|
||||
* specified as an array of the format returned by DB::parseDSN.
|
||||
*
|
||||
* @param mixed $options An associative array of option names and
|
||||
* their values. For backwards compatibility, this parameter may
|
||||
* also be a boolean that tells whether the connection should be
|
||||
* persistent. See DB_common::setOption for more information on
|
||||
* connection options.
|
||||
*
|
||||
* @return mixed a newly created DB connection object, or a DB
|
||||
* error object on error
|
||||
*
|
||||
* @see DB::parseDSN
|
||||
* @see DB::isError
|
||||
* @see DB_common::setOption
|
||||
*/
|
||||
function &connect($dsn, $options = false)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
$dsninfo = $dsn;
|
||||
} else {
|
||||
$dsninfo = DB::parseDSN($dsn);
|
||||
}
|
||||
$type = $dsninfo["phptype"];
|
||||
|
||||
if (is_array($options) && isset($options["debug"]) &&
|
||||
$options["debug"] >= 2) {
|
||||
// expose php errors with sufficient debug level
|
||||
include_once "DB/${type}.php";
|
||||
} else {
|
||||
@include_once "DB/${type}.php";
|
||||
}
|
||||
|
||||
$classname = "DB_${type}";
|
||||
if (!class_exists($classname)) {
|
||||
return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
|
||||
null, null, null, 'DB_Error', true);
|
||||
}
|
||||
|
||||
@$obj =& new $classname;
|
||||
|
||||
if (is_array($options)) {
|
||||
foreach ($options as $option => $value) {
|
||||
$test = $obj->setOption($option, $value);
|
||||
if (DB::isError($test)) {
|
||||
return $test;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$obj->setOption('persistent', $options);
|
||||
}
|
||||
$err = $obj->connect($dsninfo, $obj->getOption('persistent'));
|
||||
if (DB::isError($err)) {
|
||||
$err->addUserInfo($dsn);
|
||||
return $err;
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DB API version
|
||||
*
|
||||
* @return int the DB API version number
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function apiVersion()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a result code from a DB method is an error
|
||||
*
|
||||
* @param $value int result code
|
||||
*
|
||||
* @return bool whether $value is an error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function isError($value)
|
||||
{
|
||||
return (is_object($value) &&
|
||||
(get_class($value) == 'db_error' ||
|
||||
is_subclass_of($value, 'db_error')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a query is a data manipulation query (insert,
|
||||
* update or delete) or a data definition query (create, drop,
|
||||
* alter, grant, revoke).
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $query the query
|
||||
*
|
||||
* @return boolean whether $query is a data manipulation query
|
||||
*/
|
||||
function isManip($query)
|
||||
{
|
||||
$manips = 'INSERT|UPDATE|DELETE|'.'REPLACE|CREATE|DROP|'.
|
||||
'ALTER|GRANT|REVOKE|'.'LOCK|UNLOCK';
|
||||
if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether a result code from a DB method is a warning.
|
||||
* Warnings differ from errors in that they are generated by DB,
|
||||
* and are not fatal.
|
||||
*
|
||||
* @param mixed $value result value
|
||||
*
|
||||
* @return boolean whether $value is a warning
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function isWarning($value)
|
||||
{
|
||||
return (is_object($value) &&
|
||||
(get_class($value) == "db_warning" ||
|
||||
is_subclass_of($value, "db_warning")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a textual error message for a DB error code
|
||||
*
|
||||
* @param integer $value error code
|
||||
*
|
||||
* @return string error message, or false if the error code was
|
||||
* not recognized
|
||||
*/
|
||||
function errorMessage($value)
|
||||
{
|
||||
static $errorMessages;
|
||||
if (!isset($errorMessages)) {
|
||||
$errorMessages = array(
|
||||
DB_ERROR => 'unknown error',
|
||||
DB_ERROR_ALREADY_EXISTS => 'already exists',
|
||||
DB_ERROR_CANNOT_CREATE => 'can not create',
|
||||
DB_ERROR_CANNOT_DELETE => 'can not delete',
|
||||
DB_ERROR_CANNOT_DROP => 'can not drop',
|
||||
DB_ERROR_CONSTRAINT => 'constraint violation',
|
||||
DB_ERROR_DIVZERO => 'division by zero',
|
||||
DB_ERROR_INVALID => 'invalid',
|
||||
DB_ERROR_INVALID_DATE => 'invalid date or time',
|
||||
DB_ERROR_INVALID_NUMBER => 'invalid number',
|
||||
DB_ERROR_MISMATCH => 'mismatch',
|
||||
DB_ERROR_NODBSELECTED => 'no database selected',
|
||||
DB_ERROR_NOSUCHFIELD => 'no such field',
|
||||
DB_ERROR_NOSUCHTABLE => 'no such table',
|
||||
DB_ERROR_NOT_CAPABLE => 'DB backend not capable',
|
||||
DB_ERROR_NOT_FOUND => 'not found',
|
||||
DB_ERROR_NOT_LOCKED => 'not locked',
|
||||
DB_ERROR_SYNTAX => 'syntax error',
|
||||
DB_ERROR_UNSUPPORTED => 'not supported',
|
||||
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
|
||||
DB_ERROR_INVALID_DSN => 'invalid DSN',
|
||||
DB_ERROR_CONNECT_FAILED => 'connect failed',
|
||||
DB_OK => 'no error',
|
||||
DB_WARNING => 'unknown warning',
|
||||
DB_WARNING_READ_ONLY => 'read only',
|
||||
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
|
||||
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
|
||||
DB_ERROR_NOSUCHDB => 'no such database',
|
||||
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions'
|
||||
);
|
||||
}
|
||||
|
||||
if (DB::isError($value)) {
|
||||
$value = $value->getCode();
|
||||
}
|
||||
|
||||
return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a data source name
|
||||
*
|
||||
* A array with the following keys will be returned:
|
||||
* phptype: Database backend used in PHP (mysql, odbc etc.)
|
||||
* dbsyntax: Database used with regards to SQL syntax etc.
|
||||
* protocol: Communication protocol to use (tcp, unix etc.)
|
||||
* hostspec: Host specification (hostname[:port])
|
||||
* database: Database to use on the DBMS server
|
||||
* username: User name for login
|
||||
* password: Password for login
|
||||
*
|
||||
* The format of the supplied DSN is in its fullest form:
|
||||
*
|
||||
* phptype(dbsyntax)://username:password@protocol+hostspec/database
|
||||
*
|
||||
* Most variations are allowed:
|
||||
*
|
||||
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
|
||||
* phptype://username:password@hostspec/database_name
|
||||
* phptype://username:password@hostspec
|
||||
* phptype://username@hostspec
|
||||
* phptype://hostspec/database
|
||||
* phptype://hostspec
|
||||
* phptype(dbsyntax)
|
||||
* phptype
|
||||
*
|
||||
* @param string $dsn Data Source Name to be parsed
|
||||
*
|
||||
* @return array an associative array
|
||||
*
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
*/
|
||||
function parseDSN($dsn)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
$parsed = array(
|
||||
'phptype' => false,
|
||||
'dbsyntax' => false,
|
||||
'username' => false,
|
||||
'password' => false,
|
||||
'protocol' => false,
|
||||
'hostspec' => false,
|
||||
'port' => false,
|
||||
'socket' => false,
|
||||
'database' => false
|
||||
);
|
||||
|
||||
// Find phptype and dbsyntax
|
||||
if (($pos = strpos($dsn, '://')) !== false) {
|
||||
$str = substr($dsn, 0, $pos);
|
||||
$dsn = substr($dsn, $pos + 3);
|
||||
} else {
|
||||
$str = $dsn;
|
||||
$dsn = NULL;
|
||||
}
|
||||
|
||||
// Get phptype and dbsyntax
|
||||
// $str => phptype(dbsyntax)
|
||||
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
|
||||
$parsed['phptype'] = $arr[1];
|
||||
$parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
|
||||
} else {
|
||||
$parsed['phptype'] = $str;
|
||||
$parsed['dbsyntax'] = $str;
|
||||
}
|
||||
|
||||
if (empty($dsn)) {
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
// Get (if found): username and password
|
||||
// $dsn => username:password@protocol+hostspec/database
|
||||
if (($at = strrpos($dsn,'@')) !== false) {
|
||||
$str = substr($dsn, 0, $at);
|
||||
$dsn = substr($dsn, $at + 1);
|
||||
if (($pos = strpos($str, ':')) !== false) {
|
||||
$parsed['username'] = urldecode(substr($str, 0, $pos));
|
||||
$parsed['password'] = urldecode(substr($str, $pos + 1));
|
||||
} else {
|
||||
$parsed['username'] = urldecode($str);
|
||||
}
|
||||
}
|
||||
|
||||
// Find protocol and hostspec
|
||||
|
||||
// $dsn => proto(proto_opts)/database
|
||||
if (preg_match('|^(.+?)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
|
||||
$proto = $match[1];
|
||||
$proto_opts = (!empty($match[2])) ? $match[2] : false;
|
||||
$dsn = $match[3];
|
||||
|
||||
// $dsn => protocol+hostspec/database (old format)
|
||||
} else {
|
||||
if (strpos($dsn, '+') !== false) {
|
||||
list($proto, $dsn) = explode('+', $dsn, 2);
|
||||
}
|
||||
if (strpos($dsn, '/') !== false) {
|
||||
list($proto_opts, $dsn) = explode('/', $dsn, 2);
|
||||
} else {
|
||||
$proto_opts = $dsn;
|
||||
$dsn = null;
|
||||
}
|
||||
}
|
||||
|
||||
// process the different protocol options
|
||||
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
|
||||
$proto_opts = urldecode($proto_opts);
|
||||
if ($parsed['protocol'] == 'tcp') {
|
||||
if (strpos($proto_opts, ':') !== false) {
|
||||
list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts);
|
||||
} else {
|
||||
$parsed['hostspec'] = $proto_opts;
|
||||
}
|
||||
} elseif ($parsed['protocol'] == 'unix') {
|
||||
$parsed['socket'] = $proto_opts;
|
||||
}
|
||||
|
||||
// Get dabase if any
|
||||
// $dsn => database
|
||||
if (!empty($dsn)) {
|
||||
// /database
|
||||
if (($pos = strpos($dsn, '?')) === false) {
|
||||
$parsed['database'] = $dsn;
|
||||
// /database?param1=value1¶m2=value2
|
||||
} else {
|
||||
$parsed['database'] = substr($dsn, 0, $pos);
|
||||
$dsn = substr($dsn, $pos + 1);
|
||||
if (strpos($dsn, '&') !== false) {
|
||||
$opts = explode('&', $dsn);
|
||||
} else { // database?param1=value1
|
||||
$opts = array($dsn);
|
||||
}
|
||||
foreach ($opts as $opt) {
|
||||
list($key, $value) = explode('=', $opt);
|
||||
if (!isset($parsed[$key])) { // don't allow params overwrite
|
||||
$parsed[$key] = urldecode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a PHP database extension if it is not loaded already.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name the base name of the extension (without the .so or
|
||||
* .dll suffix)
|
||||
*
|
||||
* @return boolean true if the extension was already or successfully
|
||||
* loaded, false if it could not be loaded
|
||||
*/
|
||||
function assertExtension($name)
|
||||
{
|
||||
if (!extension_loaded($name)) {
|
||||
$dlext = OS_WINDOWS ? '.dll' : '.so';
|
||||
@dl($name . $dlext);
|
||||
}
|
||||
return extension_loaded($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DB_Error implements a class for reporting portable database error
|
||||
* messages.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class DB_Error extends PEAR_Error
|
||||
{
|
||||
/**
|
||||
* DB_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 smixed $debuginfo additional debug info, such as the last query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @see PEAR_Error
|
||||
*/
|
||||
|
||||
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
|
||||
$level = E_USER_NOTICE, $debuginfo = null)
|
||||
{
|
||||
if (is_int($code)) {
|
||||
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
|
||||
} else {
|
||||
$this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DB_Warning implements a class for reporting portable database
|
||||
* warning messages.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class DB_Warning extends PEAR_Error
|
||||
{
|
||||
/**
|
||||
* DB_Warning 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 mmixed $debuginfo additional debug info, such as the last query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @see PEAR_Error
|
||||
*/
|
||||
|
||||
function DB_Warning($code = DB_WARNING, $mode = PEAR_ERROR_RETURN,
|
||||
$level = E_USER_NOTICE, $debuginfo = null)
|
||||
{
|
||||
if (is_int($code)) {
|
||||
$this->PEAR_Error('DB Warning: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
|
||||
} else {
|
||||
$this->PEAR_Error("DB Warning: $code", 0, $mode, $level, $debuginfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements a wrapper for a DB result set.
|
||||
* A new instance of this class will be returned by the DB implementation
|
||||
* after processing a query that returns data.
|
||||
*
|
||||
* @package DB
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
|
||||
class DB_result
|
||||
{
|
||||
var $dbh;
|
||||
var $result;
|
||||
var $row_counter = null;
|
||||
/**
|
||||
* for limit queries, the row to start fetching
|
||||
* @var integer
|
||||
*/
|
||||
var $limit_from = null;
|
||||
|
||||
/**
|
||||
* for limit queries, the number of rows to fetch
|
||||
* @var integer
|
||||
*/
|
||||
var $limit_count = null;
|
||||
|
||||
/**
|
||||
* DB_result constructor.
|
||||
* @param resource $dbh DB object reference
|
||||
* @param resource $result result resource id
|
||||
*/
|
||||
|
||||
function DB_result(&$dbh, $result)
|
||||
{
|
||||
$this->dbh = &$dbh;
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses driver->fetchInto for that)
|
||||
* @param int $fetchmode format of fetched row
|
||||
* @param int $rownum the row number to fetch
|
||||
*
|
||||
* @return array a row of data, NULL on no more rows or PEAR_Error on error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function fetch_assoc($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->dbh->fetchmode;
|
||||
}
|
||||
if ($fetchmode === DB_FETCHMODE_OBJECT) {
|
||||
$fetchmode = DB_FETCHMODE_ASSOC;
|
||||
$object_class = $this->dbh->fetchmode_object_class;
|
||||
}
|
||||
if ($this->limit_from !== null) {
|
||||
if ($this->row_counter === null) {
|
||||
$this->row_counter = $this->limit_from;
|
||||
// For Interbase
|
||||
if ($this->dbh->features['limit'] == false) {
|
||||
$i = 0;
|
||||
while ($i++ < $this->limit_from) {
|
||||
$this->dbh->fetchInto($this->result, $arr, $fetchmode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->row_counter >= (
|
||||
$this->limit_from + $this->limit_count))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ($this->dbh->features['limit'] == 'emulate') {
|
||||
$rownum = $this->row_counter;
|
||||
}
|
||||
|
||||
$this->row_counter++;
|
||||
}
|
||||
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
if (isset($object_class)) {
|
||||
// default mode specified in DB_common::fetchmode_object_class property
|
||||
if ($object_class == 'stdClass') {
|
||||
$ret = (object) $arr;
|
||||
} else {
|
||||
$ret =& new $object_class($arr);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a row of data into an existing variable.
|
||||
*
|
||||
* @param mixed $arr reference to data containing the row
|
||||
* @param integer $fetchmode format of fetched row
|
||||
* @param integer $rownum the row number to fetch
|
||||
*
|
||||
* @return mixed DB_OK on success, NULL on no more rows or
|
||||
* a DB_Error object on error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->dbh->fetchmode;
|
||||
}
|
||||
if ($fetchmode === DB_FETCHMODE_OBJECT) {
|
||||
$fetchmode = DB_FETCHMODE_ASSOC;
|
||||
$object_class = $this->dbh->fetchmode_object_class;
|
||||
}
|
||||
if ($this->limit_from !== null) {
|
||||
if ($this->row_counter === null) {
|
||||
$this->row_counter = $this->limit_from;
|
||||
// For Interbase
|
||||
if ($this->dbh->features['limit'] == false) {
|
||||
$i = 0;
|
||||
while ($i++ < $this->limit_from) {
|
||||
$this->dbh->fetchInto($this->result, $arr, $fetchmode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->row_counter >= (
|
||||
$this->limit_from + $this->limit_count))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ($this->dbh->features['limit'] == 'emulate') {
|
||||
$rownum = $this->row_counter;
|
||||
}
|
||||
|
||||
$this->row_counter++;
|
||||
}
|
||||
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
|
||||
if (($res === DB_OK) && isset($object_class)) {
|
||||
// default mode specified in DB_common::fetchmode_object_class property
|
||||
if ($object_class == 'stdClass') {
|
||||
$arr = (object) $arr;
|
||||
} else {
|
||||
$arr = new $object_class($arr);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the the number of columns in a result set.
|
||||
*
|
||||
* @return int the number of columns, or a DB error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function numCols()
|
||||
{
|
||||
return $this->dbh->numCols($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @return int the number of rows, or a DB error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function numRows()
|
||||
{
|
||||
return $this->dbh->numRows($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next result if a batch of queries was executed.
|
||||
*
|
||||
* @return bool true if a new result is available or false if not.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function nextResult()
|
||||
{
|
||||
return $this->dbh->nextResult($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the resources allocated for this result set.
|
||||
* @return int error code
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
$err = $this->dbh->freeResult($this->result);
|
||||
if(DB::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
$this->result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
function tableInfo($mode = null)
|
||||
{
|
||||
return $this->dbh->tableInfo($this->result, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the actual rows number
|
||||
* @return integer
|
||||
*/
|
||||
function getRowCounter()
|
||||
{
|
||||
return $this->row_counter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pear DB Row Object
|
||||
* @see DB_common::setFetchMode()
|
||||
*/
|
||||
class DB_row
|
||||
{
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param resource row data as array
|
||||
*/
|
||||
function DB_row(&$arr)
|
||||
{
|
||||
for (reset($arr); $key = key($arr); next($arr)) {
|
||||
$this->$key = &$arr[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
90
html/service/include/DB/IDEAS
Normal file
90
html/service/include/DB/IDEAS
Normal file
@@ -0,0 +1,90 @@
|
||||
Abstracted Types (Stig)
|
||||
-----------------------
|
||||
|
||||
DB needs a set of types representing the most commonly used types in
|
||||
all backends. This type set could also be geared towards integration
|
||||
with things like XML-RPC/SOAP implementations, HTML form classes, etc.
|
||||
|
||||
Real Query Parser (Stig)
|
||||
------------------------
|
||||
|
||||
With a real query parser, DB can implement more of its portability
|
||||
based on the query, instead of having support functions for
|
||||
everything. One example would be LIMIT, another "INSERT
|
||||
... RETURNING".
|
||||
|
||||
Portable transactions (Stig)
|
||||
----------------------------
|
||||
|
||||
If DB can parse queries enough to determine what tables are affected
|
||||
by queries, it should be possible to make a replayable transaction
|
||||
log. GNOME uses an XML format for configuration data that lets you
|
||||
checkpoint state once in a while, and revert to that state later.
|
||||
With a similar approach for transactions in DB we can implement
|
||||
portable transactions and checkpointing even for the databases that
|
||||
don't support them.
|
||||
|
||||
|
||||
Error reporting clean-up/debug (Tomas)
|
||||
-------------------------------------
|
||||
Now each driver has its own raiseError method, common has a raiseError and
|
||||
DB has a DB_error class and its own isError() method. This error stuff
|
||||
overhead could be simplified with only one raiseError, droping the DB Error
|
||||
class and also the DB::isError() (use the PEAR.php ones instead).
|
||||
Other idea could be to add a system for allowing people access to all the
|
||||
queries sended by PEAR DB to the backend. Also a new PEAR_ERROR_DEBUG
|
||||
flag that automatically (show|triggers) debug info, perhaps
|
||||
with a new PEAR_(Warning|Debug) object.
|
||||
|
||||
Quote clean-up (Stig)
|
||||
---------------------
|
||||
1. Keep quote and quoteString, but move quoting of strings back into
|
||||
quoteString and make quote call it for strings.
|
||||
|
||||
2. Add an optional "operator" parameter to quote that is one of "=",
|
||||
"<", ">" or "<>" that will be inserted in front of the quoted value
|
||||
unless it is NULL, in which case it will be converted to "IS" (for
|
||||
"=") or "IS NOT" (for the others).
|
||||
|
||||
Auto free statements (Tomas)
|
||||
----------------------------
|
||||
By setting a param in query() or for the hole DB instance, PEAR DB
|
||||
could auto-free results in DB_result->fetch(Into|Row) when the driver
|
||||
returns false.
|
||||
|
||||
Datatypes in prepare syntax (Tomas)
|
||||
-----------------------------------
|
||||
Extend the actual prepare/execute placeholders to support data types, both
|
||||
to check the data introduced to the query and to "cast" the result
|
||||
to native php data types. Ex:
|
||||
|
||||
$sql = "INSERT INTO table VALUES ({{int(4)}}, {{bool}}, {{date('Y-m-d')}})";
|
||||
$row = $db->query($sql, array(8, 't', '2001-04-1'));
|
||||
|
||||
Format: {{<data_type>(<param1>,<param2>)}}
|
||||
|
||||
"param" could be the max lenght of the data, date formats, not_null
|
||||
checks or default values.
|
||||
|
||||
Other ideas could be:
|
||||
|
||||
1)
|
||||
$sql = "INSERT INTO table VALUES (?, ?, ?)";
|
||||
$sth = $db->prepare($sql, array('int(4)', 'bool', 'date');
|
||||
$res = $db->execute($sth, array($a, $b, $c);
|
||||
|
||||
2)
|
||||
$sql = "INSERT INTO table VALUES (?, ?, ?)";
|
||||
$params = array(
|
||||
0 => array($a, 'int(4)'),
|
||||
1 => array($b, 'bool')
|
||||
);
|
||||
$res = $db->query($sql, $params);
|
||||
|
||||
Auto connect feature (Tomas)
|
||||
----------------------------
|
||||
Add the ability to create for example a light and dump DB object which
|
||||
will only set up the connection when needed. With that people could
|
||||
create the DB object in a common prepend or default file without the
|
||||
need to waste system resources if the use of the database is finally
|
||||
not needed.
|
||||
15
html/service/include/DB/MAINTAINERS
Normal file
15
html/service/include/DB/MAINTAINERS
Normal file
@@ -0,0 +1,15 @@
|
||||
Maintainers for DB database backends/drivers:
|
||||
|
||||
ibase : Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
msql :
|
||||
mssql : Frank M. Kromann <frank@frontbase.com>
|
||||
mysql : Stig Bakken <ssb@fast.no>
|
||||
oci8 : Tomas V.V.Cox <cox@idecnet.com>
|
||||
odbc : Tomas V.V.Cox <cox@idecnet.com>
|
||||
pgsql : Rui Hirokawa <rui_hirokawa@ybb.ne.jp>
|
||||
Stig Bakken <ssb@fast.no>
|
||||
sybase :
|
||||
ifx : Tomas V.V.Cox <cox@idecnet.com>
|
||||
fbsql : Frank M. Kromann <frank@frontbase.com>
|
||||
dbase : Tomas V.V.Cox <cox@idecnet.com>
|
||||
ldap : Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
38
html/service/include/DB/STATUS
Normal file
38
html/service/include/DB/STATUS
Normal file
@@ -0,0 +1,38 @@
|
||||
DB driver feature matrix:
|
||||
|
||||
Symbols:
|
||||
"x" - implemented, but without tests
|
||||
"t" - implemented, but one or more tests fail
|
||||
"T" - implemented, passing all tests
|
||||
"e" - emulated, without tests
|
||||
"E" - emulated, passing all tests
|
||||
"n" - returns "not capable"
|
||||
"-" - no implementation of this feature
|
||||
|
||||
|
||||
fbsql ifx mssql oci8 pgsql
|
||||
FEATURE | ibase | msql | mysql | odbc | sybase
|
||||
simpleQuery x T x x x T T x T x
|
||||
numCols x T x x x T T x T x
|
||||
numRows x n n x x T E x T n
|
||||
errorNative x n x n n T x x T n
|
||||
prepare/execute e x e e e E T e E e
|
||||
sequences e T n n n E T n T n
|
||||
affectedRows x n x x n T T x T x
|
||||
fetch modes x T x x x T T x T x
|
||||
fetch row by number x n x x x x n x x x
|
||||
transactions x x n n x x x x x n
|
||||
auto-commit x x n n n n x x x n
|
||||
error mapping x x e - - T T x E -
|
||||
tableInfo x n n n x T n n x n
|
||||
|
||||
|
||||
Info returned by getListOf
|
||||
|
||||
fbsql ifx mssql oci8 pgsql
|
||||
TYPE | ibase | msql | mysql | odbc | sybase
|
||||
tables x - - - x x x - x x
|
||||
views - - - - x n - - x x
|
||||
users - - - - - x - - x -
|
||||
databases - - - - - x - - x -
|
||||
functions - - - - - - - - x -
|
||||
45
html/service/include/DB/TESTERS
Normal file
45
html/service/include/DB/TESTERS
Normal file
@@ -0,0 +1,45 @@
|
||||
How to run tests
|
||||
----------------
|
||||
|
||||
1) First you need the "run-tests.php" script located at the root
|
||||
directory of the PHP 4 source tar ball.
|
||||
|
||||
2) Download the lastest PEAR DB from CVS:
|
||||
|
||||
Where you want to place Pear files
|
||||
# cd /usr/local/lib
|
||||
Log to the repository (use "phpfi" as password):
|
||||
# cvs -d :pserver:cvsread@cvs.php.net:/repository login
|
||||
# cvs -d :pserver:cox@cvs.php.net:/repository co php4/run-tests.php
|
||||
# cvs -d :pserver:cvsread@cvs.php.net:/repository co php4/pear
|
||||
# cd php4
|
||||
# php -f run-tests.php -- <test file or directory>
|
||||
|
||||
<test file or directory> can be:
|
||||
|
||||
pear/DB/tests: Common PEAR DB tests
|
||||
pear/DB/tests/<backend>: Specific backend tests
|
||||
pear/DB/tests/driver: Common tests for all the drivers
|
||||
|
||||
|
||||
DB tester matrix
|
||||
----------------
|
||||
B - A - C - K - E - N - D - S
|
||||
TESTER ibase ifx msql mssql mysql oci8 odbc pgsql sybase fbsql
|
||||
John Horton - X - - - - - - - -
|
||||
Tim Zickus - - - - - X - - - -
|
||||
Tim Parkin - - - - - X - - - -
|
||||
Paul Gardiner - X - - - - - - - -
|
||||
Daniel, Adam - - - - - X - - - -
|
||||
szii@sziisoft.com - - - - - - X¹ - - -
|
||||
jmh3@linuxfreak.com - - - - - - - X - -
|
||||
Kevin Henrikson - - - - - X - - - -
|
||||
Stig Bakken - - - - X - - X - -
|
||||
Chuck Hagenbuch - - - X - - - - - -
|
||||
Ludovico Magnocavallo X - - - - - - - - -
|
||||
|
||||
MISSING TESTERS - - X - - - - - X X
|
||||
|
||||
Comments:
|
||||
|
||||
[1]: ODBC using IBM DB2
|
||||
1282
html/service/include/DB/common.php
Normal file
1282
html/service/include/DB/common.php
Normal file
File diff suppressed because it is too large
Load Diff
123
html/service/include/DB/dbase.php
Normal file
123
html/service/include/DB/dbase.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: dbase.php,v 1.2 2002/02/28 08:27:08 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's dbase
|
||||
// extension.
|
||||
//
|
||||
// XXX legend:
|
||||
// You have to compile your PHP with the --enable-dbase option
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_dbase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $res_row = array();
|
||||
var $result = 0;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_mysql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_dbase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'dbase';
|
||||
$this->dbsyntax = 'dbase';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => false,
|
||||
'transactions' => false,
|
||||
'limit' => false
|
||||
);
|
||||
$this->errorcode_map = array();
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('dbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
ob_start();
|
||||
$conn = dbase_open($dsninfo['database'], 0);
|
||||
$error = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null,
|
||||
null, null, strip_tags($error));
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = dbase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &query($query = null)
|
||||
{
|
||||
// emulate result resources
|
||||
$this->res_row[$this->result] = 0;
|
||||
return new DB_result($this, $this->result++);
|
||||
}
|
||||
|
||||
function fetchInto($res, &$row, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum === null) {
|
||||
$rownum = $this->res_row[$res]++;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$row = @dbase_get_record_with_names($this->connection, $rownum);
|
||||
} else {
|
||||
$row = @dbase_get_record($this->connection, $rownum);
|
||||
}
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function numCols($foo)
|
||||
{
|
||||
return dbase_numfields($this->connection);
|
||||
}
|
||||
|
||||
function numRows($foo)
|
||||
{
|
||||
return dbase_numrecords($this->connection);
|
||||
}
|
||||
}
|
||||
?>
|
||||
618
html/service/include/DB/fbsql.php
Normal file
618
html/service/include/DB/fbsql.php
Normal file
@@ -0,0 +1,618 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Frank M. Kromann <frank@frontbase.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: fbsql.php,v 1.14 2002/02/28 08:27:08 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's FrontBase
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the fbsql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_fbsql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $num_rows = array();
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_fbsql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_fbsql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'fbsql';
|
||||
$this->dbsyntax = 'fbsql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
1004 => DB_ERROR_CANNOT_CREATE,
|
||||
1005 => DB_ERROR_CANNOT_CREATE,
|
||||
1006 => DB_ERROR_CANNOT_CREATE,
|
||||
1007 => DB_ERROR_ALREADY_EXISTS,
|
||||
1008 => DB_ERROR_CANNOT_DROP,
|
||||
1046 => DB_ERROR_NODBSELECTED,
|
||||
1050 => DB_ERROR_ALREADY_EXISTS,
|
||||
1051 => DB_ERROR_NOSUCHTABLE,
|
||||
1054 => DB_ERROR_NOSUCHFIELD,
|
||||
1062 => DB_ERROR_ALREADY_EXISTS,
|
||||
1064 => DB_ERROR_SYNTAX,
|
||||
1100 => DB_ERROR_NOT_LOCKED,
|
||||
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
1146 => DB_ERROR_NOSUCHTABLE,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
* @access public
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('fbsql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect';
|
||||
|
||||
ini_set('track_errors', true);
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = @$connect_function($dbhost);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
ini_restore("track_errors");
|
||||
if (empty($conn)) {
|
||||
if (empty($php_errormsg)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!fbsql_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = fbsql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to fbsql and return the results as a fbsql resource
|
||||
* identifier.
|
||||
*
|
||||
* @param the SQL query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed returns a valid fbsql result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error is
|
||||
* returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @fbsql_query("$query;", $this->connection);
|
||||
if (!$result) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (DB::isManip($query)) {
|
||||
return DB_OK;
|
||||
}
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$result] = $numrows;
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal fbsql 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 @fbsql_next_result($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result fbsql result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
* @access public
|
||||
*
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@fbsql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @fbsql_fetch_array($result, FBSQL_ASSOC);
|
||||
} else {
|
||||
$arr = @fbsql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
$errno = @fbsql_errno($this->connection);
|
||||
if (!$errno) {
|
||||
return NULL;
|
||||
}
|
||||
return $this->fbsqlRaiseError($errno);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result fbsql result identifier or DB statement identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return fbsql_free_result($result);
|
||||
}
|
||||
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
function autoCommit($onoff=false)
|
||||
{
|
||||
if ($onoff) {
|
||||
$this->query("SET COMMIT TRUE");
|
||||
} else {
|
||||
$this->query("SET COMMIT FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
function commit()
|
||||
{
|
||||
fbsql_commit();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
function rollback()
|
||||
{
|
||||
fbsql_rollback();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @fbsql_num_fields($result);
|
||||
|
||||
if (!$cols) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result fbsql result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @fbsql_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @fbsql_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int native fbsql error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
return fbsql_errno($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for fbsql. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
$result = $this->query("INSERT INTO ${seqname} VALUES(NULL)");
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return fbsql_insert_id($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
return $this->query("CREATE TABLE ${seqname} ".
|
||||
'(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
|
||||
' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$sqn = preg_replace('/[^a-z0-9_]/i', '_', $seq_name);
|
||||
$seqname = sprintf($this->getOption("seqname_format"), $sqn);
|
||||
return $this->query("DROP TABLE ${seqname} RESTRICT");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
function modifyQuery($query)
|
||||
{
|
||||
if ($this->options['optimize'] == 'portability') {
|
||||
// "DELETE FROM table" gives 0 affected rows in fbsql.
|
||||
// This little hack lets you know how many rows were deleted.
|
||||
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
|
||||
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
|
||||
'DELETE FROM \1 WHERE 1=1', $query);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fbsqlRaiseError()
|
||||
|
||||
function fbsqlRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(fbsql_errno($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
fbsql_error($this->connection));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
function tableInfo($result, $mode = null) {
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
if (is_string($result)) {
|
||||
$id = @fbsql_list_fields($this->dsn['database'],
|
||||
$result, $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->fbsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @fbsql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @fbsql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @fbsql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @fbsql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @fbsql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @fbsql_field_flags ($id, $i);
|
||||
}
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @fbsql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @fbsql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @fbsql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @fbsql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @fbsql_field_flags ($id, $i);
|
||||
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 (is_string($result)) {
|
||||
@fbsql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = 'select "table_name" from information_schema.tables';
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// TODO/wishlist:
|
||||
// longReadlen
|
||||
// binmode
|
||||
|
||||
?>
|
||||
592
html/service/include/DB/ibase.php
Normal file
592
html/service/include/DB/ibase.php
Normal file
@@ -0,0 +1,592 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: ibase.php,v 1.36.2.2 2002/04/09 19:04:13 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Interbase
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_ibase extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $autocommit = 1;
|
||||
var $manip_query = array();
|
||||
|
||||
function DB_ibase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'ibase';
|
||||
$this->dbsyntax = 'ibase';
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => false
|
||||
);
|
||||
// just a few of the tons of Interbase error codes listed in the
|
||||
// Language Reference section of the Interbase manual
|
||||
$this->errorcode_map = array(
|
||||
-104 => DB_ERROR_SYNTAX,
|
||||
-150 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-151 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-155 => DB_ERROR_NOSUCHTABLE,
|
||||
-157 => DB_ERROR_NOSUCHFIELD,
|
||||
-158 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
-170 => DB_ERROR_MISMATCH,
|
||||
-171 => DB_ERROR_MISMATCH,
|
||||
-172 => DB_ERROR_INVALID,
|
||||
-204 => DB_ERROR_INVALID,
|
||||
-205 => DB_ERROR_NOSUCHFIELD,
|
||||
-206 => DB_ERROR_NOSUCHFIELD,
|
||||
-208 => DB_ERROR_INVALID,
|
||||
-219 => DB_ERROR_NOSUCHTABLE,
|
||||
-297 => DB_ERROR_CONSTRAINT,
|
||||
-530 => DB_ERROR_CONSTRAINT,
|
||||
-803 => DB_ERROR_CONSTRAINT,
|
||||
-551 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-552 => DB_ERROR_ACCESS_VIOLATION,
|
||||
-922 => DB_ERROR_NOSUCHDB,
|
||||
-923 => DB_ERROR_CONNECT_FAILED,
|
||||
-924 => DB_ERROR_CONNECT_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('interbase')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ?
|
||||
($dsninfo['hostspec'] . ':/' . $dsninfo['database']) :
|
||||
$dsninfo['database'];
|
||||
|
||||
$connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect';
|
||||
|
||||
$params = array();
|
||||
$params[] = $dbhost;
|
||||
$params[] = !empty($user) ? $user : null;
|
||||
$params[] = !empty($pw) ? $pw : null;
|
||||
$params[] = isset($dsninfo['charset']) ? $dsninfo['charset'] : null;
|
||||
$params[] = isset($dsninfo['buffers']) ? $dsninfo['buffers'] : null;
|
||||
$params[] = isset($dsninfo['dialect']) ? $dsninfo['dialect'] : null;
|
||||
$params[] = isset($dsninfo['role']) ? $dsninfo['role'] : null;
|
||||
|
||||
/*
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = $connect_function($dbhost);
|
||||
} else {
|
||||
return $this->raiseError("no host, user or password");
|
||||
}
|
||||
*/
|
||||
$conn = @call_user_func_array($connect_function, $params);
|
||||
if (!$conn) {
|
||||
return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @ibase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @ibase_query($this->connection, $query);
|
||||
if (!$result) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
if ($this->autocommit && $ismanip) {
|
||||
ibase_commit($this->connection);
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* This method is used by backends to alter limited queries
|
||||
* Uses the new FIRST n SKIP n Firebird 1.0 syntax, so it is
|
||||
* only compatible with Firebird 1.x
|
||||
*
|
||||
* @param string $query query to modify
|
||||
* @param integer $from the row to start to fetching
|
||||
* @param integer $count the numbers of rows to fetch
|
||||
*
|
||||
* @return the new (modified) query
|
||||
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
if ($this->dsn['dbsyntax'] == 'firebird') {
|
||||
$from++; // SKIP starts from 1, ie SKIP 1 starts from the first record
|
||||
$query = preg_replace('/^\s*select\s(.*)$/is',
|
||||
"SELECT FIRST $count SKIP $from $1", $query);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal ibase 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum = null)
|
||||
{
|
||||
if ($rownum !== NULL) {
|
||||
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = get_object_vars(ibase_fetch_object($result));
|
||||
if ($ar && $this->options['optimize'] == 'portability') {
|
||||
$ar = array_change_key_case($ar, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$ar = ibase_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
if ($errmsg = ibase_errmsg()) {
|
||||
return $this->ibaseRaiseError(null, $errmsg);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult()
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return ibase_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function freeQuery($query)
|
||||
{
|
||||
ibase_free_query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = ibase_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function prepare($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$stmt = ibase_prepare($query);
|
||||
$this->manip_query[(int)$stmt] = DB::isManip($query);
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function execute($stmt, $data = false)
|
||||
{
|
||||
$result = ibase_execute($stmt, $data);
|
||||
if (!$result) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
if ($this->autocommit) {
|
||||
ibase_commit($this->connection);
|
||||
}
|
||||
return DB::isManip($this->manip_query[(int)$stmt]) ? DB_OK : new DB_result($this, $result);
|
||||
}
|
||||
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
$this->autocommit = $onoff ? 1 : 0;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function commit()
|
||||
{
|
||||
return ibase_commit($this->connection);
|
||||
}
|
||||
|
||||
function rollback($trans_number)
|
||||
{
|
||||
return ibase_rollback($this->connection, $trans_number);
|
||||
}
|
||||
|
||||
function transactionInit($trans_args = 0)
|
||||
{
|
||||
return $trans_args ? ibase_trans($trans_args, $this->connection) : ibase_trans();
|
||||
}
|
||||
|
||||
// {{{ nextId()
|
||||
/**
|
||||
* Get the next value in a sequence.
|
||||
*
|
||||
* If the sequence does not exist, it will be created,
|
||||
* unless $ondemand is false.
|
||||
*
|
||||
* @access public
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @param bool $ondemand whether to create the sequence on demand
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("SELECT GEN_ID(${sqn}_SEQ, 1) FROM RDB\$GENERATORS"
|
||||
." WHERE RDB\$GENERATOR_NAME='${sqn}_SEQ'");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result)) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$arr = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
$result->free();
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* Create the sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("CREATE GENERATOR ${sqn}_SEQ");
|
||||
$this->popErrorHandling();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Drop a sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$sqn = strtoupper(preg_replace('/[^a-z0-9_]/i', '_', $seq_name));
|
||||
return $this->query("DELETE FROM RDB\$GENERATORS WHERE RDB\$GENERATOR_NAME='${sqn}_SEQ'");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _ibaseFieldFlags()
|
||||
|
||||
/**
|
||||
* get the Flags of a Field
|
||||
*
|
||||
* @param string $field_name the name of the field
|
||||
* @param string $table_name the name of the table
|
||||
*
|
||||
* @return string The flags of the field ("primary_key", "unique_key", "not_null"
|
||||
* "default", "computed" and "blob" are supported)
|
||||
* @access private
|
||||
*/
|
||||
function _ibaseFieldFlags($field_name, $table_name)
|
||||
{
|
||||
|
||||
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
|
||||
.' FROM RDB$INDEX_SEGMENTS I'
|
||||
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
|
||||
.' WHERE I.RDB$FIELD_NAME=\''.$field_name.'\''
|
||||
.' AND R.RDB$RELATION_NAME=\''.$table_name.'\'';
|
||||
$result = ibase_query($this->connection, $sql);
|
||||
if (empty($result)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
if ($obj = @ibase_fetch_object($result)) {
|
||||
ibase_free_result($result);
|
||||
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') {
|
||||
$flags = 'primary_key ';
|
||||
}
|
||||
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') {
|
||||
$flags .= 'unique_key ';
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
|
||||
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,'
|
||||
.' F.RDB$FIELD_TYPE AS FTYPE,'
|
||||
.' F.RDB$COMPUTED_SOURCE AS CSOURCE'
|
||||
.' FROM RDB$RELATION_FIELDS R '
|
||||
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
|
||||
.' WHERE R.RDB$RELATION_NAME=\''.$table_name.'\''
|
||||
.' AND R.RDB$FIELD_NAME=\''.$field_name.'\'';
|
||||
$result = ibase_query($this->connection, $sql);
|
||||
if (empty($result)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
if ($obj = @ibase_fetch_object($result)) {
|
||||
ibase_free_result($result);
|
||||
if (isset($obj->NFLAG)) {
|
||||
$flags .= 'not_null ';
|
||||
}
|
||||
if (isset($obj->DSOURCE)) {
|
||||
$flags .= 'default ';
|
||||
}
|
||||
if (isset($obj->CSOURCE)) {
|
||||
$flags .= 'computed ';
|
||||
}
|
||||
if (isset($obj->FTYPE) && $obj->FTYPE == 261) {
|
||||
$flags .= 'blob ';
|
||||
}
|
||||
}
|
||||
|
||||
return trim($flags);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support 'flags'and 'table' if called from a db_result
|
||||
*
|
||||
* @param mixed $resource Interbase result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = ibase_query($this->connection,"SELECT * FROM $result");
|
||||
if (empty($id)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->ibaseRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @ibase_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$info = @ibase_field_info($id, $i);
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = $info['name'];
|
||||
$res[$i]['type'] = $info['type'];
|
||||
$res[$i]['len'] = $info['length'];
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($info['name'], $result) : '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$info = @ibase_field_info($id, $i);
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = $info['name'];
|
||||
$res[$i]['type'] = $info['type'];
|
||||
$res[$i]['len'] = $info['length'];
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($info['name'], $result) : '';
|
||||
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 (is_resource($id)) {
|
||||
ibase_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ ibaseRaiseError()
|
||||
|
||||
function ibaseRaiseError($errno = null, $errmsg = null)
|
||||
{
|
||||
if ($errmsg === null)
|
||||
$errmsg = ibase_errmsg();
|
||||
// memo for the interbase php module hackers: we need something similar
|
||||
// to mysql_errno() to retrieve error codes instead of this ugly hack
|
||||
if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $errmsg, $m)) {
|
||||
if ($errno === null) {
|
||||
$ibase_errno = (int)$m[2];
|
||||
// try to interpret Interbase error code (that's why we need ibase_errno()
|
||||
// in the interbase module to return the real error code)
|
||||
switch ($ibase_errno) {
|
||||
case -204:
|
||||
if (is_int(strpos($m[3], 'Table unknown'))) {
|
||||
$errno = DB_ERROR_NOSUCHTABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$errno = $this->errorCode($ibase_errno);
|
||||
}
|
||||
}
|
||||
$errmsg = $m[2] . ' ' . $m[3];
|
||||
}
|
||||
|
||||
return $this->raiseError($errno, null, null, $errmsg,
|
||||
$this->last_query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
?>
|
||||
323
html/service/include/DB/ifx.php
Normal file
323
html/service/include/DB/ifx.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: ifx.php,v 1.18 2002/02/28 08:27:09 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Informix
|
||||
// extension.
|
||||
//
|
||||
|
||||
// Legend:
|
||||
// For more info on Informix errors see:
|
||||
// http://www.informix.com/answers/english/ierrors.htm
|
||||
//
|
||||
// TODO:
|
||||
// - set needed env Informix vars on connect
|
||||
// - implement native prepare/execute
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_ifx extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $affected = 0;
|
||||
var $dsn = array();
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
|
||||
function DB_ifx()
|
||||
{
|
||||
$this->phptype = 'ifx';
|
||||
$this->dbsyntax = 'ifx';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
'-201' => DB_ERROR_SYNTAX,
|
||||
'-206' => DB_ERROR_NOSUCHTABLE,
|
||||
'-217' => DB_ERROR_NOSUCHFIELD,
|
||||
'-329' => DB_ERROR_NODBSELECTED,
|
||||
'-1204' => DB_ERROR_INVALID_DATE,
|
||||
'-1205' => DB_ERROR_INVALID_DATE,
|
||||
'-1206' => DB_ERROR_INVALID_DATE,
|
||||
'-1209' => DB_ERROR_INVALID_DATE,
|
||||
'-1210' => DB_ERROR_INVALID_DATE,
|
||||
'-1212' => DB_ERROR_INVALID_DATE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect(&$dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('informix'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : '';
|
||||
$dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : '';
|
||||
$user = $dsninfo['username'] ? $dsninfo['username'] : '';
|
||||
$pw = $dsninfo['password'] ? $dsninfo['password'] : '';
|
||||
|
||||
$connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
|
||||
|
||||
$this->connection = @$connect_function($dbname, $user, $pw);
|
||||
if (!is_resource($this->connection)) {
|
||||
return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @ifx_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a query to Informix and return the results as a
|
||||
* Informix resource identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid Informix result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()?
|
||||
// the scroll is needed for fetching absolute row numbers
|
||||
// in a select query result
|
||||
$result = @ifx_query($query, $this->connection, IFX_SCROLL);
|
||||
} else {
|
||||
$result = @ifx_query($query, $this->connection);
|
||||
}
|
||||
if (!$result) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
$this->affected = ifx_affected_rows ($result);
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if (preg_match('/(SELECT)/i', $query)) {
|
||||
return $result;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal ifx 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns an _estimate_ value.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
return $this->affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result Informix result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a row and return as array.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
* @param $row (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the resulting array should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
*
|
||||
* @return int an array on success, a DB error code on failure, NULL
|
||||
* if there is no more data
|
||||
*/
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
if (($rownum !== null) && ($rownum < 0)) {
|
||||
return null;
|
||||
}
|
||||
// if $rownum is null, fetch row will return the next row
|
||||
if (!$row = @ifx_fetch_row($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ASSOC) {
|
||||
$i=0;
|
||||
$order = array();
|
||||
foreach ($row as $key => $val) {
|
||||
$order[$i++] = $val;
|
||||
}
|
||||
$row = $order;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
if (!$cols = @ifx_num_fields($result)) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result Informix result identifier
|
||||
*
|
||||
* @return bool TRUE on success, DB_error on error
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
if (!@ifx_free_result($result)) {
|
||||
return $this->ifxraiseError();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function ifxraiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(ifx_error());
|
||||
}
|
||||
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
/**
|
||||
* Map native error codes to DB's portable ones. Requires that
|
||||
* the DB implementation's constructor fills in the $errorcode_map
|
||||
* property.
|
||||
*
|
||||
* @return int a portable DB error code, or DB_ERROR if this DB
|
||||
* implementation has no mapping for the given error code.
|
||||
*/
|
||||
|
||||
function errorCode($nativecode)
|
||||
{
|
||||
if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
|
||||
$code = $match[1];
|
||||
if (isset($this->errorcode_map[$code])) {
|
||||
return $this->errorcode_map[$code];
|
||||
}
|
||||
}
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native error message of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @return int native Informix error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return ifx_error() . ' ' . ifx_errormsg();
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
210
html/service/include/DB/msql.php
Normal file
210
html/service/include/DB/msql.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: msql.php,v 1.25 2002/02/28 08:27:10 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Mini-SQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_msql extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
|
||||
function DB_msql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'msql';
|
||||
$this->dbsyntax = 'msql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('msql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
$connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost,$user);
|
||||
} else {
|
||||
$conn = $connect_function($dbhost);
|
||||
}
|
||||
if (!$conn) {
|
||||
$this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
if (!@msql_select_db($dsninfo['database'], $conn)){
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @msql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @msql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal msql 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@msql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = @msql_fetch_array($result, MSQL_ASSOC);
|
||||
} else {
|
||||
$ar = @msql_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
if ($error = msql_error()) {
|
||||
return $this->raiseError($error);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @msql_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[$result]);
|
||||
unset($this->prepare_types[$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @msql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @msql_num_rows($result);
|
||||
if (!$rows) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by a query.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
return @msql_affected_rows($this->connection);
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
?>
|
||||
500
html/service/include/DB/mssql.php
Normal file
500
html/service/include/DB/mssql.php
Normal file
@@ -0,0 +1,500 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mssql.php,v 1.40 2002/02/28 08:27:10 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Microsoft SQL Server
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_mssql extends DB_common
|
||||
{
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $autocommit = true;
|
||||
|
||||
function DB_mssql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'mssql';
|
||||
$this->dbsyntax = 'mssql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
|
||||
$this->errorcode_map = array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('mssql') && !DB::assertExtension('sybase')
|
||||
&& !DB::assertExtension('sybase_ct'))
|
||||
{
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} else {
|
||||
$conn = @$connect_function($dbhost);
|
||||
}
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, mssql_get_last_message());
|
||||
}
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mssql_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED, null, null,
|
||||
null, mssql_get_last_message());
|
||||
}
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @mssql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@mssql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$ar = @mssql_fetch_array($result);
|
||||
} else {
|
||||
$ar = @mssql_fetch_row($result);
|
||||
}
|
||||
if (!$ar) {
|
||||
/* This throws informative error messages,
|
||||
don't use it for now
|
||||
if ($msg = mssql_get_last_message()) {
|
||||
return $this->raiseError($msg);
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @mssql_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[$result]);
|
||||
unset($this->prepare_types[$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mssql_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mssql_num_rows($result);
|
||||
if ($rows === false) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @mssql_query('COMMIT TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @mssql_query('ROLLBACK TRAN', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$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()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MSSQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$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 $result;
|
||||
}
|
||||
} else {
|
||||
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$result = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE TABLE $seqname ".
|
||||
'([id] [int] IDENTITY (1, 1) NOT NULL ,' .
|
||||
'[vapor] [int] NULL)');
|
||||
}
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE $seqname");
|
||||
}
|
||||
// }}}
|
||||
|
||||
function errorCode()
|
||||
{
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$error_code = $this->getOne('select @@ERROR as ErrorCode');
|
||||
$this->popErrorHandling();
|
||||
// XXX Debug
|
||||
if (!isset($this->errorcode_map[$error_code])) {
|
||||
return DB_ERROR;
|
||||
}
|
||||
return $error_code;
|
||||
}
|
||||
|
||||
function mssqlRaiseError($code = null)
|
||||
{
|
||||
if ($code !== null) {
|
||||
$code = $this->errorCode();
|
||||
if (DB::isError($code)) {
|
||||
return $this->raiseError($code);
|
||||
}
|
||||
}
|
||||
return $this->raiseError($code, null, null, null,
|
||||
mssql_get_last_message());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support table name and flags if called from a db_result
|
||||
*
|
||||
* @param mixed $resource SQL Server result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = mssql_query("SELECT * FROM $result", $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->mssqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @mssql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @mssql_field_name($id, $i);
|
||||
$res[$i]['type'] = @mssql_field_type($id, $i);
|
||||
$res[$i]['len'] = @mssql_field_length($id, $i);
|
||||
$res[$i]['flags'] = '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res['num_fields']= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @mssql_field_name($id, $i);
|
||||
$res[$i]['type'] = @mssql_field_type($id, $i);
|
||||
$res[$i]['len'] = @mssql_field_length($id, $i);
|
||||
$res[$i]['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 (is_string($result)) {
|
||||
@mssql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "select name from sysobjects where type = 'U' order by name";
|
||||
break;
|
||||
case 'views':
|
||||
$sql = "select name from sysobjects where type = 'V'";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
?>
|
||||
847
html/service/include/DB/mysql.php
Normal file
847
html/service/include/DB/mysql.php
Normal file
@@ -0,0 +1,847 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mysql.php,v 1.89.2.1 2002/04/09 19:04:14 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's MySQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the mysql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once "DB/common.php";
|
||||
|
||||
class DB_mysql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $num_rows = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $autocommit = true;
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
|
||||
var $_db = false;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* DB_mysql constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function DB_mysql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'mysql';
|
||||
$this->dbsyntax = 'mysql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
1004 => DB_ERROR_CANNOT_CREATE,
|
||||
1005 => DB_ERROR_CANNOT_CREATE,
|
||||
1006 => DB_ERROR_CANNOT_CREATE,
|
||||
1007 => DB_ERROR_ALREADY_EXISTS,
|
||||
1008 => DB_ERROR_CANNOT_DROP,
|
||||
1046 => DB_ERROR_NODBSELECTED,
|
||||
1050 => DB_ERROR_ALREADY_EXISTS,
|
||||
1051 => DB_ERROR_NOSUCHTABLE,
|
||||
1054 => DB_ERROR_NOSUCHFIELD,
|
||||
1062 => DB_ERROR_ALREADY_EXISTS,
|
||||
1064 => DB_ERROR_SYNTAX,
|
||||
1100 => DB_ERROR_NOT_LOCKED,
|
||||
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
|
||||
1146 => DB_ERROR_NOSUCHTABLE,
|
||||
1048 => DB_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
* @access public
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('mysql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
|
||||
$dbhost = ':' . $dsninfo['socket'];
|
||||
} else {
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$dbhost .= ':' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = @$connect_function($dbhost);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
@ini_restore('track_errors');
|
||||
if (empty($conn)) {
|
||||
if (($err = @mysql_error()) != '') {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $err);
|
||||
} elseif (empty($php_errormsg)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
} else {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mysql_select_db($dsninfo['database'], $conn)) {
|
||||
switch(mysql_errno($conn)) {
|
||||
case 1049:
|
||||
return $this->raiseError(DB_ERROR_NOSUCHDB, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
case 1044:
|
||||
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
default:
|
||||
return $this->raiseError(DB_ERROR, null, null,
|
||||
null, mysql_error($conn));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
// fix to allow calls to different databases in the same script
|
||||
$this->_db = $dsninfo['database'];
|
||||
}
|
||||
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = mysql_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to MySQL and return the results as a MySQL resource
|
||||
* identifier.
|
||||
*
|
||||
* @param the SQL query
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed returns a valid MySQL result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error is
|
||||
* returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
if (!@mysql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection);
|
||||
$result = @mysql_query('BEGIN', $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @mysql_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
if (is_resource($result)) {
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$result] = $numrows;
|
||||
return $result;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal mysql 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result MySQL result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
* @access public
|
||||
*
|
||||
* @return int DB_OK on success, a DB error on failure
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!@mysql_data_seek($result, $rownum)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$arr = @mysql_fetch_array($result, MYSQL_ASSOC);
|
||||
} else {
|
||||
$arr = @mysql_fetch_row($result);
|
||||
}
|
||||
if (!$arr) {
|
||||
$errno = @mysql_errno($this->connection);
|
||||
if (!$errno) {
|
||||
return NULL;
|
||||
}
|
||||
return $this->mysqlRaiseError($errno);
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result MySQL result identifier or DB statement identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return mysql_free_result($result);
|
||||
}
|
||||
|
||||
$result = (int)$result; // $result is a prepared query handle
|
||||
if (!isset($this->prepare_tokens[$result])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// [ssb]: WTF? unset($this->prepare_types[$result]) makes PHP
|
||||
// crash on my laptop (4.1.2 as well as 4.3.0-dev)
|
||||
|
||||
$copy = $this->prepare_types;
|
||||
unset($copy[$result]);
|
||||
$this->prepare_types = $copy;
|
||||
// unset($this->prepare_types[$result]);
|
||||
|
||||
$copy = $this->prepare_tokens;
|
||||
unset($copy[$result]);
|
||||
$this->prepare_tokens = $copy;
|
||||
// unset($this->prepare_tokens[$result]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @mysql_num_fields($result);
|
||||
|
||||
if (!$cols) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result MySQL result identifier
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @mysql_num_rows($result);
|
||||
if ($rows === null) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mysql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mysql_query('COMMIT', $this->connection);
|
||||
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
if (!@mysql_select_db($this->_db, $this->connection)) {
|
||||
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
$result = @mysql_query('ROLLBACK', $this->connection);
|
||||
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @mysql_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int native MySQL error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
return mysql_errno($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MySQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
*
|
||||
* @param bool $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return mixed a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
do {
|
||||
$repeat = 0;
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("UPDATE ${seqname} ".
|
||||
'SET id=LAST_INSERT_ID(id+1)');
|
||||
$this->popErrorHandling();
|
||||
if ($result == DB_OK) {
|
||||
/** COMMON CASE **/
|
||||
$id = mysql_insert_id($this->connection);
|
||||
if ($id != 0) {
|
||||
return $id;
|
||||
}
|
||||
/** EMPTY SEQ TABLE **/
|
||||
// Sequence table must be empty for some reason, so fill it and return 1
|
||||
// Obtain a user-level lock
|
||||
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
if ($result == 0) {
|
||||
// Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error
|
||||
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
|
||||
}
|
||||
|
||||
// add the default value
|
||||
$result = $this->query("REPLACE INTO ${seqname} VALUES (0)");
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
// Release the lock
|
||||
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
// We know what the result will be, so no need to try again
|
||||
return 1;
|
||||
|
||||
/** ONDEMAND TABLE CREATION **/
|
||||
} elseif ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE)
|
||||
{
|
||||
$result = $this->createSequence($seq_name);
|
||||
// Since createSequence initializes the ID to be 1,
|
||||
// we do not need to retrieve the ID again (or we will get 2)
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
} else {
|
||||
// First ID of a newly created sequence is 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** BACKWARDS COMPAT **/
|
||||
} elseif (DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
// see _BCsequence() comment
|
||||
$result = $this->_BCsequence($seqname);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$repeat = 1;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$res = $this->query("CREATE TABLE ${seqname} ".
|
||||
'(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
|
||||
' PRIMARY KEY(id))');
|
||||
if (DB::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
// insert yields value 1, nextId call will generate ID 2
|
||||
return $this->query("INSERT INTO ${seqname} VALUES(0)");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Bacwards Compatibility with old sequence emulation implementation
|
||||
* (clean up the dupes)
|
||||
* @param string $seqname The sequence name to clean up
|
||||
* @return mixed DB_Error or true
|
||||
*/
|
||||
function _BCsequence($seqname)
|
||||
{
|
||||
// Obtain a user-level lock... this will release any previous
|
||||
// application locks, but unlike LOCK TABLES, it does not abort
|
||||
// the current transaction and is much less frequently used.
|
||||
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($result == 0) {
|
||||
// Failed to get the lock, can't do the conversion, bail
|
||||
// with a DB_ERROR_NOT_LOCKED error
|
||||
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
|
||||
}
|
||||
|
||||
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
|
||||
if (DB::isError($highest_id)) {
|
||||
return $highest_id;
|
||||
}
|
||||
// This should kill all rows except the highest
|
||||
// We should probably do something if $highest_id isn't
|
||||
// numeric, but I'm at a loss as how to handle that...
|
||||
$result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// If another thread has been waiting for this lock,
|
||||
// it will go thru the above procedure, but will have no
|
||||
// real effect
|
||||
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// {{{ quote()
|
||||
/**
|
||||
* Quote the given string so it can be safely used within string delimiters
|
||||
* in a query.
|
||||
* @param $string mixed Data to be quoted
|
||||
* @return mixed "NULL" string, quoted string or original data
|
||||
*/
|
||||
function quote($str = null)
|
||||
{
|
||||
switch (strtolower(gettype($str))) {
|
||||
case 'null':
|
||||
return 'NULL';
|
||||
case 'integer':
|
||||
return $str;
|
||||
case 'string':
|
||||
default:
|
||||
return "'".mysql_escape_string($str)."'";
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
function modifyQuery($query, $subject = null)
|
||||
{
|
||||
if ($this->options['optimize'] == 'portability') {
|
||||
// "DELETE FROM table" gives 0 affected rows in MySQL.
|
||||
// This little hack lets you know how many rows were deleted.
|
||||
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
|
||||
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
|
||||
'DELETE FROM \1 WHERE 1=1', $query);
|
||||
}
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
$query = $query . " LIMIT $from, $count";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mysqlRaiseError()
|
||||
|
||||
function mysqlRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(mysql_errno($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
@mysql_errno($this->connection) . " ** " .
|
||||
@mysql_error($this->connection));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
function tableInfo($result, $mode = null) {
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
if (is_string($result)) {
|
||||
$id = @mysql_list_fields($this->dsn['database'],
|
||||
$result, $this->connection);
|
||||
if (empty($id)) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->mysqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @mysql_num_fields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @mysql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @mysql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @mysql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @mysql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @mysql_field_flags ($id, $i);
|
||||
}
|
||||
} else { // full
|
||||
$res['num_fields']= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = @mysql_field_table ($id, $i);
|
||||
$res[$i]['name'] = @mysql_field_name ($id, $i);
|
||||
$res[$i]['type'] = @mysql_field_type ($id, $i);
|
||||
$res[$i]['len'] = @mysql_field_len ($id, $i);
|
||||
$res[$i]['flags'] = @mysql_field_flags ($id, $i);
|
||||
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 (is_string($result)) {
|
||||
@mysql_free_result($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTablesQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "SHOW TABLES";
|
||||
break;
|
||||
case 'views':
|
||||
return DB_ERROR_NOT_CAPABLE;
|
||||
case 'users':
|
||||
$sql = "select distinct User from user";
|
||||
if($this->dsn['database'] != 'mysql') {
|
||||
$dsn = $this->dsn;
|
||||
$dsn['database'] = 'mysql';
|
||||
if (DB::isError($db = DB::connect($dsn))) {
|
||||
return $db;
|
||||
}
|
||||
$sql = $db->getCol($sql);
|
||||
$db->disconnect();
|
||||
// XXX Fixme the mysql driver should take care of this
|
||||
if (!@mysql_select_db($this->dsn['database'], $this->connection)) {
|
||||
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
break;
|
||||
case 'databases':
|
||||
$sql = "SHOW DATABASES";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// TODO/wishlist:
|
||||
// longReadlen
|
||||
// binmode
|
||||
}
|
||||
|
||||
?>
|
||||
664
html/service/include/DB/oci8.php
Normal file
664
html/service/include/DB/oci8.php
Normal file
@@ -0,0 +1,664 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: James L. Pine <jlp@valinux.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: oci8.php,v 1.47.2.1 2002/04/09 19:04:15 ssb Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Oracle 8
|
||||
// call-interface extension.
|
||||
//
|
||||
|
||||
//
|
||||
// be aware... OCIError() only appears to return anything when given a
|
||||
// statement, so functions return the generic DB_ERROR instead of more
|
||||
// useful errors that have to do with feedback from the database.
|
||||
//
|
||||
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_oci8 extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $manip_query = array();
|
||||
var $prepare_types = array();
|
||||
var $autoCommit = 1;
|
||||
var $last_stmt = false;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_oci8()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'oci8';
|
||||
$this->dbsyntax = 'oci8';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
900 => DB_ERROR_SYNTAX,
|
||||
904 => DB_ERROR_NOSUCHFIELD,
|
||||
923 => DB_ERROR_SYNTAX,
|
||||
942 => DB_ERROR_NOSUCHTABLE,
|
||||
955 => DB_ERROR_ALREADY_EXISTS,
|
||||
1476 => DB_ERROR_DIVZERO,
|
||||
1722 => DB_ERROR_INVALID_NUMBER,
|
||||
2289 => DB_ERROR_NOSUCHTABLE,
|
||||
2291 => DB_ERROR_CONSTRAINT,
|
||||
2449 => DB_ERROR_CONSTRAINT,
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('oci8')) {
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
}
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$hostspec = $dsninfo['hostspec'];
|
||||
|
||||
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
|
||||
|
||||
if ($hostspec) {
|
||||
$conn = @$connect_function($user,$pw,$hostspec);
|
||||
} elseif ($user || $pw) {
|
||||
$conn = @$connect_function($user,$pw);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
if ($conn == false) {
|
||||
$error = OCIError();
|
||||
$error = (is_array($error)) ? $error['message'] : null;
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $error);
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @OCILogOff($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to oracle and return the results as an oci8 resource
|
||||
* identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid oci8 result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @OCIParse($this->connection, $query);
|
||||
if (!$result) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
if ($this->autoCommit) {
|
||||
$success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
|
||||
} else {
|
||||
$success = @OCIExecute($result,OCI_DEFAULT);
|
||||
}
|
||||
if (!$success) {
|
||||
return $this->oci8RaiseError($result);
|
||||
}
|
||||
$this->last_stmt=$result;
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal oracle result pointer to the next available result
|
||||
*
|
||||
* @param a valid oci8 result resource
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return true if a result is available otherwise return false
|
||||
*/
|
||||
function nextResult($result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
/**
|
||||
* Fetch a row and return as array.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
* @param $fetchmode how the resulting array should be indexed
|
||||
*
|
||||
* @return int an array on success, a DB error code on failure, NULL
|
||||
* if there is no more data
|
||||
*/
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$moredata = @OCIFetchInto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS + OCI_RETURN_LOBS);
|
||||
} else {
|
||||
$moredata = @OCIFetchInto($result, $row, OCI_RETURN_NULLS + OCI_RETURN_LOBS);
|
||||
}
|
||||
if (!$moredata) {
|
||||
return NULL;
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
* @param $arr (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch (not yet supported)
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function fetchInto($result, &$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=NULL)
|
||||
{
|
||||
if ($rownum !== NULL) {
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
|
||||
if ($moredata && $this->options['optimize'] == 'portability') {
|
||||
$arr = array_change_key_case($arr, CASE_LOWER);
|
||||
}
|
||||
} else {
|
||||
$moredata = @OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
|
||||
}
|
||||
if (!$moredata) {
|
||||
return NULL;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result oci8 result identifier or DB statement identifier
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @OCIFreeStatement($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
unset($this->manip_query[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
function numRows($result)
|
||||
{
|
||||
// emulate numRows for Oracle. yuck.
|
||||
if ($this->options['optimize'] == 'portability' &&
|
||||
$result === $this->last_stmt) {
|
||||
$countquery = preg_replace('/^\s*SELECT\s+(.*?)\s+FROM\s+/is',
|
||||
'SELECT COUNT(*) FROM ',
|
||||
$this->last_query);
|
||||
$save_query = $this->last_query;
|
||||
$save_stmt = $this->last_stmt;
|
||||
$count = $this->query($countquery);
|
||||
if (DB::isError($count) ||
|
||||
DB::isError($row = $count->fetch_assoc(DB_FETCHMODE_ORDERED)))
|
||||
{
|
||||
$this->last_query = $save_query;
|
||||
$this->last_stmt = $save_stmt;
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
return $row[0];
|
||||
}
|
||||
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result oci8 result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @OCINumCols($result);
|
||||
if (!$cols) {
|
||||
return $this->oci8RaiseError($result);
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that occured
|
||||
* on the current connection. This does not work, as OCIError does
|
||||
* not work unless given a statement. If OCIError does return
|
||||
* something, so will this.
|
||||
*
|
||||
* @return int native oci8 error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
if (is_resource($this->last_stmt)) {
|
||||
$error = @OCIError($this->last_stmt);
|
||||
} else {
|
||||
$error = @OCIError($this->connection);
|
||||
}
|
||||
if (is_array($error)) {
|
||||
return $error['code'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ prepare()
|
||||
|
||||
/**
|
||||
* Prepares a query for multiple execution with execute(). With
|
||||
* oci8, this is emulated.
|
||||
* @param $query query to be prepared
|
||||
*
|
||||
* @return DB statement resource
|
||||
*/
|
||||
function prepare($query)
|
||||
{
|
||||
$tokens = split('[\&\?]', $query);
|
||||
$token = 0;
|
||||
$types = array();
|
||||
for ($i = 0; $i < strlen($query); $i++) {
|
||||
switch ($query[$i]) {
|
||||
case '?':
|
||||
$types[$token++] = DB_PARAM_SCALAR;
|
||||
break;
|
||||
case '&':
|
||||
$types[$token++] = DB_PARAM_OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$binds = sizeof($tokens) - 1;
|
||||
$newquery = '';
|
||||
for ($i = 0; $i < $binds; $i++) {
|
||||
$newquery .= $tokens[$i] . ":bind" . $i;
|
||||
}
|
||||
$newquery .= $tokens[$i];
|
||||
$this->last_query = $query;
|
||||
$newquery = $this->modifyQuery($newquery);
|
||||
$stmt = @OCIParse($this->connection, $newquery);
|
||||
$this->prepare_types[$stmt] = $types;
|
||||
$this->manip_query[(int)$stmt] = DB::isManip($query);
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execute()
|
||||
|
||||
/**
|
||||
* Executes a DB statement prepared with prepare().
|
||||
*
|
||||
* @param $stmt a DB statement resource (returned from prepare())
|
||||
* @param $data data to be used in execution of the statement
|
||||
*
|
||||
* @return int returns an oci8 result resource for successful
|
||||
* SELECT queries, DB_OK for other successful queries. A DB error
|
||||
* code is returned on failure.
|
||||
*/
|
||||
function execute($stmt, $data = false)
|
||||
{
|
||||
$types=&$this->prepare_types[$stmt];
|
||||
if (($size = sizeof($types)) != sizeof($data)) {
|
||||
return $this->raiseError(DB_ERROR_MISMATCH);
|
||||
}
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (is_array($data)) {
|
||||
$pdata[$i] = &$data[$i];
|
||||
}
|
||||
else {
|
||||
$pdata[$i] = &$data;
|
||||
}
|
||||
if ($types[$i] == DB_PARAM_OPAQUE) {
|
||||
$fp = fopen($pdata[$i], "r");
|
||||
$pdata[$i] = '';
|
||||
if ($fp) {
|
||||
while (($buf = fread($fp, 4096)) != false) {
|
||||
$pdata[$i] .= $buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!@OCIBindByName($stmt, ":bind" . $i, $pdata[$i], -1)) {
|
||||
return $this->oci8RaiseError($stmt);
|
||||
}
|
||||
}
|
||||
if ($this->autoCommit) {
|
||||
$success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS);
|
||||
}
|
||||
else {
|
||||
$success = @OCIExecute($stmt, OCI_DEFAULT);
|
||||
}
|
||||
if (!$success) {
|
||||
return $this->oci8RaiseError($stmt);
|
||||
}
|
||||
$this->last_stmt = $stmt;
|
||||
if ($this->manip_query[(int)$stmt]) {
|
||||
return DB_OK;
|
||||
} else {
|
||||
return new DB_result($this, $stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*
|
||||
* @param $onoff true/false whether to autocommit
|
||||
*/
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
$this->autoCommit = (bool)$onoff;;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
/**
|
||||
* Commit transactions on the current connection
|
||||
*
|
||||
* @return DB_ERROR or DB_OK
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
$result = @OCICommit($this->connection);
|
||||
if (!$result) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back all uncommitted transactions on the current connection.
|
||||
*
|
||||
* @return DB_ERROR or DB_OK
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
$result = @OCIRollback($this->connection);
|
||||
if (!$result) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if ($this->last_stmt === false) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
$result = @OCIRowCount($this->last_stmt);
|
||||
if ($result === false) {
|
||||
return $this->oci8RaiseError($this->last_stmt);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyQuery()
|
||||
|
||||
function modifyQuery($query)
|
||||
{
|
||||
// "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle
|
||||
if (preg_match('/^\s*SELECT/i', $query) &&
|
||||
!preg_match('/\sFROM\s/i', $query)) {
|
||||
$query .= " FROM dual";
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
/**
|
||||
* Emulate the row limit support altering the query
|
||||
*
|
||||
* @param string $query The query to treat
|
||||
* @param int $from The row to start to fetch from
|
||||
* @param int $count The offset
|
||||
* @return string The modified query
|
||||
*
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
*/
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
// Let Oracle return the name of the columns instead of
|
||||
// coding a "home" SQL parser
|
||||
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
|
||||
if (!$result = OCIParse($this->connection, $q_fields)) {
|
||||
return $this->oci8RaiseError();
|
||||
}
|
||||
if (!OCIExecute($result, OCI_DEFAULT)) {
|
||||
return $this->oci8RaiseError($result);
|
||||
}
|
||||
$ncols = OCINumCols($result);
|
||||
$cols = array();
|
||||
for ( $i = 1; $i <= $ncols; $i++ ) {
|
||||
$cols[] = OCIColumnName($result, $i);
|
||||
}
|
||||
$fields = implode(', ', $cols);
|
||||
// XXX Test that (tip by John Lim)
|
||||
//if(preg_match('/^\s*SELECT\s+/is', $query, $match)) {
|
||||
// // Introduce the FIRST_ROWS Oracle query optimizer
|
||||
// $query = substr($query, strlen($match[0]), strlen($query));
|
||||
// $query = "SELECT /* +FIRST_ROWS */ " . $query;
|
||||
//}
|
||||
|
||||
// Construct the query
|
||||
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
|
||||
// Perhaps this could be optimized with the use of Unions
|
||||
$from += 1; // in Oracle rownum starts at 1
|
||||
$query = "SELECT $fields FROM".
|
||||
" (SELECT rownum as linenum, $fields FROM".
|
||||
" ($query)".
|
||||
" WHERE rownum <= ". ($from + $count) .
|
||||
") WHERE linenum >= $from";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for MySQL. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->expectError(DB_ERROR_NOSUCHTABLE);
|
||||
$result = $this->query("SELECT ${seqname}.nextval FROM dual");
|
||||
$this->popExpect();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$arr = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ oci8RaiseError()
|
||||
|
||||
function oci8RaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$error = @OCIError($this->connection);
|
||||
return $this->raiseError($this->errorCode($error['code']),
|
||||
null, null, null, $error['message']);
|
||||
} elseif (is_resource($errno)) {
|
||||
$error = @OCIError($errno);
|
||||
return $this->raiseError($this->errorCode($error['code']),
|
||||
null, null, null, $error['message']);
|
||||
}
|
||||
return $this->raiseError($this->errorCode($errno));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "SELECT table_name FROM user_tables";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
484
html/service/include/DB/odbc.php
Normal file
484
html/service/include/DB/odbc.php
Normal file
@@ -0,0 +1,484 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: odbc.php,v 1.54 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's ODBC
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
// 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
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the odbc function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_odbc extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $row = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_odbc()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'odbc';
|
||||
$this->dbsyntax = 'sql92';
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
'01004' => DB_ERROR_TRUNCATED,
|
||||
'07001' => DB_ERROR_MISMATCH,
|
||||
'21S01' => DB_ERROR_MISMATCH,
|
||||
'21S02' => DB_ERROR_MISMATCH,
|
||||
'22003' => DB_ERROR_INVALID_NUMBER,
|
||||
'22008' => DB_ERROR_INVALID_DATE,
|
||||
'22012' => DB_ERROR_DIVZERO,
|
||||
'23000' => DB_ERROR_CONSTRAINT,
|
||||
'24000' => DB_ERROR_INVALID,
|
||||
'34000' => DB_ERROR_INVALID,
|
||||
'37000' => DB_ERROR_SYNTAX,
|
||||
'42000' => DB_ERROR_SYNTAX,
|
||||
'IM001' => DB_ERROR_UNSUPPORTED,
|
||||
'S0000' => DB_ERROR_NOSUCHTABLE,
|
||||
'S0001' => DB_ERROR_NOT_FOUND,
|
||||
'S0002' => DB_ERROR_NOT_FOUND,
|
||||
'S0011' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0012' => DB_ERROR_NOT_FOUND,
|
||||
'S0021' => DB_ERROR_ALREADY_EXISTS,
|
||||
'S0022' => DB_ERROR_NOT_FOUND,
|
||||
'S1009' => DB_ERROR_INVALID,
|
||||
'S1090' => DB_ERROR_INVALID,
|
||||
'S1C00' => DB_ERROR_NOT_CAPABLE
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('odbc'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
if (!empty($dsninfo['dbsyntax'])) {
|
||||
$this->dbsyntax = $dsninfo['dbsyntax'];
|
||||
}
|
||||
switch ($this->dbsyntax) {
|
||||
case 'solid':
|
||||
$this->features = array(
|
||||
'prepare' => true,
|
||||
'pconnect' => true,
|
||||
'transactions' => true
|
||||
);
|
||||
$default_dsn = 'localhost';
|
||||
break;
|
||||
case 'navision':
|
||||
// the Navision driver doesn't support fetch row by number
|
||||
$this->features['limit'] = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
if ($this->provides('pconnect')) {
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
} else {
|
||||
$connect_function = 'odbc_connect';
|
||||
}
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
if (!is_resource($conn)) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
|
||||
null, $this->errorNative());
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$err = @odbc_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $err;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to ODBC and return the results as a ODBC resource
|
||||
* identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid ODBC result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned 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 (DB::isManip($query)) {
|
||||
$this->manip_result = $result; // For affectedRows()
|
||||
return DB_OK;
|
||||
}
|
||||
$this->row[$result] = 0;
|
||||
$this->manip_result = 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);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
$row = array();
|
||||
if ($rownum !== null) {
|
||||
$rownum++; // ODBC first row is 1
|
||||
if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
|
||||
$cols = odbc_fetch_into($result, $rownum, &$row);
|
||||
} else {
|
||||
$cols = odbc_fetch_into($result, $rownum, $row);
|
||||
}
|
||||
} else {
|
||||
if (!function_exists('version_compare') || version_compare(phpversion(), "4.0.5", "lt")) {
|
||||
$cols = odbc_fetch_into($result, &$row);
|
||||
} else {
|
||||
$cols = odbc_fetch_into($result, $row);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cols) {
|
||||
/* XXX FIXME: doesn't work with unixODBC and easysoft
|
||||
(get corrupted $errno values)
|
||||
if ($errno = odbc_error($this->connection)) {
|
||||
return $this->RaiseError($errno);
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
|
||||
for ($i = 0; $i < count($row); $i++) {
|
||||
$colName = odbc_field_name($result, $i+1);
|
||||
$a[$colName] = $row[$i];
|
||||
}
|
||||
$row = $a;
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
// Always return true
|
||||
return odbc_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @odbc_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Returns the number of rows affected by a manipulative query
|
||||
* (INSERT, DELETE, UPDATE)
|
||||
* @return mixed int affected rows, 0 when non manip queries or
|
||||
* DB error on error
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
if (empty($this->manip_result)) { // In case of SELECT stms
|
||||
return 0;
|
||||
}
|
||||
$nrows = odbc_num_rows($this->manip_result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* ODBC may or may not support counting rows in the result set of
|
||||
* SELECTs.
|
||||
*
|
||||
* @param $result the odbc result resource
|
||||
* @return the number of rows, or 0
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$nrows = odbc_num_rows($result);
|
||||
if ($nrows == -1) {
|
||||
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
|
||||
}
|
||||
return $nrows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return int ODBC error code
|
||||
*/
|
||||
|
||||
function errorNative()
|
||||
{
|
||||
if (!isset($this->connection) || !is_resource($this->connection)) {
|
||||
return odbc_error() . ' ' . odbc_errormsg();
|
||||
}
|
||||
return odbc_error($this->connection) . ' ' . odbc_errormsg($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence. We emulate sequences
|
||||
* for odbc. Will create the sequence if it does not exist.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param $seq_name the name of the sequence
|
||||
*
|
||||
* @param $ondemand whether to create the sequence table on demand
|
||||
* (default is true)
|
||||
*
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$result = $this->query("update ${seqname} set id = id + 1");
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOT_FOUND) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$result = $this->query("insert into ${seqname} (id) values(0)");
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = $this->query("select id from ${seqname}");
|
||||
if (DB::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetch_assoc(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row || !$row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
return $row['id'];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("CREATE TABLE ${seqname} ".
|
||||
'(id bigint NOT NULL,'.
|
||||
' PRIMARY KEY(id))');
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP TABLE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
function autoCommit($onoff = false)
|
||||
{
|
||||
if (!@odbc_autocommit($this->connection, $onoff)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ commit()
|
||||
|
||||
function commit()
|
||||
{
|
||||
if (!@odbc_commit($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
function rollback()
|
||||
{
|
||||
if (!@odbc_rollback($this->connection)) {
|
||||
return $this->odbcRaiseError();
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ odbcRaiseError()
|
||||
|
||||
function odbcRaiseError($errno = null)
|
||||
{
|
||||
if ($errno === null) {
|
||||
$errno = $this->errorCode(odbc_error($this->connection));
|
||||
}
|
||||
return $this->raiseError($errno, null, null, null,
|
||||
$this->errorNative());
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
810
html/service/include/DB/pgsql.php
Normal file
810
html/service/include/DB/pgsql.php
Normal file
@@ -0,0 +1,810 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Rui Hirokawa <rui_hirokawa@ybb.ne.jp> |
|
||||
// | Stig Bakken <ssb@fast.no> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: pgsql.php,v 1.65.2.3 2002/04/10 08:38:42 edink Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's PostgreSQL
|
||||
// extension.
|
||||
//
|
||||
|
||||
//
|
||||
// XXX legend:
|
||||
//
|
||||
// XXX ERRORMSG: The error message from the pgsql function should
|
||||
// be registered here.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_pgsql extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
var $transaction_opcount = 0;
|
||||
var $dsn = array();
|
||||
var $row = array();
|
||||
var $num_rows = array();
|
||||
var $affected = 0;
|
||||
var $autocommit = true;
|
||||
var $fetchmode = DB_FETCHMODE_ORDERED;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_pgsql()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'pgsql';
|
||||
$this->dbsyntax = 'pgsql';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => true,
|
||||
'limit' => 'alter'
|
||||
);
|
||||
$this->errorcode_map = array(
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $persistent (optional) whether the connection should
|
||||
* be persistent
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('pgsql'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$protocol = (isset($dsninfo['protocol'])) ? $dsninfo['protocol'] : 'tcp';
|
||||
$connstr = '';
|
||||
|
||||
if ($protocol == 'tcp') {
|
||||
if ($dsninfo['hostspec']) {
|
||||
$connstr = 'host=' . $dsninfo['hostspec'];
|
||||
}
|
||||
if ($dsninfo['port']) {
|
||||
$connstr .= ' port=' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($dsninfo['database'])) {
|
||||
$connstr .= ' dbname=' . $dsninfo['database'];
|
||||
}
|
||||
if (!empty($dsninfo['username'])) {
|
||||
$connstr .= ' user=' . $dsninfo['username'];
|
||||
}
|
||||
if (!empty($dsninfo['password'])) {
|
||||
$connstr .= ' password=' . $dsninfo['password'];
|
||||
}
|
||||
if (!empty($dsninfo['options'])) {
|
||||
$connstr .= ' options=' . $dsninfo['options'];
|
||||
}
|
||||
if (!empty($dsninfo['tty'])) {
|
||||
$connstr .= ' tty=' . $dsninfo['tty'];
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
|
||||
// catch error
|
||||
ob_start();
|
||||
$conn = $connect_function($connstr);
|
||||
$error = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if ($conn == false) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null,
|
||||
null, null, strip_tags($error));
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
/**
|
||||
* Log out and disconnect from the database.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if not connected.
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @pg_close($this->connection); // XXX ERRORMSG
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
/**
|
||||
* Send a query to PostgreSQL and return the results as a
|
||||
* PostgreSQL resource identifier.
|
||||
*
|
||||
* @param $query the SQL query
|
||||
*
|
||||
* @return int returns a valid PostgreSQL result for successful SELECT
|
||||
* queries, DB_OK for other successful queries. A DB error code
|
||||
* is returned on failure.
|
||||
*/
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$ismanip = DB::isManip($query);
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
if (!$this->autocommit && $ismanip) {
|
||||
if ($this->transaction_opcount == 0) {
|
||||
$result = @pg_exec($this->connection, "begin;");
|
||||
if (!$result) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
}
|
||||
$this->transaction_opcount++;
|
||||
}
|
||||
$result = @pg_exec($this->connection, $query);
|
||||
if (!$result) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
if ($ismanip) {
|
||||
$this->affected = @pg_cmdtuples($result);
|
||||
return DB_OK;
|
||||
} elseif (preg_match('/^\s*\(?\s*SELECT\s+/si', $query) &&
|
||||
!preg_match('/^\s*\(?\s*SELECT\s+INTO\s/si', $query)) {
|
||||
/* PostgreSQL commands:
|
||||
ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
|
||||
CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
|
||||
GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
|
||||
REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
|
||||
UNLISTEN, UPDATE, VACUUM
|
||||
*/
|
||||
$this->row[$result] = 0; // reset the row counter.
|
||||
$numrows = $this->numrows($result);
|
||||
if (is_object($numrows)) {
|
||||
return $numrows;
|
||||
}
|
||||
$this->num_rows[$result] = $numrows;
|
||||
$this->affected = 0;
|
||||
return $result;
|
||||
} else {
|
||||
$this->affected = 0;
|
||||
return DB_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal pgsql 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorCode()
|
||||
|
||||
/**
|
||||
* Map native error codes to DB's portable ones. Requires that
|
||||
* the DB implementation's constructor fills in the $errorcode_map
|
||||
* property.
|
||||
*
|
||||
* @param $nativecode the native error code, as returned by the backend
|
||||
* database extension (string or integer)
|
||||
*
|
||||
* @return int a portable DB error code, or FALSE if this DB
|
||||
* implementation has no mapping for the given error code.
|
||||
*/
|
||||
|
||||
function errorCode($errormsg)
|
||||
{
|
||||
static $error_regexps;
|
||||
if (empty($error_regexps)) {
|
||||
$error_regexps = array(
|
||||
'/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE,
|
||||
'/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS,
|
||||
'/divide by zero$/' => DB_ERROR_DIVZERO,
|
||||
'/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
|
||||
'/ttribute [\"\'].*[\"\'] not found$|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
|
||||
'/parser: parse error at or near \"/' => DB_ERROR_SYNTAX,
|
||||
'/referential integrity violation/' => DB_ERROR_CONSTRAINT
|
||||
);
|
||||
}
|
||||
foreach ($error_regexps as $regexp => $code) {
|
||||
if (preg_match($regexp, $errormsg)) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
// Fall back to DB_ERROR if there was no mapping.
|
||||
return DB_ERROR;
|
||||
}
|
||||
|
||||
// }}}
|
||||
/**
|
||||
* Fetch and return a row of data (it uses fetchInto for that)
|
||||
* @param $result PostgreSQL result identifier
|
||||
* @param $fetchmode format of fetched row array
|
||||
* @param $rownum the absolute row number to fetch
|
||||
*
|
||||
* @return array a row of data, or false on error
|
||||
*/
|
||||
function fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// {{{ fetchInto()
|
||||
|
||||
/**
|
||||
* Fetch a row and insert the data into an existing array.
|
||||
*
|
||||
* @param $result PostgreSQL result identifier
|
||||
* @param $row (reference) array where data from the row is stored
|
||||
* @param $fetchmode how the array data should be indexed
|
||||
* @param $rownum the row number to fetch
|
||||
*
|
||||
* @return int DB_OK on success, a DB error code on failure
|
||||
*/
|
||||
function fetchInto($result, &$row, $fetchmode, $rownum=null)
|
||||
{
|
||||
$rownum = ($rownum !== null) ? $rownum : $this->row[$result];
|
||||
if ($rownum >= $this->num_rows[$result]) {
|
||||
return null;
|
||||
}
|
||||
if ($fetchmode & DB_FETCHMODE_ASSOC) {
|
||||
$row = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
|
||||
} else {
|
||||
$row = @pg_fetch_row($result, $rownum);
|
||||
}
|
||||
if (!$row) {
|
||||
$err = pg_errormessage($this->connection);
|
||||
if (!$err) {
|
||||
return null;
|
||||
}
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
$this->row[$result] = ++$rownum;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with $result.
|
||||
*
|
||||
* @param $result int PostgreSQL result identifier or DB statement identifier
|
||||
*
|
||||
* @return bool TRUE on success, FALSE if $result is invalid
|
||||
*/
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @pg_freeresult($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
unset($this->row[(int)$result]);
|
||||
unset($this->num_rows[(int)$result]);
|
||||
$this->affected = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ quote()
|
||||
/**
|
||||
* Quote the given string so it can be safely used within string delimiters
|
||||
* in a query.
|
||||
* @param $string mixed Data to be quoted
|
||||
* @return mixed "NULL" string, quoted string or original data
|
||||
*/
|
||||
function quote($str = null)
|
||||
{
|
||||
switch (strtolower(gettype($str))) {
|
||||
case 'null':
|
||||
return 'NULL';
|
||||
case 'integer':
|
||||
case 'double' :
|
||||
return $str;
|
||||
case 'string':
|
||||
default:
|
||||
$str = str_replace("'", "''", $str);
|
||||
//PostgreSQL treats a backslash as an escape character.
|
||||
$str = str_replace('\\', '\\\\', $str);
|
||||
return "'$str'";
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
/**
|
||||
* Get the number of columns in a result set.
|
||||
*
|
||||
* @param $result resource PostgreSQL result identifier
|
||||
*
|
||||
* @return int the number of columns per row in $result
|
||||
*/
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @pg_numfields($result);
|
||||
if (!$cols) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numRows()
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
*
|
||||
* @param $result resource PostgreSQL result identifier
|
||||
*
|
||||
* @return int the number of rows in $result
|
||||
*/
|
||||
function numRows($result)
|
||||
{
|
||||
$rows = @pg_numrows($result);
|
||||
if ($rows === null) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ errorNative()
|
||||
|
||||
/**
|
||||
* Get the native error code of the last error (if any) that
|
||||
* occured on the current connection.
|
||||
*
|
||||
* @return int native PostgreSQL error code
|
||||
*/
|
||||
function errorNative()
|
||||
{
|
||||
return pg_errormessage($this->connection);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoCommit()
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits
|
||||
*/
|
||||
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()
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
// (disabled) hack to shut up error messages from libpq.a
|
||||
//@fclose(@fopen("php://stderr", "w"));
|
||||
$result = @pg_exec($this->connection, "end;");
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ rollback()
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
if ($this->transaction_opcount > 0) {
|
||||
$result = @pg_exec($this->connection, "abort;");
|
||||
$this->transaction_opcount = 0;
|
||||
if (!$result) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return int number of rows affected by the last query or DB_ERROR
|
||||
*/
|
||||
function affectedRows()
|
||||
{
|
||||
return $this->affected;
|
||||
}
|
||||
// }}}
|
||||
// {{{ nextId()
|
||||
|
||||
/**
|
||||
* Get the next value in a sequence.
|
||||
*
|
||||
* We are using native PostgreSQL sequences. If a sequence does
|
||||
* not exist, it will be created, unless $ondemand is false.
|
||||
*
|
||||
* @access public
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @param bool $ondemand whether to create the sequence on demand
|
||||
* @return a sequence integer, or a DB error
|
||||
*/
|
||||
function nextId($seq_name, $ondemand = true)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$repeat = 0;
|
||||
do {
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("SELECT NEXTVAL('${seqname}')");
|
||||
$this->popErrorHandling();
|
||||
if ($ondemand && DB::isError($result) &&
|
||||
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
|
||||
$repeat = 1;
|
||||
$result = $this->createSequence($seq_name);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
} else {
|
||||
$repeat = 0;
|
||||
}
|
||||
} while ($repeat);
|
||||
if (DB::isError($result)) {
|
||||
return $this->raiseError($result);
|
||||
}
|
||||
$arr = $result->fetch_assoc(DB_FETCHMODE_ORDERED);
|
||||
$result->free();
|
||||
return $arr[0];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* Create the sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||
$result = $this->query("CREATE SEQUENCE ${seqname}");
|
||||
$this->popErrorHandling();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* Drop a sequence
|
||||
*
|
||||
* @param string $seq_name the name of the sequence
|
||||
* @return mixed DB_OK on success or DB error on error
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$seqname = $this->getSequenceName($seq_name);
|
||||
return $this->query("DROP SEQUENCE ${seqname}");
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ modifyLimitQuery()
|
||||
|
||||
function modifyLimitQuery($query, $from, $count)
|
||||
{
|
||||
$query = $query . " LIMIT $count, $from";
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ pgsqlRaiseError()
|
||||
|
||||
function pgsqlRaiseError($errno = null)
|
||||
{
|
||||
$native = $this->errorNative();
|
||||
if ($errno === null) {
|
||||
$err = $this->errorCode($native);
|
||||
} else {
|
||||
$err = $errno;
|
||||
}
|
||||
return $this->raiseError($err, null, null, null, $native);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _pgFieldFlags()
|
||||
|
||||
/**
|
||||
* Flags of a Field
|
||||
*
|
||||
* @param int $resource PostgreSQL result identifier
|
||||
* @param int $num_field the field number
|
||||
*
|
||||
* @return string The flags of the field ("not_null", "default_xx", "primary_key",
|
||||
* "unique" and "multiple_key" are supported)
|
||||
* @access private
|
||||
*/
|
||||
function _pgFieldFlags($resource, $num_field, $table_name)
|
||||
{
|
||||
$field_name = @pg_fieldname($resource, $num_field);
|
||||
|
||||
$result = pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ
|
||||
WHERE tab.relname = typ.typname
|
||||
AND typ.typrelid = f.attrelid
|
||||
AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name'");
|
||||
if (pg_numrows($result) > 0) {
|
||||
$row = pg_fetch_row($result, 0);
|
||||
$flags = ($row[0] == 't') ? 'not_null ' : '';
|
||||
|
||||
if ($row[1] == 't') {
|
||||
$result = pg_exec($this->connection, "SELECT a.adsrc
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
|
||||
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
|
||||
AND f.attrelid = a.adrelid AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name'");
|
||||
$row = pg_fetch_row($result, 0);
|
||||
$num = str_replace('\'', '', $row[0]);
|
||||
|
||||
$flags .= "default_$num ";
|
||||
}
|
||||
}
|
||||
$result = pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
|
||||
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
|
||||
WHERE tab.relname = typ.typname
|
||||
AND typ.typrelid = f.attrelid
|
||||
AND f.attrelid = i.indrelid
|
||||
AND f.attname = '$field_name'
|
||||
AND tab.relname = '$table_name'");
|
||||
$count = pg_numrows($result);
|
||||
|
||||
for ($i = 0; $i < $count ; $i++) {
|
||||
$row = pg_fetch_row($result, $i);
|
||||
$keys = explode(" ", $row[2]);
|
||||
|
||||
if (in_array($num_field + 1, $keys)) {
|
||||
$flags .= ($row[0] == 't') ? 'unique ' : '';
|
||||
$flags .= ($row[1] == 't') ? 'primary ' : '';
|
||||
if (count($keys) > 1)
|
||||
$flags .= 'multiple_key ';
|
||||
}
|
||||
}
|
||||
|
||||
return trim($flags);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: doesn't support table name and flags if called from a db_result
|
||||
*
|
||||
* @param mixed $resource PostgreSQL result identifier or table name
|
||||
* @param int $mode A valid tableInfo mode (DB_TABLEINFO_ORDERTABLE or
|
||||
* DB_TABLEINFO_ORDER)
|
||||
*
|
||||
* @return array An array with all the information
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$count = 0;
|
||||
$id = 0;
|
||||
$res = array();
|
||||
|
||||
/*
|
||||
* depending on $mode, metadata returns the following values:
|
||||
*
|
||||
* - mode is false (default):
|
||||
* $result[]:
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDER
|
||||
* $result[]:
|
||||
* ["num_fields"] number of metadata records
|
||||
* [0]["table"] table name
|
||||
* [0]["name"] field name
|
||||
* [0]["type"] field type
|
||||
* [0]["len"] field length
|
||||
* [0]["flags"] field flags
|
||||
* ["order"][field name] index of field named "field name"
|
||||
* The last one is used, if you have a field name, but no index.
|
||||
* Test: if (isset($result['meta']['myfield'])) { ...
|
||||
*
|
||||
* - mode is DB_TABLEINFO_ORDERTABLE
|
||||
* the same as above. but additionally
|
||||
* ["ordertable"][table name][field name] index of field
|
||||
* named "field name"
|
||||
*
|
||||
* this is, because if you have fields from different
|
||||
* tables with the same field name * they override each
|
||||
* other with DB_TABLEINFO_ORDER
|
||||
*
|
||||
* you can combine DB_TABLEINFO_ORDER and
|
||||
* DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
|
||||
* DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
|
||||
*/
|
||||
|
||||
// if $result is a string, then we want information about a
|
||||
// table without a resultset
|
||||
|
||||
if (is_string($result)) {
|
||||
$id = pg_exec($this->connection,"SELECT * FROM $result");
|
||||
if (empty($id)) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
} else { // else we want information about a resultset
|
||||
$id = $result;
|
||||
if (empty($id)) {
|
||||
return $this->pgsqlRaiseError();
|
||||
}
|
||||
}
|
||||
|
||||
$count = @pg_numfields($id);
|
||||
|
||||
// made this IF due to performance (one if is faster than $count if's)
|
||||
if (empty($mode)) {
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @pg_fieldname ($id, $i);
|
||||
$res[$i]['type'] = @pg_fieldtype ($id, $i);
|
||||
$res[$i]['len'] = @pg_fieldsize ($id, $i);
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_pgFieldflags($id, $i, $result) : '';
|
||||
}
|
||||
|
||||
} else { // full
|
||||
$res["num_fields"]= $count;
|
||||
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$res[$i]['table'] = (is_string($result)) ? $result : '';
|
||||
$res[$i]['name'] = @pg_fieldname ($id, $i);
|
||||
$res[$i]['type'] = @pg_fieldtype ($id, $i);
|
||||
$res[$i]['len'] = @pg_fieldsize ($id, $i);
|
||||
$res[$i]['flags'] = (is_string($result)) ? $this->_pgFieldFlags($id, $i, $result) : '';
|
||||
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 (is_resource($id)) {
|
||||
@pg_freeresult($id);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTablesQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables': {
|
||||
$sql = "SELECT c.relname as \"Name\"
|
||||
FROM pg_class c, pg_user u
|
||||
WHERE c.relowner = u.usesysid AND c.relkind = 'r'
|
||||
AND not exists (select 1 from pg_views where viewname = c.relname)
|
||||
AND c.relname !~ '^pg_'
|
||||
UNION
|
||||
SELECT c.relname as \"Name\"
|
||||
FROM pg_class c
|
||||
WHERE c.relkind = 'r'
|
||||
AND not exists (select 1 from pg_views where viewname = c.relname)
|
||||
AND not exists (select 1 from pg_user where usesysid = c.relowner)
|
||||
AND c.relname !~ '^pg_'";
|
||||
break;
|
||||
}
|
||||
case 'views': {
|
||||
// Table cols: viewname | viewowner | definition
|
||||
$sql = "SELECT viewname FROM pg_views";
|
||||
break;
|
||||
}
|
||||
case 'users': {
|
||||
// cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil
|
||||
$sql = 'SELECT usename FROM pg_user';
|
||||
break;
|
||||
}
|
||||
case 'databases': {
|
||||
$sql = 'SELECT datname FROM pg_database';
|
||||
break;
|
||||
}
|
||||
case 'functions': {
|
||||
$sql = 'SELECT proname FROM pg_proc';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
// Local variables:
|
||||
// tab-width: 4
|
||||
// c-basic-offset: 4
|
||||
// End:
|
||||
?>
|
||||
444
html/service/include/DB/storage.php
Normal file
444
html/service/include/DB/storage.php
Normal file
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Stig Bakken <stig@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: storage.php,v 1.28 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// DB_storage: a class that lets you return SQL data as objects that
|
||||
// can be manipulated and that updates the database accordingly.
|
||||
//
|
||||
|
||||
require_once "PEAR.php";
|
||||
require_once "DB.php";
|
||||
|
||||
/**
|
||||
* DB_storage provides an object interface to a table row. It lets
|
||||
* you add, delete and change rows without using SQL.
|
||||
*
|
||||
* @author Stig Bakken <stig@php.net>
|
||||
*
|
||||
* @package DB
|
||||
*/
|
||||
class DB_storage extends PEAR
|
||||
{
|
||||
/** 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
|
||||
*
|
||||
* @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 DB_storage($table, $keycolumn, &$dbh, $validator = null)
|
||||
{
|
||||
$this->PEAR('DB_Error');
|
||||
$this->_table = $table;
|
||||
$this->_keycolumn = $keycolumn;
|
||||
$this->_dbh = $dbh;
|
||||
$this->_readonly = false;
|
||||
$this->_validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$qval = $this->_dbh->quote($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->fetch_assoc(DB_FETCHMODE_ASSOC);
|
||||
if (DB::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (empty($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a simple description of this DB_storage object.
|
||||
* @return string object description
|
||||
*/
|
||||
function toString()
|
||||
{
|
||||
$info = 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 the contents of this object to "standard output".
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
reset($this->_properties);
|
||||
while (list($prop, $foo) = each($this->_properties)) {
|
||||
print "$prop = ";
|
||||
print htmlentities($this->$prop);
|
||||
print "<BR>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = get_class($this);
|
||||
$obj = new $classname($table);
|
||||
reset($data);
|
||||
while (list($name, $value) = each($data)) {
|
||||
$obj->_properties[$name] = true;
|
||||
$obj->$name = &$value;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, calls DB_storage::store() if there are changes
|
||||
* that are to be kept.
|
||||
*/
|
||||
function _DB_storage()
|
||||
{
|
||||
if (empty($this->_discard) && sizeof($this->_changes)) {
|
||||
$this->store();
|
||||
}
|
||||
$this->_properties = array();
|
||||
$this->_changes = array();
|
||||
$this->_table = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores changes to this object in the database.
|
||||
*
|
||||
* @return DB_OK or a DB error
|
||||
*/
|
||||
function store()
|
||||
{
|
||||
while (list($name, $changed) = each($this->_changes)) {
|
||||
$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 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
251
html/service/include/DB/sybase.php
Normal file
251
html/service/include/DB/sybase.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: sybase.php,v 1.30 2002/02/28 08:27:11 sebastian Exp $
|
||||
//
|
||||
// Database independent query interface definition for PHP's Sybase
|
||||
// extension.
|
||||
//
|
||||
|
||||
require_once 'DB/common.php';
|
||||
|
||||
class DB_sybase extends DB_common
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $connection;
|
||||
var $phptype, $dbsyntax;
|
||||
var $prepare_tokens = array();
|
||||
var $prepare_types = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
function DB_sybase()
|
||||
{
|
||||
$this->DB_common();
|
||||
$this->phptype = 'sybase';
|
||||
$this->dbsyntax = 'sybase';
|
||||
$this->features = array(
|
||||
'prepare' => false,
|
||||
'pconnect' => true,
|
||||
'transactions' => false,
|
||||
'limit' => 'emulate'
|
||||
);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ connect()
|
||||
|
||||
function connect($dsninfo, $persistent = false)
|
||||
{
|
||||
if (!DB::assertExtension('sybase') && !DB::assertExtension('sybase_ct'))
|
||||
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
$connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = $connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = $connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = $connect_function($dbhost);
|
||||
} else {
|
||||
$conn = $connect_function();
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@sybase_select_db($dsninfo['database'], $conn)) {
|
||||
return $this->raiseError(DB_ERROR_NODBSELECTED);
|
||||
}
|
||||
}
|
||||
$this->connection = $conn;
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ disconnect()
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
$ret = @sybase_close($this->connection);
|
||||
$this->connection = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ simpleQuery()
|
||||
|
||||
function simpleQuery($query)
|
||||
{
|
||||
$this->last_query = $query;
|
||||
$query = $this->modifyQuery($query);
|
||||
$result = @sybase_query($query, $this->connection);
|
||||
if (!$result) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
// Determine which queries that should return data, and which
|
||||
// should return an error code only.
|
||||
return DB::isManip($query) ? DB_OK : $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ nextResult()
|
||||
|
||||
/**
|
||||
* Move the internal sybase 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 false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetch_assoc()
|
||||
function &fetch_assoc($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
|
||||
{
|
||||
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
|
||||
$fetchmode = $this->fetchmode;
|
||||
}
|
||||
$res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
|
||||
if ($res !== DB_OK) {
|
||||
return $res;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchInto()
|
||||
|
||||
function fetchInto($result, &$ar, $fetchmode, $rownum=null)
|
||||
{
|
||||
if ($rownum !== null) {
|
||||
if (!sybase_data_seek($result, $rownum)) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
}
|
||||
$ar = ($fetchmode & DB_FETCHMODE_ASSOC) ? @sybase_fetch_array($result) : @sybase_fetch_row($result);
|
||||
if (!$ar) {
|
||||
// reported not work as seems that sybase_get_last_message()
|
||||
// always return a message here
|
||||
//if ($errmsg = sybase_get_last_message()) {
|
||||
// return $this->raiseError($errmsg);
|
||||
//} else {
|
||||
return null;
|
||||
//}
|
||||
}
|
||||
return DB_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ freeResult()
|
||||
|
||||
function freeResult($result)
|
||||
{
|
||||
if (is_resource($result)) {
|
||||
return @sybase_free_result($result);
|
||||
}
|
||||
if (!isset($this->prepare_tokens[(int)$result])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->prepare_tokens[(int)$result]);
|
||||
unset($this->prepare_types[(int)$result]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ numCols()
|
||||
|
||||
function numCols($result)
|
||||
{
|
||||
$cols = @sybase_num_fields($result);
|
||||
if (!$cols) {
|
||||
return $this->raiseError();
|
||||
}
|
||||
return $cols;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ affectedRows()
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query. For other queries, this function returns 0.
|
||||
*
|
||||
* @return number of rows affected by the last query
|
||||
*/
|
||||
|
||||
function affectedRows()
|
||||
{
|
||||
if (DB::isManip($this->last_query)) {
|
||||
$result = @sybase_affected_rows($this->connection);
|
||||
} else {
|
||||
$result = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSpecialQuery()
|
||||
|
||||
/**
|
||||
* Returns the query needed to get some backend info
|
||||
* @param string $type What kind of info you want to retrieve
|
||||
* @return string The SQL query string
|
||||
*/
|
||||
function getSpecialQuery($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'tables':
|
||||
$sql = "select name from sysobjects where type = 'U' order by name";
|
||||
break;
|
||||
case 'views':
|
||||
$sql = "select name from sysobjects where type = 'V'";
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
391
html/service/include/Net/Curl.php
Normal file
391
html/service/include/Net/Curl.php
Normal file
@@ -0,0 +1,391 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Sterling Hughes <sterling@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Curl.php,v 1.9 2002/02/28 08:27:14 sebastian Exp $
|
||||
//
|
||||
// A nice friendly OO interface for CURL
|
||||
//
|
||||
require_once('PEAR.php');
|
||||
|
||||
class Net_Curl extends PEAR
|
||||
{
|
||||
// {{{ Public Properties
|
||||
|
||||
/**
|
||||
* The URL for cURL to work with
|
||||
*
|
||||
* @var string $url
|
||||
* @access public
|
||||
*/
|
||||
var $url;
|
||||
|
||||
/**
|
||||
* The SSL version for the transfer
|
||||
*
|
||||
* @var integer $sslVersion
|
||||
* @access public
|
||||
*/
|
||||
var $sslVersion;
|
||||
|
||||
/**
|
||||
* The filename of the SSL certificate
|
||||
*
|
||||
* @var string $sslCert
|
||||
* @access public
|
||||
*/
|
||||
var $sslCert;
|
||||
|
||||
/**
|
||||
* The password corresponding to the certificate
|
||||
* in the $sslCert property
|
||||
*
|
||||
* @var string $sslCertPasswd
|
||||
* @access public
|
||||
*/
|
||||
var $sslCertPasswd;
|
||||
|
||||
/**
|
||||
* User Agent string when making an HTTP request
|
||||
*
|
||||
* @var string $userAgent
|
||||
* @access public
|
||||
*/
|
||||
var $userAgent;
|
||||
|
||||
/**
|
||||
* Whether or not to include the header in the results
|
||||
* of the CURL transfer
|
||||
*
|
||||
* @var boolean $header
|
||||
*/
|
||||
var $header = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to output debug information while executing a
|
||||
* curl transfer
|
||||
*
|
||||
* @var boolean $verbose
|
||||
* @access public
|
||||
*/
|
||||
var $verbose = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to display a progress meter for the current transfer
|
||||
*
|
||||
* @var boolean $progress
|
||||
* @access public
|
||||
*/
|
||||
var $progress = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to suppress error messages
|
||||
*
|
||||
* @var boolean $mute
|
||||
* @access public
|
||||
*/
|
||||
var $mute = 1;
|
||||
|
||||
/**
|
||||
* Whether or not to follow HTTP Location headers.
|
||||
*
|
||||
* @var boolean $follow_location
|
||||
* @access public
|
||||
*/
|
||||
var $follow_location = 1;
|
||||
|
||||
/**
|
||||
* Time allowed for current transfer, in seconds. 0 means no limit
|
||||
*
|
||||
* @var int $timeout
|
||||
* @access public
|
||||
*/
|
||||
var $timeout = 0;
|
||||
|
||||
/**
|
||||
* Whether or not to return the results of the
|
||||
* current transfer
|
||||
*
|
||||
* @var boolean $return_transfer
|
||||
* @access public
|
||||
*/
|
||||
var $return_transfer = 1;
|
||||
|
||||
/**
|
||||
* The type of transfer to perform
|
||||
*
|
||||
* @var string $type
|
||||
* @access public
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* The file to upload
|
||||
*
|
||||
* @var string $file
|
||||
* @access public
|
||||
*/
|
||||
var $file;
|
||||
|
||||
/**
|
||||
* The file size of the file pointed to by the $file
|
||||
* property
|
||||
*
|
||||
* @var integer $file_size
|
||||
* @access public
|
||||
*/
|
||||
var $file_size;
|
||||
|
||||
/**
|
||||
* The cookies to send to the remote site
|
||||
*
|
||||
* @var array $cookies
|
||||
* @access public
|
||||
*/
|
||||
var $cookies;
|
||||
|
||||
/**
|
||||
* The fields to send in a 'POST' request
|
||||
*
|
||||
* @var array $fields
|
||||
* @access public
|
||||
*/
|
||||
var $fields;
|
||||
|
||||
/**
|
||||
* The proxy server to go through
|
||||
*
|
||||
* @var string $proxy
|
||||
* @access public
|
||||
*/
|
||||
var $proxy;
|
||||
|
||||
/**
|
||||
* The username for the Proxy server
|
||||
*
|
||||
* @var string $proxyUser
|
||||
* @access public
|
||||
*/
|
||||
var $proxyUser;
|
||||
|
||||
/**
|
||||
* The password for the Proxy server
|
||||
*
|
||||
* @var string $proxyPassword
|
||||
* @access public
|
||||
*/
|
||||
var $proxyPassword;
|
||||
|
||||
// }}}
|
||||
// {{{ Private Properties
|
||||
|
||||
/**
|
||||
* The current curl handle
|
||||
*
|
||||
* @var resource $_ch
|
||||
* @access public
|
||||
*/
|
||||
var $_ch;
|
||||
|
||||
// }}}
|
||||
// {{{ Net_Curl()
|
||||
|
||||
/**
|
||||
* The Net_Curl constructor, called when a new Net_Curl object
|
||||
* is initialized
|
||||
*
|
||||
* @param string [$url] The URL to fetch (can be set
|
||||
* using the $url property as well)
|
||||
*
|
||||
* @return object Net_Curl $obj A new Net_Curl object
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function Net_Curl($url = "")
|
||||
{
|
||||
if ($url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
if (!$ch) {
|
||||
$this = new PEAR_Error("Couldn't initialize a new curl handle");
|
||||
}
|
||||
|
||||
$this->_ch = $ch;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execute()
|
||||
|
||||
/**
|
||||
* Executes a prepared CURL transfer
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function execute()
|
||||
{
|
||||
$ch = &$this->_ch;
|
||||
$ret = true;
|
||||
|
||||
// Basic stuff
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||
$ret = curl_setopt($ch, CURLOPT_HEADER, $this->header);
|
||||
|
||||
// Whether or not to return the transfer contents
|
||||
if ($this->return_transfer && !isset($this->file)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
}
|
||||
|
||||
// SSL Checks
|
||||
|
||||
if (isset($this->sslVersion)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLVERSION, $this->sslVersion);
|
||||
}
|
||||
|
||||
if (isset($this->sslCert)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLCERT, $this->sslCert);
|
||||
}
|
||||
|
||||
if (isset($this->sslCertPasswd)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->sslCertPasswd);
|
||||
}
|
||||
|
||||
// Proxy Related checks
|
||||
|
||||
if (isset($this->proxy)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
|
||||
}
|
||||
|
||||
if (isset($this->proxyUser) || isset($this->proxyPassword)) {
|
||||
$proxyString = $this->proxyUser . ":" . $this->proxyPassword;
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyString);
|
||||
}
|
||||
|
||||
|
||||
// Transfer type
|
||||
|
||||
if (isset($this->type)) {
|
||||
switch (strtolower($this->type)) {
|
||||
case 'post':
|
||||
$ret = curl_setopt($ch, CURLOPT_POST, 1);
|
||||
break;
|
||||
case 'put':
|
||||
$ret = curl_setopt($ch, CURLOPT_PUT, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Transfer upload, etc. related
|
||||
|
||||
if (isset($this->file)) {
|
||||
if (!isset($this->file_size)) {
|
||||
$this->file_size = filesize($this->file);
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_INFILE, $this->file);
|
||||
$ret = curl_setopt($ch, CURLOPT_INFILESIZE, $this->file_size);
|
||||
}
|
||||
|
||||
if (isset($this->fields)) {
|
||||
if (!isset($this->type)) {
|
||||
$this->type = 'post';
|
||||
$ret = curl_setopt($ch, CURLOPT_POST, 1);
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_POSTFIELDS, $this->fields);
|
||||
}
|
||||
|
||||
|
||||
// Error related
|
||||
|
||||
if ($this->progress) {
|
||||
$ret = curl_setopt($ch, CURLOPT_PROGRESS, 1);
|
||||
}
|
||||
|
||||
if ($this->verbose) {
|
||||
$ret = curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
||||
}
|
||||
|
||||
if (!$this->mute) {
|
||||
$ret = curl_setopt($ch, CURLOPT_MUTE, 0);
|
||||
}
|
||||
|
||||
// Other stuff
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
|
||||
|
||||
if ($this->timeout) {
|
||||
$ret = curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
|
||||
}
|
||||
|
||||
if (isset($this->userAgent)) {
|
||||
$ret = curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Cookies and the such
|
||||
|
||||
if (isset($this->cookies)) {
|
||||
foreach ($this->cookies as $name => $value) {
|
||||
$cookie_data .= urlencode($name) . ": " . urlencode($value) . ";";
|
||||
}
|
||||
|
||||
$ret = curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
|
||||
}
|
||||
|
||||
$ret = curl_exec($ch);
|
||||
if (!$ret) {
|
||||
$errObj = new PEAR_Error(curl_error($ch), curl_errno($ch));
|
||||
return($errObj);
|
||||
}
|
||||
|
||||
return($ret);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ close()
|
||||
|
||||
/**
|
||||
* Closes the curl transfer and finishes the object (kinda ;)
|
||||
*
|
||||
* @access public
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if ($this->_ch) {
|
||||
curl_close($this->_ch);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
?>
|
||||
448
html/service/include/Net/Dig.php
Normal file
448
html/service/include/Net/Dig.php
Normal file
@@ -0,0 +1,448 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Colin Viebrock <colin@easyDNS.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Dig.php,v 1.4 2002/02/28 08:27:15 sebastian Exp $
|
||||
//
|
||||
// A nice friendly OO interface to dig
|
||||
//
|
||||
require_once('PEAR.php');
|
||||
|
||||
class Net_Dig extends PEAR
|
||||
{
|
||||
// {{{ Public Properties
|
||||
|
||||
/**
|
||||
* The address to dig
|
||||
*
|
||||
* @var string $address
|
||||
* @access public
|
||||
*/
|
||||
var $address;
|
||||
|
||||
/**
|
||||
* The server to use for digging
|
||||
*
|
||||
* @var string $server
|
||||
* @access public
|
||||
*/
|
||||
var $server;
|
||||
|
||||
/**
|
||||
* The type of DNS records to dig for
|
||||
*
|
||||
* @var string $query_type
|
||||
* @access public
|
||||
*/
|
||||
var $query_type;
|
||||
|
||||
/**
|
||||
* The last system command executed (for debugging)
|
||||
*
|
||||
* @var string $cmd
|
||||
* @access public
|
||||
*/
|
||||
var $cmd;
|
||||
|
||||
/**
|
||||
* The raw output of the system command (for debugging)
|
||||
*
|
||||
* @var string $raw_data
|
||||
* @access public
|
||||
*/
|
||||
var $raw_data;
|
||||
|
||||
/**
|
||||
* The location of the system dig program
|
||||
*
|
||||
* @var string $dig_prg
|
||||
* @access public
|
||||
*/
|
||||
var $dig_prog;
|
||||
|
||||
/**
|
||||
* The parsed result of the last dig
|
||||
*
|
||||
* @var string $result
|
||||
* @access public
|
||||
*/
|
||||
var $result;
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ Net_Dig()
|
||||
|
||||
/**
|
||||
* The Net_Dig constructor
|
||||
* Called when a new Net_Dig object is initialized
|
||||
*
|
||||
* @param string [$address] The address to dig (can be set
|
||||
* using the $address property as well)
|
||||
*
|
||||
* @param string [$server] The server to dig at (can be set
|
||||
* using the $server property as well)
|
||||
*
|
||||
* @return object Net_Dig $obj A new Net_Dig object
|
||||
*
|
||||
* @access public
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function Net_Dig($address = false, $server = false )
|
||||
{
|
||||
|
||||
$this->address = $address;
|
||||
$this->server = $server;
|
||||
$this->query_type = false;
|
||||
|
||||
$this->cmd = '';
|
||||
$this->raw_data = '';
|
||||
|
||||
$this->result = false;
|
||||
|
||||
$this->dig_prog = trim(`which dig`);
|
||||
if (!$this->dig_prog) {
|
||||
$this = new PEAR_Error("Couldn't find system dig program");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
|
||||
// {{{ dig()
|
||||
|
||||
/**
|
||||
* Does a dig of the given address (or $this->address)
|
||||
*
|
||||
* @param string [$address] The address to dig (can be set
|
||||
* using the $address property as well)
|
||||
*
|
||||
* @return object Net_Dig_result $obj A new Net_Dig_result object
|
||||
*
|
||||
* @access public
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function dig($address=false)
|
||||
{
|
||||
|
||||
if ($address) {
|
||||
$this->address = $address;
|
||||
}
|
||||
|
||||
if (!$this->address) {
|
||||
return new PEAR_Error("No address specified");
|
||||
}
|
||||
|
||||
if (!$this->_validate_type()) {
|
||||
return new PEAR_Error($this->query_type." is an invalid query type");
|
||||
}
|
||||
|
||||
$cmd = escapeshellcmd(
|
||||
sprintf("%s %s %s %s",
|
||||
$this->dig_prog,
|
||||
($this->server ? '@'.$this->server : ''),
|
||||
$this->address,
|
||||
($this->query_type ? $this->query_type : '' )
|
||||
)
|
||||
);
|
||||
|
||||
$this->cmd = $cmd;
|
||||
|
||||
|
||||
$this->raw_data = `$cmd`;
|
||||
$this->raw_data = trim( $this->raw_data );
|
||||
|
||||
return $this->_parse_data();
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ _validate_type()
|
||||
|
||||
/**
|
||||
* Validates the value of $this->query_type
|
||||
*
|
||||
* @return boolean $return True if $this->query_type is a
|
||||
* valid dig query, otherwise false
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _validate_type()
|
||||
{
|
||||
$return = true;
|
||||
if ($this->query_type) {
|
||||
$this->query_type = strtolower($this->query_type);
|
||||
switch ($this->query_type) {
|
||||
case 'a':
|
||||
case 'any':
|
||||
case 'mx':
|
||||
case 'ns':
|
||||
case 'soa':
|
||||
case 'hinfo':
|
||||
case 'axfr':
|
||||
case 'txt':
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
|
||||
// {{{ _parse_data()
|
||||
|
||||
/**
|
||||
* Parses the raw data in $this->raw_data
|
||||
*
|
||||
* @return obj Net_Dig_result $return A Net_Dig_result object
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _parse_data()
|
||||
{
|
||||
|
||||
if (!$this->raw_data) {
|
||||
return new PEAR_Error("No raw data to parse");
|
||||
}
|
||||
|
||||
$regex = '/' .
|
||||
'^;(.*?)' .
|
||||
';; QUESTION SECTION\:(.*?)' .
|
||||
'(;; ANSWER SECTION\:(.*?))?' .
|
||||
'(;; AUTHORITY SECTION\:(.*?))?' .
|
||||
'(;; ADDITIONAL SECTION\:(.*?))?' .
|
||||
'(;;.*)' .
|
||||
'/ims';
|
||||
|
||||
if (preg_match($regex, $this->raw_data, $matches)) {
|
||||
|
||||
$result = new Net_Dig_result;
|
||||
|
||||
/* Start parsing the data */
|
||||
|
||||
|
||||
/* the header ... */
|
||||
|
||||
|
||||
$temp = explode("\n", trim($matches[1]));
|
||||
if (preg_match('/DiG (.*?) /i', $temp[0], $m)) {
|
||||
$result->dig_version = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/status: (.*?), id: (.*?)$/i', $temp[3], $m)) {
|
||||
$result->status = trim($m[1]);
|
||||
$result->id = trim($m[2]);
|
||||
}
|
||||
|
||||
if (preg_match('/flags: (.*?); query: (.*?), answer: (.*?), authority: (.*?), additional: (.*?)$/i', $temp[4], $m)) {
|
||||
$result->flags = trim($m[1]);
|
||||
$result->query_count = (int)trim($m[2]);
|
||||
$result->answer_count = (int)trim($m[3]);
|
||||
$result->authority_count = (int)trim($m[4]);
|
||||
$result->additional_count = (int)trim($m[5]);
|
||||
}
|
||||
|
||||
|
||||
/* query section */
|
||||
|
||||
$line = trim(preg_replace('/^(;*)/', '', trim($matches[2])));
|
||||
list($host, $class, $type) = preg_split('/[\s]+/', $line, 3);
|
||||
$result->query[] = new Net_Dig_resource($host, false, $class, $type, false);
|
||||
|
||||
|
||||
/* answer section */
|
||||
|
||||
$temp = trim($matches[4]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->answer[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* authority section */
|
||||
|
||||
$temp = trim($matches[6]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->authority[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* additional section */
|
||||
|
||||
$temp = trim($matches[8]);
|
||||
if ($temp) {
|
||||
$temp = explode("\n", $temp);
|
||||
if (count($temp)) {
|
||||
foreach($temp as $line) {
|
||||
$result->additional[] = $this->_parse_resource($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* footer */
|
||||
|
||||
$temp = explode("\n", trim($matches[9]));
|
||||
if (preg_match('/query time: (.*?)$/i', $temp[0], $m)) {
|
||||
$result->query_time = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/server: (.*?)#(.*?)\(/i', $temp[1], $m)) {
|
||||
$result->dig_server = trim($m[1]);
|
||||
$result->dig_port = trim($m[2]);
|
||||
}
|
||||
|
||||
/* done */
|
||||
|
||||
$result->consistency_check = (
|
||||
(count($result->query) == $result->query_count) &&
|
||||
(count($result->answer) == $result->answer_count) &&
|
||||
(count($result->authority) == $result->authority_count) &&
|
||||
(count($result->additional) == $result->additional_count)
|
||||
);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
return new PEAR_Error("Can't parse raw data");
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// {{{ _parse_resource()
|
||||
|
||||
/**
|
||||
* Parses a resource record line
|
||||
*
|
||||
* @param string $line The line to parse
|
||||
*
|
||||
* @return obj Net_Dig_resource $return A Net_Dig_resource object
|
||||
*
|
||||
* @access private
|
||||
* @author Colin Viebrock <colin@easyDNS.com>
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function _parse_resource($line)
|
||||
{
|
||||
|
||||
/* trim and remove leading ;, if present */
|
||||
|
||||
$line = trim(preg_replace('/^(;*)/', '', trim($line)));
|
||||
|
||||
if ($line) {
|
||||
list($host, $ttl, $class, $type, $data) = preg_split('/[\s]+/', $line, 5);
|
||||
return new Net_Dig_resource($host, $ttl, $class, $type, $data);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Net_Dig_result {
|
||||
|
||||
// {{{ Public Properties
|
||||
|
||||
var $status;
|
||||
var $id;
|
||||
var $flags;
|
||||
var $query_count;
|
||||
var $answer_count;
|
||||
var $authority_count;
|
||||
var $additional_count;
|
||||
|
||||
var $dig_version;
|
||||
var $dig_server;
|
||||
var $dig_port;
|
||||
|
||||
var $query;
|
||||
var $answer;
|
||||
var $authority;
|
||||
var $additional;
|
||||
|
||||
var $consistency_check;
|
||||
|
||||
function Net_Dig_result() {
|
||||
$this->status = false;
|
||||
$this->id = false;
|
||||
$this->flags = false;
|
||||
$this->query_count = false;
|
||||
$this->answer_count = false;
|
||||
$this->authority_count = false;
|
||||
$this->additional_count = false;
|
||||
|
||||
$this->dig_version = false;
|
||||
$this->dig_server = false;
|
||||
$this->dig_port = false;
|
||||
|
||||
$this->query = array();
|
||||
$this->answer = array();
|
||||
$this->authority = array();
|
||||
$this->additional = array();
|
||||
|
||||
$this->consistency_check = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Net_Dig_resource {
|
||||
|
||||
var $host;
|
||||
var $ttl;
|
||||
var $class;
|
||||
var $type;
|
||||
var $data;
|
||||
|
||||
function Net_Dig_resource($host=false, $ttl=false, $class=false, $type=false, $data=false) {
|
||||
$this->host = $host;
|
||||
$this->ttl = $ttl;
|
||||
$this->class = $class;
|
||||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
400
html/service/include/Net/SMTP.php
Normal file
400
html/service/include/Net/SMTP.php
Normal file
@@ -0,0 +1,400 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 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: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* Provides an implementation of the SMTP protocol using PEAR's
|
||||
* Net_Socket:: class.
|
||||
*/
|
||||
class Net_SMTP extends PEAR {
|
||||
|
||||
/**
|
||||
* The server to connect to.
|
||||
* @var string
|
||||
*/
|
||||
var $host = 'localhost';
|
||||
|
||||
/**
|
||||
* The port to connect to.
|
||||
* @var int
|
||||
*/
|
||||
var $port = 25;
|
||||
|
||||
/**
|
||||
* The value to give when sending EHLO or HELO.
|
||||
* @var string
|
||||
*/
|
||||
var $localhost = 'localhost';
|
||||
|
||||
/**
|
||||
* The socket resource being used to connect to the SMTP server.
|
||||
* @var resource
|
||||
*/
|
||||
var $socket;
|
||||
|
||||
/**
|
||||
* The most recent reply code
|
||||
* @var int
|
||||
*/
|
||||
var $code;
|
||||
|
||||
/**
|
||||
* Stores detected features of the SMTP server.
|
||||
* @var array
|
||||
*/
|
||||
var $esmtp;
|
||||
|
||||
/**
|
||||
* The last line read from the server.
|
||||
* @var string
|
||||
*/
|
||||
var $lastline;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Instantiates a new Net_SMTP object, overriding any defaults
|
||||
* with parameters that are passed in.
|
||||
*
|
||||
* @param string The server to connect to.
|
||||
* @param int The port to connect to.
|
||||
* @param string The value to give when sending EHLO or HELO.
|
||||
*/
|
||||
function Net_SMTP($host = null, $port = null, $localhost = null) {
|
||||
if (isset($host)) $this->host = $host;
|
||||
if (isset($port)) $this->port = $port;
|
||||
if (isset($localhost)) $this->localhost = $localhost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to connect to the SMTP server.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function connect() {
|
||||
include_once 'Net/Socket.php';
|
||||
|
||||
if (PEAR::isError($this->socket = new Net_Socket())) { return new PEAR_Error('unable to create a socket object'); }
|
||||
if (PEAR::isError($this->socket->connect($this->host, $this->port))) { return new PEAR_Error('unable to open socket'); }
|
||||
|
||||
if (PEAR::isError($this->validateResponse('220'))) { return new PEAR_Error('smtp server not 220 ready'); }
|
||||
if (!$this->identifySender()) { return new PEAR_Error('unable to identify smtp server'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to disconnect from the SMTP server.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function disconnect() {
|
||||
if (PEAR::isError($this->socket->write("QUIT\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('221')) { return new PEAR_Error('221 Bye not received'); }
|
||||
if (PEAR::isError($this->socket->disconnect())) { return new PEAR_Error('socket disconnect failed'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to do SMTP authentication.
|
||||
*
|
||||
* @param string The userid to authenticate as.
|
||||
* @param string The password to authenticate with.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function auth($uid, $pwd) {
|
||||
/* Note: not currently checking if AUTH LOGIN is allowed */
|
||||
/* Note: only allows one authentication mechanism */
|
||||
|
||||
if (!isset($this->esmtp['AUTH'])) { return new PEAR_Error('auth not supported'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write("AUTH LOGIN\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('334')) { return new PEAR_Error('AUTH LOGIN not recognized'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write(base64_encode($uid) . "\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('334')) { return new PEAR_Error('354 not received'); }
|
||||
|
||||
if (PEAR::isError($this->socket->write(base64_encode($pwd) . "\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!$this->validateResponse('235')) { return new PEAR_Error('235 not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the HELO command.
|
||||
*
|
||||
* @param string The domain name to say we are.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function helo($domain) {
|
||||
if (PEAR::isError($this->socket->write("HELO $domain\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the MAIL FROM: command.
|
||||
*
|
||||
* @param string The sender (reverse path) to set.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function mailFrom($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("MAIL FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the RCPT TO: command.
|
||||
*
|
||||
* @param string The recipient (forward path) to add.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function rcptTo($forward_path) {
|
||||
/* Note: 251 is also a valid response code */
|
||||
|
||||
if (PEAR::isError($this->socket->write("RCPT TO: <$forward_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error($this->lastline); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the DATA command.
|
||||
*
|
||||
* @param string The message body to send.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function data($data) {
|
||||
$data = preg_replace("/([^\r]{1})\n/", "\\1\r\n", $data);
|
||||
$data = preg_replace("/\n\n/", "\n\r\n", $data);
|
||||
$data = preg_replace("/\n\./", "\n..", $data);
|
||||
|
||||
if (PEAR::isError($this->socket->write("DATA\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('354'))) { return new PEAR_Error('354 not received'); }
|
||||
if (PEAR::isError($this->socket->write($data . "\r\n.\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the SEND FROM: command.
|
||||
*
|
||||
* @param string The reverse path to send.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function send_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SEND FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the SOML FROM: command.
|
||||
*
|
||||
* @param string The reverse path to send.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function soml_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SOML FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the SAML FROM: command.
|
||||
*
|
||||
* @param string The reverse path to send.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function saml_from($reverse_path) {
|
||||
if (PEAR::isError($this->socket->write("SAML FROM:<$reverse_path>\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the RSET command.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function rset() {
|
||||
if (PEAR::isError($this->socket->write("RSET\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the VRFY command.
|
||||
*
|
||||
* @param string The string to verify
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function vrfy($string) {
|
||||
/* Note: 251 is also a valid response code */
|
||||
if (PEAR::isError($this->socket->write("VRFY $string\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the NOOP command.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
*/
|
||||
function noop() {
|
||||
if (PEAR::isError($this->socket->write("NOOP\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('250 OK not received'); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to send the EHLO command and obtain a list of ESMTP
|
||||
* extensions available, and failing that just send HELO.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access private
|
||||
*/
|
||||
function identifySender() {
|
||||
if (PEAR::isError($this->socket->write("EHLO $this->localhost\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
|
||||
$extensions = array();
|
||||
if (!($this->validateAndParseResponse('250', $extensions))) {
|
||||
if (PEAR::isError($this->socket->write("HELO $this->localhost\r\n"))) { return new PEAR_Error('write to socket failed'); }
|
||||
if (!($this->validateResponse('250'))) { return new PEAR_Error('HELO not accepted', $this->code); }
|
||||
return true;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($extensions); $i++) {
|
||||
$verb = strtok($extensions[$i], ' ');
|
||||
$arguments = substr($extensions[$i], strlen($verb) + 1, strlen($extensions[$i]) - strlen($verb) - 2);
|
||||
$this->esmtp[$verb] = $arguments;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a response from the server and see if the response code
|
||||
* matches what we are expecting.
|
||||
*
|
||||
* @param int The response code we are expecting.
|
||||
*
|
||||
* @return boolean True if we get what we expect, false otherwise.
|
||||
* @access private
|
||||
*/
|
||||
function validateResponse($code) {
|
||||
while ($this->lastline = $this->socket->readLine()) {
|
||||
$reply_code = strtok($this->lastline, ' ');
|
||||
if (!(strcmp($code, $reply_code))) {
|
||||
$this->code = $reply_code;
|
||||
return true;
|
||||
} else {
|
||||
$reply_code = strtok($this->lastline, '-');
|
||||
if (strcmp($code, $reply_code)) {
|
||||
$this->code = $reply_code;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a response from the server and see if the response code
|
||||
* matches what we are expecting. Also save the rest of the
|
||||
* response in the array passed by reference as the second
|
||||
* argument.
|
||||
*
|
||||
* @param int The response code we are expecting.
|
||||
* @param array An array to dump the rest of the response into.
|
||||
*
|
||||
* @return boolean True if we get what we expect, false otherwise.
|
||||
* @access private
|
||||
*/
|
||||
function validateAndParseResponse($code, &$arguments) {
|
||||
$arguments = array();
|
||||
|
||||
while ($this->lastline = $this->socket->readLine()) {
|
||||
$reply_code = strtok($this->lastline, ' ');
|
||||
if (!(strcmp($code, $reply_code))) {
|
||||
$arguments[] = substr($this->lastline, strlen($code) + 1, strlen($this->lastline) - strlen($code) - 1);
|
||||
$this->code = $reply_code;
|
||||
return true;
|
||||
} else {
|
||||
$reply_code = strtok($this->lastline, '-');
|
||||
if (strcmp($code, $reply_code)) {
|
||||
$this->code = $reply_code;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$arguments[] = substr($this->lastline, strlen($code) + 1, strlen($this->lastline) - strlen($code) - 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
456
html/service/include/Net/Socket.php
Normal file
456
html/service/include/Net/Socket.php
Normal file
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.0 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Stig Bakken <ssb@php.net> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Socket.php,v 1.9 2004/04/26 23:02:41 chagenbu Exp $
|
||||
//
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* Generalized Socket class. More docs to be written.
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
*/
|
||||
class Net_Socket extends PEAR {
|
||||
// {{{ properties
|
||||
|
||||
/** Socket file pointer. */
|
||||
var $fp = null;
|
||||
|
||||
/** Whether the socket is blocking. */
|
||||
var $blocking = true;
|
||||
|
||||
/** Whether the socket is persistent. */
|
||||
var $persistent = false;
|
||||
|
||||
/** The IP address to connect to. */
|
||||
var $addr = '';
|
||||
|
||||
/** The port number to connect to. */
|
||||
var $port = 0;
|
||||
|
||||
/** Number of seconds to wait on socket connections before
|
||||
assuming there's no more data. */
|
||||
var $timeout = false;
|
||||
|
||||
/** Number of bytes to read at a time in readLine() and
|
||||
readAll(). */
|
||||
var $lineLength = 2048;
|
||||
// }}}
|
||||
|
||||
// {{{ constructor
|
||||
/**
|
||||
* Constructs a new Net_Socket object.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Net_Socket()
|
||||
{
|
||||
$this->PEAR();
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ connect()
|
||||
/**
|
||||
* Connect to the specified port. If called when the socket is
|
||||
* already connected, it disconnects and connects again.
|
||||
*
|
||||
* @param $addr string IP address or host name
|
||||
* @param $port int TCP port number
|
||||
* @param $persistent bool (optional) whether the connection is
|
||||
* persistent (kept open between requests by the web server)
|
||||
* @param $timeout int (optional) how long to wait for data
|
||||
* @param $options array see options for stream_context_create
|
||||
* @access public
|
||||
* @return mixed true on success or error object
|
||||
*/
|
||||
function connect($addr, $port, $persistent = null, $timeout = null, $options = null)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
@fclose($this->fp);
|
||||
$this->fp = null;
|
||||
}
|
||||
|
||||
if (strspn($addr, '.0123456789') == strlen($addr)) {
|
||||
$this->addr = $addr;
|
||||
} else {
|
||||
$this->addr = gethostbyname($addr);
|
||||
}
|
||||
$this->port = $port % 65536;
|
||||
if ($persistent !== null) {
|
||||
$this->persistent = $persistent;
|
||||
}
|
||||
if ($timeout !== null) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
if ($options && function_exists('stream_context_create')) {
|
||||
if ($this->timeout) {
|
||||
$timeout = $this->timeout;
|
||||
} else {
|
||||
$timeout = 0;
|
||||
}
|
||||
$context = stream_context_create($options);
|
||||
$fp = $openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context);
|
||||
} else {
|
||||
if ($this->timeout) {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
|
||||
} else {
|
||||
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
return $this->raiseError($errstr, $errno);
|
||||
}
|
||||
|
||||
$this->fp = $fp;
|
||||
|
||||
return $this->setBlocking($this->blocking);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ disconnect()
|
||||
/**
|
||||
* Disconnects from the peer, closes the socket.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function disconnect()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
fclose($this->fp);
|
||||
$this->fp = null;
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ isBlocking()
|
||||
/**
|
||||
* Find out if the socket is in blocking mode.
|
||||
*
|
||||
* @access public
|
||||
* @return bool the current blocking mode.
|
||||
*/
|
||||
function isBlocking()
|
||||
{
|
||||
return $this->blocking;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ setBlocking()
|
||||
/**
|
||||
* Sets whether the socket connection should be blocking or
|
||||
* not. A read call to a non-blocking socket will return immediately
|
||||
* if there is no data available, whereas it will block until there
|
||||
* is data for blocking sockets.
|
||||
*
|
||||
* @param $mode bool true for blocking sockets, false for nonblocking
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setBlocking($mode)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$this->blocking = $mode;
|
||||
socket_set_blocking($this->fp, $this->blocking);
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ setTimeout()
|
||||
/**
|
||||
* Sets the timeout value on socket descriptor,
|
||||
* expressed in the sum of seconds and microseconds
|
||||
*
|
||||
* @param $seconds int seconds
|
||||
* @param $microseconds int microseconds
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function setTimeout($seconds, $microseconds)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
socket_set_timeout($this->fp, $seconds, $microseconds);
|
||||
return true;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ getStatus()
|
||||
/**
|
||||
* Returns information about an existing socket resource.
|
||||
* Currently returns four entries in the result array:
|
||||
*
|
||||
* <p>
|
||||
* timed_out (bool) - The socket timed out waiting for data<br>
|
||||
* blocked (bool) - The socket was blocked<br>
|
||||
* eof (bool) - Indicates EOF event<br>
|
||||
* unread_bytes (int) - Number of bytes left in the socket buffer<br>
|
||||
* </p>
|
||||
*
|
||||
* @access public
|
||||
* @return mixed Array containing information about existing socket resource or an error object otherwise
|
||||
*/
|
||||
function getStatus()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return socket_get_status($this->fp);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ gets()
|
||||
/**
|
||||
* Get a specified line of data
|
||||
*
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function gets($size)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return fgets($this->fp, $size);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ read()
|
||||
/**
|
||||
* Read a specified amount of data. This is guaranteed to return,
|
||||
* and has the added benefit of getting everything in one fread()
|
||||
* chunk; if you know the size of the data you're getting
|
||||
* beforehand, this is definitely the way to go.
|
||||
*
|
||||
* @param $size The number of bytes to read from the socket.
|
||||
* @access public
|
||||
* @return $size bytes of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function read($size)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return fread($this->fp, $size);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ write()
|
||||
/**
|
||||
* Write a specified amount of data.
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success or an error object otherwise
|
||||
*/
|
||||
function write($data)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return fwrite($this->fp, $data);
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ writeLine()
|
||||
/**
|
||||
* Write a line of data to the socket, followed by a trailing "\r\n".
|
||||
*
|
||||
* @access public
|
||||
* @return mixed fputs result, or an error
|
||||
*/
|
||||
function writeLine ($data)
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return $this->write($data . "\r\n");
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ eof()
|
||||
/**
|
||||
* Tests for end-of-file on a socket descriptor
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function eof()
|
||||
{
|
||||
return (is_resource($this->fp) && feof($this->fp));
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readByte()
|
||||
/**
|
||||
* Reads a byte of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 byte of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readByte()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
return ord($this->read(1));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readWord()
|
||||
/**
|
||||
* Reads a word of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 word of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readWord()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$buf = $this->read(2);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readInt()
|
||||
/**
|
||||
* Reads an int of data
|
||||
*
|
||||
* @access public
|
||||
* @return 1 int of data from the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readInt()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$buf = $this->read(4);
|
||||
return (ord($buf[0]) + (ord($buf[1]) << 8) +
|
||||
(ord($buf[2]) << 16) + (ord($buf[3]) << 24));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readString()
|
||||
/**
|
||||
* Reads a zeroterminated string of data
|
||||
*
|
||||
* @access public
|
||||
* @return string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readString()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$string = '';
|
||||
while (($char = $this->read(1)) != "\x00") {
|
||||
$string .= $char;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readIPAddress()
|
||||
/**
|
||||
* Reads an IP Address and returns it in a dot formated string
|
||||
*
|
||||
* @access public
|
||||
* @return Dot formated string, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readIPAddress()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$buf = $this->read(4);
|
||||
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
|
||||
ord($buf[2]), ord($buf[3]));
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readLine()
|
||||
/**
|
||||
* Read until either the end of the socket or a newline, whichever
|
||||
* comes first. Strips the trailing newline from the returned data.
|
||||
*
|
||||
* @access public
|
||||
* @return All available data up to a newline, without that
|
||||
* newline, or until the end of the socket, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readLine()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$line = '';
|
||||
$timeout = time() + $this->timeout;
|
||||
while (!$this->eof() && (!$this->timeout || time() < $timeout)) {
|
||||
$line .= $this->gets($this->lineLength);
|
||||
if (substr($line, -2) == "\r\n" ||
|
||||
substr($line, -1) == "\n") {
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ readAll()
|
||||
/**
|
||||
* Read until the socket closes. THIS FUNCTION WILL NOT EXIT if the
|
||||
* socket is in blocking mode until the socket closes.
|
||||
*
|
||||
* @access public
|
||||
* @return All data until the socket closes, or a PEAR_Error if
|
||||
* not connected.
|
||||
*/
|
||||
function readAll()
|
||||
{
|
||||
if (is_resource($this->fp)) {
|
||||
$data = '';
|
||||
while (!$this->eof())
|
||||
$data .= $this->read($this->lineLength);
|
||||
return $data;
|
||||
}
|
||||
return $this->raiseError("not connected");
|
||||
}
|
||||
// }}}
|
||||
|
||||
}
|
||||
793
html/service/include/PEAR.php
Normal file
793
html/service/include/PEAR.php
Normal file
@@ -0,0 +1,793 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.0 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Sterling Hughes <sterling@php.net> |
|
||||
// | Stig Bakken <ssb@fast.no> |
|
||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: PEAR.php,v 1.32.2.2 2002/04/09 19:04:07 ssb Exp $
|
||||
//
|
||||
|
||||
define('PEAR_ERROR_RETURN', 1);
|
||||
define('PEAR_ERROR_PRINT', 2);
|
||||
define('PEAR_ERROR_TRIGGER', 4);
|
||||
define('PEAR_ERROR_DIE', 8);
|
||||
define('PEAR_ERROR_CALLBACK', 16);
|
||||
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
define('OS_WINDOWS', true);
|
||||
define('OS_UNIX', false);
|
||||
define('PEAR_OS', 'Windows');
|
||||
} else {
|
||||
define('OS_WINDOWS', false);
|
||||
define('OS_UNIX', true);
|
||||
define('PEAR_OS', 'Unix'); // blatant assumption
|
||||
}
|
||||
|
||||
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
||||
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
||||
$GLOBALS['_PEAR_default_error_callback'] = '';
|
||||
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||
|
||||
//
|
||||
// Tests needed: - PEAR inheritance
|
||||
//
|
||||
|
||||
/**
|
||||
* Base class for other PEAR classes. Provides rudimentary
|
||||
* emulation of destructors.
|
||||
*
|
||||
* If you want a destructor in your class, inherit PEAR and make a
|
||||
* destructor method called _yourclassname (same name as the
|
||||
* constructor, but with a "_" prefix). Also, in your constructor you
|
||||
* have to call the PEAR constructor: $this->PEAR();.
|
||||
* The destructor method will be called without parameters. Note that
|
||||
* at in some SAPI implementations (such as Apache), any output during
|
||||
* the request shutdown (in which destructors are called) seems to be
|
||||
* discarded. If you need to get any debug information from your
|
||||
* destructor, use error_log(), syslog() or something similar.
|
||||
*
|
||||
* @since PHP 4.0.2
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
*/
|
||||
class PEAR
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Whether to enable internal debug messages.
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $_debug = false;
|
||||
|
||||
/**
|
||||
* Default error mode for this object.
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_default_error_mode = null;
|
||||
|
||||
/**
|
||||
* Default error options used for this object when error mode
|
||||
* is PEAR_ERROR_TRIGGER.
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $_default_error_options = null;
|
||||
|
||||
/**
|
||||
* Default error handler (callback) for this object, if error mode is
|
||||
* PEAR_ERROR_CALLBACK.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_default_error_handler = '';
|
||||
|
||||
/**
|
||||
* Which class to use for error objects.
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_error_class = 'PEAR_Error';
|
||||
|
||||
/**
|
||||
* An array of expected errors.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_expected_errors = array();
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor. Registers this object in
|
||||
* $_PEAR_destructor_object_list for destructor emulation if a
|
||||
* destructor object exists.
|
||||
*
|
||||
* @param string (optional) which class to use for error objects,
|
||||
* defaults to PEAR_Error.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function PEAR($error_class = null)
|
||||
{
|
||||
$classname = get_class($this);
|
||||
if ($this->_debug) {
|
||||
print "PEAR constructor called, class=$classname\n";
|
||||
}
|
||||
if ($error_class !== null) {
|
||||
$this->_error_class = $error_class;
|
||||
}
|
||||
while ($classname) {
|
||||
$destructor = "_$classname";
|
||||
if (method_exists($this, $destructor)) {
|
||||
global $_PEAR_destructor_object_list;
|
||||
$_PEAR_destructor_object_list[] = &$this;
|
||||
break;
|
||||
} else {
|
||||
$classname = get_parent_class($classname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ destructor
|
||||
|
||||
/**
|
||||
* Destructor (the emulated type of...). Does nothing right now,
|
||||
* but is included for forward compatibility, so subclass
|
||||
* destructors should always call it.
|
||||
*
|
||||
* See the note in the class desciption about output from
|
||||
* destructors.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function _PEAR() {
|
||||
if ($this->_debug) {
|
||||
printf("PEAR destructor called, class=%s\n", get_class($this));
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ isError()
|
||||
|
||||
/**
|
||||
* Tell whether a value is a PEAR error.
|
||||
*
|
||||
* @param mixed the value to test
|
||||
* @access public
|
||||
* @return bool true if parameter is an error
|
||||
*/
|
||||
function isError($data) {
|
||||
return (bool)(is_object($data) &&
|
||||
(get_class($data) == 'pear_error' ||
|
||||
is_subclass_of($data, 'pear_error')));
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setErrorHandling()
|
||||
|
||||
/**
|
||||
* Sets how errors generated by this DB object should be handled.
|
||||
* Can be invoked both in objects and statically. If called
|
||||
* statically, setErrorHandling sets the default behaviour for all
|
||||
* PEAR objects. If called in an object, setErrorHandling sets
|
||||
* the default behaviour for that object.
|
||||
*
|
||||
* @param int $mode
|
||||
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or
|
||||
* PEAR_ERROR_CALLBACK.
|
||||
*
|
||||
* @param mixed $options
|
||||
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
|
||||
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
|
||||
*
|
||||
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
|
||||
* to be the callback function or method. A callback
|
||||
* function is a string with the name of the function, a
|
||||
* callback method is an array of two elements: the element
|
||||
* at index 0 is the object, and the element at index 1 is
|
||||
* the name of the method to call in the object.
|
||||
*
|
||||
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
|
||||
* a printf format string used when printing the error
|
||||
* message.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @see PEAR_ERROR_RETURN
|
||||
* @see PEAR_ERROR_PRINT
|
||||
* @see PEAR_ERROR_TRIGGER
|
||||
* @see PEAR_ERROR_DIE
|
||||
* @see PEAR_ERROR_CALLBACK
|
||||
*
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
|
||||
function setErrorHandling($mode = null, $options = null)
|
||||
{
|
||||
if (isset($this)) {
|
||||
$setmode = &$this->_default_error_mode;
|
||||
$setoptions = &$this->_default_error_options;
|
||||
//$setcallback = &$this->_default_error_callback;
|
||||
} else {
|
||||
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
|
||||
//$setcallback = &$GLOBALS['_PEAR_default_error_callback'];
|
||||
}
|
||||
|
||||
switch ($mode) {
|
||||
case PEAR_ERROR_RETURN:
|
||||
case PEAR_ERROR_PRINT:
|
||||
case PEAR_ERROR_TRIGGER:
|
||||
case PEAR_ERROR_DIE:
|
||||
case null:
|
||||
$setmode = $mode;
|
||||
$setoptions = $options;
|
||||
break;
|
||||
|
||||
case PEAR_ERROR_CALLBACK:
|
||||
$setmode = $mode;
|
||||
if ((is_string($options) && function_exists($options)) ||
|
||||
(is_array($options) && method_exists(@$options[0], @$options[1])))
|
||||
{
|
||||
$setoptions = $options;
|
||||
} else {
|
||||
trigger_error("invalid error callback", E_USER_WARNING);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger_error("invalid error mode", E_USER_WARNING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ expectError()
|
||||
|
||||
/**
|
||||
* This method is used to tell which errors you expect to get.
|
||||
* Expected errors are always returned with error mode
|
||||
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
|
||||
* and this method pushes a new element onto it. The list of
|
||||
* expected errors are in effect until they are popped off the
|
||||
* stack with the popExpect() method.
|
||||
*
|
||||
* @param mixed a single error code or an array of error codes
|
||||
* to expect
|
||||
*
|
||||
* @return int the new depth of the "expected errors" stack
|
||||
*/
|
||||
function expectError($code = "*")
|
||||
{
|
||||
if (is_array($code)) {
|
||||
array_push($this->_expected_errors, $code);
|
||||
} else {
|
||||
array_push($this->_expected_errors, array($code));
|
||||
}
|
||||
return sizeof($this->_expected_errors);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ popExpect()
|
||||
|
||||
/**
|
||||
* This method pops one element off the expected error codes
|
||||
* stack.
|
||||
*
|
||||
* @return array the list of error codes that were popped
|
||||
*/
|
||||
function popExpect()
|
||||
{
|
||||
return array_pop($this->_expected_errors);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ raiseError()
|
||||
|
||||
/**
|
||||
* This method is a wrapper that returns an instance of the
|
||||
* configured error class with this object's default error
|
||||
* handling applied. If the $mode and $options parameters are not
|
||||
* specified, the object's defaults are used.
|
||||
*
|
||||
* @param $message a text error message or a PEAR error object
|
||||
*
|
||||
* @param $code a numeric error code (it is up to your class
|
||||
* to define these if you want to use codes)
|
||||
*
|
||||
* @param $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or
|
||||
* PEAR_ERROR_CALLBACK.
|
||||
*
|
||||
* @param $options If $mode is PEAR_ERROR_TRIGGER, this parameter
|
||||
* specifies the PHP-internal error level (one of
|
||||
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
|
||||
* If $mode is PEAR_ERROR_CALLBACK, this
|
||||
* parameter specifies the callback function or
|
||||
* method. In other error modes this parameter
|
||||
* is ignored.
|
||||
*
|
||||
* @param $userinfo If you need to pass along for example debug
|
||||
* information, this parameter is meant for that.
|
||||
*
|
||||
* @param $error_class The returned error object will be instantiated
|
||||
* from this class, if specified.
|
||||
*
|
||||
* @param $skipmsg If true, raiseError will only pass error codes,
|
||||
* the error message parameter will be dropped.
|
||||
*
|
||||
* @access public
|
||||
* @return object a PEAR error object
|
||||
* @see PEAR::setErrorHandling
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function &raiseError($message = null,
|
||||
$code = null,
|
||||
$mode = null,
|
||||
$options = null,
|
||||
$userinfo = null,
|
||||
$error_class = null,
|
||||
$skipmsg = false)
|
||||
{
|
||||
// The error is yet a PEAR error object
|
||||
if (is_object($message)) {
|
||||
$code = $message->getCode();
|
||||
$userinfo = $message->getUserInfo();
|
||||
$error_class = $message->getType();
|
||||
$message = $message->getMessage();
|
||||
}
|
||||
|
||||
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
|
||||
if ($exp[0] == "*" ||
|
||||
(is_int(reset($exp)) && in_array($code, $exp)) ||
|
||||
(is_string(reset($exp)) && in_array($message, $exp))) {
|
||||
$mode = PEAR_ERROR_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode === null) {
|
||||
if (isset($this) && isset($this->_default_error_mode)) {
|
||||
$mode = $this->_default_error_mode;
|
||||
} else {
|
||||
$mode = $GLOBALS['_PEAR_default_error_mode'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == PEAR_ERROR_TRIGGER && $options === null) {
|
||||
if (isset($this)) {
|
||||
if (isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
}
|
||||
} else {
|
||||
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == PEAR_ERROR_CALLBACK) {
|
||||
if (!is_string($options) &&
|
||||
!(is_array($options) && sizeof($options) == 2 &&
|
||||
is_object($options[0]) && is_string($options[1])))
|
||||
{
|
||||
if (isset($this) && isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
} else {
|
||||
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($options === null) {
|
||||
if (isset($this)) {
|
||||
if (isset($this->_default_error_options)) {
|
||||
$options = $this->_default_error_options;
|
||||
}
|
||||
} else {
|
||||
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($error_class !== null) {
|
||||
$ec = $error_class;
|
||||
} elseif (isset($this) && isset($this->_error_class)) {
|
||||
$ec = $this->_error_class;
|
||||
} else {
|
||||
$ec = 'PEAR_Error';
|
||||
}
|
||||
if ($skipmsg) {
|
||||
return new $ec($code, $mode, $options, $userinfo);
|
||||
} else {
|
||||
return new $ec($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ pushErrorHandling()
|
||||
|
||||
/**
|
||||
* Push a new error handler on top of the error handler options stack. With this
|
||||
* you can easily override the actual error handler for some code and restore
|
||||
* it later with popErrorHandling.
|
||||
*
|
||||
* @param $mode mixed (same as setErrorHandling)
|
||||
* @param $options mixed (same as setErrorHandling)
|
||||
*
|
||||
* @return bool Always true
|
||||
*
|
||||
* @see PEAR::setErrorHandling
|
||||
*/
|
||||
function pushErrorHandling($mode, $options = null)
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
if (!is_array($stack)) {
|
||||
if (isset($this)) {
|
||||
$def_mode = &$this->_default_error_mode;
|
||||
$def_options = &$this->_default_error_options;
|
||||
// XXX Used anywhere?
|
||||
//$def_callback = &$this->_default_error_callback;
|
||||
} else {
|
||||
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||
// XXX Used anywhere?
|
||||
//$def_callback = &$GLOBALS['_PEAR_default_error_callback'];
|
||||
}
|
||||
$stack = array();
|
||||
$stack[] = array($def_mode, $def_options);
|
||||
}
|
||||
|
||||
if (isset($this)) {
|
||||
$this->setErrorHandling($mode, $options);
|
||||
} else {
|
||||
PEAR::setErrorHandling($mode, $options);
|
||||
}
|
||||
$stack[] = array($mode, $options);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ popErrorHandling()
|
||||
|
||||
/**
|
||||
* Pop the last error handler used
|
||||
*
|
||||
* @return bool Always true
|
||||
*
|
||||
* @see PEAR::pushErrorHandling
|
||||
*/
|
||||
function popErrorHandling()
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
array_pop($stack);
|
||||
list($mode, $options) = $stack[sizeof($stack) - 1];
|
||||
if (isset($this)) {
|
||||
$this->setErrorHandling($mode, $options);
|
||||
} else {
|
||||
PEAR::setErrorHandling($mode, $options);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
// {{{ _PEAR_call_destructors()
|
||||
|
||||
function _PEAR_call_destructors()
|
||||
{
|
||||
global $_PEAR_destructor_object_list;
|
||||
if (is_array($_PEAR_destructor_object_list) &&
|
||||
sizeof($_PEAR_destructor_object_list))
|
||||
{
|
||||
reset($_PEAR_destructor_object_list);
|
||||
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
|
||||
$classname = get_class($objref);
|
||||
while ($classname) {
|
||||
$destructor = "_$classname";
|
||||
if (method_exists($objref, $destructor)) {
|
||||
$objref->$destructor();
|
||||
break;
|
||||
} else {
|
||||
$classname = get_parent_class($classname);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Empty the object list to ensure that destructors are
|
||||
// not called more than once.
|
||||
$_PEAR_destructor_object_list = array();
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
class PEAR_Error
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $error_message_prefix = '';
|
||||
var $mode = PEAR_ERROR_RETURN;
|
||||
var $level = E_USER_NOTICE;
|
||||
var $code = -1;
|
||||
var $message = '';
|
||||
var $userinfo = '';
|
||||
|
||||
// Wait until we have a stack-groping function in PHP.
|
||||
//var $file = '';
|
||||
//var $line = 0;
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* PEAR_Error constructor
|
||||
*
|
||||
* @param $message error message
|
||||
*
|
||||
* @param $code (optional) error code
|
||||
*
|
||||
* @param $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
|
||||
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER or
|
||||
* PEAR_ERROR_CALLBACK
|
||||
*
|
||||
* @param $level (optional) error level, _OR_ in the case of
|
||||
* PEAR_ERROR_CALLBACK, the callback function or object/method
|
||||
* tuple.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
function PEAR_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
if ($mode === null) {
|
||||
$mode = PEAR_ERROR_RETURN;
|
||||
}
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
$this->mode = $mode;
|
||||
$this->userinfo = $userinfo;
|
||||
if ($mode & PEAR_ERROR_CALLBACK) {
|
||||
$this->level = E_USER_NOTICE;
|
||||
$this->callback = $options;
|
||||
} else {
|
||||
if ($options === null) {
|
||||
$options = E_USER_NOTICE;
|
||||
}
|
||||
$this->level = $options;
|
||||
$this->callback = null;
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||
if (is_null($options) || is_int($options)) {
|
||||
$format = "%s";
|
||||
} else {
|
||||
$format = $options;
|
||||
}
|
||||
printf($format, $this->getMessage());
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||
trigger_error($this->getMessage(), $this->level);
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_DIE) {
|
||||
$msg = $this->getMessage();
|
||||
if (is_null($options) || is_int($options)) {
|
||||
$format = "%s";
|
||||
if (substr($msg, -1) != "\n") {
|
||||
$msg .= "\n";
|
||||
}
|
||||
} else {
|
||||
$format = $options;
|
||||
}
|
||||
die(sprintf($format, $msg));
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||
if (is_string($this->callback) && strlen($this->callback)) {
|
||||
call_user_func($this->callback, $this);
|
||||
} elseif (is_array($this->callback) &&
|
||||
sizeof($this->callback) == 2 &&
|
||||
is_object($this->callback[0]) &&
|
||||
is_string($this->callback[1]) &&
|
||||
strlen($this->callback[1])) {
|
||||
@call_user_method($this->callback[1], $this->callback[0],
|
||||
$this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getMode()
|
||||
|
||||
/**
|
||||
* Get the error mode from an error object.
|
||||
*
|
||||
* @return int error mode
|
||||
* @access public
|
||||
*/
|
||||
function getMode() {
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getCallback()
|
||||
|
||||
/**
|
||||
* Get the callback function/method from an error object.
|
||||
*
|
||||
* @return mixed callback function or object/method array
|
||||
* @access public
|
||||
*/
|
||||
function getCallback() {
|
||||
return $this->callback;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getMessage()
|
||||
|
||||
|
||||
/**
|
||||
* Get the error message from an error object.
|
||||
*
|
||||
* @return string full error message
|
||||
* @access public
|
||||
*/
|
||||
function getMessage ()
|
||||
{
|
||||
return ($this->error_message_prefix . $this->message);
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ getCode()
|
||||
|
||||
/**
|
||||
* Get error code from an error object
|
||||
*
|
||||
* @return int error code
|
||||
* @access public
|
||||
*/
|
||||
function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getType()
|
||||
|
||||
/**
|
||||
* Get the name of this error/exception.
|
||||
*
|
||||
* @return string error/exception name (type)
|
||||
* @access public
|
||||
*/
|
||||
function getType ()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getUserInfo()
|
||||
|
||||
/**
|
||||
* Get additional user-supplied information.
|
||||
*
|
||||
* @return string user-supplied information
|
||||
* @access public
|
||||
*/
|
||||
function getUserInfo ()
|
||||
{
|
||||
return $this->userinfo;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDebugInfo()
|
||||
|
||||
/**
|
||||
* Get additional debug information supplied by the application.
|
||||
*
|
||||
* @return string debug information
|
||||
* @access public
|
||||
*/
|
||||
function getDebugInfo ()
|
||||
{
|
||||
return $this->getUserInfo();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ addUserInfo()
|
||||
|
||||
function addUserInfo($info)
|
||||
{
|
||||
if (empty($this->userinfo)) {
|
||||
$this->userinfo = $info;
|
||||
} else {
|
||||
$this->userinfo .= " ** $info";
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ toString()
|
||||
|
||||
/**
|
||||
* Make a string representation of this object.
|
||||
*
|
||||
* @return string a string with an object summary
|
||||
* @access public
|
||||
*/
|
||||
function toString() {
|
||||
$modes = array();
|
||||
$levels = array(E_USER_NOTICE => 'notice',
|
||||
E_USER_WARNING => 'warning',
|
||||
E_USER_ERROR => 'error');
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||
if (is_array($this->callback)) {
|
||||
$callback = get_class($this->callback[0]) . '::' .
|
||||
$this->callback[1];
|
||||
} else {
|
||||
$callback = $this->callback;
|
||||
}
|
||||
return sprintf('[%s: message="%s" code=%d mode=callback '.
|
||||
'callback=%s prefix="%s" info="%s"]',
|
||||
get_class($this), $this->message, $this->code,
|
||||
$callback, $this->error_message_prefix,
|
||||
$this->userinfo);
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||
$modes[] = 'callback';
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||
$modes[] = 'print';
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||
$modes[] = 'trigger';
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_DIE) {
|
||||
$modes[] = 'die';
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_RETURN) {
|
||||
$modes[] = 'return';
|
||||
}
|
||||
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
|
||||
'prefix="%s" info="%s"]',
|
||||
get_class($this), $this->message, $this->code,
|
||||
implode("|", $modes), $levels[$this->level],
|
||||
$this->error_message_prefix,
|
||||
$this->userinfo);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
register_shutdown_function("_PEAR_call_destructors");
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: php
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
39
html/service/include/dbconnect.inc.php
Normal file
39
html/service/include/dbconnect.inc.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/*=======================================================================
|
||||
*
|
||||
* dbconnect.inc.php
|
||||
*
|
||||
* Autor: Marc Vollmann
|
||||
*
|
||||
=======================================================================*/
|
||||
|
||||
|
||||
include_once ("../../include/glob_defs.inc.php");
|
||||
|
||||
/**
|
||||
* Zuweisung zur Variable $dsn je nach benutzter Datenquelle aus-/kommentieren
|
||||
*/
|
||||
|
||||
if ($phpVersion >= "5.1") :
|
||||
date_default_timezone_set('Europe/Berlin');
|
||||
endif;
|
||||
|
||||
include_once ("../../lib/inc_lib_db.inc.php");
|
||||
|
||||
$dbCreds = array("dbHost" => $dbhostOnly, "dbUser" => $dblogin, "dbPassword" => $dbpassword, "dbName" => $dbname, "dbPort" => $dbport, "dbTable" => "user");
|
||||
|
||||
$db = new DB($dbCreds);
|
||||
|
||||
$db->dbQ('SET NAMES latin1');
|
||||
$db->dbQ('SET @@SESSION.old_passwords=0');
|
||||
|
||||
|
||||
|
||||
$db2 = $db;
|
||||
|
||||
// Wrapper for deprecated DB functions
|
||||
if ($phpVersion >= "7.0") :
|
||||
function mysql_escape_string($string) { global $db; return $db->escape($string); };
|
||||
endif;
|
||||
|
||||
?>
|
||||
97
html/service/include/glob_defs.inc.php
Normal file
97
html/service/include/glob_defs.inc.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/*=======================================================================
|
||||
*
|
||||
* glob_defs.inc.php
|
||||
*
|
||||
* Autor: Carsten Annacker, Marc Vollmann
|
||||
*
|
||||
=======================================================================*/
|
||||
|
||||
|
||||
$dbhost="172.16.0.123:3391";
|
||||
|
||||
$dblogin=(PHP_VERSION_ID != '50638' ? "phoenix" : "phoenix_new");
|
||||
// $dblogin=(PHP_VERSION_ID != '50638' ? "service" : "service_new");
|
||||
$dbpassword="AdAdgkS13";
|
||||
// $dbpassword="srvc_79531";
|
||||
$dbname="phoenix";
|
||||
|
||||
$dbhost2="172.16.0.123:3391";
|
||||
$dblogin2=$dblogin;
|
||||
$dbpassword2=$dbpassword;
|
||||
$dbname2="phoenix";
|
||||
|
||||
$dbhost3="172.16.0.123:3391";
|
||||
$dblogin3=$dblogin2;
|
||||
$dbpassword3=$dbpassword2;
|
||||
$dbname3=$dbname2;
|
||||
|
||||
$dbhostStatistic = "172.16.0.148:3391";
|
||||
|
||||
$dbhostJob2History = "172.16.0.123:3381";
|
||||
|
||||
function my_addslashes($a) {
|
||||
if (!(strpos($a, "'") === false
|
||||
&& strpos($a, "\"") === false
|
||||
&& strpos($a, "\\") === false)) {
|
||||
return addslashes($a);
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
// http://php.net/manual/de/function.addslashes.php
|
||||
function addslashes_array($a) {
|
||||
if (is_array($a)){
|
||||
foreach($a as $k => $v) {
|
||||
$b[$k] = addslashes_array($v);
|
||||
}
|
||||
return $b;
|
||||
} else {
|
||||
return my_addslashes($a);
|
||||
}
|
||||
}
|
||||
|
||||
// Seit Firefox 48.0 wird offensichtlich in jedem Fall Unicode in den Get-Vars übertragen, auch wenn die Website selbst nicht Unicode ist.
|
||||
// Daher müssen die Parameter mit potentiellen Umlauten erst decoded werden (siehe auch job_options.php).
|
||||
foreach ($_GET as $k => $v) {
|
||||
$_GET[$k] = preg_replace("/([\xC2\xC3])([\x80-\xBF])/e", "chr(ord('\\1')<<6&0xC0|ord('\\2')&0x3F)", $v);
|
||||
}
|
||||
|
||||
//print_r($_POST);
|
||||
if (!get_magic_quotes_gpc()) {
|
||||
if (!empty($HTTP_POST_VARS)) {
|
||||
foreach ($HTTP_POST_VARS as $k => $v) {
|
||||
$HTTP_POST_VARS[$k] = addslashes_array($v);
|
||||
}
|
||||
} else {
|
||||
foreach ($_POST as $k => $v) {
|
||||
$_POST[$k] = addslashes_array($v);
|
||||
}
|
||||
}
|
||||
if (!empty($HTTP_GET_VARS)) {
|
||||
foreach ($HTTP_GET_VARS as $k => $v) {
|
||||
$HTTP_GET_VARS[$k] = addslashes_array($v);
|
||||
}
|
||||
} else {
|
||||
foreach ($_GET as $k => $v) {
|
||||
$_GET[$k] = addslashes_array($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
//print_r($_POST);
|
||||
|
||||
$HTTP_POST_VARS = !empty($HTTP_POST_VARS) ? $HTTP_POST_VARS : $_POST;
|
||||
$HTTP_GET_VARS = !empty($HTTP_GET_VARS) ? $HTTP_GET_VARS : $_GET;
|
||||
$HTTP_COOKIE_VARS = !empty($HTTP_COOKIE_VARS) ? $HTTP_COOKIE_VARS : $_COOKIE;
|
||||
$HTTP_SERVER_VARS = !empty($HTTP_SERVER_VARS) ? $HTTP_SERVER_VARS : $_SERVER;
|
||||
$HTTP_ENV_VARS = !empty($HTTP_ENV_VARS) ? $HTTP_ENV_VARS : $_ENV;
|
||||
$HTTP_POST_FILES = !empty($HTTP_POST_FILES) ? $HTTP_POST_FILES : $_FILES;
|
||||
|
||||
if (!isset($PHP_SELF))
|
||||
$PHP_SELF = $_SERVER["PHP_SELF"];
|
||||
|
||||
// ini_set('default_charset', 'iso-8895-15');
|
||||
$htmlEntitiesCharset = "ISO-8859-15";
|
||||
$htmlEntitiesFlags = ENT_COMPAT | ENT_HTML401;
|
||||
|
||||
?>
|
||||
18
html/service/include/index.html
Normal file
18
html/service/include/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>votian</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="description" content="votian"> <meta name="keywords" content="votian">
|
||||
<meta http-equiv="refresh" content="0; URL=../LN/index.php">
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFA" leftmargin="1" topmargin="1" marginwidth="0" marginheight="0" link="#990000" vlink="#990000" alink="#990000">
|
||||
<a href="../LN/index.php">Bitte hier klicken, wenn Sie nicht automatisch weitergeleitet werden...</a>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user