class DB in Flickr API 5
Database independent query interface
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): <pre> 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. </pre>
@category Database @package DB @author Stig Bakken <ssb@php.net> @author Tomas V.V.Cox <cox@idecnet.com> @author Daniel Convissor <danielc@php.net> @copyright 1997-2005 The PHP Group @license http://www.php.net/license/3_0.txt PHP License 3.0 @version Release: @package_version@ @link http://pear.php.net/package/DB
Hierarchy
- class \DB
Expanded class hierarchy of DB
File
- phpFlickr/
PEAR/ DB.php, line 431
View source
class DB {
// {{{ &factory()
/**
* Create a new DB object for the specified database type but don't
* connect to the database
*
* @param string $type the database type (eg "mysql")
* @param array $options an associative array of option names and values
*
* @return object a new DB object. A DB_Error object on failure.
*
* @see DB_common::setOption()
*/
function &factory($type, $options = false) {
if (!is_array($options)) {
$options = array(
'persistent' => $options,
);
}
if (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)) {
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, "Unable to include the DB/{$type}.php" . " file for '{$dsn}'", 'DB_Error', true);
return $tmp;
}
@($obj =& new $classname());
foreach ($options as $option => $value) {
$test = $obj
->setOption($option, $value);
if (DB::isError($test)) {
return $test;
}
}
return $obj;
}
// }}}
// {{{ &connect()
/**
* Create a new DB object including a connection to the specified database
*
* Example 1.
* <code>
* require_once 'DB.php';
*
* $dsn = 'pgsql://user:password@host/database';
* $options = array(
* 'debug' => 2,
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param mixed $dsn the string "data source name" or array in the
* format returned by DB::parseDSN()
* @param array $options an associative array of option names and values
*
* @return object a new DB object. A DB_Error object on failure.
*
* @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(),
* DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(),
* DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(),
* DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(),
* DB_sybase::connect()
*
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
*/
function &connect($dsn, $options = []) {
$dsninfo = DB::parseDSN($dsn);
$type = $dsninfo['phptype'];
if (!is_array($options)) {
/*
* For backwards compatibility. $options used to be boolean,
* indicating whether the connection should be persistent.
*/
$options = array(
'persistent' => $options,
);
}
if (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)) {
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, "Unable to include the DB/{$type}.php" . " file for '{$dsn}'", 'DB_Error', true);
return $tmp;
}
@($obj =& new $classname());
foreach ($options as $option => $value) {
$test = $obj
->setOption($option, $value);
if (DB::isError($test)) {
return $test;
}
}
$err = $obj
->connect($dsninfo, $obj
->getOption('persistent'));
if (DB::isError($err)) {
$err
->addUserInfo($dsn);
return $err;
}
return $obj;
}
// }}}
// {{{ apiVersion()
/**
* Return the DB API version
*
* @return string the DB API version number
*/
function apiVersion() {
return '@package_version@';
}
// }}}
// {{{ isError()
/**
* Determines if a variable is a DB_Error object
*
* @param mixed $value the variable to check
*
* @return bool whether $value is DB_Error object
*/
function isError($value) {
return is_a($value, 'DB_Error');
}
// }}}
// {{{ isConnection()
/**
* Determines if a value is a DB_<driver> object
*
* @param mixed $value the value to test
*
* @return bool whether $value is a DB_<driver> object
*/
function isConnection($value) {
return is_object($value) && is_subclass_of($value, 'db_common') && method_exists($value, 'simpleQuery');
}
// }}}
// {{{ isManip()
/**
* Tell whether a query is a data manipulation or data definition query
*
* Examples of data manipulation queries are INSERT, UPDATE and DELETE.
* Examples of data definition queries are CREATE, DROP, ALTER, GRANT,
* REVOKE.
*
* @param string $query the query
*
* @return boolean whether $query is a data manipulation query
*/
function isManip($query) {
$manips = 'INSERT|UPDATE|DELETE|REPLACE|' . 'CREATE|DROP|' . 'LOAD DATA|SELECT .* INTO|COPY|' . 'ALTER|GRANT|REVOKE|' . 'LOCK|UNLOCK';
if (preg_match('/^\\s*"?(' . $manips . ')\\s+/i', $query)) {
return true;
}
return false;
}
// }}}
// {{{ errorMessage()
/**
* Return a textual error message for a DB error code
*
* @param integer $value the DB error code
*
* @return string the 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_ACCESS_VIOLATION => 'insufficient permissions',
DB_ERROR_ALREADY_EXISTS => 'already exists',
DB_ERROR_CANNOT_CREATE => 'can not create',
DB_ERROR_CANNOT_DROP => 'can not drop',
DB_ERROR_CONNECT_FAILED => 'connect failed',
DB_ERROR_CONSTRAINT => 'constraint violation',
DB_ERROR_CONSTRAINT_NOT_NULL => 'null value violates not-null constraint',
DB_ERROR_DIVZERO => 'division by zero',
DB_ERROR_EXTENSION_NOT_FOUND => 'extension not found',
DB_ERROR_INVALID => 'invalid',
DB_ERROR_INVALID_DATE => 'invalid date or time',
DB_ERROR_INVALID_DSN => 'invalid DSN',
DB_ERROR_INVALID_NUMBER => 'invalid number',
DB_ERROR_MISMATCH => 'mismatch',
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
DB_ERROR_NODBSELECTED => 'no database selected',
DB_ERROR_NOSUCHDB => 'no such database',
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_TRUNCATED => 'truncated',
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
DB_OK => 'no error',
);
}
if (DB::isError($value)) {
$value = $value
->getCode();
}
return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR];
}
// }}}
// {{{ parseDSN()
/**
* Parse a data source name
*
* Additional keys can be added by appending a URI query string to the
* end of the DSN.
*
* The format of the supplied DSN is in its fullest form:
* <code>
* phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
* </code>
*
* Most variations are allowed:
* <code>
* phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
* phptype://username:password@hostspec/database_name
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
* </code>
*
* @param string $dsn Data Source Name to be parsed
*
* @return array an associative array with the following keys:
* + 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
*/
function parseDSN($dsn) {
$parsed = array(
'phptype' => false,
'dbsyntax' => false,
'username' => false,
'password' => false,
'protocol' => false,
'hostspec' => false,
'port' => false,
'socket' => false,
'database' => false,
);
if (is_array($dsn)) {
$dsn = array_merge($parsed, $dsn);
if (!$dsn['dbsyntax']) {
$dsn['dbsyntax'] = $dsn['phptype'];
}
return $dsn;
}
// 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'] = !$arr[2] ? $arr[1] : $arr[2];
}
else {
$parsed['phptype'] = $str;
$parsed['dbsyntax'] = $str;
}
if (!count($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'] = rawurldecode(substr($str, 0, $pos));
$parsed['password'] = rawurldecode(substr($str, $pos + 1));
}
else {
$parsed['username'] = rawurldecode($str);
}
}
// Find protocol and hostspec
if (preg_match('|^([^(]+)\\((.*?)\\)/?(.*?)$|', $dsn, $match)) {
// $dsn => proto(proto_opts)/database
$proto = $match[1];
$proto_opts = $match[2] ? $match[2] : false;
$dsn = $match[3];
}
else {
// $dsn => protocol+hostspec/database (old format)
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 = rawurldecode($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 ($dsn) {
if (($pos = strpos($dsn, '?')) === false) {
// /database
$parsed['database'] = rawurldecode($dsn);
}
else {
// /database?param1=value1¶m2=value2
$parsed['database'] = rawurldecode(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] = rawurldecode($value);
}
}
}
}
return $parsed;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DB:: |
function | Return the DB API version | ||
DB:: |
function | Create a new DB object including a connection to the specified database | ||
DB:: |
function | Return a textual error message for a DB error code | ||
DB:: |
function | Create a new DB object for the specified database type but don't connect to the database | ||
DB:: |
function | Determines if a value is a DB_<driver> object | ||
DB:: |
function | Determines if a variable is a DB_Error object | ||
DB:: |
function | Tell whether a query is a data manipulation or data definition query | ||
DB:: |
function | Parse a data source name |