1
0
mirror of https://github.com/dg/dibi.git synced 2025-02-24 10:53:17 +01:00
php-dibi/dibi/dibi.php

636 lines
15 KiB
PHP
Raw Normal View History

2008-07-17 03:51:29 +00:00
<?php
/**
* dibi - smart database abstraction layer (http://dibiphp.com)
2008-07-17 03:51:29 +00:00
*
2012-01-02 20:24:16 +01:00
* Copyright (c) 2005, 2012 David Grudl (http://davidgrudl.com)
2008-07-17 03:51:29 +00:00
*
* For the full copyright and license information, please view
* the file license.txt that was distributed with this source code.
2008-07-17 03:51:29 +00:00
*/
/**
* Check PHP configuration.
*/
if (version_compare(PHP_VERSION, '5.2.0', '<')) {
throw new Exception('dibi needs PHP 5.2.0 or newer.');
2008-07-17 03:51:29 +00:00
}
@set_magic_quotes_runtime(FALSE); // intentionally @
2008-07-17 03:51:29 +00:00
require_once dirname(__FILE__) . '/libs/interfaces.php';
2010-10-06 16:02:20 +02:00
require_once dirname(__FILE__) . '/libs/DibiDateTime.php';
require_once dirname(__FILE__) . '/libs/DibiObject.php';
require_once dirname(__FILE__) . '/libs/DibiLiteral.php';
2011-01-25 18:00:29 +01:00
require_once dirname(__FILE__) . '/libs/DibiHashMap.php';
2008-07-17 03:51:29 +00:00
require_once dirname(__FILE__) . '/libs/DibiException.php';
require_once dirname(__FILE__) . '/libs/DibiConnection.php';
require_once dirname(__FILE__) . '/libs/DibiResult.php';
require_once dirname(__FILE__) . '/libs/DibiResultIterator.php';
require_once dirname(__FILE__) . '/libs/DibiRow.php';
2008-07-17 03:51:29 +00:00
require_once dirname(__FILE__) . '/libs/DibiTranslator.php';
require_once dirname(__FILE__) . '/libs/DibiDataSource.php';
require_once dirname(__FILE__) . '/libs/DibiFluent.php';
require_once dirname(__FILE__) . '/libs/DibiDatabaseInfo.php';
require_once dirname(__FILE__) . '/libs/DibiEvent.php';
require_once dirname(__FILE__) . '/libs/DibiFileLogger.php';
require_once dirname(__FILE__) . '/libs/DibiFirePhpLogger.php';
if (interface_exists('Nette\Diagnostics\IBarPanel') || interface_exists('IBarPanel')) {
require_once dirname(__FILE__) . '/bridges/Nette/DibiNettePanel.php';
}
2008-07-17 03:51:29 +00:00
/**
* Interface for database drivers.
*
* This class is static container class for creating DB objects and
* store connections info.
*
2010-09-14 18:40:41 +02:00
* @author David Grudl
2012-01-03 04:50:11 +01:00
* @package dibi
2008-07-17 03:51:29 +00:00
*/
class dibi
{
2011-02-16 19:27:38 +01:00
/** column type */
const TEXT = 's', // as 'string'
BINARY = 'bin',
BOOL = 'b',
INTEGER = 'i',
FLOAT = 'f',
DATE = 'd',
DATETIME = 't',
TIME = 't';
const IDENTIFIER = 'n',
AFFECTED_ROWS = 'a';
2011-02-16 19:27:38 +01:00
/** @deprecated */
const FIELD_TEXT = dibi::TEXT,
FIELD_BINARY = dibi::BINARY,
FIELD_BOOL = dibi::BOOL,
FIELD_INTEGER = dibi::INTEGER,
FIELD_FLOAT = dibi::FLOAT,
FIELD_DATE = dibi::DATE,
FIELD_DATETIME = dibi::DATETIME,
FIELD_TIME = dibi::TIME;
/** version */
2013-06-23 02:18:09 +02:00
const VERSION = '2.2-dev',
2011-02-16 19:27:38 +01:00
REVISION = '$WCREV$ released on $WCDATE$';
/** sorting order */
const ASC = 'ASC',
DESC = 'DESC';
2008-07-17 03:51:29 +00:00
2008-10-28 15:24:47 +00:00
/** @var DibiConnection[] Connection registry storage for DibiConnection objects */
2008-07-17 03:51:29 +00:00
private static $registry = array();
2008-10-28 15:24:47 +00:00
/** @var DibiConnection Current connection */
2008-07-17 03:51:29 +00:00
private static $connection;
2008-10-28 15:24:47 +00:00
/** @var array @see addHandler */
2008-07-17 03:51:29 +00:00
private static $handlers = array();
2008-10-28 15:24:47 +00:00
/** @var string Last SQL command @see dibi::query() */
2008-07-17 03:51:29 +00:00
public static $sql;
2008-10-28 15:24:47 +00:00
/** @var int Elapsed time for last query */
2008-07-17 03:51:29 +00:00
public static $elapsedTime;
2008-10-28 15:24:47 +00:00
/** @var int Elapsed time for all queries */
2008-07-17 03:51:29 +00:00
public static $totalTime;
2008-10-28 15:24:47 +00:00
/** @var int Number or queries */
2008-07-17 03:51:29 +00:00
public static $numOfQueries = 0;
2008-10-28 15:24:47 +00:00
/** @var string Default dibi driver */
2008-07-17 03:51:29 +00:00
public static $defaultDriver = 'mysql';
/**
* Static class - cannot be instantiated.
*/
final public function __construct()
{
throw new LogicException("Cannot instantiate static class " . get_class($this));
}
/********************* connections handling ****************d*g**/
/**
* Creates a new DibiConnection object and connects it to specified database.
* @param mixed connection parameters
* @param string connection name
2008-07-17 03:51:29 +00:00
* @return DibiConnection
* @throws DibiException
*/
public static function connect($config = array(), $name = 0)
{
return self::$connection = self::$registry[$name] = new DibiConnection($config, $name);
}
/**
* Disconnects from database (doesn't destroy DibiConnection object).
* @return void
*/
public static function disconnect()
{
self::getConnection()->disconnect();
}
/**
* Returns TRUE when connection was established.
* @return bool
*/
public static function isConnected()
{
return (self::$connection !== NULL) && self::$connection->isConnected();
}
/**
* Retrieve active connection.
* @param string connection registy name
* @return DibiConnection
2008-07-17 03:51:29 +00:00
* @throws DibiException
*/
public static function getConnection($name = NULL)
{
if ($name === NULL) {
if (self::$connection === NULL) {
throw new DibiException('Dibi is not connected to database.');
}
return self::$connection;
}
if (!isset(self::$registry[$name])) {
throw new DibiException("There is no connection named '$name'.");
}
return self::$registry[$name];
}
2010-08-31 22:39:57 +02:00
/**
* Sets connection.
* @param DibiConnection
* @return DibiConnection
*/
public static function setConnection(DibiConnection $connection)
{
return self::$connection = $connection;
}
2008-07-17 03:51:29 +00:00
/**
* Change active connection.
* @param string connection registy name
* @return void
* @throws DibiException
*/
public static function activate($name)
{
self::$connection = self::getConnection($name);
}
/********************* monostate for active connection ****************d*g**/
/**
* Generates and executes SQL query - Monostate for DibiConnection::query().
* @param array|mixed one or more arguments
* @return DibiResult|int result set object (if any)
2008-07-17 03:51:29 +00:00
* @throws DibiException
*/
public static function query($args)
{
$args = func_get_args();
return self::getConnection()->query($args);
}
/**
* Executes the SQL query - Monostate for DibiConnection::nativeQuery().
* @param string SQL statement.
* @return DibiResult|int result set object (if any)
2008-07-17 03:51:29 +00:00
*/
public static function nativeQuery($sql)
{
return self::getConnection()->nativeQuery($sql);
}
/**
* Generates and prints SQL query - Monostate for DibiConnection::test().
* @param array|mixed one or more arguments
* @return bool
*/
public static function test($args)
{
$args = func_get_args();
return self::getConnection()->test($args);
}
/**
* Generates and returns SQL query as DibiDataSource - Monostate for DibiConnection::test().
* @param array|mixed one or more arguments
* @return DibiDataSource
*/
public static function dataSource($args)
{
$args = func_get_args();
return self::getConnection()->dataSource($args);
}
2008-07-17 03:51:29 +00:00
/**
* Executes SQL query and fetch result - Monostate for DibiConnection::query() & fetch().
* @param array|mixed one or more arguments
* @return DibiRow
2008-07-17 03:51:29 +00:00
* @throws DibiException
*/
public static function fetch($args)
{
$args = func_get_args();
return self::getConnection()->query($args)->fetch();
}
/**
* Executes SQL query and fetch results - Monostate for DibiConnection::query() & fetchAll().
* @param array|mixed one or more arguments
* @return array of DibiRow
2008-07-17 03:51:29 +00:00
* @throws DibiException
*/
public static function fetchAll($args)
{
$args = func_get_args();
return self::getConnection()->query($args)->fetchAll();
}
/**
* Executes SQL query and fetch first column - Monostate for DibiConnection::query() & fetchSingle().
* @param array|mixed one or more arguments
* @return string
* @throws DibiException
*/
public static function fetchSingle($args)
{
$args = func_get_args();
return self::getConnection()->query($args)->fetchSingle();
}
/**
* Executes SQL query and fetch pairs - Monostate for DibiConnection::query() & fetchPairs().
* @param array|mixed one or more arguments
* @return string
* @throws DibiException
*/
public static function fetchPairs($args)
{
$args = func_get_args();
return self::getConnection()->query($args)->fetchPairs();
}
2008-07-17 03:51:29 +00:00
/**
* Gets the number of affected rows.
* Monostate for DibiConnection::getAffectedRows()
* @return int number of rows
* @throws DibiException
*/
public static function getAffectedRows()
{
return self::getConnection()->getAffectedRows();
}
/**
* Gets the number of affected rows. Alias for getAffectedRows().
2008-07-17 03:51:29 +00:00
* @return int number of rows
* @throws DibiException
*/
public static function affectedRows()
{
return self::getConnection()->getAffectedRows();
2008-07-17 03:51:29 +00:00
}
/**
* Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
* Monostate for DibiConnection::getInsertId()
* @param string optional sequence name
* @return int
* @throws DibiException
*/
public static function getInsertId($sequence=NULL)
{
return self::getConnection()->getInsertId($sequence);
}
/**
* Retrieves the ID generated for an AUTO_INCREMENT column. Alias for getInsertId().
2008-07-17 03:51:29 +00:00
* @param string optional sequence name
* @return int
* @throws DibiException
*/
public static function insertId($sequence=NULL)
{
return self::getConnection()->getInsertId($sequence);
2008-07-17 03:51:29 +00:00
}
/**
* Begins a transaction - Monostate for DibiConnection::begin().
2009-06-30 14:08:49 +00:00
* @param string optional savepoint name
2008-07-17 03:51:29 +00:00
* @return void
* @throws DibiException
*/
2008-11-17 16:17:16 +00:00
public static function begin($savepoint = NULL)
2008-07-17 03:51:29 +00:00
{
2008-11-17 16:17:16 +00:00
self::getConnection()->begin($savepoint);
2008-07-17 03:51:29 +00:00
}
/**
2008-11-17 16:17:16 +00:00
* Commits statements in a transaction - Monostate for DibiConnection::commit($savepoint = NULL).
2009-06-30 14:08:49 +00:00
* @param string optional savepoint name
2008-07-17 03:51:29 +00:00
* @return void
* @throws DibiException
*/
2008-11-17 16:17:16 +00:00
public static function commit($savepoint = NULL)
2008-07-17 03:51:29 +00:00
{
2008-11-17 16:17:16 +00:00
self::getConnection()->commit($savepoint);
2008-07-17 03:51:29 +00:00
}
/**
* Rollback changes in a transaction - Monostate for DibiConnection::rollback().
2009-06-30 14:08:49 +00:00
* @param string optional savepoint name
2008-07-17 03:51:29 +00:00
* @return void
* @throws DibiException
*/
2008-11-17 16:17:16 +00:00
public static function rollback($savepoint = NULL)
2008-07-17 03:51:29 +00:00
{
2008-11-17 16:17:16 +00:00
self::getConnection()->rollback($savepoint);
}
/**
* Gets a information about the current database - Monostate for DibiConnection::getDatabaseInfo().
* @return DibiDatabaseInfo
*/
public static function getDatabaseInfo()
{
return self::getConnection()->getDatabaseInfo();
2008-07-17 03:51:29 +00:00
}
/**
* Import SQL dump from file - extreme fast!
* @param string filename
* @return int count of sql commands
*/
public static function loadFile($file)
{
return self::getConnection()->loadFile($file);
}
/**
* Replacement for majority of dibi::methods() in future.
*/
2008-07-22 22:37:14 +00:00
public static function __callStatic($name, $args)
2008-07-17 03:51:29 +00:00
{
//if ($name = 'select', 'update', ...') {
2013-07-02 18:42:55 +02:00
// return self::command()->$name($args);
2008-07-17 03:51:29 +00:00
//}
return call_user_func_array(array(self::getConnection(), $name), $args);
}
/********************* fluent SQL builders ****************d*g**/
/**
* @return DibiFluent
*/
public static function command()
{
return self::getConnection()->command();
2008-07-17 03:51:29 +00:00
}
/**
* @param string column name
* @return DibiFluent
*/
public static function select($args)
{
$args = func_get_args();
return call_user_func_array(array(self::getConnection(), 'select'), $args);
2008-07-17 03:51:29 +00:00
}
/**
* @param string table
* @param array
* @return DibiFluent
*/
public static function update($table, $args)
2008-07-17 03:51:29 +00:00
{
return self::getConnection()->update($table, $args);
2008-07-17 03:51:29 +00:00
}
/**
* @param string table
* @param array
* @return DibiFluent
*/
public static function insert($table, $args)
2008-07-17 03:51:29 +00:00
{
return self::getConnection()->insert($table, $args);
2008-07-17 03:51:29 +00:00
}
/**
* @param string table
* @return DibiFluent
*/
public static function delete($table)
{
return self::getConnection()->delete($table);
2008-07-17 03:51:29 +00:00
}
/********************* data types ****************d*g**/
/**
2013-10-16 21:16:37 +02:00
* @deprecated
2008-07-17 03:51:29 +00:00
*/
public static function datetime($time = NULL)
{
2013-10-16 21:16:37 +02:00
trigger_error(__METHOD__ . '() is deprecated; create DateTime object instead.', E_USER_WARNING);
return new DibiDateTime($time);
2008-07-17 03:51:29 +00:00
}
/**
* @deprecated
2008-07-17 03:51:29 +00:00
*/
public static function date($date = NULL)
{
2013-10-16 21:16:37 +02:00
trigger_error(__METHOD__ . '() is deprecated; create DateTime object instead.', E_USER_WARNING);
return new DibiDateTime($date);
2008-07-17 03:51:29 +00:00
}
/********************* substitutions ****************d*g**/
/**
* Returns substitution hashmap - Monostate for DibiConnection::getSubstitutes().
2011-01-25 18:00:29 +01:00
* @return DibiHashMap
*/
public static function getSubstitutes()
{
return self::getConnection()->getSubstitutes();
}
/** @deprecated */
2008-07-17 03:51:29 +00:00
public static function addSubst($expr, $subst)
{
trigger_error(__METHOD__ . '() is deprecated; use dibi::getSubstitutes()->expr = val; instead.', E_USER_WARNING);
self::getSubstitutes()->$expr = $subst;
2008-07-17 03:51:29 +00:00
}
/** @deprecated */
2008-07-17 03:51:29 +00:00
public static function removeSubst($expr)
{
trigger_error(__METHOD__ . '() is deprecated; use unset(dibi::getSubstitutes()->expr) instead.', E_USER_WARNING);
$substitutes = self::getSubstitutes();
2008-07-17 03:51:29 +00:00
if ($expr === TRUE) {
foreach ($substitutes as $expr => $foo) {
unset($substitutes->$expr);
}
2008-07-17 03:51:29 +00:00
} else {
unset($substitutes->$expr);
2008-07-17 03:51:29 +00:00
}
}
/** @deprecated */
public static function setSubstFallback($callback)
2008-07-17 03:51:29 +00:00
{
trigger_error(__METHOD__ . '() is deprecated; use dibi::getSubstitutes()->setCallback() instead.', E_USER_WARNING);
self::getSubstitutes()->setCallback($callback);
}
2008-07-17 03:51:29 +00:00
/********************* misc tools ****************d*g**/
/**
* Prints out a syntax highlighted version of the SQL command or DibiResult.
* @param string|DibiResult
* @param bool return output instead of printing it?
* @return string
*/
public static function dump($sql = NULL, $return = FALSE)
{
ob_start();
if ($sql instanceof DibiResult) {
$sql->dump();
} else {
2013-07-02 18:42:55 +02:00
if ($sql === NULL) {
$sql = self::$sql;
}
2008-07-17 03:51:29 +00:00
2012-01-11 23:46:20 +01:00
static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';
2008-07-17 03:51:29 +00:00
// insert new lines
$sql = " $sql ";
2008-07-17 03:51:29 +00:00
$sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
// reduce spaces
$sql = preg_replace('#[ \t]{2,}#', " ", $sql);
$sql = wordwrap($sql, 100);
2010-04-04 02:57:43 +02:00
$sql = preg_replace("#([ \t]*\r?\n){2,}#", "\n", $sql);
2008-07-17 03:51:29 +00:00
2012-10-03 22:56:49 +02:00
// syntax highlight
$highlighter = "#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is";
if (PHP_SAPI === 'cli') {
2012-10-03 22:56:49 +02:00
if (substr(getenv('TERM'), 0, 5) === 'xterm') {
$sql = preg_replace_callback($highlighter, array('dibi', 'cliHighlightCallback'), $sql);
}
echo trim($sql) . "\n\n";
2012-10-03 22:56:49 +02:00
} else {
2010-08-27 01:06:05 +02:00
$sql = htmlSpecialChars($sql);
2012-10-03 22:56:49 +02:00
$sql = preg_replace_callback($highlighter, array('dibi', 'highlightCallback'), $sql);
2013-06-23 01:57:48 +02:00
echo '<pre class="dump">', trim($sql), "</pre>\n\n";
}
2008-07-17 03:51:29 +00:00
}
if ($return) {
return ob_get_clean();
} else {
ob_end_flush();
}
}
private static function highlightCallback($matches)
{
2013-06-23 01:57:48 +02:00
if (!empty($matches[1])) { // comment
2008-07-17 03:51:29 +00:00
return '<em style="color:gray">' . $matches[1] . '</em>';
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[2])) { // error
2008-07-17 03:51:29 +00:00
return '<strong style="color:red">' . $matches[2] . '</strong>';
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[3])) { // most important keywords
2008-07-17 03:51:29 +00:00
return '<strong style="color:blue">' . $matches[3] . '</strong>';
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[4])) { // other keywords
2008-07-17 03:51:29 +00:00
return '<strong style="color:green">' . $matches[4] . '</strong>';
2013-06-23 01:57:48 +02:00
}
2008-07-17 03:51:29 +00:00
}
2012-10-03 22:56:49 +02:00
private static function cliHighlightCallback($matches)
{
2013-06-23 01:57:48 +02:00
if (!empty($matches[1])) { // comment
2012-10-03 22:56:49 +02:00
return "\033[1;30m" . $matches[1] . "\033[0m";
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[2])) { // error
2012-10-03 22:56:49 +02:00
return "\033[1;31m" . $matches[2] . "\033[0m";
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[3])) { // most important keywords
2012-10-03 22:56:49 +02:00
return "\033[1;34m" . $matches[3] . "\033[0m";
2013-06-23 01:57:48 +02:00
} elseif (!empty($matches[4])) { // other keywords
2012-10-03 22:56:49 +02:00
return "\033[1;32m" . $matches[4] . "\033[0m";
2013-06-23 01:57:48 +02:00
}
2012-10-03 22:56:49 +02:00
}
2008-07-17 03:51:29 +00:00
}