Sources for file plugins/class/db.php in version 4.0 Beta 1
Click on a comment to hide it. Click here to show all comments.
/**
* Project: Xnyo 4: Bubbles
* File: plugins/class/db.php
*
* Version: 4.0-dev
* SVN Id: $Id: db.php 5 2007-05-18 03:49:07Z bok $
* SVN URL: $HeadURL: http://svn.syd.wholesalebroadband.com.au/xnyo/trunk/plugins/class/db.php $
* Authors: Robert Amos <bok[at]odynia.org>
*
* Copyright (c) 2001-2007 Robert Amos <bok[at]odynia.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
/**
* This file creates the XnyoDB object.
**/
class XnyoDB implements XnyoClassPlugin
{
// Plugin Information
public $_plugin_info = array
(
'name' => 'Xnyo Database Management',
'description' => 'Controls and manages connections to the databases.',
'action' => XNYO_PLUGIN_ACTION_GLOBAL,
'varname' => 'db'
);
/**
* Data Types
**/
const INT = 'int';
const TEXT = 'text';
const VARCHAR = 'text';
const LOB = 'lob';
const STMT = 'stmt';
const BOOL = 'bool';
const FLOAT = 'float';
const CHAR = 'char';
const BIT = 'bit';
// storage
private $databases = array();
private $connections = array();
private $resources = array();
private $tables = array();
private $table;
private $database;
private $resource;
private $connection;
private $statement;
private $xnyo;
/**
* Constructor
**/
public function __construct ()
{
$this->xnyo = $GLOBALS['xnyo_parent'];
}
/**
* Add a new Database to the ones we know about
**/
public function add ($type, $short, $database)
{
if (XNYO_DEBUG) $this->xnyo->d('Adding database <b>%s</b> (<b>%s</b>) to the database using the
alias <b>%s</b>', $database, $type, $short);
$this->databases[$short] = array
(
'dbname' => $database,
'type' => $type
);
return true;
}
/**
* Sets the hostname for a known database connection
**/
public function set_host ($short, $host, $port=null)
{
// error handling
if (!isset($this->databases[$short]))
throw new XnyoError('Unable to set hostname for database <b>%s</b> because no such database is
known.', $short);
if (XNYO_DEBUG) $this->xnyo->d('Setting host/port for database alias <b>%s</b> to <b>%s</b>',
$short, (is_null($port) ? $host : $host.':'.$port));
// set the hostname
$this->databases[$short]['host'] = $host;
// and port
if (!is_null($port))
$this->databases[$short]['port'] = $port;
}
/**
* Sets the username / password for a known database connection
**/
public function set_credentials ($short, $user, $pass=null)
{
// error handling
if (!isset($this->databases[$short]))
throw new XnyoError('Unable to set credentials for database <b>%s</b> because no such database is
known.', $short);
if (XNYO_DEBUG) $this->xnyo->d('Setting user/pass for database alias <b>%s</b> to <b>%s</b>',
$short, (is_null($pass) ? $user : $user.':'.$pass));
// set the username
$this->databases[$short]['user'] = $user;
// and the password
if (!is_null($pass))
$this->databases[$short]['pass'] = $pass;
}
/**
* Swap
*
* This functions switches the active database connection to the table specified in the appropriate
dbspec file
**/
public function swap ($table)
{
// have we already loaded this table before?
if (!is_object($this->tables[$table]))
// no, load up the table specifications
$this->load_table($table);
if (XNYO_DEBUG) $this->xnyo->d('Switching to table <b>%s</b>, database connection <b>%s</b>.',
$table, $this->tables[$table]->database);
return $this->set_active($table);
}
/**
* Spawn
*
* Same as the swap function above, but instead of adding the new connection to the collection
* it returns it.
**/
public function spawn ($table)
{
// have we already loaded this table?
if (!is_object($this->tables[$table]))
// no, load up the table specifications
$this->load_table($table);
// create a new instance
if (XNYO_DEBUG) $this->xnyo->d('Creating new instance of table connection <b>%s</b>', $table);
return $this->create_instance($table);
}
/**
* Announce
*
* A XnyoActiveRecord based object uses this method
* to announce its presence to the XnyoDB controller
**/
public function announce ($obj)
{
// set the tables reference
$table = strtolower(get_class($obj));
$this->tables[$table] = $obj;
// check for a valid database
if (!isset($this->databases[$this->tables[$table]->database]) ||
!is_array($this->databases[$this->tables[$table]->database]) ||
!isset($this->databases[$this->tables[$table]->database]['type']))
throw new XnyoError ('Database <b>%s</b> specified for dbspec table plugin <b>%s</b> is not valid
or has not been configured.', $this->tables[$table]->database, $table);
// include that database plugin
$this->xnyo->inc($this->databases[$this->tables[$table]->database]['type'], XNYO_PLUGIN_DATABASE);
// do we have a connection to this database?
$db = $this->tables[$table]->database;
if (!isset($this->resources[$db]) || !is_object($this->resources[$db]))
$this->connect($db);
// create a connection object.
$c = $this->databases[$db]['type'];
if (XNYO_DEBUG) $this->xnyo->d('Creating connection object for database <b>%s</b> using class
<b>%s</b>', $db, $c);
$this->connections[$db] = new $c ($this->databases[$db], $this->resources[$db]);
// get the columns in this table
$this->tables[$table]->columns =
$this->connections[$db]->getColumns($this->tables[$table]->table);
// return the resource
return $this->connections[$db];
}
/**
* Load up a table's details
**/
private function load_table ($table)
{
if (XNYO_DEBUG) $this->xnyo->d('Loading up table specification for <b>%s</b>', $table);
// go ahead and load it
$this->xnyo->inc($table, XNYO_PLUGIN_DBSPEC);
$this->tables[$table] = new $table();
// include that database plugin
$this->xnyo->inc($this->databases[$this->tables[$table]->database]['type'], XNYO_PLUGIN_DATABASE);
// do we have a connection to this database?
$db = $this->tables[$table]->database;
if (!is_object($this->resources[$db]))
$this->connect($db);
// create a connection object.
$c = $this->databases[$db]['type'];
if (XNYO_DEBUG) $this->xnyo->d('Creating connection object for database <b>%s</b> using class
<b>%s</b>', $db, $c);
$this->connections[$db] = new $c ($this->databases[$db], $this->resources[$db]);
// get the columns in this table
$this->tables[$table]->columns =
$this->connections[$db]->getColumns($this->tables[$table]->table);
}
/**
* Connect to a database
**/
private function connect ($db)
{
// this is just a matter of creating a connection object of the driver and getting the resultant
PDO object
$class = $this->databases[$db]['type'].'Connection';
if (XNYO_DEBUG) $this->xnyo->d('Connecting to database <b>%s</b> using connection class
<b>%s</b>', $this->databases[$db]['dbname'], $class);
$tmp = new $class ($this->databases[$db]);
$this->resources[$db] = $tmp->connect();
$this->resources[$db]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (XNYO_DEBUG) $this->xnyo->d('Connected successfully to database <b>%s</b> (<b>%s</b>)',
$this->databases[$db]['dbname'], $this->databases[$db]['type']);
}
/**
* Set the active table / connection
**/
private function set_active ($table)
{
// repoint the references
$this->table = &$this->tables[$table];
$this->database = &$this->databases[$this->tables[$table]->database];
$this->resource = &$this->resources[$this->tables[$table]->database];
$this->connection = &$this->connections[$this->tables[$table]->database];
$this->statement = &$this->connection->statement;
return true;
}
/**
* Create an instance of the table connection
**/
public function create_instance ($table)
{
return clone $this->connections[$table];
}
/**
* Xnyo to PDO Type Conversion
**/
public static function XnyoToPDOType ($t)
{
switch ($t)
{
case XnyoDB::INT:
return PDO::PARAM_INT;
case XnyoDB::FLOAT:
case XnyoDB::CHAR:
case XnyoDB::BIT:
case XnyoDB::TEXT:
case XnyoDB::VARCHAR:
return PDO::PARAM_STR;
case XnyoDB::LOB:
return PDO::PARAM_LOB;
case XnyoDB::STMT:
return PDO::PARAM_STMT;
case XnyoDB::BOOL:
return PDO::PARAM_BOOL;
default:
return PDO::PARAM_STR;
}
}
/**
* Begins a Transaction
*
* http://php.net/pdo-begintransaction
**/
public function beginTransaction ()
{
return $this->connection->beginTransaction();
}
/**
* Commits the current transaction
*
* http://php.net/pdo-commit
**/
public function commit ()
{
return $this->connection->commit();
}
/**
* Returns the SQLSTATE
*
* http://php.net/pdo-errorcode
**/
public function errorCode ()
{
return $this->connection->errorCode();
}
/**
* Return an array of error information about the last operation performed.
*
* http://php.net/pdo-errorinfo
**/
public function errorInfo()
{
return $this->connection->errorInfo();
}
/**
* Executes an SQL statement and returns the number of rows affected.
*
* http://php.net/pdo-exec
**/
public function exec ($s)
{
return $this->connection->exec($s);
}
/**
* Get a database connection attribute
*
* http://php.net/pdo-getattribute
**/
public function getAttribute ($i)
{
return $this->connection->getAttribute($i);
}
/**
* Get an array of the available PDO drivers
*
* http://php.net/pdo-getavailabledrivers
**/
public function getAvailableDrivers ()
{
return $this->connection->getAvailableDrivers;
}
/**
* Gets the ID of the last inserted row or sequence value
*
* http://php.net/pdo-lastinsertid
**/
public function lastInsertId ($seq=null)
{
if (is_null($seq))
return $this->connection->lastInsertId();
return $this->connection->lastInsertId($seq);
}
/**
* Prepares an SQL statement.
*
* http://php.net/pdo-prepare
**/
public function prepare ($s, $opt=null)
{
if (is_null($opt))
return $this->connection->prepare($s);
return $this->connection->prepare($s, $opt);
}
/**
* Executes an SQL statement
*
* http://php.net/pdo-query
**/
public function query ($s)
{
$args = func_get_args();
return call_user_func_array(array($this->connection, 'query'), $args);
}
/**
* Quotes a string for use in a query
*
* http://php.net/pdo-quote
**/
public function quote ($s, $p=null)
{
if (is_null($p))
$p = PDO::PARAM_STR;
return $this->connection->quote($s, $p);
}
/**
* Rolls back a transaction
*
* http://php.net/pdo-rollback
**/
public function rollBack ()
{
return $this->connection->rollBack();
}
/**
* Set a connection attribute
*
* http://php.net/pdo-setattribute
**/
public function setAttribute ($a, $v)
{
return $this->connection->setAttribute($a, $v);
}
/**
* Bind a column to a PHP variable
*
* http://php.net/pdostatement-bindcolumn
**/
public function bindColumn ($column, $param, $type=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to bind to column <b>%s</b> because there is no current PDOStatement
object. Use $db->prepare($sql);', $column);
if (is_null($type))
return $this->connection->statement->bindColumn($column, $param);
return $this->connection->statement->bindColumn($column, $param);
}
/**
* Bind a parameter to the specified variable name (as a reference)
*
* http://php.net/pdostatement-bindparam
**/
public function bindParam ($param, $var, $type=null, $length=null, $opt=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to bind to parameter <b>%s</b> because there is no current
PDOStatement object. Use $db->prepare($sql);', $param);
// too many args to do them all!
$args = func_get_args();
return call_user_func_array(array($this->connection->statement, 'bindParam'), $args);
}
/**
* Bind a parameter to the specified varaible's value (no reference)
*
* http://php.net/pdostatement-bindvalue
**/
public function bindValue ($param, $value, $type=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to set value for column <b>%s</b> to <b>%s</b> because there is no
current PDOStatement object. Use $db->prepare($sql);', $param, $value);
if (is_null($type))
return $this->connection->statement->bindValue($param, $value);
return $this->connection->statement->bindValue($param, $value, $type);
}
/**
* Closes the cursor, enabling the statement to be executed again.
*
* http://php.net/pdostatement-closecursor
**/
public function closeCursor ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to close active cursor as there is no PDOStatement object to close it
on. Use $db->prepare($sql);');
return $this->connection->statement->closeCursor();
}
/**
* Gets the number of columns in the result set
*
* http://php.net/pdostatement-columncount
**/
public function columnCount ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to count columns because there is no PDOStatement object. Use
$db->prepare($sql);');
return $this->connection->statement->columnCount();
}
/**
* Gets the SQLSTATE associated with a statement
*
* http://php.net/pdostatement-errorcode
**/
public function errorCodeStatement()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to get error code because there is no PDOStatement object. Use
$db->prepare($sql);');
return $this->connection->statement->errorCode();
}
/**
* Gets an array of error information about the statement
*
* http://php.net/pdostatement-errorinfo
**/
public function errorInfoStatement ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to get error information because there is no PDOStatement object. Use
$db->prepare($sql);');
return $this->connection->statement->errorInfo();
}
/**
* Executes a prepared statement
*
* http://php.net/pdostatement-execute
**/
public function execute ($input=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to execute statement because there is no PDOStatement object. Use
$db->prepare($sql);');
if (is_null($input))
return $this->connection->statement->execute();
return $this->connection->statement->execute($input);
}
/**
* Fetches the next row from a result set
*
* http://php.net/pdostatement-fetch
**/
public function fetch ($style=null, $ori=null, $offset=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to fetch next row because there is no PDOStatement object. Use
$db->prepare($sql);');
if (is_null($style))
$style = PDO::FETCH_BOTH;
if (is_null($ori))
$ori = PDO::FETCH_ORI_NEXT;
if (is_null($offset))
return $this->connection->statement->fetch($style, $ori);
return $this->connection->statement->fetch($style, $ori, $offset);
}
/**
* Returns an array containing all of the result set rows
*
* http://php.net/pdostatement-fetchall
**/
public function fetchAll ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to fetch all results because there is no PDOStatement object. Use
$db->prepare($sql);');
$args = func_get_args();
return call_user_func_array(array($this->connection->statement, 'fetchAll'), $args);
}
/**
* Returns a single column from the next row of a result set
*
* http://php.net/pdostatement-fetchcolumn
**/
public function fetchColumn ($col=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to fetch column because there is no PDOStatement object. Use
$db->prepare($sql);');
if (is_null($col))
$col = 0;
return $this->connection->statement->fetchColumn($col);
}
/**
* Fetches the next row and returns it as an object.
*
* http://php.net/pdostatement-fetchobject
**/
public function fetchObject ($class=null, $const_args=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to fetch object because there is no PDOStatement object. Use
$db->prepare($sql);');
if (is_null($class))
$class = 'stdClass';
if (is_null($const_args))
$const_args = array();
return $this->connection->statement->fetchObject($class, $const_args);
}
/**
* Get a statement attribute
*
* http://php.net/pdostatement-getattribute
**/
public function getAttributeStatement ($a)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to get statement attribute <b>%s</b> because there is no PDOStatement
object. Use $db->prepare($sql);', $a);
return $this->connection->statement->getAttribute($a);
}
/**
* Gets the column meta data for the specified column
*
* http://php.net/pdostatement-getcolumnmeta
**/
public function getColumnMeta ($col=null)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to get column metadata because there is no PDOStatement object. Use
$db->prepare($sql);');
if (is_null($col))
$col = 0;
return $this->connection->statement->getColumnMeta($col);
}
/**
* Advances to the next rowset in a multi-rowset statement handle
*
* http://php.net/pdostatement-nextrowset
**/
public function nextRowset ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to advance to the next rowset because there is no PDOStatement
object. Use $db->prepare($sql);');
return $this->connection->statement->nextRowset();
}
/**
* Returns the number of rows affected by the last SQL Statement
*
* http://php.net/pdostatement-rowcount
**/
public function rowCount ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to count the number of rows because there is no PDOStatement object.
Use $db->prepare($sql);');
return $this->connection->statement->rowCount();
}
/**
* Sets a statement attribute
*
* http://php.net/pdostatement-setattribute
**/
public function setAttributeStatement ($a, $v)
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to set statement attribute because there is no PDOStatement object.
Use $db->prepare($sql);');
return $this->connection->statement->setAttribute($a, $v);
}
/**
* Set the default fetch mode for this statement
*
* http://php.net/pdostatement-setfetchmode
**/
public function setFetchMode ()
{
if (!is_object($this->connection->statement))
throw new XnyoError('Unable to set default fetch mode because there is no PDOStatement object.
Use $db->prepare($sql);');
$args = func_get_args();
return call_user_func_array(array($this->connection->statement, 'setFetchMode'), $args);
}
}
