1
0
mirror of https://github.com/dg/dibi.git synced 2025-01-18 06:38:45 +01:00

* removed $throwExceptions (always throws)

* added DibiLogger, dibi::notify(), dibi::startLogger()
* miniprofiler dibi::$numOfQueries, $totalTime, $elapsedTime
* simplified DibiException, added DibiDatabaseException
* Dibi::nativeQuery splitted into DibiDriver::doQuery & nativeQuery()
* moved dibi::dumpResult -> DibiResult::dump()
* moved dibi::test() -> DibiDriver::test()
* DibiTranslator generates $mask
This commit is contained in:
David Grudl 2007-09-29 07:53:25 +00:00
parent 0d8478d1d3
commit d35a850311
26 changed files with 689 additions and 703 deletions

View File

@ -14,7 +14,7 @@
* @author David Grudl
* @copyright Copyright (c) 2005-2007 David Grudl aka -dgx- (http://www.dgx.cz)
* @license New BSD License
* @version 0.8e (Revision: $WCREV$, Date: $WCDATE$)
* @version 0.9a (Revision: $WCREV$, Date: $WCDATE$)
* @category Database
* @package Dibi
* @link http://dibi.texy.info/
@ -28,8 +28,9 @@
*/
if (version_compare(PHP_VERSION , '5.0.3', '<'))
if (version_compare(PHP_VERSION , '5.0.3', '<')) {
die('dibi needs PHP 5.0.3 or newer');
}
// libraries
@ -37,6 +38,7 @@ require_once dirname(__FILE__).'/libs/driver.php';
require_once dirname(__FILE__).'/libs/resultset.php';
require_once dirname(__FILE__).'/libs/translator.php';
require_once dirname(__FILE__).'/libs/exception.php';
require_once dirname(__FILE__).'/libs/logger.php';
@ -87,7 +89,7 @@ class dibi
FIELD_COUNTER = 'c', // counter or autoincrement, is integer
// dibi version
VERSION = '0.8e (Revision: $WCREV$, Date: $WCDATE$)';
VERSION = '0.9a (Revision: $WCREV$, Date: $WCDATE$)';
/**
@ -102,36 +104,6 @@ class dibi
*/
private static $connection;
/**
* Last SQL command @see dibi::query()
* @var string
*/
public static $sql;
/**
* File for logging SQL queries
* @var string|NULL
*/
public static $logFile;
/**
* Mode parameter used by fopen()
* @var string
*/
public static $logMode = 'a';
/**
* To log all queries or error queries (debug mode)
* @var bool
*/
public static $logAll = FALSE;
/**
* dibi::query() error mode
* @var bool
*/
public static $throwExceptions = TRUE;
/**
* Substitutions for identifiers
* @var array
@ -145,9 +117,36 @@ class dibi
private static $handlers = array();
/**
* Last SQL command @see dibi::query()
* @var string
*/
public static $sql;
/**
* Elapsed time for last query
* @var int
*/
private static $timer;
public static $elapsedTime;
/**
* Elapsed time for all queries
* @var int
*/
public static $totalTime;
/**
* Number or queries
* @var int
*/
public static $numOfQueries = 0;
/**
* Start time
* @var int
*/
private static $time;
@ -173,12 +172,10 @@ class dibi
parse_str($config, $config);
}
// config['driver'] is required
if (empty($config['driver'])) {
throw new DibiException('Driver is not specified.');
}
// include dibi driver
$class = "Dibi$config[driver]Driver";
if (!class_exists($class)) {
include_once dirname(__FILE__) . "/drivers/$config[driver].php";
@ -188,13 +185,8 @@ class dibi
}
}
// create connection object and store in list
/** like $connection = $class::connect($config); */
self::$connection = self::$registry[$name] = new $class($config);
if (self::$logAll) self::log("OK: connected to DB '$config[driver]'");
return self::$connection;
// create connection object and store in list; like $connection = $class::connect($config);
return self::$connection = self::$registry[$name] = new $class($config);
}
@ -260,7 +252,6 @@ class dibi
*/
public static function query($args)
{
// receive arguments
if (!is_array($args)) $args = func_get_args();
return self::getConnection()->query($args);
@ -269,29 +260,29 @@ class dibi
/**
* Generates and prints SQL query
* Executes the SQL query - Monostate for DibiDriver::nativeQuery()
*
* @param string SQL statement.
* @return object|bool Result set object or TRUE on success, FALSE on failure
*/
public static function nativeQuery($sql)
{
return self::getConnection()->nativeQuery($sql);
}
/**
* Generates and prints SQL query - Monostate for DibiDriver::test()
*
* @param array|mixed one or more arguments
* @return bool
*/
public static function test($args)
{
// receive arguments
if (!is_array($args)) $args = func_get_args();
// and generate SQL
$trans = new DibiTranslator(self::getConnection());
try {
$sql = $trans->translate($args);
} catch (DibiException $e) {
return FALSE;
}
if ($sql === FALSE) return FALSE;
self::dump($sql);
return TRUE;
return self::getConnection()->test($args);
}
@ -323,25 +314,12 @@ class dibi
/**
* Executes the SQL query - Monostate for DibiDriver::nativeQuery()
*
* @param string SQL statement.
* @return object|bool Result set object or TRUE on success, FALSE on failure
*/
public static function nativeQuery($sql)
{
return self::getConnection()->nativeQuery($sql);
}
/**
* Begins a transaction - Monostate for DibiDriver::begin()
*/
public static function begin()
{
return self::getConnection()->begin();
self::getConnection()->begin();
}
@ -351,7 +329,7 @@ class dibi
*/
public static function commit()
{
return self::getConnection()->commit();
self::getConnection()->commit();
}
@ -361,84 +339,7 @@ class dibi
*/
public static function rollback()
{
return self::getConnection()->rollback();
}
private static function dumpHighlight($matches)
{
if (!empty($matches[1])) // comment
return '<em style="color:gray">'.$matches[1].'</em>';
if (!empty($matches[2])) // error
return '<strong style="color:red">'.$matches[2].'</strong>';
if (!empty($matches[3])) // most important keywords
return '<strong style="color:blue">'.$matches[3].'</strong>';
if (!empty($matches[4])) // other keywords
return '<strong style="color:green">'.$matches[4].'</strong>';
}
/**
* Prints out a syntax highlighted version of the SQL command
*
* @param string SQL command
* @param bool return or print?
* @return void
*/
public static function dump($sql, $return = FALSE) {
static $keywords2 = 'ALL|DISTINCT|AS|ON|INTO|AND|OR|AS';
static $keywords1 = 'SELECT|UPDATE|INSERT|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN';
// insert new lines
$sql = preg_replace("#\\b(?:$keywords1)\\b#", "\n\$0", $sql);
$sql = trim($sql);
// reduce spaces
$sql = preg_replace('# {2,}#', ' ', $sql);
$sql = wordwrap($sql, 100);
$sql = htmlSpecialChars($sql);
$sql = preg_replace("#\n{2,}#", "\n", $sql);
// syntax highlight
$sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql);
$sql = '<pre class="dump">' . $sql . "</pre>\n";
// print & return
if (!$return) echo $sql;
return $sql;
}
/**
* Displays complete result-set as HTML table
*
* @param object DibiResult
* @return void
*/
public static function dumpResult(DibiResult $res)
{
echo '<table class="dump"><tr>';
echo '<th>#row</th>';
foreach ($res->getFields() as $field)
echo '<th>' . $field . '</th>';
echo '</tr>';
foreach ($res as $row => $fields) {
echo '<tr><th>', $row, '</th>';
foreach ($fields as $field) {
if (is_object($field)) $field = $field->__toString();
echo '<td>', htmlSpecialChars($field), '</td>';
}
echo '</tr>';
}
echo '</table>';
self::getConnection()->rollback();
}
@ -489,117 +390,123 @@ class dibi
/**
* Add new event handler
*
* @param string event name
* @param callback
* @return void
*/
public static function addHandler($event, $callback)
public static function addHandler($callback)
{
if (!is_callable($callback)) {
throw new DibiException("Invalid callback");
}
self::$handlers[$event][] = $callback;
self::$handlers[] = $callback;
}
/**
* Invoke registered handlers
* Event notification (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback)
*
* @param string event name
* @param array arguments passed into handler
* @param string event name
* @param DibiDriver
* @param mixed
* @return void
*/
public static function invokeEvent($event, $args)
public static function notify($event, DibiDriver $driver = NULL, $arg = NULL)
{
if (!isset(self::$handlers[$event])) return;
if ($event === 'beforeQuery') {
self::$numOfQueries++;
self::$elapsedTime = FALSE;
self::$time = -microtime(TRUE);
self::$sql = $arg;
foreach (self::$handlers[$event] as $handler) {
call_user_func_array($handler, $args);
} elseif ($event === 'afterQuery') {
self::$elapsedTime = self::$time + microtime(TRUE);
self::$totalTime += self::$elapsedTime;
}
}
public static function beforeQuery($driver, $sql)
{
self::$sql = $sql;
self::$timer = -microtime(true);
foreach (self::$handlers as $handler) {
call_user_func($handler, $event, $driver, $arg);
}
}
/**
* Error logging - EXPERIMENTAL
* Enable profiler & logger
*
* @param string filename
* @param bool log all queries?
* @return DibiProfiler
*/
public static function afterQuery($driver, $sql, $res)
public static function startLogger($file, $logQueries = FALSE)
{
if ($res === FALSE) { // query error
if (self::$logFile) { // log to file
$info = $driver->errorInfo();
if ($info['code']) {
$info['message'] = "[$info[code]] $info[message]";
}
self::log(
"ERROR: $info[message]"
. "\n-- SQL: " . self::$sql
. "\n-- driver: " . $driver->getConfig('driver')
. ";\n-- " . date('Y-m-d H:i:s ')
);
}
if (self::$throwExceptions) {
$info = $driver->errorInfo();
throw new DibiException('Query error (driver ' . $driver->getConfig('driver') . ')', $info, self::$sql);
} else {
$info = $driver->errorInfo();
if ($info['code']) {
$info['message'] = "[$info[code]] $info[message]";
}
trigger_error("self: $info[message]", E_USER_WARNING);
return FALSE;
}
}
if (self::$logFile && self::$logAll) { // log success
self::$timer += microtime(true);
$msg = $res instanceof DibiResult ? 'object('.get_class($res).') rows: '.$res->rowCount() : 'OK';
self::log(
"OK: " . self::$sql
. ";\n-- result: $msg"
. "\n-- takes: " . sprintf('%0.3f', self::$timer * 1000) . ' ms'
. "\n-- driver: " . $driver->getConfig('driver')
. "\n-- " . date('Y-m-d H:i:s ')
);
}
$logger = new DibiLogger($file);
$logger->logQueries = $logQueries;
self::addHandler(array($logger, 'handler'));
return $logger;
}
/**
* Error logging - EXPERIMENTAL
* Prints out a syntax highlighted version of the SQL command or DibiResult
*
* @param string|DibiResult
* @param bool return or print?
* @return string
*/
public static function log($message)
public static function dump($sql = NULL, $return = FALSE)
{
if (self::$logFile == NULL || self::$logMode == NULL) return;
ob_start();
if ($sql instanceof DibiResult) {
$sql->dump();
$f = fopen(self::$logFile, self::$logMode);
if (!$f) return;
flock($f, LOCK_EX);
fwrite($f, $message. "\n\n");
fclose($f);
} else {
if ($sql === NULL) $sql = self::$sql;
static $keywords2 = 'ALL|DISTINCT|AS|ON|INTO|AND|OR|AS';
static $keywords1 = 'SELECT|UPDATE|INSERT|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN';
// insert new lines
$sql = preg_replace("#\\b(?:$keywords1)\\b#", "\n\$0", $sql);
$sql = trim($sql);
// reduce spaces
$sql = preg_replace('# {2,}#', ' ', $sql);
$sql = wordwrap($sql, 100);
$sql = htmlSpecialChars($sql);
$sql = preg_replace("#\n{2,}#", "\n", $sql);
// syntax highlight
$sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'highlightCallback'), $sql);
echo '<pre class="dump">', $sql, "</pre>\n";
}
if ($return) {
return ob_get_clean();
} else {
ob_end_flush();
}
}
private static function highlightCallback($matches)
{
if (!empty($matches[1])) // comment
return '<em style="color:gray">'.$matches[1].'</em>';
if (!empty($matches[2])) // error
return '<strong style="color:red">'.$matches[2].'</strong>';
if (!empty($matches[3])) // most important keywords
return '<strong style="color:blue">'.$matches[3].'</strong>';
if (!empty($matches[4])) // other keywords
return '<strong style="color:green">'.$matches[4].'</strong>';
}
} // class dibi
// this is experimental:
dibi::addHandler('beforeQuery', array('dibi', 'beforeQuery'));
dibi::addHandler('afterQuery', array('dibi', 'afterQuery'));

