mirror of
https://github.com/dg/dibi.git
synced 2025-08-05 05:37:39 +02:00
+ rewritten support for logging & error handling
+ modifier %sn * modifier %sql * changed modifier behaviour: NULL is always 'NULL'
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
Copyright notice
|
Copyright notice
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
dibi (C) David Grudl, 2005-2006 <dave@dgx.cz>
|
dibi (C) David Grudl, 2005-2007 <dave@dgx.cz>
|
||||||
|
|
||||||
For more information, visit the homepage http://dibi.texy.info/
|
For more information, visit the homepage http://dibi.texy.info/
|
||||||
or author's weblog: http://www.dgx.cz/trine/
|
or author's weblog: http://www.dgx.cz/trine/
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1,3 +1,2 @@
|
|||||||
1) better logging, error logging, exceptions
|
- better examples
|
||||||
|
- documentation
|
||||||
2) complete phpdoc
|
|
||||||
|
155
dibi/dibi.php
155
dibi/dibi.php
@@ -14,11 +14,11 @@
|
|||||||
* @license GNU GENERAL PUBLIC LICENSE v2
|
* @license GNU GENERAL PUBLIC LICENSE v2
|
||||||
* @package dibi
|
* @package dibi
|
||||||
* @category Database
|
* @category Database
|
||||||
* @version 0.6e $Revision$ $Date$
|
* @version 0.7a $Revision$ $Date$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
define('DIBI', 'Version 0.6e $Revision$');
|
define('DIBI', 'Version 0.7a $Revision$');
|
||||||
|
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION , '5.0.3', '<'))
|
if (version_compare(PHP_VERSION , '5.0.3', '<'))
|
||||||
@@ -33,10 +33,6 @@ require_once dirname(__FILE__).'/libs/exception.php';
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// required since PHP 5.1.0
|
|
||||||
// if (function_exists('date_default_timezone_set'))
|
|
||||||
// date_default_timezone_set('Europe/Prague'); // or 'GMT'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +58,7 @@ interface IDibiVariable
|
|||||||
* Interface for database drivers
|
* Interface for database drivers
|
||||||
*
|
*
|
||||||
* This class is static container class for creating DB objects and
|
* This class is static container class for creating DB objects and
|
||||||
* store debug & connections info.
|
* store connections info.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class dibi
|
class dibi
|
||||||
@@ -84,24 +80,15 @@ class dibi
|
|||||||
FIELD_COUNTER = 'c'; // counter or autoincrement, is integer
|
FIELD_COUNTER = 'c'; // counter or autoincrement, is integer
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query rrror modes
|
|
||||||
*/
|
|
||||||
const
|
|
||||||
ERR_SILENT = 1,
|
|
||||||
ERR_WARNING = 2,
|
|
||||||
ERR_EXCEPTION = 3;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection registry storage for DibiDriver objects
|
* Connection registry storage for DibiDriver objects
|
||||||
* @var array
|
* @var DibiDriver[]
|
||||||
*/
|
*/
|
||||||
static private $registry = array();
|
static private $registry = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current connection
|
* Current connection
|
||||||
* @var object DibiDriver
|
* @var DibiDriver
|
||||||
*/
|
*/
|
||||||
static private $conn;
|
static private $conn;
|
||||||
|
|
||||||
@@ -110,26 +97,30 @@ class dibi
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
static public $sql;
|
static public $sql;
|
||||||
static public $error;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File for logging SQL queryies - strongly recommended to use with NSafeStream
|
* File for logging SQL queries
|
||||||
* @var string|NULL
|
* @var string|NULL
|
||||||
*/
|
*/
|
||||||
static public $logFile;
|
static public $logFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode parameter used by fopen()
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
static public $logMode = 'a';
|
static public $logMode = 'a';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query error mode
|
* To log all queries or error queries (debug mode)
|
||||||
*/
|
|
||||||
static public $errorMode = dibi::ERR_SILENT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable/disable debug mode
|
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
static public $debug = false;
|
static public $logAll = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dibi::query() error mode
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
static public $throwExceptions = FALSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Substitutions for identifiers
|
* Substitutions for identifiers
|
||||||
@@ -178,7 +169,7 @@ class dibi
|
|||||||
/** like $conn = $className::connect($config); */
|
/** like $conn = $className::connect($config); */
|
||||||
self::$conn = self::$registry[$name] = call_user_func(array($className, 'connect'), $config);
|
self::$conn = self::$registry[$name] = call_user_func(array($className, 'connect'), $config);
|
||||||
|
|
||||||
if (dibi::$debug) dibi::log("Successfully connected to DB '$config[driver]'");
|
if (dibi::$logAll) dibi::log("OK: connected to DB '$config[driver]'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -198,6 +189,7 @@ class dibi
|
|||||||
* Retrieve active connection
|
* Retrieve active connection
|
||||||
*
|
*
|
||||||
* @return object DibiDriver object.
|
* @return object DibiDriver object.
|
||||||
|
* @throw DibiException
|
||||||
*/
|
*/
|
||||||
static public function getConnection()
|
static public function getConnection()
|
||||||
{
|
{
|
||||||
@@ -214,6 +206,7 @@ class dibi
|
|||||||
*
|
*
|
||||||
* @param string connection registy name
|
* @param string connection registy name
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throw DibiException
|
||||||
*/
|
*/
|
||||||
static public function activate($name)
|
static public function activate($name)
|
||||||
{
|
{
|
||||||
@@ -246,49 +239,60 @@ class dibi
|
|||||||
|
|
||||||
// and generate SQL
|
// and generate SQL
|
||||||
$trans = new DibiTranslator($conn, self::$substs);
|
$trans = new DibiTranslator($conn, self::$substs);
|
||||||
self::$sql = $trans->translate($args);
|
if (!$trans->translate($args)) {
|
||||||
|
if (self::$logFile) // log to file
|
||||||
|
self::log(
|
||||||
|
"ERROR: SQL generate error"
|
||||||
|
. "\n-- SQL: " . $trans->sql
|
||||||
|
. ";\n-- " . date('Y-m-d H:i:s ')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dibi::$throwExceptions)
|
||||||
|
throw new DibiException('SQL generate error', array('sql' => $trans->sql));
|
||||||
|
else {
|
||||||
|
trigger_error("dibi: SQL generate error: $trans->sql", E_USER_WARNING);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$sql = $trans->sql;
|
||||||
|
|
||||||
// execute SQL
|
// execute SQL
|
||||||
$timer = -microtime(true);
|
$timer = -microtime(true);
|
||||||
try {
|
|
||||||
$res = $conn->query(self::$sql);
|
$res = $conn->query(self::$sql);
|
||||||
self::$error = FALSE;
|
|
||||||
|
|
||||||
} catch (DibiException $e) {
|
if ($res === FALSE) { // query error
|
||||||
$res = FALSE;
|
if (self::$logFile) { // log to file
|
||||||
self::$error = $e;
|
$info = $conn->errorInfo();
|
||||||
if (dibi::$errorMode === self::ERR_WARNING) {
|
self::log(
|
||||||
trigger_error('[dibi] ' . $e->getMessage(), E_USER_WARNING);
|
"ERROR: [$info[code]] $info[message]"
|
||||||
}
|
. "\n-- SQL: " . self::$sql
|
||||||
}
|
. ";\n-- " . date('Y-m-d H:i:s ')
|
||||||
$timer += microtime(true);
|
|
||||||
|
|
||||||
// optional log to file
|
|
||||||
if (self::$logFile != NULL)
|
|
||||||
{
|
|
||||||
if (self::$error)
|
|
||||||
$msg = self::$error->getMessage();
|
|
||||||
elseif ($res instanceof DibiResult)
|
|
||||||
$msg = 'object('.get_class($res).') rows: '.$res->rowCount();
|
|
||||||
else
|
|
||||||
$msg = 'OK';
|
|
||||||
|
|
||||||
dibi::log(self::$sql
|
|
||||||
. ";\r\n-- Result: $msg"
|
|
||||||
. "\r\n-- Takes: " . sprintf('%0.3f', $timer * 1000) . ' ms'
|
|
||||||
. "\r\n\r\n"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dibi::$debug)
|
if (dibi::$throwExceptions) {
|
||||||
{
|
$info = $conn->errorInfo();
|
||||||
echo self::$error ? "\n[ERROR] " : "\n[OK] ";
|
$info['sql'] = self::$sql;
|
||||||
echo htmlSpecialChars(trim(strtr(self::$sql, "\r\n\t", ' ')));
|
throw new DibiException('Query error', $info);
|
||||||
echo "\n<br />";
|
} else {
|
||||||
|
$info = $conn->errorInfo();
|
||||||
|
trigger_error("dibi: [$info[code]] $info[message]", E_USER_WARNING);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$error && dibi::$errorMode === self::ERR_EXCEPTION)
|
if (self::$logFile && self::$logAll) { // log success
|
||||||
throw self::$error;
|
$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', $timer * 1000) . ' ms'
|
||||||
|
. ";\n-- " . date('Y-m-d H:i:s ')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
@@ -298,10 +302,10 @@ class dibi
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates and returns SQL query
|
* Generates and prints SQL query
|
||||||
*
|
*
|
||||||
* @param array|mixed one or more arguments
|
* @param array|mixed one or more arguments
|
||||||
* @return string
|
* @return bool
|
||||||
*/
|
*/
|
||||||
static public function test($args)
|
static public function test($args)
|
||||||
{
|
{
|
||||||
@@ -309,19 +313,14 @@ class dibi
|
|||||||
if (!is_array($args))
|
if (!is_array($args))
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
|
|
||||||
$dump = TRUE; // !!! todo
|
|
||||||
|
|
||||||
// and generate SQL
|
// and generate SQL
|
||||||
try {
|
|
||||||
$trans = new DibiTranslator(self::getConnection(), self::$substs);
|
$trans = new DibiTranslator(self::getConnection(), self::$substs);
|
||||||
$sql = $trans->translate($args);
|
$ok = $trans->translate($args);
|
||||||
if ($dump) self::dump($sql);
|
if (!$ok) echo 'ERROR: ';
|
||||||
return $sql;
|
|
||||||
|
|
||||||
} catch (DibiException $e) {
|
self::dump($trans->sql);
|
||||||
if ($dump) self::dump($e->getSql());
|
|
||||||
return FALSE;
|
return $ok;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -382,15 +381,15 @@ class dibi
|
|||||||
|
|
||||||
$sql = trim($sql);
|
$sql = trim($sql);
|
||||||
// reduce spaces
|
// reduce spaces
|
||||||
// $sql = preg_replace('# +#', ' ', $sql);
|
$sql = preg_replace('# {2,}#', ' ', $sql);
|
||||||
|
|
||||||
$sql = wordwrap($sql, 100);
|
$sql = wordwrap($sql, 100);
|
||||||
$sql = htmlSpecialChars($sql);
|
$sql = htmlSpecialChars($sql);
|
||||||
$sql = str_replace("\n", '<br />', $sql);
|
$sql = preg_replace("#\n{2,}#", "\n", $sql);
|
||||||
|
|
||||||
// syntax highlight
|
// syntax highlight
|
||||||
$sql = preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql);
|
$sql = preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql);
|
||||||
$sql = '<pre class="dibi">' . $sql . '</pre>';
|
$sql = '<pre class="dibi">' . $sql . "</pre>\n";
|
||||||
|
|
||||||
// print & return
|
// print & return
|
||||||
if (!$return) echo $sql;
|
if (!$return) echo $sql;
|
||||||
@@ -461,7 +460,9 @@ class dibi
|
|||||||
if (self::$logFile == NULL || self::$logMode == NULL) return;
|
if (self::$logFile == NULL || self::$logMode == NULL) return;
|
||||||
|
|
||||||
$f = fopen(self::$logFile, self::$logMode);
|
$f = fopen(self::$logFile, self::$logMode);
|
||||||
fwrite($f, $message. "\r\n\r\n");
|
if (!$f) return;
|
||||||
|
flock($f, LOCK_EX);
|
||||||
|
fwrite($f, $message. "\n\n");
|
||||||
fclose($f);
|
fclose($f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,6 @@ class DibiMySqlDriver extends DibiDriver {
|
|||||||
|
|
||||||
public
|
public
|
||||||
$formats = array(
|
$formats = array(
|
||||||
'NULL' => "NULL",
|
|
||||||
'TRUE' => "1",
|
'TRUE' => "1",
|
||||||
'FALSE' => "0",
|
'FALSE' => "0",
|
||||||
'date' => "'Y-m-d'",
|
'date' => "'Y-m-d'",
|
||||||
@@ -107,16 +106,11 @@ class DibiMySqlDriver extends DibiDriver {
|
|||||||
$this->insertId = $this->affectedRows = FALSE;
|
$this->insertId = $this->affectedRows = FALSE;
|
||||||
$res = @mysql_query($sql, $this->conn);
|
$res = @mysql_query($sql, $this->conn);
|
||||||
|
|
||||||
|
if ($res === FALSE) return FALSE;
|
||||||
|
|
||||||
if (is_resource($res))
|
if (is_resource($res))
|
||||||
return new DibiMySqlResult($res);
|
return new DibiMySqlResult($res);
|
||||||
|
|
||||||
if ($res === FALSE)
|
|
||||||
throw new DibiException("Query error", array(
|
|
||||||
'message' => mysql_error($this->conn),
|
|
||||||
'code' => mysql_errno($this->conn),
|
|
||||||
'sql' => $sql,
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->affectedRows = mysql_affected_rows($this->conn);
|
$this->affectedRows = mysql_affected_rows($this->conn);
|
||||||
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
||||||
|
|
||||||
@@ -157,6 +151,15 @@ class DibiMySqlDriver extends DibiDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function errorInfo()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'message' => mysql_error($this->conn),
|
||||||
|
'code' => mysql_errno($this->conn),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function escape($value, $appendQuotes = FALSE)
|
public function escape($value, $appendQuotes = FALSE)
|
||||||
{
|
{
|
||||||
return $appendQuotes
|
return $appendQuotes
|
||||||
|
@@ -32,7 +32,6 @@ class DibiMySqliDriver extends DibiDriver {
|
|||||||
|
|
||||||
public
|
public
|
||||||
$formats = array(
|
$formats = array(
|
||||||
'NULL' => "NULL",
|
|
||||||
'TRUE' => "1",
|
'TRUE' => "1",
|
||||||
'FALSE' => "0",
|
'FALSE' => "0",
|
||||||
'date' => "'Y-m-d'",
|
'date' => "'Y-m-d'",
|
||||||
@@ -74,12 +73,11 @@ class DibiMySqliDriver extends DibiDriver {
|
|||||||
$this->insertId = $this->affectedRows = FALSE;
|
$this->insertId = $this->affectedRows = FALSE;
|
||||||
$res = @mysqli_query($this->conn, $sql);
|
$res = @mysqli_query($this->conn, $sql);
|
||||||
|
|
||||||
|
if ($res === FALSE) return FALSE;
|
||||||
|
|
||||||
if (is_object($res))
|
if (is_object($res))
|
||||||
return new DibiMySqliResult($res);
|
return new DibiMySqliResult($res);
|
||||||
|
|
||||||
if ($res === FALSE)
|
|
||||||
throw new DibiException("Query error", $this->errorInfo($sql));
|
|
||||||
|
|
||||||
$this->affectedRows = mysqli_affected_rows($this->conn);
|
$this->affectedRows = mysqli_affected_rows($this->conn);
|
||||||
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
||||||
|
|
||||||
@@ -124,12 +122,11 @@ class DibiMySqliDriver extends DibiDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function errorInfo($sql = NULL)
|
public function errorInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'message' => mysqli_error($this->conn),
|
'message' => mysqli_error($this->conn),
|
||||||
'code' => mysqli_errno($this->conn),
|
'code' => mysqli_errno($this->conn),
|
||||||
'sql' => $sql,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@ class DibiOdbcDriver extends DibiDriver {
|
|||||||
|
|
||||||
public
|
public
|
||||||
$formats = array(
|
$formats = array(
|
||||||
'NULL' => "NULL",
|
|
||||||
'TRUE' => "-1",
|
'TRUE' => "-1",
|
||||||
'FALSE' => "0",
|
'FALSE' => "0",
|
||||||
'date' => "#m/d/Y#",
|
'date' => "#m/d/Y#",
|
||||||
@@ -75,12 +74,11 @@ class DibiOdbcDriver extends DibiDriver {
|
|||||||
|
|
||||||
$res = @odbc_exec($this->conn, $sql);
|
$res = @odbc_exec($this->conn, $sql);
|
||||||
|
|
||||||
|
if ($res === FALSE) return FALSE;
|
||||||
|
|
||||||
if (is_resource($res))
|
if (is_resource($res))
|
||||||
return new DibiOdbcResult($res);
|
return new DibiOdbcResult($res);
|
||||||
|
|
||||||
if ($res === FALSE)
|
|
||||||
throw new DibiException("Query error", $this->errorInfo($sql));
|
|
||||||
|
|
||||||
$this->affectedRows = odbc_num_rows($this->conn);
|
$this->affectedRows = odbc_num_rows($this->conn);
|
||||||
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
||||||
|
|
||||||
@@ -122,12 +120,11 @@ class DibiOdbcDriver extends DibiDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function errorInfo($sql = NULL)
|
public function errorInfo()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'message' => odbc_errormsg($this->conn),
|
'message' => odbc_errormsg($this->conn),
|
||||||
'code' => odbc_error($this->conn),
|
'code' => odbc_error($this->conn),
|
||||||
'sql' => $sql,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@ class DibiPostgreDriver extends DibiDriver {
|
|||||||
|
|
||||||
public
|
public
|
||||||
$formats = array(
|
$formats = array(
|
||||||
'NULL' => "NULL",
|
|
||||||
'TRUE' => "1",
|
'TRUE' => "1",
|
||||||
'FALSE' => "0",
|
'FALSE' => "0",
|
||||||
'date' => "'Y-m-d'",
|
'date' => "'Y-m-d'",
|
||||||
@@ -80,15 +79,11 @@ class DibiPostgreDriver extends DibiDriver {
|
|||||||
$errorMsg = '';
|
$errorMsg = '';
|
||||||
$res = @pg_query($this->conn, $sql);
|
$res = @pg_query($this->conn, $sql);
|
||||||
|
|
||||||
|
if ($res === FALSE) return FALSE;
|
||||||
|
|
||||||
if (is_resource($res))
|
if (is_resource($res))
|
||||||
return new DibiPostgreResult($res);
|
return new DibiPostgreResult($res);
|
||||||
|
|
||||||
if ($res === FALSE)
|
|
||||||
throw new DibiException("Query error", array(
|
|
||||||
'message' => pg_last_error($this->conn),
|
|
||||||
'sql' => $sql,
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->affectedRows = pg_affected_rows($this->conn);
|
$this->affectedRows = pg_affected_rows($this->conn);
|
||||||
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
if ($this->affectedRows < 0) $this->affectedRows = FALSE;
|
||||||
|
|
||||||
@@ -126,6 +121,15 @@ class DibiPostgreDriver extends DibiDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function errorInfo()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'message' => pg_last_error($this->conn),
|
||||||
|
'code' => NULL,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function escape($value, $appendQuotes = FALSE)
|
public function escape($value, $appendQuotes = FALSE)
|
||||||
{
|
{
|
||||||
return $appendQuotes
|
return $appendQuotes
|
||||||
|
@@ -28,11 +28,11 @@ class DibiSqliteDriver extends DibiDriver {
|
|||||||
private
|
private
|
||||||
$conn,
|
$conn,
|
||||||
$insertId = FALSE,
|
$insertId = FALSE,
|
||||||
$affectedRows = FALSE;
|
$affectedRows = FALSE,
|
||||||
|
$errorMsg;
|
||||||
|
|
||||||
public
|
public
|
||||||
$formats = array(
|
$formats = array(
|
||||||
'NULL' => "NULL",
|
|
||||||
'TRUE' => "1",
|
'TRUE' => "1",
|
||||||
'FALSE' => "0",
|
'FALSE' => "0",
|
||||||
'date' => "'Y-m-d'",
|
'date' => "'Y-m-d'",
|
||||||
@@ -75,13 +75,9 @@ class DibiSqliteDriver extends DibiDriver {
|
|||||||
$this->insertId = $this->affectedRows = FALSE;
|
$this->insertId = $this->affectedRows = FALSE;
|
||||||
|
|
||||||
$errorMsg = '';
|
$errorMsg = '';
|
||||||
$res = @sqlite_query($this->conn, $sql, SQLITE_ASSOC, $errorMsg);
|
$res = @sqlite_query($this->conn, $sql, SQLITE_ASSOC, $this->errorMsg);
|
||||||
|
|
||||||
if ($res === FALSE)
|
if ($res === FALSE) return FALSE;
|
||||||
throw new DibiException("Query error", array(
|
|
||||||
'message' => $errorMsg,
|
|
||||||
'sql' => $sql,
|
|
||||||
));
|
|
||||||
|
|
||||||
if (is_resource($res))
|
if (is_resource($res))
|
||||||
return new DibiSqliteResult($res);
|
return new DibiSqliteResult($res);
|
||||||
@@ -126,6 +122,15 @@ class DibiSqliteDriver extends DibiDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function errorInfo()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'message' => $this->errorMsg,
|
||||||
|
'code' => NULL,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function escape($value, $appendQuotes = FALSE)
|
public function escape($value, $appendQuotes = FALSE)
|
||||||
{
|
{
|
||||||
return $appendQuotes
|
return $appendQuotes
|
||||||
|
@@ -39,7 +39,6 @@ abstract class DibiDriver
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $formats = array(
|
public $formats = array(
|
||||||
'NULL' => "NULL", // NULL
|
|
||||||
'TRUE' => "1", // boolean true
|
'TRUE' => "1", // boolean true
|
||||||
'FALSE' => "0", // boolean false
|
'FALSE' => "0", // boolean false
|
||||||
'date' => "'Y-m-d'", // format used by date()
|
'date' => "'Y-m-d'", // format used by date()
|
||||||
@@ -54,7 +53,7 @@ abstract class DibiDriver
|
|||||||
* @return DibiDriver
|
* @return DibiDriver
|
||||||
* @throw DibiException
|
* @throw DibiException
|
||||||
*/
|
*/
|
||||||
/*abstract disallowed PHP 5.2*/ static public function connect($config) {}
|
/*abstract disallowed since PHP 5.2*/ static public function connect($config) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ abstract class DibiDriver
|
|||||||
* Executes the SQL query
|
* Executes the SQL query
|
||||||
*
|
*
|
||||||
* @param string SQL statement.
|
* @param string SQL statement.
|
||||||
* @return object|bool Result set object or TRUE on success, Exception on failure
|
* @return object|bool Result set object or TRUE on success, FALSE on failure
|
||||||
*/
|
*/
|
||||||
abstract public function query($sql);
|
abstract public function query($sql);
|
||||||
|
|
||||||
@@ -123,6 +122,11 @@ abstract class DibiDriver
|
|||||||
abstract public function rollback();
|
abstract public function rollback();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last error
|
||||||
|
* @return array with items 'message' and 'code'
|
||||||
|
*/
|
||||||
|
abstract public function errorInfo();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -38,20 +38,13 @@ class DibiException extends Exception
|
|||||||
if (isset($info['message']))
|
if (isset($info['message']))
|
||||||
$message = "$message: $info[message]";
|
$message = "$message: $info[message]";
|
||||||
|
|
||||||
/* experimental */
|
|
||||||
dibi::log($message);
|
|
||||||
if (dibi::$debug) {
|
|
||||||
echo '[dibi error] ' . $message;
|
|
||||||
if (isset($info['sql'])) dibi::dump($info['sql']);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct($message);
|
parent::__construct($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getSql()
|
public function getSql()
|
||||||
{
|
{
|
||||||
return @$this->info['sql'];
|
return isset($this->info['sql']) ? $this->info['sql'] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,6 +36,8 @@ class DibiTranslator
|
|||||||
$ifLevel,
|
$ifLevel,
|
||||||
$ifLevelStart;
|
$ifLevelStart;
|
||||||
|
|
||||||
|
public $sql;
|
||||||
|
|
||||||
|
|
||||||
public function __construct($driver, $subst)
|
public function __construct($driver, $subst)
|
||||||
{
|
{
|
||||||
@@ -74,7 +76,7 @@ class DibiTranslator
|
|||||||
$this->ifLevel++;
|
$this->ifLevel++;
|
||||||
if (!$comment && !$arg) {
|
if (!$comment && !$arg) {
|
||||||
// open comment
|
// open comment
|
||||||
$sql[] = '/*';
|
$sql[] = "\0";
|
||||||
$this->ifLevelStart = $this->ifLevel;
|
$this->ifLevelStart = $this->ifLevel;
|
||||||
$comment = TRUE;
|
$comment = TRUE;
|
||||||
}
|
}
|
||||||
@@ -102,13 +104,17 @@ class DibiTranslator
|
|||||||
$mod = FALSE;
|
$mod = FALSE;
|
||||||
} // foreach
|
} // foreach
|
||||||
|
|
||||||
if ($comment) $sql[] = '*/';
|
if ($comment) $sql[] = "\0";
|
||||||
|
|
||||||
$sql = implode(' ', $sql);
|
$sql = implode(' ', $sql);
|
||||||
|
|
||||||
// remove comments
|
// remove comments
|
||||||
$sql = preg_replace('#\/\*.*?\*\/#s', '', $sql);
|
// TODO: check !!!
|
||||||
|
$sql = preg_replace('#\x00.*?\x00#s', '', $sql);
|
||||||
|
|
||||||
|
$this->sql = $sql;
|
||||||
|
|
||||||
|
return !$this->hasError;
|
||||||
if ($this->hasError)
|
if ($this->hasError)
|
||||||
throw new DibiException('Errors during generating SQL', array('sql' => $sql));
|
throw new DibiException('Errors during generating SQL', array('sql' => $sql));
|
||||||
|
|
||||||
@@ -132,17 +138,9 @@ class DibiTranslator
|
|||||||
// split into identifier & modifier
|
// split into identifier & modifier
|
||||||
$pair = explode('%', $k, 2);
|
$pair = explode('%', $k, 2);
|
||||||
|
|
||||||
if (isset($pair[1])) {
|
|
||||||
$mod = $pair[1];
|
|
||||||
// %? skips NULLS
|
|
||||||
if (isset($mod[0]) && '?' == $mod[0]) {
|
|
||||||
if (NULL === $v) continue;
|
|
||||||
$mod = substr($mod, 1);
|
|
||||||
}
|
|
||||||
} else $mod = FALSE;
|
|
||||||
|
|
||||||
// generate array
|
// generate array
|
||||||
$vx[] = $this->quote($pair[0]) . '=' . $this->formatValue($v, $mod);
|
$vx[] = $this->quote($pair[0]) . '='
|
||||||
|
. $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
|
||||||
}
|
}
|
||||||
return implode(', ', $vx);
|
return implode(', ', $vx);
|
||||||
|
|
||||||
@@ -152,18 +150,9 @@ class DibiTranslator
|
|||||||
// split into identifier & modifier
|
// split into identifier & modifier
|
||||||
$pair = explode('%', $k, 2);
|
$pair = explode('%', $k, 2);
|
||||||
|
|
||||||
if (isset($pair[1])) {
|
|
||||||
$mod = $pair[1];
|
|
||||||
// %m? skips NULLS
|
|
||||||
if (isset($mod[0]) && '?' == $mod[0]) {
|
|
||||||
if ($v === NULL) continue;
|
|
||||||
$mod = substr($mod, 1);
|
|
||||||
}
|
|
||||||
} else $mod = FALSE;
|
|
||||||
|
|
||||||
// generate arrays
|
// generate arrays
|
||||||
$kx[] = $this->quote($pair[0]);
|
$kx[] = $this->quote($pair[0]);
|
||||||
$vx[] = $this->formatValue($v, $mod);
|
$vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
|
||||||
}
|
}
|
||||||
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
|
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
|
||||||
|
|
||||||
@@ -179,17 +168,21 @@ class DibiTranslator
|
|||||||
|
|
||||||
// with modifier procession
|
// with modifier procession
|
||||||
if ($modifier) {
|
if ($modifier) {
|
||||||
|
if ($value === NULL) return 'NULL';
|
||||||
|
|
||||||
if ($value instanceof IDibiVariable)
|
if ($value instanceof IDibiVariable)
|
||||||
return $value->toSql($this->driver, $modifier);
|
return $value->toSql($this->driver, $modifier);
|
||||||
|
|
||||||
if (!is_scalar($value) && !is_null($value)) { // array is already processed
|
if (!is_scalar($value)) { // array is already processed
|
||||||
$this->hasError = TRUE;
|
$this->hasError = TRUE;
|
||||||
return '**Unexpected '.gettype($value).'**';
|
return '**Unexpected ' . gettype($value) . '**';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($modifier) {
|
switch ($modifier) {
|
||||||
case "s": // string
|
case 's': // string
|
||||||
return $this->driver->escape($value, TRUE);
|
return $this->driver->escape($value, TRUE);
|
||||||
|
case 'sn': // string or NULL
|
||||||
|
return $value == '' ? 'NULL' : $this->driver->escape($value, TRUE);
|
||||||
case 'b': // boolean
|
case 'b': // boolean
|
||||||
return $value
|
return $value
|
||||||
? $this->driver->formats['TRUE']
|
? $this->driver->formats['TRUE']
|
||||||
@@ -209,7 +202,8 @@ class DibiTranslator
|
|||||||
: $value);
|
: $value);
|
||||||
case 'n': // identifier name
|
case 'n': // identifier name
|
||||||
return $this->quote($value);
|
return $this->quote($value);
|
||||||
case 'p': // preserve as SQL
|
case 'sql':// preserve as SQL
|
||||||
|
case 'p': // back compatibility
|
||||||
$value = (string) $value;
|
$value = (string) $value;
|
||||||
|
|
||||||
// speed-up - is regexp required?
|
// speed-up - is regexp required?
|
||||||
@@ -229,11 +223,11 @@ class DibiTranslator
|
|||||||
(\')((?:\'\'|[^\'])*)\'| ## 3,4) string
|
(\')((?:\'\'|[^\'])*)\'| ## 3,4) string
|
||||||
(")((?:""|[^"])*)"| ## 5,6) "string"
|
(")((?:""|[^"])*)"| ## 5,6) "string"
|
||||||
%(else|end)| ## 7) conditional SQL
|
%(else|end)| ## 7) conditional SQL
|
||||||
%([a-zA-Z]{1,2})$| ## 8) right modifier
|
%([a-zA-Z]{1,3})$| ## 8) right modifier
|
||||||
(\'|") ## 9) lone-quote
|
(\'|") ## 9) lone-quote
|
||||||
)/xs',
|
)/xs',
|
||||||
*/
|
*/
|
||||||
. preg_replace_callback('/(?=`|\[|\'|"|%)(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|%(else|end)|%([a-zA-Z]{1,2})$|(\'|"))/s',
|
. preg_replace_callback('/(?=`|\[|\'|"|%)(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|%(else|end)|%([a-zA-Z]{1,3})$|(\'|"))/s',
|
||||||
array($this, 'cb'),
|
array($this, 'cb'),
|
||||||
substr($value, $toSkip)
|
substr($value, $toSkip)
|
||||||
);
|
);
|
||||||
@@ -263,14 +257,14 @@ class DibiTranslator
|
|||||||
if (is_bool($value))
|
if (is_bool($value))
|
||||||
return $value ? $this->driver->formats['TRUE'] : $this->driver->formats['FALSE'];
|
return $value ? $this->driver->formats['TRUE'] : $this->driver->formats['FALSE'];
|
||||||
|
|
||||||
if (is_null($value))
|
if ($value === NULL)
|
||||||
return $this->driver->formats['NULL'];
|
return 'NULL';
|
||||||
|
|
||||||
if ($value instanceof IDibiVariable)
|
if ($value instanceof IDibiVariable)
|
||||||
return $value->toSql($this->driver);
|
return $value->toSql($this->driver);
|
||||||
|
|
||||||
$this->hasError = TRUE;
|
$this->hasError = TRUE;
|
||||||
return '**Unexpected '.gettype($value).'**';
|
return '**Unexpected ' . gettype($value) . '**';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +300,7 @@ class DibiTranslator
|
|||||||
// close comment
|
// close comment
|
||||||
$this->ifLevelStart = 0;
|
$this->ifLevelStart = 0;
|
||||||
$this->comment = FALSE;
|
$this->comment = FALSE;
|
||||||
return '*/';
|
return "\0";
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -315,11 +309,11 @@ class DibiTranslator
|
|||||||
if ($this->ifLevelStart == $this->ifLevel) {
|
if ($this->ifLevelStart == $this->ifLevel) {
|
||||||
$this->ifLevelStart = 0;
|
$this->ifLevelStart = 0;
|
||||||
$this->comment = FALSE;
|
$this->comment = FALSE;
|
||||||
return '*/';
|
return "\0";
|
||||||
} elseif (!$this->comment) {
|
} elseif (!$this->comment) {
|
||||||
$this->ifLevelStart = $this->ifLevel;
|
$this->ifLevelStart = $this->ifLevel;
|
||||||
$this->comment = TRUE;
|
$this->comment = TRUE;
|
||||||
return '/*';
|
return "\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
require_once '../dibi/dibi.php';
|
require_once '../dibi/dibi.php';
|
||||||
|
|
||||||
dibi::$debug = true;
|
|
||||||
|
|
||||||
// mysql
|
// mysql
|
||||||
dibi::connect(array(
|
dibi::connect(array(
|
||||||
|
@@ -4,9 +4,20 @@
|
|||||||
require_once '../dibi/dibi.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
|
// enable log to this file
|
||||||
dibi::$logFile = 'log.sql';
|
dibi::$logFile = 'log.sql';
|
||||||
|
|
||||||
|
// append mode
|
||||||
|
dibi::$logMode = 'a';
|
||||||
|
|
||||||
|
// log all queries
|
||||||
|
dibi::$logAll = TRUE;
|
||||||
|
|
||||||
|
|
||||||
// mysql
|
// mysql
|
||||||
dibi::connect(array(
|
dibi::connect(array(
|
||||||
@@ -14,7 +25,7 @@ dibi::connect(array(
|
|||||||
'host' => 'localhost',
|
'host' => 'localhost',
|
||||||
'username' => 'root',
|
'username' => 'root',
|
||||||
'password' => 'xxx', // change to real password!
|
'password' => 'xxx', // change to real password!
|
||||||
'database' => 'test',
|
'database' => 'xxx',
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ pre.dibi { padding-bottom: 10px; }
|
|||||||
|
|
||||||
require_once '../dibi/dibi.php';
|
require_once '../dibi/dibi.php';
|
||||||
|
|
||||||
|
|
||||||
// required since PHP 5.1.0
|
// 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'); // or 'GMT'
|
date_default_timezone_set('Europe/Prague'); // or 'GMT'
|
||||||
@@ -33,9 +32,8 @@ $arr3 = array(
|
|||||||
$arr4 = array(
|
$arr4 = array(
|
||||||
'a' => 12,
|
'a' => 12,
|
||||||
'b' => NULL,
|
'b' => NULL,
|
||||||
'c%?' => NULL,
|
'c%t' => time(), // modifier 'T' means datetime
|
||||||
'd%t' => time(), // modifier 'T' means datetime
|
'd' => 'any string',
|
||||||
'e' => 'any string',
|
|
||||||
);
|
);
|
||||||
$arr5 = array('RAND()', '[col1] > [col2]');
|
$arr5 = array('RAND()', '[col1] > [col2]');
|
||||||
|
|
||||||
@@ -48,12 +46,15 @@ WHERE ([test.a] LIKE %d", '1995-03-01', "
|
|||||||
OR [b2] IN (%s", $arr1, ")
|
OR [b2] IN (%s", $arr1, ")
|
||||||
OR [b3] IN (", $arr2, ")
|
OR [b3] IN (", $arr2, ")
|
||||||
OR [b4] IN (%n", $arr3, ")
|
OR [b4] IN (%n", $arr3, ")
|
||||||
OR [b4] IN (%p", $arr5, ")
|
OR [b5] IN (%sql", $arr5, ")
|
||||||
|
OR [b6] IN (", array(), ")
|
||||||
AND [c] = 'embedded '' string'
|
AND [c] = 'embedded '' string'
|
||||||
OR [d]=%i", 10.3, "
|
OR [d]=%i", 10.3, "
|
||||||
OR [true]=", true, "
|
OR [e]=%i", NULL, "
|
||||||
OR [false]=", false, "
|
OR [true]=", TRUE, "
|
||||||
OR [null]=", NULL, "
|
OR [false]=", FALSE, "
|
||||||
|
OR [str_null]=%sn", '', "
|
||||||
|
OR [str_not_null]=%sn", 'hello', "
|
||||||
LIMIT 10");
|
LIMIT 10");
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +67,8 @@ $n = 123;
|
|||||||
dibi::test("UPDATE [test] SET", $arr4, " WHERE [id]=%i", $n);
|
dibi::test("UPDATE [test] SET", $arr4, " WHERE [id]=%i", $n);
|
||||||
|
|
||||||
|
|
||||||
// array with modifier %a - means strings
|
// array with modifier %a - assoc
|
||||||
dibi::test("UPDATE [test] SET%a", $arr4, " WHERE [id]=%i", $n);
|
dibi::test("UPDATE [test] SET%a", $arr4, " WHERE [id]=%i", $n);
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ dibi::connect(array(
|
|||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
// create new substitution :blog: ==> wp_items_
|
// create new substitution :blog: ==> wp_
|
||||||
dibi::addSubst('blog', 'wp_');
|
dibi::addSubst('blog', 'wp_');
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1 +1 @@
|
|||||||
Dibi Version 0.6e
|
Dibi Version 0.7a
|
||||||
|
Reference in New Issue
Block a user