View File

@ -12,35 +12,25 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for MS SQL database
*
*/
class DibiMSSqlDriver extends DibiDriver
class DibiMsSqlDriver extends DibiDriver
{
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
/**
* @param array connect configuration
* @throws DibiException
*/
public function __construct($config)
{
if (!extension_loaded('mssql')) {
throw new DibiException("PHP extension 'mssql' is not loaded");
}
if (!isset($config['host'])) $config['host'] = NULL;
if (!isset($config['username'])) $config['username'] = NULL;
if (!isset($config['password'])) $config['password'] = NULL;
@ -52,7 +42,11 @@ class DibiMSSqlDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('mssql')) {
throw new DibiException("PHP extension 'mssql' is not loaded");
}
$config = $this->getConfig();
if (empty($config['persistent'])) {
$connection = @mssql_connect($config['host'], $config['username'], $config['password'], TRUE);
@ -61,30 +55,28 @@ class DibiMSSqlDriver extends DibiDriver
}
if (!is_resource($connection)) {
throw new DibiException("Connecting error (driver mssql)'");
throw new DibiDatabaseException("Can't connect to DB");
}
if (!empty($config['database']) && !@mssql_select_db($config['database'], $connection)) {
throw new DibiException("Connecting error (driver mssql)");
throw new DibiDatabaseException("Can't select DB '$config[database]'");
}
dibi::notify('connected', $this);
return $connection;
}
public function nativeQuery($sql)
protected function doQuery($sql)
{
$res = @mssql_query($sql, $this->getConnection());
if ($res === FALSE) {
return FALSE;
throw new DibiDatabaseException('Query error', 0, $sql);
} elseif (is_resource($res)) {
return new DibiMSSqlResult($res);
} else {
return TRUE;
}
}
@ -107,21 +99,24 @@ class DibiMSSqlDriver extends DibiDriver
public function begin()
{
return mssql_query('BEGIN TRANSACTION', $this->getConnection());
$this->doQuery('BEGIN TRANSACTION');
dibi::notify('begin', $this);
}
public function commit()
{
return mssql_query('COMMIT', $this->getConnection());
$this->doQuery('COMMIT');
dibi::notify('commit', $this);
}
public function rollback()
{
return mssql_query('ROLLBACK', $this->getConnection());
$this->doQuery('ROLLBACK');
dibi::notify('rollback', $this);
}
@ -171,12 +166,12 @@ class DibiMSSqlDriver extends DibiDriver
}
if ($offset) {
throw new DibiException('Offset is not implemented in driver odbc');
throw new DibiException('Offset is not implemented');
}
}
} // DibiMSSqlDriver
} // DibiMsSqlDriver
@ -188,15 +183,6 @@ class DibiMSSqlDriver extends DibiDriver
class DibiMSSqlResult extends DibiResult
{
private $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,23 +12,18 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for MySQL database
*
*/
class DibiMySqlDriver extends DibiDriver
{
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
/**
@ -37,10 +32,6 @@ class DibiMySqlDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('mysql')) {
throw new DibiException("PHP extension 'mysql' is not loaded");
}
// default values
if (empty($config['username'])) $config['username'] = ini_get('mysql.default_user');
if (empty($config['password'])) $config['password'] = ini_get('mysql.default_password');
@ -57,7 +48,11 @@ class DibiMySqlDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('mysql')) {
throw new DibiException("PHP extension 'mysql' is not loaded");
}
$config = $this->getConfig();
if (isset($config['protocol']) && $config['protocol'] === 'unix') { // host can be socket
$host = ':' . $config['host'];
@ -82,45 +77,37 @@ class DibiMySqlDriver extends DibiDriver
ini_set('track_errors', $save);
}
if (!is_resource($connection)) {
throw new DibiException("Connecting error (driver mysql)'", array(
'message' => mysql_error() ? mysql_error() : $php_errormsg,
'code' => mysql_errno(),
));
$msg = mysql_error();
if (!$msg) $msg = $php_errormsg;
throw new DibiDatabaseException($msg, mysql_errno());
}
if (!empty($config['charset'])) {
@mysql_query("SET NAMES '" . $config['charset'] . "'", $connection);
// don't handle this error...
}
if (!empty($config['database']) && !@mysql_select_db($config['database'], $connection)) {
throw new DibiException("Connecting error (driver mysql)", array(
'message' => mysql_error($connection),
'code' => mysql_errno($connection),
));
throw new DibiDatabaseException(mysql_error($connection), mysql_errno($connection));
}
dibi::notify('connected', $this);
return $connection;
}
public function nativeQuery($sql)
protected function doQuery($sql)
{
$res = @mysql_query($sql, $this->getConnection());
$connection = $this->getConnection();
$res = @mysql_query($sql, $connection);
if ($res === FALSE) {
return FALSE;
throw new DibiDatabaseException(mysql_error($connection), mysql_errno($connection), $sql);
} elseif (is_resource($res)) {
return new DibiMySqlResult($res);
} else {
return TRUE;
}
}
@ -144,21 +131,24 @@ class DibiMySqlDriver extends DibiDriver
public function begin()
{
return mysql_query('BEGIN', $this->getConnection());
$this->doQuery('BEGIN');
dibi::notify('begin', $this);
}
public function commit()
{
return mysql_query('COMMIT', $this->getConnection());
$this->doQuery('COMMIT');
dibi::notify('commit', $this);
}
public function rollback()
{
return mysql_query('ROLLBACK', $this->getConnection());
$this->doQuery('ROLLBACK');
dibi::notify('rollback', $this);
}
@ -223,15 +213,6 @@ class DibiMySqlDriver extends DibiDriver
class DibiMySqlResult extends DibiResult
{
private $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,23 +12,18 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for MySQLi database
*
*/
class DibiMySqliDriver extends DibiDriver
{
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
@ -38,10 +33,6 @@ class DibiMySqliDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('mysqli')) {
throw new DibiException("PHP extension 'mysqli' is not loaded");
}
// default values
if (empty($config['username'])) $config['username'] = ini_get('mysqli.default_user');
if (empty($config['password'])) $config['password'] = ini_get('mysqli.default_password');
@ -59,38 +50,38 @@ class DibiMySqliDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('mysqli')) {
throw new DibiException("PHP extension 'mysqli' is not loaded");
}
$config = $this->getConfig();
$connection = @mysqli_connect($config['host'], $config['username'], $config['password'], $config['database'], $config['port']);
if (!$connection) {
throw new DibiException("Connecting error (driver mysqli)", array(
'message' => mysqli_connect_error(),
'code' => mysqli_connect_errno(),
));
throw new DibiDatabaseException(mysqli_connect_error(), mysqli_connect_errno());
}
if (!empty($config['charset'])) {
mysqli_query($connection, "SET NAMES '" . $config['charset'] . "'");
}
dibi::notify('connected', $this);
return $connection;
}
public function nativeQuery($sql)
protected function doQuery($sql)
{
$res = @mysqli_query($this->getConnection(), $sql);
$connection = $this->getConnection();
$res = @mysqli_query($connection, $sql);
if ($res === FALSE) {
return FALSE;
throw new DibiDatabaseException(mysqli_error($connection), mysqli_errno($connection), $sql);
} elseif (is_object($res)) {
return new DibiMySqliResult($res);
} else {
return TRUE;
}
}
@ -114,7 +105,11 @@ class DibiMySqliDriver extends DibiDriver
public function begin()
{
return mysqli_autocommit($this->getConnection(), FALSE);
$connection = $this->getConnection();
if (!mysqli_autocommit($connection, FALSE)) {
throw new DibiDatabaseException(mysqli_error($connection), mysqli_errno($connection));
}
dibi::notify('begin', $this);
}
@ -122,9 +117,11 @@ class DibiMySqliDriver extends DibiDriver
public function commit()
{
$connection = $this->getConnection();
$ok = mysqli_commit($connection);
if (!mysqli_commit($connection)) {
throw new DibiDatabaseException(mysqli_error($connection), mysqli_errno($connection));
}
mysqli_autocommit($connection, TRUE);
return $ok;
dibi::notify('commit', $this);
}
@ -132,9 +129,11 @@ class DibiMySqliDriver extends DibiDriver
public function rollback()
{
$connection = $this->getConnection();
$ok = mysqli_rollback($connection);
if (!mysqli_rollback($connection)) {
throw new DibiDatabaseException(mysqli_error($connection), mysqli_errno($connection));
}
mysqli_autocommit($connection, TRUE);
return $ok;
dibi::notify('rollback', $this);
}
@ -199,15 +198,6 @@ class DibiMySqliDriver extends DibiDriver
class DibiMySqliResult extends DibiResult
{
private $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,26 +12,24 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver interacting with databases via ODBC connections
*
*/
class DibiOdbcDriver extends DibiDriver
{
private
$affectedRows = FALSE;
public $formats = array(
'TRUE' => "-1",
'FALSE' => "0",
'date' => "#m/d/Y#",
'datetime' => "#m/d/Y H:i:s#",
);
public
$formats = array(
'TRUE' => "-1",
'FALSE' => "0",
'date' => "#m/d/Y#",
'datetime' => "#m/d/Y H:i:s#",
);
/**
* Affected rows
* @var mixed
*/
private $affectedRows = FALSE;
@ -41,9 +39,6 @@ class DibiOdbcDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('odbc'))
throw new DibiException("PHP extension 'odbc' is not loaded");
// default values
if (empty($config['username'])) $config['username'] = ini_get('odbc.default_user');
if (empty($config['password'])) $config['password'] = ini_get('odbc.default_pw');
@ -68,7 +63,11 @@ class DibiOdbcDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('odbc')) {
throw new DibiException("PHP extension 'odbc' is not loaded");
}
$config = $this->getConfig();
if (empty($config['persistent'])) {
$connection = @odbc_connect($config['database'], $config['username'], $config['password']);
@ -77,12 +76,10 @@ class DibiOdbcDriver extends DibiDriver
}
if (!is_resource($connection)) {
throw new DibiException("Connecting error (driver odbc)", array(
'message' => odbc_errormsg(),
'code' => odbc_error(),
));
throw new DibiDatabaseException(odbc_errormsg(), odbc_error());
}
dibi::notify('connected', $this);
return $connection;
}
@ -91,19 +88,26 @@ class DibiOdbcDriver extends DibiDriver
public function nativeQuery($sql)
{
$this->affectedRows = FALSE;
$res = @odbc_exec($this->getConnection(), $sql);
$res = parent::nativeQuery($sql);
if ($res instanceof DibiResult) {
$this->affectedRows = odbc_num_rows($res->getResource());
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
}
return $res;
}
protected function doQuery($sql)
{
$connection = $this->getConnection();
$res = @odbc_exec($connection, $sql);
if ($res === FALSE) {
return FALSE;
throw new DibiDatabaseException(odbc_errormsg($connection), odbc_error($connection), $sql);
} elseif (is_resource($res)) {
$this->affectedRows = odbc_num_rows($res);
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
return new DibiOdbcResult($res);
} else {
return TRUE;
}
}
@ -125,7 +129,11 @@ class DibiOdbcDriver extends DibiDriver
public function begin()
{
return odbc_autocommit($this->getConnection(), FALSE);
$connection = $this->getConnection();
if (!odbc_autocommit($connection, FALSE)) {
throw new DibiDatabaseException(odbc_errormsg($connection), odbc_error($connection));
}
dibi::notify('begin', $this);
}
@ -133,9 +141,11 @@ class DibiOdbcDriver extends DibiDriver
public function commit()
{
$connection = $this->getConnection();
$ok = odbc_commit($connection);
if (!odbc_commit($connection)) {
throw new DibiDatabaseException(odbc_errormsg($connection), odbc_error($connection));
}
odbc_autocommit($connection, TRUE);
return $ok;
dibi::notify('commit', $this);
}
@ -143,9 +153,11 @@ class DibiOdbcDriver extends DibiDriver
public function rollback()
{
$connection = $this->getConnection();
$ok = odbc_rollback($connection);
if (!odbc_rollback($connection)) {
throw new DibiDatabaseException(odbc_errormsg($connection), odbc_error($connection));
}
odbc_autocommit($connection, TRUE);
return $ok;
dibi::notify('rollback', $this);
}
@ -209,16 +221,9 @@ class DibiOdbcDriver extends DibiDriver
class DibiOdbcResult extends DibiResult
{
private $resource;
private $row = 0;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,23 +12,18 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for PDO
*
*/
class DibiPdoDriver extends DibiDriver
{
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
@ -38,10 +33,6 @@ class DibiPdoDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('pdo')) {
throw new DibiException("PHP extension 'pdo' is not loaded");
}
if (empty($config['dsn'])) {
throw new DibiException("DSN must be specified (driver odbc)");
}
@ -56,24 +47,25 @@ class DibiPdoDriver extends DibiDriver
protected function connect()
{
return new PDO($this->config['dsn'], $this->config['username'], $this->config['password']);
if (!extension_loaded('pdo')) {
throw new DibiException("PHP extension 'pdo' is not loaded");
}
$config = $this->getConfig();
$connection = new PDO($config['dsn'], $config['username'], $config['password']);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
dibi::notify('connected', $this);
return $connection;
}
public function nativeQuery($sql)
protected function doQuery($sql)
{
// TODO: or exec() ?
$res = $this->getConnection()->query($sql);
if ($res === FALSE) {
return FALSE;
} elseif ($res instanceof PDOStatement) {
if ($res instanceof PDOStatement) {
return new DibiPdoResult($res);
} else {
return TRUE;
}
}
@ -95,21 +87,24 @@ class DibiPdoDriver extends DibiDriver
public function begin()
{
return $this->getConnection()->beginTransaction();
$this->getConnection()->beginTransaction();
dibi::notify('begin', $this);
}
public function commit()
{
return $this->getConnection()->commit();
$this->getConnection()->commit();
dibi::notify('commit', $this);
}
public function rollback()
{
return $this->getConnection()->rollBack();
$this->getConnection()->rollBack();
dibi::notify('rollback', $this);
}
@ -171,19 +166,9 @@ class DibiPdoDriver extends DibiDriver
class DibiPdoResult extends DibiResult
{
/** @var PDOStatement */
private $resource;
private $row = 0;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{
return $this->resource->rowCount();

View File

@ -12,26 +12,24 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for PostgreSql database
*
*/
class DibiPostgreDriver extends DibiDriver
{
private
$affectedRows = FALSE;
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "'Y-m-d'",
'datetime' => "'Y-m-d H:i:s'",
);
/**
* Affected rows
* @var mixed
*/
private $affectedRows = FALSE;
@ -41,10 +39,6 @@ class DibiPostgreDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('pgsql')) {
throw new DibiException("PHP extension 'pgsql' is not loaded");
}
if (empty($config['string'])) {
throw new DibiException("Connection string must be specified (driver postgre)");
}
@ -58,7 +52,11 @@ class DibiPostgreDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('pgsql')) {
throw new DibiException("PHP extension 'pgsql' is not loaded");
}
$config = $this->getConfig();
if (isset($config['persistent'])) {
$connection = @pg_connect($config['string'], $config['type']);
@ -67,15 +65,15 @@ class DibiPostgreDriver extends DibiDriver
}
if (!is_resource($connection)) {
throw new DibiException("Connecting error (driver postgre)", array(
'message' => pg_last_error(),
));
throw new DibiDatabaseException(pg_last_error());
}
if (!empty($config['charset'])) {
@pg_set_client_encoding($connection, $config['charset']);
// don't handle this error...
}
dibi::notify('connected', $this);
return $connection;
}
@ -84,20 +82,26 @@ class DibiPostgreDriver extends DibiDriver
public function nativeQuery($sql)
{
$this->affectedRows = FALSE;
$res = parent::nativeQuery($sql);
if ($res instanceof DibiResult) {
$this->affectedRows = pg_affected_rows($res->getResource());
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
}
return $res;
}
$res = @pg_query($this->getConnection(), $sql);
protected function doQuery($sql)
{
$connection = $this->getConnection();
$res = @pg_query($connection, $sql);
if ($res === FALSE) {
return FALSE;
throw new DibiDatabaseException(pg_last_error($connection), 0, $sql);
} elseif (is_resource($res)) {
$this->affectedRows = pg_affected_rows($res);
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
return new DibiPostgreResult($res);
} else {
return TRUE;
}
}
@ -114,9 +118,9 @@ class DibiPostgreDriver extends DibiDriver
{
if (empty($sequence)) {
// PostgreSQL 8.1 is needed
$res = pg_query($this->getConnection(), "SELECT LASTVAL() AS seq");
$res = $this->doQuery("SELECT LASTVAL() AS seq");
} else {
$res = pg_query($this->getConnection(), "SELECT CURRVAL('$sequence') AS seq");
$res = $this->doQuery("SELECT CURRVAL('$sequence') AS seq");
}
if (is_resource($res)) {
@ -132,21 +136,24 @@ class DibiPostgreDriver extends DibiDriver
public function begin()
{
return pg_query($this->getConnection(), 'BEGIN');
$this->doQuery('BEGIN');
dibi::notify('begin', $this);
}
public function commit()
{
return pg_query($this->getConnection(), 'COMMIT');
$this->doQuery('COMMIT');
dibi::notify('commit', $this);
}
public function rollback()
{
return pg_query($this->getConnection(), 'ROLLBACK');
$this->doQuery('ROLLBACK');
dibi::notify('rollback', $this);
}
@ -210,15 +217,6 @@ class DibiPostgreDriver extends DibiDriver
class DibiPostgreResult extends DibiResult
{
private $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,23 +12,18 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* The dibi driver for SQlite database
*
*/
class DibiSqliteDriver extends DibiDriver
{
public
$formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "U",
'datetime' => "U",
);
public $formats = array(
'TRUE' => "1",
'FALSE' => "0",
'date' => "U",
'datetime' => "U",
);
@ -38,10 +33,6 @@ class DibiSqliteDriver extends DibiDriver
*/
public function __construct($config)
{
if (!extension_loaded('sqlite')) {
throw new DibiException("PHP extension 'sqlite' is not loaded");
}
if (empty($config['database'])) {
throw new DibiException("Database must be specified (driver sqlite)");
}
@ -55,7 +46,11 @@ class DibiSqliteDriver extends DibiDriver
protected function connect()
{
$config = $this->config;
if (!extension_loaded('sqlite')) {
throw new DibiException("PHP extension 'sqlite' is not loaded");
}
$config = $this->getConfig();
$errorMsg = '';
if (empty($config['persistent'])) {
@ -65,28 +60,26 @@ class DibiSqliteDriver extends DibiDriver
}
if (!$connection) {
throw new DibiException("Connecting error (driver sqlite)", array(
'message' => $errorMsg,
));
throw new DibiDatabaseException($errorMsg);
}
dibi::notify('connected', $this);
return $connection;
}
public function nativeQuery($sql)
protected function doQuery($sql)
{
$res = @sqlite_query($this->getConnection(), $sql, SQLITE_ASSOC);
$connection = $this->getConnection();
$res = @sqlite_query($connection, $sql, SQLITE_ASSOC);
if ($res === FALSE) {
return FALSE;
$code = sqlite_last_error($connection);
throw new DibiDatabaseException(sqlite_error_string($code), $code, $sql);
} elseif (is_resource($res)) {
return new DibiSqliteResult($res);
} else {
return TRUE;
}
}
@ -110,21 +103,24 @@ class DibiSqliteDriver extends DibiDriver
public function begin()
{
return sqlite_query($this->getConnection(), 'BEGIN');
$this->doQuery('BEGIN');
dibi::notify('begin', $this);
}
public function commit()
{
return sqlite_query($this->getConnection(), 'COMMIT');
$this->doQuery('COMMIT');
dibi::notify('commit', $this);
}
public function rollback()
{
return sqlite_query($this->getConnection(), 'ROLLBACK');
$this->doQuery('ROLLBACK');
dibi::notify('rollback', $this);
}
@ -184,15 +180,6 @@ class DibiSqliteDriver extends DibiDriver
class DibiSqliteResult extends DibiResult
{
private $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function rowCount()
{

View File

@ -12,10 +12,6 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* dibi Common Driver
@ -27,7 +23,7 @@ abstract class DibiDriver
* Current connection configuration
* @var array
*/
protected $config;
private $config;
/**
* Connection resource
@ -57,7 +53,10 @@ abstract class DibiDriver
public function __construct($config)
{
$this->config = $config;
if (empty($config['lazy'])) $this->connection = $this->connect();
if (empty($config['lazy'])) {
$this->connection = $this->connect();
}
}
@ -102,7 +101,9 @@ abstract class DibiDriver
*/
final public function getConnection()
{
if (!$this->connection) $this->connection = $this->connect();
if (!$this->connection) {
$this->connection = $this->connect();
}
return $this->connection;
}
@ -110,7 +111,7 @@ abstract class DibiDriver
/**
* Generates and executes SQL query
* Generates (translates) and executes SQL query
*
* @param array|mixed one or more arguments
* @return int|DibiResult
@ -118,25 +119,32 @@ abstract class DibiDriver
*/
final public function query($args)
{
// receive arguments
if (!is_array($args)) $args = func_get_args();
// and generate SQL
$trans = new DibiTranslator($this);
$sql = $trans->translate($args);
if ($trans->translate($args)) {
return $this->nativeQuery($trans->sql);
} else {
throw new DibiException('SQL translate error: ' . $trans->sql);
}
}
// event handler
dibi::invokeEvent('beforeQuery', array($this, $sql));
if ($sql === FALSE) return FALSE;
// execute SQL
$res = $this->nativeQuery($sql);
/**
* Generates and prints SQL query
*
* @param array|mixed one or more arguments
* @return bool
*/
final public function test($args)
{
if (!is_array($args)) $args = func_get_args();
// event handler
dibi::invokeEvent('afterQuery', array($this, $sql, $res));
return $res;
$trans = new DibiTranslator($this);
$ok = $trans->translate($args);
dibi::dump($trans->sql);
return $ok;
}
@ -145,9 +153,27 @@ abstract class DibiDriver
* Executes the SQL query
*
* @param string SQL statement.
* @return object|bool Result set object or TRUE on success, FALSE on failure
* @return DibiResult|NULL Result set object
* @throws DibiException
*/
abstract public function nativeQuery($sql);
public function nativeQuery($sql)
{
dibi::notify('beforeQuery', $this, $sql);
$res = $this->doQuery($sql);
dibi::notify('afterQuery', $this, $res);
return $res;
}
/**
* Internal: Executes the SQL query
*
* @param string SQL statement.
* @return DibiResult|NULL Result set object
* @throws DibiDatabaseException
*/
abstract protected function doQuery($sql);
@ -171,6 +197,7 @@ abstract class DibiDriver
/**
* Begins a transaction (if supported).
* @return void
*/
abstract public function begin();
@ -178,6 +205,7 @@ abstract class DibiDriver
/**
* Commits statements in a transaction.
* @return void
*/
abstract public function commit();
@ -185,6 +213,7 @@ abstract class DibiDriver
/**
* Rollback changes in a transaction.
* @return void
*/
abstract public function rollback();

View File

@ -12,28 +12,29 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* dibi exception class
*
* dibi common exception
*/
class DibiException extends Exception
{
private
$sql,
$dbError;
}
public function __construct($message, $dbError = NULL, $sql = NULL)
/**
* database server exception
*/
class DibiDatabaseException extends DibiException
{
/** @var string */
private $sql;
public function __construct($message = NULL, $code = 0, $sql = NULL)
{
$this->dbError = $dbError;
$this->sql = $sql;
parent::__construct($message);
$this->sql = $sql;
dibi::notify('exception', NULL, $this);
}
@ -45,31 +46,13 @@ class DibiException extends Exception
final public function getDbError()
{
return $this->dbError;
}
public function __toString()
{
$s = parent::__toString();
if ($this->dbError) {
$s .= "\n\nDatabase error: ";
if (isset($this->dbError['code'])) {
$s .= "[" . $this->dbError['code'] . "] ";
}
$s .= $this->dbError['message'];
}
if ($this->sql) {
$s .= "\nSQL: " . $this->sql;
}
return $s;
}
} // class DibiException
}

105
dibi/libs/logger.php Normal file
View File

@ -0,0 +1,105 @@
<?php
/**
* This file is part of the "dibi" project (http://dibi.texy.info/)
*
* @author David Grudl
* @copyright Copyright (c) 2005-2007 David Grudl aka -dgx- (http://www.dgx.cz)
* @license New BSD License
* @version $Revision$ $Date$
* @category Database
* @package Dibi
*/
/**
* dibi basic logger & profiler
*/
final class DibiLogger
{
/** @var string Name of the file where SQL errors should be logged */
private $file;
/** @var bool */
public $logErrors = TRUE;
/** @var bool */
public $logQueries = TRUE;
/**
* @param string filename
*/
public function __construct($file)
{
$this->file = $file;
}
/**
* Event handler (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback)
*
* @param string event name
* @param mixed
* @param mixed
* @return void
*/
public function handler($event, $driver, $arg)
{
if ($event === 'afterQuery' && $this->logQueries) {
$this->write(
"OK: " . dibi::$sql
. ($arg instanceof DibiResult ? ";\n-- rows: " . $arg->rowCount() : '')
. "\n-- takes: " . sprintf('%0.3f', dibi::$elapsedTime * 1000) . ' ms'
. "\n-- driver: " . $driver->getConfig('driver')
. "\n-- " . date('Y-m-d H:i:s')
. "\n\n"
);
return;
}
if ($event === 'exception' && $this->logErrors) {
// $arg is DibiDatabaseException
$message = $arg->getMessage();
$code = $arg->getCode();
if ($code) {
$message = "[$code] $message";
}
$this->write(
"ERROR: $message"
. "\n-- SQL: " . dibi::$sql
. "\n-- driver: " //. $driver->getConfig('driver')
. ";\n-- " . date('Y-m-d H:i:s')
. "\n\n"
);
}
}
private function write($message)
{
$handle = fopen($this->file, 'a');
if (!$handle) return; // or throw exception?
flock($handle, LOCK_EX);
fwrite($handle, $message);
fclose($handle);
}
/**#@+
* Access to undeclared property
* @throws Exception
*/
private function &__get($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __set($name, $value) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
private function __unset($name) { throw new Exception("Access to undeclared property: " . get_class($this) . "::$$name"); }
/**#@-*/
}

View File

@ -12,13 +12,9 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
// PHP < 5.1 compatibility
if (!interface_exists('Countable', false)) {
if (!interface_exists('Countable', FALSE)) {
interface Countable
{
function count();
@ -54,6 +50,13 @@ abstract class DibiResult implements IteratorAggregate, Countable
protected $meta;
/**
* Resultset resource
* @var resource
*/
protected $resource;
private static $types = array(
dibi::FIELD_TEXT => 'string',
dibi::FIELD_BINARY => 'string',
@ -65,6 +68,25 @@ abstract class DibiResult implements IteratorAggregate, Countable
public function __construct($resource)
{
$this->resource = $resource;
}
/**
* Returns the resultset resource
*
* @return resource
*/
final public function getResource()
{
return $this->resource;
}
/**
* Moves cursor position without fetching row
*
@ -402,6 +424,39 @@ abstract class DibiResult implements IteratorAggregate, Countable
/**
* Displays complete result-set as HTML table
*
* @return void
*/
public function dump()
{
echo '<table class="dump">';
echo '<thead>';
echo '<tr>';
echo '<th>#row</th>';
foreach ($this->getFields() as $field) {
echo '<th>' . htmlSpecialChars($field) . '</th>';
}
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach ($this as $row => $fields) {
echo '<tr><th>', $row, '</th>';
foreach ($fields as $field) {
//if (is_object($field)) $field = $field->__toString();
echo '<td>', htmlSpecialChars($field), '</td>';
}
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
}
/** these are the required IteratorAggregate functions */
final public function getIterator($offset = NULL, $count = NULL)
{

View File

@ -12,10 +12,6 @@
*/
// security - include dibi.php, not this file
if (!class_exists('dibi', FALSE)) die();
/**
* dibi translator
@ -23,13 +19,29 @@ if (!class_exists('dibi', FALSE)) die();
*/
final class DibiTranslator
{
private
$driver,
$modifier,
$hasError,
$comment,
$ifLevel,
$ifLevelStart;
/** @var string */
public $sql;
/** @var string NOT USED YET */
public $mask;
/** @var DibiDriver */
private $driver;
/** @var string last modifier */
private $modifier;
/** @var bool */
private $hasError;
/** @var bool */
private $comment;
/** @var int */
private $ifLevel;
/** @var int */
private $ifLevelStart;
@ -44,8 +56,7 @@ final class DibiTranslator
* Generates SQL
*
* @param array
* @return string|FALSE
* @throws DibiException
* @return bool
*/
public function translate($args)
{
@ -61,7 +72,7 @@ final class DibiTranslator
$comment = FALSE;
// iterate
$sql = array();
$sql = $mask = array();
$i = 0;
foreach ($args as $arg)
{
@ -84,7 +95,7 @@ final class DibiTranslator
if (is_string($arg) && (!$mod || $mod === 'sql')) {
$mod = FALSE;
// will generate new mod
$sql[] = $this->formatValue($arg, 'sql');
$mask[] = $sql[] = $this->formatValue($arg, 'sql');
continue;
}
@ -96,12 +107,13 @@ final class DibiTranslator
$mod = $commandIns ? 'v' : 'a';
} else {
$mod = $commandIns ? 'l' : 'a';
if ($lastArr === $i - 1) $sql[] = ',';
if ($lastArr === $i - 1) $mask[] = $sql[] = ',';
}
$lastArr = $i;
}
// default processing
$mask[] = '?';
if (!$comment) {
$sql[] = $this->formatValue($arg, $mod);
}
@ -110,33 +122,15 @@ final class DibiTranslator
if ($comment) $sql[] = "\0";
$sql = implode(' ', $sql);
//$this->mask = implode(' ', $mask);
$this->sql = implode(' ', $sql);
// remove comments
// TODO: check !!!
$sql = preg_replace('#\x00.*?\x00#s', '', $sql);
$this->sql = preg_replace('#\x00.*?\x00#s', '', $this->sql);
if ($this->hasError) {
// TODO: do it better, remove dibi::$...
if (dibi::$logFile) { // log to file
dibi::log(
"ERROR: SQL generate error"
. "\n-- SQL: " . $sql
. ";\n-- " . date('Y-m-d H:i:s ')
);
}
if (dibi::$throwExceptions) {
throw new DibiException('SQL generate error', NULL, $sql);
} else {
trigger_error("dibi: SQL generate error: $sql", E_USER_WARNING);
return FALSE;
}
}
// OK
return $sql;
return !$this->hasError;
}
@ -203,7 +197,7 @@ final class DibiTranslator
if (!is_scalar($value)) { // array is already processed
$this->hasError = TRUE;
return '**Unexpected ' . gettype($value) . '**';
return '**Unexpected type ' . gettype($value) . '**';
}
switch ($modifier) {
@ -280,7 +274,7 @@ final class DibiTranslator
case 'a':
case 'v':
$this->hasError = TRUE;
return "**Unexpected ".gettype($value)."**";
return '**Unexpected type ' . gettype($value) . '**';
case 'if':
$this->hasError = TRUE;

View File

@ -1,4 +1,4 @@
<pre>
<h1>dibi connect example</h1>
<?php
require_once '../dibi/dibi.php';
@ -10,9 +10,10 @@ try {
'driver' => 'sqlite',
'database' => 'sample.sdb',
));
echo '<p>Connected to Sqlite</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -20,9 +21,10 @@ try {
// connects to MySQL using DSN
try {
dibi::connect('driver=mysql&host=localhost&username=root&password=xxx&database=test&charset=utf8');
echo '<p>Connected to MySQL</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -38,9 +40,10 @@ try {
'database' => 'dibi',
'charset' => 'utf8',
));
echo '<p>Connected to MySQL</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -52,11 +55,12 @@ try {
'driver' => 'odbc',
'username' => 'root',
'password' => '***',
'database' => 'Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\\Database.mdb',
'database' => 'Driver={Microsoft Access Driver (*.mdb)};Dbq='.dirname(__FILE__).'/sample.mdb',
));
echo '<p>Connected to ODBC</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -69,9 +73,10 @@ try {
'string' => 'host=localhost port=5432 dbname=mary',
'persistent' => TRUE,
));
echo '<p>Connected to PostgreSql</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -83,9 +88,10 @@ try {
'driver' => 'pdo',
'dsn' => 'sqlite2::memory:',
));
echo '<p>Connected to Sqlite via PDO</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}
@ -98,7 +104,8 @@ try {
'username' => 'root',
'password' => 'xxx',
));
echo '<p>Connected to MS SQL</p>';
} catch (DibiException $e) {
echo 'DibiException: ', $e;
echo '<pre>', $e, '</pre>';
}

View File

@ -1,10 +1,13 @@
<h1>dibi user datatype example</h1>
<?php
require_once '../dibi/dibi.php';
// required since PHP 5.1.0
if (function_exists('date_default_timezone_set'))
if (function_exists('date_default_timezone_set')) {
date_default_timezone_set('Europe/Prague');
}
/**

View File

@ -1,10 +1,8 @@
<h1>dibi dump example</h1>
<?php
require_once '../dibi/dibi.php';
if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Prague');
dibi::connect(array(
'driver' => 'sqlite',
@ -19,17 +17,14 @@ INNER JOIN [orders] USING ([product_id])
INNER JOIN [customers] USING ([customer_id])
');
// get last SQL
$sql = dibi::$sql;
echo '<h2>dibi::dump()</h2>';
// dump it
echo '<h1>dibi::dump()</h1>';
dibi::dump($sql);
// dump last query (dibi::$sql)
dibi::dump();
// dump result table
echo '<h1>dibi::dumpResult()</h1>';
echo '<h2>DibiResult::dump()</h2>';
dibi::dumpResult($res);
$res->dump();

View File

@ -1,3 +1,4 @@
<h1>dibi fetch example</h1>
<pre>
<?php

View File

@ -1,24 +0,0 @@
OK: connected to DB 'sqlite'
OK: SELECT * FROM [customers] WHERE [customer_id] = 1;
-- result: object(DibiSqliteResult) rows: 1
-- takes: 0.331 ms
-- driver: sqlite
-- 2007-05-12 00:14:11
OK: SELECT * FROM [customers] WHERE [customer_id] < 5;
-- result: object(DibiSqliteResult) rows: 4
-- takes: 0.324 ms
-- driver: sqlite
-- 2007-05-12 00:14:11
ERROR: [1] SQL logic error or missing database
-- SQL: SELECT FROM [customers] WHERE [customer_id] < 5
-- driver: sqlite;
-- 2007-05-12 00:14:11
ERROR: [1] SQL logic error or missing database
-- SQL: SELECT FROM [customers] WHERE [customer_id] < 38
-- driver: sqlite;
-- 2007-05-12 00:14:11

View File

@ -1,21 +1,10 @@
<h1>dibi logger example</h1>
<?php
require_once '../dibi/dibi.php';
// required since PHP 5.1.0
if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Prague'); // or 'GMT'
// enable log to this file
dibi::$logFile = 'log.sql';
// append mode
dibi::$logMode = 'a';
// log all queries
dibi::$logAll = TRUE;
// enable log to this file, TRUE means "log all queries"
dibi::startLogger('log.sql', TRUE);
@ -26,43 +15,20 @@ dibi::connect(array(
// generate user-level errors
dibi::$throwExceptions = FALSE;
echo '<h1>User-level errors</h1>';
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] = %i', 1);
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < %i', 5);
$res = dibi::query('SELECT FROM [customers] WHERE [customer_id] < %i', 5);
echo "<br />See file ", dibi::$logFile;
// generate DibiException
dibi::$throwExceptions = TRUE;
echo '<h1>DibiException</h1>';
try {
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] = %i', 1);
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < %i', 5);
$res = dibi::query('SELECT FROM [customers] WHERE [customer_id] < %i', 38);
} catch (DibiException $e) {
echo '<h2>Dibi Exception:</h2>';
echo '<pre>', $e, '</pre>';
echo '<h2>$e->getSql()</h2>';
$sql = $e->getSql();
echo "SQL: $sql\n";
echo '<h2>$e->getDbError()</h2>';
$error = $e->getDbError();
echo '<pre>';
print_r($error);
echo '</pre>';
}
echo "<h2>File log.sql:</h2>";
echo '<pre>', file_get_contents('log.sql'), '</pre>';

View File

@ -1,3 +1,4 @@
<h1>dibi metatypes example</h1>
<pre>
<?php

25
examples/profiler.php Normal file
View File

@ -0,0 +1,25 @@
<h1>Dibi profiler example</h1>
<?php
require_once '../dibi/dibi.php';
dibi::connect(array(
'driver' => 'sqlite',
'database' => 'sample.sdb',
));
for ($i=0; $i<20; $i++) {
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < %i', $i);
}
?>
<p>Last query: <strong><?php echo dibi::$sql; ?></strong></p>
<p>Number of queries: <strong><?php echo dibi::$numOfQueries; ?></strong></p>
<p>Elapsed time for last query: <strong><?php echo sprintf('%0.3f', dibi::$elapsedTime * 1000); ?> ms</strong></p>
<p>Total elapsed time: <strong><?php echo sprintf('%0.3f', dibi::$totalTime * 1000); ?> ms</strong></p>

BIN
examples/sample.mdb Normal file

Binary file not shown.

View File

@ -1,14 +1,16 @@
<style>
pre.dibi { padding-bottom: 10px; }
</style>
<h1>dibi SQL builder example</h1>
<pre>
<?php
require_once '../dibi/dibi.php';
// required since PHP 5.1.0
if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Prague'); // or 'GMT'
if (function_exists('date_default_timezone_set')) {
date_default_timezone_set('Europe/Prague');
}
dibi::connect(array(
@ -79,3 +81,6 @@ dibi::test("SELECT %f", '-.12345678912345678912345678e10');
// hex numbers
dibi::test("SELECT %i", '0x11');
// invalid input
dibi::test("SELECT %s", (object) array(123), ', %m', 123);

View File

@ -1,6 +1,7 @@
<style>
pre.dibi { padding-bottom: 10px; }
</style>
<h1>dibi conditional SQL example</h1>
<pre>
<?php

View File

@ -1,3 +1,4 @@
<h1>dibi prefix & substitute example</h1>
<?php
require_once '../dibi/dibi.php';

View File

@ -1,4 +1,4 @@
Dibi version 0.8e
Dibi version 0.9a
Revision: $WCREV$
Date: $WCDATE$