From c0bd3761deb3945b4975a247cb47eeaeb6c2e4c3 Mon Sep 17 00:00:00 2001
From: David Grudl empty result set empty result set
- * public $onClick; // declaration in class
- * $this->onClick[] = 'callback'; // attaching event handler
- * if (!empty($this->onClick)) ... // are there any handlers?
- * $this->onClick($sender, $arg); // raises the event with arguments
- *
- *
- * Adding method to class (i.e. to all instances) works similar to JavaScript
- * prototype property. The syntax for adding a new method is:
- *
- * function MyClass_prototype_newMethod(MyClass $obj, $arg, ...) { ... }
- * $obj = new MyClass;
- * $obj->newMethod($x); // equivalent to MyClass_prototype_newMethod($obj, $x);
- *
- *
- * @author David Grudl
- * @copyright Copyright (c) 2004, 2008 David Grudl
- * @package Nette
- * @version $Revision$ $Date$
- */
-abstract class Object
-{
-
- /**
- * Returns the name of the class of this object.
- *
- * @return string
- */
- final public function getClass()
- {
- return get_class($this);
- }
-
-
-
- /**
- * Access to reflection.
- *
- * @return ReflectionObject
- */
- final public function getReflection()
- {
- return new ReflectionObject($this);
- }
-
-
-
- /**
- * Call to undefined method.
- *
- * @param string method name
- * @param array arguments
- * @return mixed
- * @throws ::MemberAccessException
- */
- protected function __call($name, $args)
- {
- $class = get_class($this);
-
- if ($name === '') {
- throw new /*::*/MemberAccessException("Call to class '$class' method without name.");
- }
-
- // event functionality
- if (self::hasEvent($class, $name)) {
- $list = $this->$name;
- if (is_array($list) || $list instanceof Traversable) {
- foreach ($list as $handler) {
- call_user_func_array($handler, $args);
- }
- }
- return;
- }
-
- // object prototypes support Class__method()
- // (or use class Class__method { static function ... } with autoloading?)
- $cl = $class;
- do {
- if (function_exists($nm = $cl . '_prototype_' . $name)) {
- array_unshift($args, $this);
- return call_user_func_array($nm, $args);
- }
- } while ($cl = get_parent_class($cl));
-
- throw new /*::*/MemberAccessException("Call to undefined method $class::$name().");
- }
-
-
-
- /**
- * Call to undefined static method.
- *
- * @param string method name (in lower case!)
- * @param array arguments
- * @return mixed
- * @throws ::MemberAccessException
- */
- protected static function __callStatic($name, $args)
- {
- $class = get_called_class();
- throw new /*::*/MemberAccessException("Call to undefined static method $class::$name().");
- }
-
-
-
- /**
- * Returns property value. Do not call directly.
- *
- * @param string property name
- * @return mixed property value
- * @throws ::MemberAccessException if the property is not defined.
- */
- protected function &__get($name)
- {
- $class = get_class($this);
-
- if ($name === '') {
- throw new /*::*/MemberAccessException("Cannot read an class '$class' property without name.");
- }
-
- // property getter support
- $m = 'get' . $name;
- if (self::hasAccessor($class, $m)) {
- // ampersands:
- // - uses &__get() because declaration should be forward compatible (e.g. with Nette::Web::Html)
- // - doesn't call &$this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
- $val = $this->$m();
- return $val;
-
- } else {
- throw new /*::*/MemberAccessException("Cannot read an undeclared property $class::\$$name.");
- }
- }
-
-
-
- /**
- * Sets value of a property. Do not call directly.
- *
- * @param string property name
- * @param mixed property value
- * @return void
- * @throws ::MemberAccessException if the property is not defined or is read-only
- */
- protected function __set($name, $value)
- {
- $class = get_class($this);
-
- if ($name === '') {
- throw new /*::*/MemberAccessException("Cannot assign to an class '$class' property without name.");
- }
-
- // property setter support
- if (self::hasAccessor($class, 'get' . $name)) {
- $m = 'set' . $name;
- if (self::hasAccessor($class, $m)) {
- $this->$m($value);
-
- } else {
- throw new /*::*/MemberAccessException("Cannot assign to a read-only property $class::\$$name.");
- }
-
- } else {
- throw new /*::*/MemberAccessException("Cannot assign to an undeclared property $class::\$$name.");
- }
- }
-
-
-
- /**
- * Is property defined?
- *
- * @param string property name
- * @return bool
- */
- protected function __isset($name)
- {
- return $name !== '' && self::hasAccessor(get_class($this), 'get' . $name);
- }
-
-
-
- /**
- * Access to undeclared property.
- *
- * @param string property name
- * @return void
- * @throws ::MemberAccessException
- */
- protected function __unset($name)
- {
- $class = get_class($this);
- throw new /*::*/MemberAccessException("Cannot unset an property $class::\$$name.");
- }
-
-
-
- /**
- * Has property an accessor?
- *
- * @param string class name
- * @param string method name
- * @return bool
- */
- private static function hasAccessor($c, $m)
- {
- static $cache;
- if (!isset($cache[$c])) {
- // get_class_methods returns private, protected and public methods of Object (doesn't matter)
- // and ONLY PUBLIC methods of descendants (perfect!)
- // but returns static methods too (nothing doing...)
- // and is much faster than reflection
- // (works good since 5.0.4)
- $cache[$c] = array_flip(get_class_methods($c));
- }
- // case-sensitive checking, capitalize the fourth character
- $m[3] = $m[3] & "\xDF";
- return isset($cache[$c][$m]);
- }
-
-
-
- /**
- * Is property an event?
- *
- * @param string class name
- * @param string method name
- * @return bool
- */
- private static function hasEvent($c, $m)
- {
- return preg_match('#^on[A-Z]#', $m) && property_exists($c, $m);
- }
-
-}
+
+ * $val = $obj->label; // equivalent to $val = $obj->getLabel();
+ * $obj->label = 'Nette'; // equivalent to $obj->setLabel('Nette');
+ *
+ * Property names are case-sensitive, and they are written in the camelCaps
+ * or PascalCaps.
+ *
+ * Event functionality is provided by declaration of property named 'on{Something}'
+ * Multiple handlers are allowed.
+ *
+ * public $onClick; // declaration in class
+ * $this->onClick[] = 'callback'; // attaching event handler
+ * if (!empty($this->onClick)) ... // are there any handlers?
+ * $this->onClick($sender, $arg); // raises the event with arguments
+ *
+ *
+ * Adding method to class (i.e. to all instances) works similar to JavaScript
+ * prototype property. The syntax for adding a new method is:
+ *
+ * function MyClass_prototype_newMethod(MyClass $obj, $arg, ...) { ... }
+ * $obj = new MyClass;
+ * $obj->newMethod($x); // equivalent to MyClass_prototype_newMethod($obj, $x);
+ *
+ *
+ * @author David Grudl
+ * @copyright Copyright (c) 2004, 2008 David Grudl
+ * @package Nette
+ */
+abstract class Object
+{
+
+ /**
+ * Returns the name of the class of this object.
+ *
+ * @return string
+ */
+ final public function getClass()
+ {
+ return get_class($this);
+ }
+
+
+
+ /**
+ * Access to reflection.
+ *
+ * @return ReflectionObject
+ */
+ final public function getReflection()
+ {
+ return new ReflectionObject($this);
+ }
+
+
+
+ /**
+ * Call to undefined method.
+ *
+ * @param string method name
+ * @param array arguments
+ * @return mixed
+ * @throws ::MemberAccessException
+ */
+ protected function __call($name, $args)
+ {
+ $class = get_class($this);
+
+ if ($name === '') {
+ throw new /*::*/MemberAccessException("Call to class '$class' method without name.");
+ }
+
+ // event functionality
+ if (self::hasEvent($class, $name)) {
+ $list = $this->$name;
+ if (is_array($list) || $list instanceof Traversable) {
+ foreach ($list as $handler) {
+ call_user_func_array($handler, $args);
+ }
+ }
+ return;
+ }
+
+ // object prototypes support Class__method()
+ // (or use class Class__method { static function ... } with autoloading?)
+ $cl = $class;
+ do {
+ if (function_exists($nm = $cl . '_prototype_' . $name)) {
+ array_unshift($args, $this);
+ return call_user_func_array($nm, $args);
+ }
+ } while ($cl = get_parent_class($cl));
+
+ throw new /*::*/MemberAccessException("Call to undefined method $class::$name().");
+ }
+
+
+
+ /**
+ * Call to undefined static method.
+ *
+ * @param string method name (in lower case!)
+ * @param array arguments
+ * @return mixed
+ * @throws ::MemberAccessException
+ */
+ protected static function __callStatic($name, $args)
+ {
+ $class = get_called_class();
+ throw new /*::*/MemberAccessException("Call to undefined static method $class::$name().");
+ }
+
+
+
+ /**
+ * Returns property value. Do not call directly.
+ *
+ * @param string property name
+ * @return mixed property value
+ * @throws ::MemberAccessException if the property is not defined.
+ */
+ protected function &__get($name)
+ {
+ $class = get_class($this);
+
+ if ($name === '') {
+ throw new /*::*/MemberAccessException("Cannot read an class '$class' property without name.");
+ }
+
+ // property getter support
+ $m = 'get' . $name;
+ if (self::hasAccessor($class, $m)) {
+ // ampersands:
+ // - uses &__get() because declaration should be forward compatible (e.g. with Nette::Web::Html)
+ // - doesn't call &$this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
+ $val = $this->$m();
+ return $val;
+
+ } else {
+ throw new /*::*/MemberAccessException("Cannot read an undeclared property $class::\$$name.");
+ }
+ }
+
+
+
+ /**
+ * Sets value of a property. Do not call directly.
+ *
+ * @param string property name
+ * @param mixed property value
+ * @return void
+ * @throws ::MemberAccessException if the property is not defined or is read-only
+ */
+ protected function __set($name, $value)
+ {
+ $class = get_class($this);
+
+ if ($name === '') {
+ throw new /*::*/MemberAccessException("Cannot assign to an class '$class' property without name.");
+ }
+
+ // property setter support
+ if (self::hasAccessor($class, 'get' . $name)) {
+ $m = 'set' . $name;
+ if (self::hasAccessor($class, $m)) {
+ $this->$m($value);
+
+ } else {
+ throw new /*::*/MemberAccessException("Cannot assign to a read-only property $class::\$$name.");
+ }
+
+ } else {
+ throw new /*::*/MemberAccessException("Cannot assign to an undeclared property $class::\$$name.");
+ }
+ }
+
+
+
+ /**
+ * Is property defined?
+ *
+ * @param string property name
+ * @return bool
+ */
+ protected function __isset($name)
+ {
+ return $name !== '' && self::hasAccessor(get_class($this), 'get' . $name);
+ }
+
+
+
+ /**
+ * Access to undeclared property.
+ *
+ * @param string property name
+ * @return void
+ * @throws ::MemberAccessException
+ */
+ protected function __unset($name)
+ {
+ $class = get_class($this);
+ throw new /*::*/MemberAccessException("Cannot unset an property $class::\$$name.");
+ }
+
+
+
+ /**
+ * Has property an accessor?
+ *
+ * @param string class name
+ * @param string method name
+ * @return bool
+ */
+ private static function hasAccessor($c, $m)
+ {
+ static $cache;
+ if (!isset($cache[$c])) {
+ // get_class_methods returns private, protected and public methods of Object (doesn't matter)
+ // and ONLY PUBLIC methods of descendants (perfect!)
+ // but returns static methods too (nothing doing...)
+ // and is much faster than reflection
+ // (works good since 5.0.4)
+ $cache[$c] = array_flip(get_class_methods($c));
+ }
+ // case-sensitive checking, capitalize the fourth character
+ $m[3] = $m[3] & "\xDF";
+ return isset($cache[$c][$m]);
+ }
+
+
+
+ /**
+ * Is property an event?
+ *
+ * @param string class name
+ * @param string method name
+ * @return bool
+ */
+ private static function hasEvent($c, $m)
+ {
+ return preg_match('#^on[A-Z]#', $m) && property_exists($c, $m);
+ }
+
+}
diff --git a/dibi/dibi.php b/dibi/dibi.php
index a1a74e00..4cf8c2a9 100644
--- a/dibi/dibi.php
+++ b/dibi/dibi.php
@@ -1,796 +1,793 @@
-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 object DibiConnection object.
- * @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];
- }
-
-
-
- /**
- * 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|NULL result set object (if any)
- * @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|NULL result set object (if any)
- */
- 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);
- }
-
-
-
- /**
- * Executes SQL query and fetch result - Monostate for DibiConnection::query() & fetch().
- *
- * @param array|mixed one or more arguments
- * @return array
- * @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
- * @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();
- }
-
-
-
- /**
- * Gets the number of affected rows.
- * Monostate for DibiConnection::affectedRows()
- *
- * @return int number of rows
- * @throws DibiException
- */
- public static function affectedRows()
- {
- return self::getConnection()->affectedRows();
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- * Monostate for DibiConnection::insertId()
- *
- * @param string optional sequence name
- * @return int
- * @throws DibiException
- */
- public static function insertId($sequence=NULL)
- {
- return self::getConnection()->insertId($sequence);
- }
-
-
-
- /**
- * Begins a transaction - Monostate for DibiConnection::begin().
- * @return void
- * @throws DibiException
- */
- public static function begin()
- {
- self::getConnection()->begin();
- }
-
-
-
- /**
- * Commits statements in a transaction - Monostate for DibiConnection::commit().
- * @return void
- * @throws DibiException
- */
- public static function commit()
- {
- self::getConnection()->commit();
- }
-
-
-
- /**
- * Rollback changes in a transaction - Monostate for DibiConnection::rollback().
- * @return void
- * @throws DibiException
- */
- public static function rollback()
- {
- self::getConnection()->rollback();
- }
-
-
-
- /**
- * 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.
- */
- protected static function __callStatic($name, $args)
- {
- //if ($name = 'select', 'update', ...') {
- // return self::command()->$name($args);
- //}
- return call_user_func_array(array(self::getConnection(), $name), $args);
- }
-
-
-
- /********************* fluent SQL builders ****************d*g**/
-
-
-
- /**
- * @return DibiFluent
- */
- public static function command()
- {
- return new DibiFluent(self::getConnection());
- }
-
-
-
- /**
- * @param string column name
- * @return DibiFluent
- */
- public static function select($args)
- {
- $args = func_get_args();
- return self::command()->__call('select', $args);
- }
-
-
-
- /**
- * @param string table
- * @param array
- * @return DibiFluent
- */
- public static function update($table, array $args)
- {
- return self::command()->update('%n', $table)->set($args);
- }
-
-
-
- /**
- * @param string table
- * @param array
- * @return DibiFluent
- */
- public static function insert($table, array $args)
- {
- return self::command()->insert()
- ->into('%n', $table, '(%n)', array_keys($args))->values('%l', array_values($args));
- }
-
-
-
- /**
- * @param string table
- * @return DibiFluent
- */
- public static function delete($table)
- {
- return self::command()->delete()->from('%n', $table);
- }
-
-
-
- /********************* data types ****************d*g**/
-
-
-
- /**
- * Pseudotype for timestamp representation.
- *
- * @param mixed datetime
- * @return DibiVariable
- */
- public static function datetime($time = NULL)
- {
- if ($time === NULL) {
- $time = time(); // current time
- } elseif (is_string($time)) {
- $time = strtotime($time); // try convert to timestamp
- } else {
- $time = (int) $time;
- }
- return new DibiVariable($time, dibi::FIELD_DATETIME);
- }
-
-
-
- /**
- * Pseudotype for date representation.
- *
- * @param mixed date
- * @return DibiVariable
- */
- public static function date($date = NULL)
- {
- $var = self::datetime($date);
- $var->modifier = dibi::FIELD_DATE;
- return $var;
- }
-
-
-
- /********************* substitutions ****************d*g**/
-
-
-
- /**
- * Create a new substitution pair for indentifiers.
- *
- * @param string from
- * @param string to
- * @return void
- */
- public static function addSubst($expr, $subst)
- {
- self::$substs[$expr] = $subst;
- }
-
-
-
- /**
- * Sets substitution fallback handler.
- *
- * @param callback
- * @return void
- */
- public static function setSubstFallback($callback)
- {
- if (!is_callable($callback)) {
- throw new InvalidArgumentException("Invalid callback.");
- }
-
- self::$substFallBack = $callback;
- }
-
-
-
- /**
- * Remove substitution pair.
- *
- * @param mixed from or TRUE
- * @return void
- */
- public static function removeSubst($expr)
- {
- if ($expr === TRUE) {
- self::$substs = array();
- } else {
- unset(self::$substs[':'.$expr.':']);
- }
- }
-
-
-
- /**
- * Provides substitution.
- *
- * @param string
- * @return string
- */
- public static function substitute($value)
- {
- if (strpos($value, ':') === FALSE) {
- return $value;
-
- } else {
- return preg_replace_callback('#:(.*):#U', array('dibi', 'subCb'), $value);
- }
- }
-
-
-
- /**
- * Substitution callback.
- *
- * @param array
- * @return string
- */
- private static function subCb($m)
- {
- $m = $m[1];
- if (isset(self::$substs[$m])) {
- return self::$substs[$m];
-
- } elseif (self::$substFallBack) {
- return self::$substs[$m] = call_user_func(self::$substFallBack, $m);
-
- } else {
- return $m;
- }
- }
-
-
-
- /********************* event handling ****************d*g**/
-
-
-
- /**
- * Add new event handler.
- *
- * @param callback
- * @return void
- * @throws InvalidArgumentException
- */
- public static function addHandler($callback)
- {
- if (!is_callable($callback)) {
- throw new InvalidArgumentException("Invalid callback.");
- }
-
- self::$handlers[] = $callback;
- }
-
-
-
- /**
- * Event notification (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback).
- *
- * @param DibiConnection
- * @param string event name
- * @param mixed
- * @return void
- */
- public static function notify(DibiConnection $connection = NULL, $event, $arg = NULL)
- {
- foreach (self::$handlers as $handler) {
- call_user_func($handler, $connection, $event, $arg);
- }
- }
-
-
-
- /**
- * Enable profiler & logger.
- *
- * @param string filename
- * @param bool log all queries?
- * @return DibiProfiler
- */
- public static function startLogger($file, $logQueries = FALSE)
- {
- require_once dirname(__FILE__) . '/libs/DibiLogger.php';
-
- $logger = new DibiLogger($file);
- $logger->logQueries = $logQueries;
- self::addHandler(array($logger, 'handler'));
- return $logger;
- }
-
-
-
- /********************* 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 {
- if ($sql === NULL) $sql = self::$sql;
-
- static $keywords1 = 'SELECT|UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
- static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|TRUE|FALSE';
-
- // insert new lines
- $sql = ' ' . $sql;
- $sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
-
- // reduce spaces
- $sql = preg_replace('#[ \t]{2,}#', " ", $sql);
-
- $sql = wordwrap($sql, 100);
- $sql = htmlSpecialChars($sql);
- $sql = preg_replace("#\n{2,}#", "\n", $sql);
-
- // syntax highlight
- $sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is", array('dibi', 'highlightCallback'), $sql);
- $sql = trim($sql);
- echo '', $sql, "
\n";
- }
-
- if ($return) {
- return ob_get_clean();
- } else {
- ob_end_flush();
- }
- }
-
-
-
- private static function highlightCallback($matches)
- {
- if (!empty($matches[1])) // comment
- return '' . $matches[1] . '';
-
- if (!empty($matches[2])) // error
- return '' . $matches[2] . '';
-
- if (!empty($matches[3])) // most important keywords
- return '' . $matches[3] . '';
-
- if (!empty($matches[4])) // other keywords
- return '' . $matches[4] . '';
- }
-
-
-
- /**
- * Returns brief descriptions.
- * @return string
- * @return array
- */
- public static function getColophon($sender = NULL)
- {
- $arr = array(
- 'Number of SQL queries: ' . dibi::$numOfQueries
- . (dibi::$totalTime === NULL ? '' : ', elapsed time: ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms'),
- );
- if ($sender === 'bluescreen') {
- $arr[] = 'dibi version ' . dibi::VERSION;
- }
- return $arr;
- }
-
-}
+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 object DibiConnection object.
+ * @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];
+ }
+
+
+
+ /**
+ * 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|NULL result set object (if any)
+ * @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|NULL result set object (if any)
+ */
+ 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);
+ }
+
+
+
+ /**
+ * Executes SQL query and fetch result - Monostate for DibiConnection::query() & fetch().
+ *
+ * @param array|mixed one or more arguments
+ * @return array
+ * @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
+ * @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();
+ }
+
+
+
+ /**
+ * Gets the number of affected rows.
+ * Monostate for DibiConnection::affectedRows()
+ *
+ * @return int number of rows
+ * @throws DibiException
+ */
+ public static function affectedRows()
+ {
+ return self::getConnection()->affectedRows();
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ * Monostate for DibiConnection::insertId()
+ *
+ * @param string optional sequence name
+ * @return int
+ * @throws DibiException
+ */
+ public static function insertId($sequence=NULL)
+ {
+ return self::getConnection()->insertId($sequence);
+ }
+
+
+
+ /**
+ * Begins a transaction - Monostate for DibiConnection::begin().
+ * @return void
+ * @throws DibiException
+ */
+ public static function begin()
+ {
+ self::getConnection()->begin();
+ }
+
+
+
+ /**
+ * Commits statements in a transaction - Monostate for DibiConnection::commit().
+ * @return void
+ * @throws DibiException
+ */
+ public static function commit()
+ {
+ self::getConnection()->commit();
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction - Monostate for DibiConnection::rollback().
+ * @return void
+ * @throws DibiException
+ */
+ public static function rollback()
+ {
+ self::getConnection()->rollback();
+ }
+
+
+
+ /**
+ * 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.
+ */
+ protected static function __callStatic($name, $args)
+ {
+ //if ($name = 'select', 'update', ...') {
+ // return self::command()->$name($args);
+ //}
+ return call_user_func_array(array(self::getConnection(), $name), $args);
+ }
+
+
+
+ /********************* fluent SQL builders ****************d*g**/
+
+
+
+ /**
+ * @return DibiFluent
+ */
+ public static function command()
+ {
+ return new DibiFluent(self::getConnection());
+ }
+
+
+
+ /**
+ * @param string column name
+ * @return DibiFluent
+ */
+ public static function select($args)
+ {
+ $args = func_get_args();
+ return self::command()->__call('select', $args);
+ }
+
+
+
+ /**
+ * @param string table
+ * @param array
+ * @return DibiFluent
+ */
+ public static function update($table, array $args)
+ {
+ return self::command()->update('%n', $table)->set($args);
+ }
+
+
+
+ /**
+ * @param string table
+ * @param array
+ * @return DibiFluent
+ */
+ public static function insert($table, array $args)
+ {
+ return self::command()->insert()
+ ->into('%n', $table, '(%n)', array_keys($args))->values('%l', array_values($args));
+ }
+
+
+
+ /**
+ * @param string table
+ * @return DibiFluent
+ */
+ public static function delete($table)
+ {
+ return self::command()->delete()->from('%n', $table);
+ }
+
+
+
+ /********************* data types ****************d*g**/
+
+
+
+ /**
+ * Pseudotype for timestamp representation.
+ *
+ * @param mixed datetime
+ * @return DibiVariable
+ */
+ public static function datetime($time = NULL)
+ {
+ if ($time === NULL) {
+ $time = time(); // current time
+ } elseif (is_string($time)) {
+ $time = strtotime($time); // try convert to timestamp
+ } else {
+ $time = (int) $time;
+ }
+ return new DibiVariable($time, dibi::FIELD_DATETIME);
+ }
+
+
+
+ /**
+ * Pseudotype for date representation.
+ *
+ * @param mixed date
+ * @return DibiVariable
+ */
+ public static function date($date = NULL)
+ {
+ $var = self::datetime($date);
+ $var->modifier = dibi::FIELD_DATE;
+ return $var;
+ }
+
+
+
+ /********************* substitutions ****************d*g**/
+
+
+
+ /**
+ * Create a new substitution pair for indentifiers.
+ *
+ * @param string from
+ * @param string to
+ * @return void
+ */
+ public static function addSubst($expr, $subst)
+ {
+ self::$substs[$expr] = $subst;
+ }
+
+
+
+ /**
+ * Sets substitution fallback handler.
+ *
+ * @param callback
+ * @return void
+ */
+ public static function setSubstFallback($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new InvalidArgumentException("Invalid callback.");
+ }
+
+ self::$substFallBack = $callback;
+ }
+
+
+
+ /**
+ * Remove substitution pair.
+ *
+ * @param mixed from or TRUE
+ * @return void
+ */
+ public static function removeSubst($expr)
+ {
+ if ($expr === TRUE) {
+ self::$substs = array();
+ } else {
+ unset(self::$substs[':'.$expr.':']);
+ }
+ }
+
+
+
+ /**
+ * Provides substitution.
+ *
+ * @param string
+ * @return string
+ */
+ public static function substitute($value)
+ {
+ if (strpos($value, ':') === FALSE) {
+ return $value;
+
+ } else {
+ return preg_replace_callback('#:(.*):#U', array('dibi', 'subCb'), $value);
+ }
+ }
+
+
+
+ /**
+ * Substitution callback.
+ *
+ * @param array
+ * @return string
+ */
+ private static function subCb($m)
+ {
+ $m = $m[1];
+ if (isset(self::$substs[$m])) {
+ return self::$substs[$m];
+
+ } elseif (self::$substFallBack) {
+ return self::$substs[$m] = call_user_func(self::$substFallBack, $m);
+
+ } else {
+ return $m;
+ }
+ }
+
+
+
+ /********************* event handling ****************d*g**/
+
+
+
+ /**
+ * Add new event handler.
+ *
+ * @param callback
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public static function addHandler($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new InvalidArgumentException("Invalid callback.");
+ }
+
+ self::$handlers[] = $callback;
+ }
+
+
+
+ /**
+ * Event notification (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback).
+ *
+ * @param DibiConnection
+ * @param string event name
+ * @param mixed
+ * @return void
+ */
+ public static function notify(DibiConnection $connection = NULL, $event, $arg = NULL)
+ {
+ foreach (self::$handlers as $handler) {
+ call_user_func($handler, $connection, $event, $arg);
+ }
+ }
+
+
+
+ /**
+ * Enable profiler & logger.
+ *
+ * @param string filename
+ * @param bool log all queries?
+ * @return DibiProfiler
+ */
+ public static function startLogger($file, $logQueries = FALSE)
+ {
+ require_once dirname(__FILE__) . '/libs/DibiLogger.php';
+
+ $logger = new DibiLogger($file);
+ $logger->logQueries = $logQueries;
+ self::addHandler(array($logger, 'handler'));
+ return $logger;
+ }
+
+
+
+ /********************* 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 {
+ if ($sql === NULL) $sql = self::$sql;
+
+ static $keywords1 = 'SELECT|UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
+ static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|TRUE|FALSE';
+
+ // insert new lines
+ $sql = ' ' . $sql;
+ $sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
+
+ // reduce spaces
+ $sql = preg_replace('#[ \t]{2,}#', " ", $sql);
+
+ $sql = wordwrap($sql, 100);
+ $sql = htmlSpecialChars($sql);
+ $sql = preg_replace("#\n{2,}#", "\n", $sql);
+
+ // syntax highlight
+ $sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is", array('dibi', 'highlightCallback'), $sql);
+ $sql = trim($sql);
+ echo '', $sql, "
\n";
+ }
+
+ if ($return) {
+ return ob_get_clean();
+ } else {
+ ob_end_flush();
+ }
+ }
+
+
+
+ private static function highlightCallback($matches)
+ {
+ if (!empty($matches[1])) // comment
+ return '' . $matches[1] . '';
+
+ if (!empty($matches[2])) // error
+ return '' . $matches[2] . '';
+
+ if (!empty($matches[3])) // most important keywords
+ return '' . $matches[3] . '';
+
+ if (!empty($matches[4])) // other keywords
+ return '' . $matches[4] . '';
+ }
+
+
+
+ /**
+ * Returns brief descriptions.
+ * @return string
+ * @return array
+ */
+ public static function getColophon($sender = NULL)
+ {
+ $arr = array(
+ 'Number of SQL queries: ' . dibi::$numOfQueries
+ . (dibi::$totalTime === NULL ? '' : ', elapsed time: ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms'),
+ );
+ if ($sender === 'bluescreen') {
+ $arr[] = 'dibi ' . dibi::VERSION . ' (revision ' . dibi::REVISION . ')';
+ }
+ return $arr;
+ }
+
+}
diff --git a/dibi/drivers/mssql.php b/dibi/drivers/mssql.php
index 63fe73ca..b3fce4e2 100644
--- a/dibi/drivers/mssql.php
+++ b/dibi/drivers/mssql.php
@@ -1,364 +1,364 @@
-connection = @mssql_connect($config['host'], $config['username'], $config['password'], TRUE); // intentionally @
- } else {
- $this->connection = @mssql_pconnect($config['host'], $config['username'], $config['password']); // intentionally @
- }
-
- if (!is_resource($this->connection)) {
- throw new DibiDriverException("Can't connect to DB.");
- }
-
- if (isset($config['database']) && !@mssql_select_db($config['database'], $this->connection)) { // intentionally @
- throw new DibiDriverException("Can't select DB '$config[database]'.");
- }
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- mssql_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- $this->resultSet = @mssql_query($sql, $this->connection); // intentionally @
-
- if ($this->resultSet === FALSE) {
- throw new DibiDriverException('Query error', 0, $sql);
- }
-
- return is_resource($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return mssql_rows_affected($this->connection);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- throw new NotSupportedException('MS SQL does not support autoincrementing.');
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->query('BEGIN TRANSACTION');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- $this->query('COMMIT');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- $this->query('ROLLBACK');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . str_replace("'", "''", $value) . "'";
-
- case dibi::IDENTIFIER:
- return '[' . str_replace('.', '].[', $value) . ']';
-
- case dibi::FIELD_BOOL:
- return $value ? -1 : 0;
-
- case dibi::FIELD_DATE:
- return date("'Y-m-d'", $value);
-
- case dibi::FIELD_DATETIME:
- return date("'Y-m-d H:i:s'", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- // offset suppot is missing...
- if ($limit >= 0) {
- $sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ')';
- }
-
- if ($offset) {
- throw new NotImplementedException('Offset is not implemented.');
- }
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- return mssql_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return mssql_fetch_array($this->resultSet, $type ? MSSQL_ASSOC : MSSQL_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- return mssql_data_seek($this->resultSet, $row);
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- mssql_free_result($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = mssql_num_fields($this->resultSet);
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $info = (array) mssql_fetch_field($this->resultSet, $i);
- $info['table'] = $info['column_source'];
- $meta[] = $info;
- }
- return $meta;
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = @mssql_connect($config['host'], $config['username'], $config['password'], TRUE); // intentionally @
+ } else {
+ $this->connection = @mssql_pconnect($config['host'], $config['username'], $config['password']); // intentionally @
+ }
+
+ if (!is_resource($this->connection)) {
+ throw new DibiDriverException("Can't connect to DB.");
+ }
+
+ if (isset($config['database']) && !@mssql_select_db($config['database'], $this->connection)) { // intentionally @
+ throw new DibiDriverException("Can't select DB '$config[database]'.");
+ }
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ mssql_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ $this->resultSet = @mssql_query($sql, $this->connection); // intentionally @
+
+ if ($this->resultSet === FALSE) {
+ throw new DibiDriverException('Query error', 0, $sql);
+ }
+
+ return is_resource($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return mssql_rows_affected($this->connection);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ throw new NotSupportedException('MS SQL does not support autoincrementing.');
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->query('BEGIN TRANSACTION');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ $this->query('COMMIT');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ $this->query('ROLLBACK');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . str_replace("'", "''", $value) . "'";
+
+ case dibi::IDENTIFIER:
+ return '[' . str_replace('.', '].[', $value) . ']';
+
+ case dibi::FIELD_BOOL:
+ return $value ? -1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date("'Y-m-d'", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("'Y-m-d H:i:s'", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ // offset suppot is missing...
+ if ($limit >= 0) {
+ $sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ')';
+ }
+
+ if ($offset) {
+ throw new NotImplementedException('Offset is not implemented.');
+ }
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ return mssql_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return mssql_fetch_array($this->resultSet, $type ? MSSQL_ASSOC : MSSQL_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ return mssql_data_seek($this->resultSet, $row);
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ mssql_free_result($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = mssql_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $info = (array) mssql_fetch_field($this->resultSet, $i);
+ $info['table'] = $info['column_source'];
+ $meta[] = $info;
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/mysql.php b/dibi/drivers/mysql.php
index d87112ee..2a3fbf39 100644
--- a/dibi/drivers/mysql.php
+++ b/dibi/drivers/mysql.php
@@ -1,432 +1,432 @@
-connection = @mysql_connect($host, $config['username'], $config['password'], TRUE, $config['options']); // intentionally @
- } else {
- $this->connection = @mysql_pconnect($host, $config['username'], $config['password'], $config['options']); // intentionally @
- }
-
- if (!is_resource($this->connection)) {
- throw new DibiDriverException(mysql_error(), mysql_errno());
- }
-
- if (isset($config['charset'])) {
- $ok = FALSE;
- if (function_exists('mysql_set_charset')) {
- // affects the character set used by mysql_real_escape_string() (was added in MySQL 5.0.7 and PHP 5.2.3)
- $ok = @mysql_set_charset($config['charset'], $this->connection); // intentionally @
- }
- if (!$ok) $ok = @mysql_query("SET NAMES '$config[charset]'", $this->connection); // intentionally @
- if (!$ok) $this->throwException();
- }
-
- if (isset($config['database'])) {
- @mysql_select_db($config['database'], $this->connection) or $this->throwException(); // intentionally @
- }
-
- if (isset($config['sqlmode'])) {
- if (!@mysql_query("SET sql_mode='$config[sqlmode]'", $this->connection)) $this->throwException(); // intentionally @
- }
-
- $this->buffered = empty($config['unbuffered']);
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- mysql_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- if ($this->buffered) {
- $this->resultSet = @mysql_query($sql, $this->connection); // intentionally @
- } else {
- $this->resultSet = @mysql_unbuffered_query($sql, $this->connection); // intentionally @
- }
-
- if (mysql_errno($this->connection)) {
- $this->throwException($sql);
- }
-
- return is_resource($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return mysql_affected_rows($this->connection);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- return mysql_insert_id($this->connection);
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->query('START TRANSACTION');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- $this->query('COMMIT');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- $this->query('ROLLBACK');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . mysql_real_escape_string($value, $this->connection) . "'";
-
- case dibi::IDENTIFIER:
- return '`' . str_replace('.', '`.`', $value) . '`';
-
- case dibi::FIELD_BOOL:
- return $value ? 1 : 0;
-
- case dibi::FIELD_DATE:
- return date("'Y-m-d'", $value);
-
- case dibi::FIELD_DATETIME:
- return date("'Y-m-d H:i:s'", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- if ($limit < 0 && $offset < 1) return;
-
- // see http://dev.mysql.com/doc/refman/5.0/en/select.html
- $sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
- . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Row count is not available for unbuffered queries.');
- }
- return mysql_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return mysql_fetch_array($this->resultSet, $type ? MYSQL_ASSOC : MYSQL_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Cannot seek an unbuffered result set.');
- }
-
- return mysql_data_seek($this->resultSet, $row);
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- mysql_free_result($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = mysql_num_fields($this->resultSet);
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = (array) mysql_fetch_field($this->resultSet, $i);
- }
- return $meta;
- }
-
-
-
- /**
- * Converts database error to DibiDriverException.
- *
- * @throws DibiDriverException
- */
- protected function throwException($sql = NULL)
- {
- throw new DibiDriverException(mysql_error($this->connection), mysql_errno($this->connection), $sql);
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = @mysql_connect($host, $config['username'], $config['password'], TRUE, $config['options']); // intentionally @
+ } else {
+ $this->connection = @mysql_pconnect($host, $config['username'], $config['password'], $config['options']); // intentionally @
+ }
+
+ if (!is_resource($this->connection)) {
+ throw new DibiDriverException(mysql_error(), mysql_errno());
+ }
+
+ if (isset($config['charset'])) {
+ $ok = FALSE;
+ if (function_exists('mysql_set_charset')) {
+ // affects the character set used by mysql_real_escape_string() (was added in MySQL 5.0.7 and PHP 5.2.3)
+ $ok = @mysql_set_charset($config['charset'], $this->connection); // intentionally @
+ }
+ if (!$ok) $ok = @mysql_query("SET NAMES '$config[charset]'", $this->connection); // intentionally @
+ if (!$ok) $this->throwException();
+ }
+
+ if (isset($config['database'])) {
+ @mysql_select_db($config['database'], $this->connection) or $this->throwException(); // intentionally @
+ }
+
+ if (isset($config['sqlmode'])) {
+ if (!@mysql_query("SET sql_mode='$config[sqlmode]'", $this->connection)) $this->throwException(); // intentionally @
+ }
+
+ $this->buffered = empty($config['unbuffered']);
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ mysql_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ if ($this->buffered) {
+ $this->resultSet = @mysql_query($sql, $this->connection); // intentionally @
+ } else {
+ $this->resultSet = @mysql_unbuffered_query($sql, $this->connection); // intentionally @
+ }
+
+ if (mysql_errno($this->connection)) {
+ $this->throwException($sql);
+ }
+
+ return is_resource($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return mysql_affected_rows($this->connection);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ return mysql_insert_id($this->connection);
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->query('START TRANSACTION');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ $this->query('COMMIT');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ $this->query('ROLLBACK');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . mysql_real_escape_string($value, $this->connection) . "'";
+
+ case dibi::IDENTIFIER:
+ return '`' . str_replace('.', '`.`', $value) . '`';
+
+ case dibi::FIELD_BOOL:
+ return $value ? 1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date("'Y-m-d'", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("'Y-m-d H:i:s'", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ if ($limit < 0 && $offset < 1) return;
+
+ // see http://dev.mysql.com/doc/refman/5.0/en/select.html
+ $sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
+ . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Row count is not available for unbuffered queries.');
+ }
+ return mysql_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return mysql_fetch_array($this->resultSet, $type ? MYSQL_ASSOC : MYSQL_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Cannot seek an unbuffered result set.');
+ }
+
+ return mysql_data_seek($this->resultSet, $row);
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ mysql_free_result($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = mysql_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = (array) mysql_fetch_field($this->resultSet, $i);
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Converts database error to DibiDriverException.
+ *
+ * @throws DibiDriverException
+ */
+ protected function throwException($sql = NULL)
+ {
+ throw new DibiDriverException(mysql_error($this->connection), mysql_errno($this->connection), $sql);
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/mysqli.php b/dibi/drivers/mysqli.php
index 8991f3de..78fa0508 100644
--- a/dibi/drivers/mysqli.php
+++ b/dibi/drivers/mysqli.php
@@ -1,411 +1,411 @@
-connection = mysqli_init();
- @mysqli_real_connect($this->connection, $config['host'], $config['username'], $config['password'], $config['database'], $config['port'], $config['socket'], $config['options']); // intentionally @
-
- if ($errno = mysqli_connect_errno()) {
- throw new DibiDriverException(mysqli_connect_error(), $errno);
- }
-
- if (isset($config['charset'])) {
- $ok = FALSE;
- if (version_compare(PHP_VERSION , '5.1.5', '>=')) {
- // affects the character set used by mysql_real_escape_string() (was added in MySQL 5.0.7 and PHP 5.0.5, fixed in PHP 5.1.5)
- $ok = @mysqli_set_charset($this->connection, $config['charset']); // intentionally @
- }
- if (!$ok) $ok = @mysqli_query($this->connection, "SET NAMES '$config[charset]'"); // intentionally @
- if (!$ok) $this->throwException();
- }
-
- if (isset($config['sqlmode'])) {
- if (!@mysqli_query($this->connection, "SET sql_mode='$config[sqlmode]'")) $this->throwException(); // intentionally @
- }
-
- $this->buffered = empty($config['unbuffered']);
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- mysqli_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- $this->resultSet = @mysqli_query($this->connection, $sql, $this->buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); // intentionally @
-
- if (mysqli_errno($this->connection)) {
- $this->throwException($sql);
- }
-
- return is_object($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return mysqli_affected_rows($this->connection);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- return mysqli_insert_id($this->connection);
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->query('START TRANSACTION');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- $this->query('COMMIT');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- $this->query('ROLLBACK');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . mysqli_real_escape_string($this->connection, $value) . "'";
-
- case dibi::IDENTIFIER:
- return '`' . str_replace('.', '`.`', $value) . '`';
-
- case dibi::FIELD_BOOL:
- return $value ? 1 : 0;
-
- case dibi::FIELD_DATE:
- return date("'Y-m-d'", $value);
-
- case dibi::FIELD_DATETIME:
- return date("'Y-m-d H:i:s'", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- if ($limit < 0 && $offset < 1) return;
-
- // see http://dev.mysql.com/doc/refman/5.0/en/select.html
- $sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
- . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Row count is not available for unbuffered queries.');
- }
- return mysqli_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return mysqli_fetch_array($this->resultSet, $type ? MYSQLI_ASSOC : MYSQLI_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Cannot seek an unbuffered result set.');
- }
- return mysqli_data_seek($this->resultSet, $row);
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- mysqli_free_result($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = mysqli_num_fields($this->resultSet);
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = (array) mysqli_fetch_field_direct($this->resultSet, $i);
- }
- return $meta;
- }
-
-
-
- /**
- * Converts database error to DibiDriverException.
- *
- * @throws DibiDriverException
- */
- protected function throwException($sql = NULL)
- {
- throw new DibiDriverException(mysqli_error($this->connection), mysqli_errno($this->connection), $sql);
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mysqli
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mysqli_result
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = mysqli_init();
+ @mysqli_real_connect($this->connection, $config['host'], $config['username'], $config['password'], $config['database'], $config['port'], $config['socket'], $config['options']); // intentionally @
+
+ if ($errno = mysqli_connect_errno()) {
+ throw new DibiDriverException(mysqli_connect_error(), $errno);
+ }
+
+ if (isset($config['charset'])) {
+ $ok = FALSE;
+ if (version_compare(PHP_VERSION , '5.1.5', '>=')) {
+ // affects the character set used by mysql_real_escape_string() (was added in MySQL 5.0.7 and PHP 5.0.5, fixed in PHP 5.1.5)
+ $ok = @mysqli_set_charset($this->connection, $config['charset']); // intentionally @
+ }
+ if (!$ok) $ok = @mysqli_query($this->connection, "SET NAMES '$config[charset]'"); // intentionally @
+ if (!$ok) $this->throwException();
+ }
+
+ if (isset($config['sqlmode'])) {
+ if (!@mysqli_query($this->connection, "SET sql_mode='$config[sqlmode]'")) $this->throwException(); // intentionally @
+ }
+
+ $this->buffered = empty($config['unbuffered']);
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ mysqli_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ $this->resultSet = @mysqli_query($this->connection, $sql, $this->buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); // intentionally @
+
+ if (mysqli_errno($this->connection)) {
+ $this->throwException($sql);
+ }
+
+ return is_object($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return mysqli_affected_rows($this->connection);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ return mysqli_insert_id($this->connection);
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->query('START TRANSACTION');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ $this->query('COMMIT');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ $this->query('ROLLBACK');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . mysqli_real_escape_string($this->connection, $value) . "'";
+
+ case dibi::IDENTIFIER:
+ return '`' . str_replace('.', '`.`', $value) . '`';
+
+ case dibi::FIELD_BOOL:
+ return $value ? 1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date("'Y-m-d'", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("'Y-m-d H:i:s'", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ if ($limit < 0 && $offset < 1) return;
+
+ // see http://dev.mysql.com/doc/refman/5.0/en/select.html
+ $sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
+ . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Row count is not available for unbuffered queries.');
+ }
+ return mysqli_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return mysqli_fetch_array($this->resultSet, $type ? MYSQLI_ASSOC : MYSQLI_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Cannot seek an unbuffered result set.');
+ }
+ return mysqli_data_seek($this->resultSet, $row);
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ mysqli_free_result($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = mysqli_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = (array) mysqli_fetch_field_direct($this->resultSet, $i);
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Converts database error to DibiDriverException.
+ *
+ * @throws DibiDriverException
+ */
+ protected function throwException($sql = NULL)
+ {
+ throw new DibiDriverException(mysqli_error($this->connection), mysqli_errno($this->connection), $sql);
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mysqli
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mysqli_result
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/odbc.php b/dibi/drivers/odbc.php
index 69cd73f0..52e70440 100644
--- a/dibi/drivers/odbc.php
+++ b/dibi/drivers/odbc.php
@@ -1,404 +1,404 @@
-connection = @odbc_connect($config['dsn'], $config['username'], $config['password']); // intentionally @
- } else {
- $this->connection = @odbc_pconnect($config['dsn'], $config['username'], $config['password']); // intentionally @
- }
-
- if (!is_resource($this->connection)) {
- throw new DibiDriverException(odbc_errormsg() . ' ' . odbc_error());
- }
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- odbc_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- $this->resultSet = @odbc_exec($this->connection, $sql); // intentionally @
-
- if ($this->resultSet === FALSE) {
- $this->throwException($sql);
- }
-
- return is_resource($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return odbc_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- throw new NotSupportedException('ODBC does not support autoincrementing.');
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- if (!odbc_autocommit($this->connection, FALSE)) {
- $this->throwException();
- }
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- if (!odbc_commit($this->connection)) {
- $this->throwException();
- }
- odbc_autocommit($this->connection, TRUE);
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- if (!odbc_rollback($this->connection)) {
- $this->throwException();
- }
- odbc_autocommit($this->connection, TRUE);
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . str_replace("'", "''", $value) . "'";
-
- case dibi::IDENTIFIER:
- return '[' . str_replace('.', '].[', $value) . ']';
-
- case dibi::FIELD_BOOL:
- return $value ? -1 : 0;
-
- case dibi::FIELD_DATE:
- return date("#m/d/Y#", $value);
-
- case dibi::FIELD_DATETIME:
- return date("#m/d/Y H:i:s#", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- // offset suppot is missing...
- if ($limit >= 0) {
- $sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ')';
- }
-
- if ($offset) throw new InvalidArgumentException('Offset is not implemented in driver odbc.');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- // will return -1 with many drivers :-(
- return odbc_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- if ($type) {
- return odbc_fetch_array($this->resultSet, ++$this->row);
- } else {
- $set = $this->resultSet;
- if (!odbc_fetch_row($set, ++$this->row)) return FALSE;
- $count = odbc_num_fields($set);
- $cols = array();
- for ($i = 1; $i <= $count; $i++) $cols[] = odbc_result($set, $i);
- return $cols;
- }
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- $this->row = $row;
- return TRUE;
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- odbc_free_result($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = odbc_num_fields($this->resultSet);
- $meta = array();
- for ($i = 1; $i <= $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = array(
- 'name' => odbc_field_name($this->resultSet, $i),
- 'table' => NULL,
- 'type' => odbc_field_type($this->resultSet, $i),
- 'length' => odbc_field_len($this->resultSet, $i),
- 'scale' => odbc_field_scale($this->resultSet, $i),
- 'precision' => odbc_field_precision($this->resultSet, $i),
- );
- }
- return $meta;
- }
-
-
-
- /**
- * Converts database error to DibiDriverException.
- *
- * @throws DibiDriverException
- */
- protected function throwException($sql = NULL)
- {
- throw new DibiDriverException(odbc_errormsg($this->connection) . ' ' . odbc_error($this->connection), 0, $sql);
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = @odbc_connect($config['dsn'], $config['username'], $config['password']); // intentionally @
+ } else {
+ $this->connection = @odbc_pconnect($config['dsn'], $config['username'], $config['password']); // intentionally @
+ }
+
+ if (!is_resource($this->connection)) {
+ throw new DibiDriverException(odbc_errormsg() . ' ' . odbc_error());
+ }
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ odbc_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ $this->resultSet = @odbc_exec($this->connection, $sql); // intentionally @
+
+ if ($this->resultSet === FALSE) {
+ $this->throwException($sql);
+ }
+
+ return is_resource($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return odbc_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ throw new NotSupportedException('ODBC does not support autoincrementing.');
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ if (!odbc_autocommit($this->connection, FALSE)) {
+ $this->throwException();
+ }
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ if (!odbc_commit($this->connection)) {
+ $this->throwException();
+ }
+ odbc_autocommit($this->connection, TRUE);
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ if (!odbc_rollback($this->connection)) {
+ $this->throwException();
+ }
+ odbc_autocommit($this->connection, TRUE);
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . str_replace("'", "''", $value) . "'";
+
+ case dibi::IDENTIFIER:
+ return '[' . str_replace('.', '].[', $value) . ']';
+
+ case dibi::FIELD_BOOL:
+ return $value ? -1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date("#m/d/Y#", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("#m/d/Y H:i:s#", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ // offset suppot is missing...
+ if ($limit >= 0) {
+ $sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ')';
+ }
+
+ if ($offset) throw new InvalidArgumentException('Offset is not implemented in driver odbc.');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ // will return -1 with many drivers :-(
+ return odbc_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ if ($type) {
+ return odbc_fetch_array($this->resultSet, ++$this->row);
+ } else {
+ $set = $this->resultSet;
+ if (!odbc_fetch_row($set, ++$this->row)) return FALSE;
+ $count = odbc_num_fields($set);
+ $cols = array();
+ for ($i = 1; $i <= $count; $i++) $cols[] = odbc_result($set, $i);
+ return $cols;
+ }
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ $this->row = $row;
+ return TRUE;
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ odbc_free_result($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = odbc_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 1; $i <= $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = array(
+ 'name' => odbc_field_name($this->resultSet, $i),
+ 'table' => NULL,
+ 'type' => odbc_field_type($this->resultSet, $i),
+ 'length' => odbc_field_len($this->resultSet, $i),
+ 'scale' => odbc_field_scale($this->resultSet, $i),
+ 'precision' => odbc_field_precision($this->resultSet, $i),
+ );
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Converts database error to DibiDriverException.
+ *
+ * @throws DibiDriverException
+ */
+ protected function throwException($sql = NULL)
+ {
+ throw new DibiDriverException(odbc_errormsg($this->connection) . ' ' . odbc_error($this->connection), 0, $sql);
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/oracle.php b/dibi/drivers/oracle.php
index 19957bac..993e68e6 100644
--- a/dibi/drivers/oracle.php
+++ b/dibi/drivers/oracle.php
@@ -1,387 +1,387 @@
-connection = @oci_new_connect($config['username'], $config['password'], $config['database'], $config['charset']); // intentionally @
-
- if (!$this->connection) {
- $err = oci_error();
- throw new DibiDriverException($err['message'], $err['code']);
- }
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- oci_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
-
- $this->resultSet = oci_parse($this->connection, $sql);
- if ($this->resultSet) {
- oci_execute($this->resultSet, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
- $err = oci_error($this->resultSet);
- if ($err) {
- throw new DibiDriverException($err['message'], $err['code'], $sql);
- }
- } else {
- $this->throwException($sql);
- }
-
- return is_resource($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- throw new NotImplementedException;
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- throw new NotSupportedException('Oracle does not support autoincrementing.');
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->autocommit = FALSE;
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- if (!oci_commit($this->connection)) {
- $this->throwException();
- }
- $this->autocommit = TRUE;
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- if (!oci_rollback($this->connection)) {
- $this->throwException();
- }
- $this->autocommit = TRUE;
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
-
- case dibi::IDENTIFIER:
- return '[' . str_replace('.', '].[', $value) . ']'; // TODO: not tested
-
- case dibi::FIELD_BOOL:
- return $value ? 1 : 0;
-
- case dibi::FIELD_DATE:
- return date("U", $value);
-
- case dibi::FIELD_DATETIME:
- return date("U", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- if ($limit < 0 && $offset < 1) return;
- $sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- return oci_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return oci_fetch_array($this->resultSet, ($type ? OCI_ASSOC : OCI_NUM) | OCI_RETURN_NULLS);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- throw new NotImplementedException;
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- oci_free_statement($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = oci_num_fields($this->resultSet);
- $meta = array();
- for ($i = 1; $i <= $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = array(
- 'name' => oci_field_name($this->resultSet, $i),
- 'table' => NULL,
- 'type' => oci_field_type($this->resultSet, $i),
- 'size' => oci_field_size($this->resultSet, $i),
- 'scale' => oci_field_scale($this->resultSet, $i),
- 'precision' => oci_field_precision($this->resultSet, $i),
- );
- }
- return $meta;
- }
-
-
-
- /**
- * Converts database error to DibiDriverException.
- *
- * @throws DibiDriverException
- */
- protected function throwException($sql = NULL)
- {
- $err = oci_error($this->connection);
- throw new DibiDriverException($err['message'], $err['code'], $sql);
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = @oci_new_connect($config['username'], $config['password'], $config['database'], $config['charset']); // intentionally @
+
+ if (!$this->connection) {
+ $err = oci_error();
+ throw new DibiDriverException($err['message'], $err['code']);
+ }
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ oci_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+
+ $this->resultSet = oci_parse($this->connection, $sql);
+ if ($this->resultSet) {
+ oci_execute($this->resultSet, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
+ $err = oci_error($this->resultSet);
+ if ($err) {
+ throw new DibiDriverException($err['message'], $err['code'], $sql);
+ }
+ } else {
+ $this->throwException($sql);
+ }
+
+ return is_resource($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ throw new NotImplementedException;
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ throw new NotSupportedException('Oracle does not support autoincrementing.');
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->autocommit = FALSE;
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ if (!oci_commit($this->connection)) {
+ $this->throwException();
+ }
+ $this->autocommit = TRUE;
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ if (!oci_rollback($this->connection)) {
+ $this->throwException();
+ }
+ $this->autocommit = TRUE;
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
+
+ case dibi::IDENTIFIER:
+ return '[' . str_replace('.', '].[', $value) . ']'; // TODO: not tested
+
+ case dibi::FIELD_BOOL:
+ return $value ? 1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date("U", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("U", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ if ($limit < 0 && $offset < 1) return;
+ $sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ return oci_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return oci_fetch_array($this->resultSet, ($type ? OCI_ASSOC : OCI_NUM) | OCI_RETURN_NULLS);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ throw new NotImplementedException;
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ oci_free_statement($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = oci_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 1; $i <= $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = array(
+ 'name' => oci_field_name($this->resultSet, $i),
+ 'table' => NULL,
+ 'type' => oci_field_type($this->resultSet, $i),
+ 'size' => oci_field_size($this->resultSet, $i),
+ 'scale' => oci_field_scale($this->resultSet, $i),
+ 'precision' => oci_field_precision($this->resultSet, $i),
+ );
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Converts database error to DibiDriverException.
+ *
+ * @throws DibiDriverException
+ */
+ protected function throwException($sql = NULL)
+ {
+ $err = oci_error($this->connection);
+ throw new DibiDriverException($err['message'], $err['code'], $sql);
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/pdo.php b/dibi/drivers/pdo.php
index 2b22edd3..5f50829b 100644
--- a/dibi/drivers/pdo.php
+++ b/dibi/drivers/pdo.php
@@ -1,427 +1,427 @@
-connection = $config['pdo'];
-
- } else try {
- $this->connection = new PDO($config['dsn'], $config['username'], $config['password'], $config['options']);
-
- } catch (PDOException $e) {
- throw new DibiDriverException($e->getMessage(), $e->getCode());
- }
-
- if (!$this->connection) {
- throw new DibiDriverException('Connecting error.');
- }
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- $this->connection = NULL;
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- // must detect if SQL returns result set or num of affected rows
- $cmd = strtoupper(substr(ltrim($sql), 0, 6));
- $list = array('UPDATE'=>1, 'DELETE'=>1, 'INSERT'=>1, 'REPLAC'=>1);
-
- if (isset($list[$cmd])) {
- $this->resultSet = NULL;
- $this->affectedRows = $this->connection->exec($sql);
-
- if ($this->affectedRows === FALSE) {
- $this->throwException($sql);
- }
-
- return NULL;
-
- } else {
- $this->resultSet = $this->connection->query($sql);
- $this->affectedRows = FALSE;
-
- if ($this->resultSet === FALSE) {
- $this->throwException($sql);
- }
-
- return clone $this;
- }
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return $this->affectedRows;
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- return $this->connection->lastInsertId();
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- if (!$this->connection->beginTransaction()) {
- $this->throwException();
- }
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- if (!$this->connection->commit()) {
- $this->throwException();
- }
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- if (!$this->connection->rollBack()) {
- $this->throwException();
- }
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- return $this->connection->quote($value, PDO::PARAM_STR);
-
- case dibi::FIELD_BINARY:
- return $this->connection->quote($value, PDO::PARAM_LOB);
-
- case dibi::IDENTIFIER:
- switch ($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME)) {
- case 'mysql':
- return '`' . str_replace('.', '`.`', $value) . '`';
-
- case 'pgsql':
- $a = strrpos($value, '.');
- if ($a === FALSE) {
- return '"' . str_replace('"', '""', $value) . '"';
- } else {
- return substr($value, 0, $a) . '."' . str_replace('"', '""', substr($value, $a + 1)) . '"';
- }
-
- case 'sqlite':
- case 'sqlite2':
- case 'odbc':
- case 'oci': // TODO: not tested
- case 'mssql':
- return '[' . str_replace('.', '].[', $value) . ']';
-
- default:
- return $value;
- }
-
- case dibi::FIELD_BOOL:
- return $this->connection->quote($value, PDO::PARAM_BOOL);
-
- case dibi::FIELD_DATE:
- return date("'Y-m-d'", $value);
-
- case dibi::FIELD_DATETIME:
- return date("'Y-m-d H:i:s'", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- throw new NotSupportedException('PDO does not support applying limit or offset.');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- throw new DibiDriverException('Row count is not available for unbuffered queries.');
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return $this->resultSet->fetch($type ? PDO::FETCH_ASSOC : PDO::FETCH_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- throw new DibiDriverException('Cannot seek an unbuffered result set.');
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- * @throws DibiException
- */
- public function getColumnsMeta()
- {
- $count = $this->resultSet->columnCount();
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $info = @$this->resultSet->getColumnsMeta($i); // intentionally @
- if ($info === FALSE) {
- throw new DibiDriverException('Driver does not support meta data.');
- }
- $meta[] = $info;
- }
- return $meta;
- }
-
-
-
- /**
- * Converts database error to DibiDriverException.
- *
- * @throws DibiDriverException
- */
- protected function throwException($sql = NULL)
- {
- $err = $this->connection->errorInfo();
- throw new DibiDriverException("SQLSTATE[$err[0]]: $err[2]", $err[1], $sql);
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return PDO
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return PDOStatement
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = $config['pdo'];
+
+ } else try {
+ $this->connection = new PDO($config['dsn'], $config['username'], $config['password'], $config['options']);
+
+ } catch (PDOException $e) {
+ throw new DibiDriverException($e->getMessage(), $e->getCode());
+ }
+
+ if (!$this->connection) {
+ throw new DibiDriverException('Connecting error.');
+ }
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ $this->connection = NULL;
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ // must detect if SQL returns result set or num of affected rows
+ $cmd = strtoupper(substr(ltrim($sql), 0, 6));
+ $list = array('UPDATE'=>1, 'DELETE'=>1, 'INSERT'=>1, 'REPLAC'=>1);
+
+ if (isset($list[$cmd])) {
+ $this->resultSet = NULL;
+ $this->affectedRows = $this->connection->exec($sql);
+
+ if ($this->affectedRows === FALSE) {
+ $this->throwException($sql);
+ }
+
+ return NULL;
+
+ } else {
+ $this->resultSet = $this->connection->query($sql);
+ $this->affectedRows = FALSE;
+
+ if ($this->resultSet === FALSE) {
+ $this->throwException($sql);
+ }
+
+ return clone $this;
+ }
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return $this->affectedRows;
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ return $this->connection->lastInsertId();
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ if (!$this->connection->beginTransaction()) {
+ $this->throwException();
+ }
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ if (!$this->connection->commit()) {
+ $this->throwException();
+ }
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ if (!$this->connection->rollBack()) {
+ $this->throwException();
+ }
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ return $this->connection->quote($value, PDO::PARAM_STR);
+
+ case dibi::FIELD_BINARY:
+ return $this->connection->quote($value, PDO::PARAM_LOB);
+
+ case dibi::IDENTIFIER:
+ switch ($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME)) {
+ case 'mysql':
+ return '`' . str_replace('.', '`.`', $value) . '`';
+
+ case 'pgsql':
+ $a = strrpos($value, '.');
+ if ($a === FALSE) {
+ return '"' . str_replace('"', '""', $value) . '"';
+ } else {
+ return substr($value, 0, $a) . '."' . str_replace('"', '""', substr($value, $a + 1)) . '"';
+ }
+
+ case 'sqlite':
+ case 'sqlite2':
+ case 'odbc':
+ case 'oci': // TODO: not tested
+ case 'mssql':
+ return '[' . str_replace('.', '].[', $value) . ']';
+
+ default:
+ return $value;
+ }
+
+ case dibi::FIELD_BOOL:
+ return $this->connection->quote($value, PDO::PARAM_BOOL);
+
+ case dibi::FIELD_DATE:
+ return date("'Y-m-d'", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("'Y-m-d H:i:s'", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ throw new NotSupportedException('PDO does not support applying limit or offset.');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ throw new DibiDriverException('Row count is not available for unbuffered queries.');
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return $this->resultSet->fetch($type ? PDO::FETCH_ASSOC : PDO::FETCH_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ throw new DibiDriverException('Cannot seek an unbuffered result set.');
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ * @throws DibiException
+ */
+ public function getColumnsMeta()
+ {
+ $count = $this->resultSet->columnCount();
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $info = @$this->resultSet->getColumnsMeta($i); // intentionally @
+ if ($info === FALSE) {
+ throw new DibiDriverException('Driver does not support meta data.');
+ }
+ $meta[] = $info;
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Converts database error to DibiDriverException.
+ *
+ * @throws DibiDriverException
+ */
+ protected function throwException($sql = NULL)
+ {
+ $err = $this->connection->errorInfo();
+ throw new DibiDriverException("SQLSTATE[$err[0]]: $err[2]", $err[1], $sql);
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return PDO
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return PDOStatement
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/postgre.php b/dibi/drivers/postgre.php
index 42212b37..e19c7bf4 100644
--- a/dibi/drivers/postgre.php
+++ b/dibi/drivers/postgre.php
@@ -1,426 +1,426 @@
-connection = pg_connect($string, PGSQL_CONNECT_FORCE_NEW);
- } else {
- $this->connection = pg_pconnect($string, PGSQL_CONNECT_FORCE_NEW);
- }
- if (DibiDriverException::catchError($msg)) {
- throw new DibiDriverException($msg, 0);
- }
-
- if (!is_resource($this->connection)) {
- throw new DibiDriverException('Connecting error.');
- }
-
- if (isset($config['charset'])) {
- DibiDriverException::tryError();
- pg_set_client_encoding($this->connection, $config['charset']);
- if (DibiDriverException::catchError($msg)) {
- throw new DibiDriverException($msg, 0);
- }
- }
-
- if (isset($config['schema'])) {
- $this->query('SET search_path TO ' . $config['schema']);
- }
-
- $this->escMethod = version_compare(PHP_VERSION , '5.2.0', '>=');
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- pg_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @param bool update affected rows?
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- $this->resultSet = @pg_query($this->connection, $sql); // intentionally @
-
- if ($this->resultSet === FALSE) {
- throw new DibiDriverException(pg_last_error($this->connection), 0, $sql);
- }
-
- return is_resource($this->resultSet) && pg_num_fields($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return pg_affected_rows($this->resultSet);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- if ($sequence === NULL) {
- // PostgreSQL 8.1 is needed
- $has = $this->query("SELECT LASTVAL()");
- } else {
- $has = $this->query("SELECT CURRVAL('$sequence')");
- }
-
- if (!$has) return FALSE;
-
- $row = $this->fetch(FALSE);
- $this->free();
- return is_array($row) ? $row[0] : FALSE;
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->query('START TRANSACTION');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- $this->query('COMMIT');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- $this->query('ROLLBACK');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- if ($this->escMethod) {
- return "'" . pg_escape_string($this->connection, $value) . "'";
- } else {
- return "'" . pg_escape_string($value) . "'";
- }
-
- case dibi::FIELD_BINARY:
- if ($this->escMethod) {
- return "'" . pg_escape_bytea($this->connection, $value) . "'";
- } else {
- return "'" . pg_escape_bytea($value) . "'";
- }
-
- case dibi::IDENTIFIER:
- $a = strrpos($value, '.');
- if ($a === FALSE) {
- return '"' . str_replace('"', '""', $value) . '"';
- } else {
- // table.col delimite as table."col"
- return substr($value, 0, $a) . '."' . str_replace('"', '""', substr($value, $a + 1)) . '"';
- }
-
- case dibi::FIELD_BOOL:
- return $value ? 'TRUE' : 'FALSE';
-
- case dibi::FIELD_DATE:
- return date("'Y-m-d'", $value);
-
- case dibi::FIELD_DATETIME:
- return date("'Y-m-d H:i:s'", $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_BINARY:
- return pg_unescape_bytea($value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- if ($limit >= 0)
- $sql .= ' LIMIT ' . (int) $limit;
-
- if ($offset > 0)
- $sql .= ' OFFSET ' . (int) $offset;
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- return pg_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return pg_fetch_array($this->resultSet, NULL, $type ? PGSQL_ASSOC : PGSQL_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- return pg_result_seek($this->resultSet, $row);
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- pg_free_result($this->resultSet);
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $hasTable = version_compare(PHP_VERSION , '5.2.0', '>=');
- $count = pg_num_fields($this->resultSet);
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = array(
- 'name' => pg_field_name($this->resultSet, $i),
- 'table' => $hasTable ? pg_field_table($this->resultSet, $i) : NULL,
- 'type' => pg_field_type($this->resultSet, $i),
- 'size' => pg_field_size($this->resultSet, $i),
- 'prtlen' => pg_field_prtlen($this->resultSet, $i),
- );
- }
- return $meta;
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+connection = pg_connect($string, PGSQL_CONNECT_FORCE_NEW);
+ } else {
+ $this->connection = pg_pconnect($string, PGSQL_CONNECT_FORCE_NEW);
+ }
+ if (DibiDriverException::catchError($msg)) {
+ throw new DibiDriverException($msg, 0);
+ }
+
+ if (!is_resource($this->connection)) {
+ throw new DibiDriverException('Connecting error.');
+ }
+
+ if (isset($config['charset'])) {
+ DibiDriverException::tryError();
+ pg_set_client_encoding($this->connection, $config['charset']);
+ if (DibiDriverException::catchError($msg)) {
+ throw new DibiDriverException($msg, 0);
+ }
+ }
+
+ if (isset($config['schema'])) {
+ $this->query('SET search_path TO ' . $config['schema']);
+ }
+
+ $this->escMethod = version_compare(PHP_VERSION , '5.2.0', '>=');
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ pg_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @param bool update affected rows?
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ $this->resultSet = @pg_query($this->connection, $sql); // intentionally @
+
+ if ($this->resultSet === FALSE) {
+ throw new DibiDriverException(pg_last_error($this->connection), 0, $sql);
+ }
+
+ return is_resource($this->resultSet) && pg_num_fields($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return pg_affected_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ if ($sequence === NULL) {
+ // PostgreSQL 8.1 is needed
+ $has = $this->query("SELECT LASTVAL()");
+ } else {
+ $has = $this->query("SELECT CURRVAL('$sequence')");
+ }
+
+ if (!$has) return FALSE;
+
+ $row = $this->fetch(FALSE);
+ $this->free();
+ return is_array($row) ? $row[0] : FALSE;
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->query('START TRANSACTION');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ $this->query('COMMIT');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ $this->query('ROLLBACK');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ if ($this->escMethod) {
+ return "'" . pg_escape_string($this->connection, $value) . "'";
+ } else {
+ return "'" . pg_escape_string($value) . "'";
+ }
+
+ case dibi::FIELD_BINARY:
+ if ($this->escMethod) {
+ return "'" . pg_escape_bytea($this->connection, $value) . "'";
+ } else {
+ return "'" . pg_escape_bytea($value) . "'";
+ }
+
+ case dibi::IDENTIFIER:
+ $a = strrpos($value, '.');
+ if ($a === FALSE) {
+ return '"' . str_replace('"', '""', $value) . '"';
+ } else {
+ // table.col delimite as table."col"
+ return substr($value, 0, $a) . '."' . str_replace('"', '""', substr($value, $a + 1)) . '"';
+ }
+
+ case dibi::FIELD_BOOL:
+ return $value ? 'TRUE' : 'FALSE';
+
+ case dibi::FIELD_DATE:
+ return date("'Y-m-d'", $value);
+
+ case dibi::FIELD_DATETIME:
+ return date("'Y-m-d H:i:s'", $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_BINARY:
+ return pg_unescape_bytea($value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ if ($limit >= 0)
+ $sql .= ' LIMIT ' . (int) $limit;
+
+ if ($offset > 0)
+ $sql .= ' OFFSET ' . (int) $offset;
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ return pg_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return pg_fetch_array($this->resultSet, NULL, $type ? PGSQL_ASSOC : PGSQL_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ return pg_result_seek($this->resultSet, $row);
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ pg_free_result($this->resultSet);
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $hasTable = version_compare(PHP_VERSION , '5.2.0', '>=');
+ $count = pg_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = array(
+ 'name' => pg_field_name($this->resultSet, $i),
+ 'table' => $hasTable ? pg_field_table($this->resultSet, $i) : NULL,
+ 'type' => pg_field_type($this->resultSet, $i),
+ 'size' => pg_field_size($this->resultSet, $i),
+ 'prtlen' => pg_field_prtlen($this->resultSet, $i),
+ );
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/drivers/sqlite.php b/dibi/drivers/sqlite.php
index f05e3bd9..de1cc3fb 100644
--- a/dibi/drivers/sqlite.php
+++ b/dibi/drivers/sqlite.php
@@ -1,381 +1,381 @@
-fmtDate = isset($config['format:date']) ? $config['format:date'] : 'U';
- $this->fmtDateTime = isset($config['format:datetime']) ? $config['format:datetime'] : 'U';
-
- $errorMsg = '';
- if (empty($config['persistent'])) {
- $this->connection = @sqlite_open($config['database'], 0666, $errorMsg); // intentionally @
- } else {
- $this->connection = @sqlite_popen($config['database'], 0666, $errorMsg); // intentionally @
- }
-
- if (!$this->connection) {
- throw new DibiDriverException($errorMsg);
- }
-
- $this->buffered = empty($config['unbuffered']);
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- public function disconnect()
- {
- sqlite_close($this->connection);
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return IDibiDriver|NULL
- * @throws DibiDriverException
- */
- public function query($sql)
- {
- DibiDriverException::tryError();
- if ($this->buffered) {
- $this->resultSet = sqlite_query($this->connection, $sql);
- } else {
- $this->resultSet = sqlite_unbuffered_query($this->connection, $sql);
- }
- if (DibiDriverException::catchError($msg)) {
- throw new DibiDriverException($msg, sqlite_last_error($this->connection), $sql);
- }
-
- return is_resource($this->resultSet) ? clone $this : NULL;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int|FALSE number of rows or FALSE on error
- */
- public function affectedRows()
- {
- return sqlite_changes($this->connection);
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @return int|FALSE int on success or FALSE on failure
- */
- public function insertId($sequence)
- {
- return sqlite_last_insert_rowid($this->connection);
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- * @throws DibiDriverException
- */
- public function begin()
- {
- $this->query('BEGIN');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function commit()
- {
- $this->query('COMMIT');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- * @throws DibiDriverException
- */
- public function rollback()
- {
- $this->query('ROLLBACK');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string value
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string encoded value
- * @throws InvalidArgumentException
- */
- public function escape($value, $type)
- {
- switch ($type) {
- case dibi::FIELD_TEXT:
- case dibi::FIELD_BINARY:
- return "'" . sqlite_escape_string($value) . "'";
-
- case dibi::IDENTIFIER:
- return '[' . str_replace('.', '].[', $value) . ']';
-
- case dibi::FIELD_BOOL:
- return $value ? 1 : 0;
-
- case dibi::FIELD_DATE:
- return date($this->fmtDate, $value);
-
- case dibi::FIELD_DATETIME:
- return date($this->fmtDateTime, $value);
-
- default:
- throw new InvalidArgumentException('Unsupported type.');
- }
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- * @throws InvalidArgumentException
- */
- public function unescape($value, $type)
- {
- throw new InvalidArgumentException('Unsupported type.');
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- if ($limit < 0 && $offset < 1) return;
- $sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- public function rowCount()
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Row count is not available for unbuffered queries.');
- }
- return sqlite_num_rows($this->resultSet);
- }
-
-
-
- /**
- * Fetches the row at current position and moves the internal cursor to the next position.
- * internal usage only
- *
- * @param bool TRUE for associative array, FALSE for numeric
- * @return array array on success, nonarray if no next record
- */
- public function fetch($type)
- {
- return sqlite_fetch_array($this->resultSet, $type ? SQLITE_ASSOC : SQLITE_NUM);
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- public function seek($row)
- {
- if (!$this->buffered) {
- throw new DibiDriverException('Cannot seek an unbuffered result set.');
- }
- return sqlite_seek($this->resultSet, $row);
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- public function free()
- {
- $this->resultSet = NULL;
- }
-
-
-
- /**
- * Returns metadata for all columns in a result set.
- *
- * @return array
- */
- public function getColumnsMeta()
- {
- $count = sqlite_num_fields($this->resultSet);
- $meta = array();
- for ($i = 0; $i < $count; $i++) {
- // items 'name' and 'table' are required
- $meta[] = array(
- 'name' => sqlite_field_name($this->resultSet, $i),
- 'table' => NULL,
- );
- }
- return $meta;
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return mixed
- */
- public function getResource()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- public function getResultResource()
- {
- return $this->resultSet;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- function getDibiReflection()
- {}
-
-}
+fmtDate = isset($config['format:date']) ? $config['format:date'] : 'U';
+ $this->fmtDateTime = isset($config['format:datetime']) ? $config['format:datetime'] : 'U';
+
+ $errorMsg = '';
+ if (empty($config['persistent'])) {
+ $this->connection = @sqlite_open($config['database'], 0666, $errorMsg); // intentionally @
+ } else {
+ $this->connection = @sqlite_popen($config['database'], 0666, $errorMsg); // intentionally @
+ }
+
+ if (!$this->connection) {
+ throw new DibiDriverException($errorMsg);
+ }
+
+ $this->buffered = empty($config['unbuffered']);
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ public function disconnect()
+ {
+ sqlite_close($this->connection);
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return IDibiDriver|NULL
+ * @throws DibiDriverException
+ */
+ public function query($sql)
+ {
+ DibiDriverException::tryError();
+ if ($this->buffered) {
+ $this->resultSet = sqlite_query($this->connection, $sql);
+ } else {
+ $this->resultSet = sqlite_unbuffered_query($this->connection, $sql);
+ }
+ if (DibiDriverException::catchError($msg)) {
+ throw new DibiDriverException($msg, sqlite_last_error($this->connection), $sql);
+ }
+
+ return is_resource($this->resultSet) ? clone $this : NULL;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int|FALSE number of rows or FALSE on error
+ */
+ public function affectedRows()
+ {
+ return sqlite_changes($this->connection);
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @return int|FALSE int on success or FALSE on failure
+ */
+ public function insertId($sequence)
+ {
+ return sqlite_last_insert_rowid($this->connection);
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function begin()
+ {
+ $this->query('BEGIN');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function commit()
+ {
+ $this->query('COMMIT');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ * @throws DibiDriverException
+ */
+ public function rollback()
+ {
+ $this->query('ROLLBACK');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string encoded value
+ * @throws InvalidArgumentException
+ */
+ public function escape($value, $type)
+ {
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ case dibi::FIELD_BINARY:
+ return "'" . sqlite_escape_string($value) . "'";
+
+ case dibi::IDENTIFIER:
+ return '[' . str_replace('.', '].[', $value) . ']';
+
+ case dibi::FIELD_BOOL:
+ return $value ? 1 : 0;
+
+ case dibi::FIELD_DATE:
+ return date($this->fmtDate, $value);
+
+ case dibi::FIELD_DATETIME:
+ return date($this->fmtDateTime, $value);
+
+ default:
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ * @throws InvalidArgumentException
+ */
+ public function unescape($value, $type)
+ {
+ throw new InvalidArgumentException('Unsupported type.');
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ if ($limit < 0 && $offset < 1) return;
+ $sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Row count is not available for unbuffered queries.');
+ }
+ return sqlite_num_rows($this->resultSet);
+ }
+
+
+
+ /**
+ * Fetches the row at current position and moves the internal cursor to the next position.
+ * internal usage only
+ *
+ * @param bool TRUE for associative array, FALSE for numeric
+ * @return array array on success, nonarray if no next record
+ */
+ public function fetch($type)
+ {
+ return sqlite_fetch_array($this->resultSet, $type ? SQLITE_ASSOC : SQLITE_NUM);
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ public function seek($row)
+ {
+ if (!$this->buffered) {
+ throw new DibiDriverException('Cannot seek an unbuffered result set.');
+ }
+ return sqlite_seek($this->resultSet, $row);
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function free()
+ {
+ $this->resultSet = NULL;
+ }
+
+
+
+ /**
+ * Returns metadata for all columns in a result set.
+ *
+ * @return array
+ */
+ public function getColumnsMeta()
+ {
+ $count = sqlite_num_fields($this->resultSet);
+ $meta = array();
+ for ($i = 0; $i < $count; $i++) {
+ // items 'name' and 'table' are required
+ $meta[] = array(
+ 'name' => sqlite_field_name($this->resultSet, $i),
+ 'table' => NULL,
+ );
+ }
+ return $meta;
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return mixed
+ */
+ public function getResource()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ public function getResultResource()
+ {
+ return $this->resultSet;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ function getDibiReflection()
+ {}
+
+}
diff --git a/dibi/libs/DibiConnection.php b/dibi/libs/DibiConnection.php
index 1368f5c0..4784189f 100644
--- a/dibi/libs/DibiConnection.php
+++ b/dibi/libs/DibiConnection.php
@@ -1,497 +1,501 @@
-config = $config;
- $this->driver = new $class;
-
- if (empty($config['lazy'])) {
- $this->connect();
- }
- }
-
-
-
- /**
- * Automatically frees the resources allocated for this result set.
- *
- * @return void
- */
- public function __destruct()
- {
- // disconnects and rolls back transaction - do not rely on auto-disconnect and rollback!
- $this->disconnect();
- }
-
-
-
- /**
- * Connects to a database.
- *
- * @return void
- */
- final protected function connect()
- {
- if (!$this->connected) {
- $this->driver->connect($this->config);
- $this->connected = TRUE;
- dibi::notify($this, 'connected');
- }
- }
-
-
-
- /**
- * Disconnects from a database.
- *
- * @return void
- */
- final public function disconnect()
- {
- if ($this->connected) {
- if ($this->inTxn) {
- $this->rollback();
- }
- $this->driver->disconnect();
- $this->connected = FALSE;
- dibi::notify($this, 'disconnected');
- }
- }
-
-
-
- /**
- * Returns TRUE when connection was established.
- *
- * @return bool
- */
- final public function isConnected()
- {
- return $this->connected;
- }
-
-
-
- /**
- * Returns configuration variable. If no $key is passed, returns the entire array.
- *
- * @see self::__construct
- * @param string
- * @param mixed default value to use if key not found
- * @return mixed
- */
- final public function getConfig($key = NULL, $default = NULL)
- {
- if ($key === NULL) {
- return $this->config;
-
- } elseif (isset($this->config[$key])) {
- return $this->config[$key];
-
- } else {
- return $default;
- }
- }
-
-
-
- /**
- * Apply configuration alias or default values.
- *
- * @param array connect configuration
- * @param string key
- * @param string alias key
- * @return void
- */
- public static function alias(&$config, $key, $alias=NULL)
- {
- if (isset($config[$key])) return;
-
- if ($alias !== NULL && isset($config[$alias])) {
- $config[$key] = $config[$alias];
- unset($config[$alias]);
- } else {
- $config[$key] = NULL;
- }
- }
-
-
-
- /**
- * Returns the connection resource.
- *
- * @return resource
- */
- final public function getResource()
- {
- return $this->driver->getResource();
- }
-
-
-
- /**
- * Generates (translates) and executes SQL query.
- *
- * @param array|mixed one or more arguments
- * @return DibiResult|NULL result set object (if any)
- * @throws DibiException
- */
- final public function query($args)
- {
- $args = func_get_args();
- $this->connect();
- $trans = new DibiTranslator($this->driver);
- if ($trans->translate($args)) {
- return $this->nativeQuery($trans->sql);
- } else {
- throw new DibiException('SQL translate error: ' . $trans->sql);
- }
- }
-
-
-
- /**
- * Generates and prints SQL query.
- *
- * @param array|mixed one or more arguments
- * @return bool
- */
- final public function test($args)
- {
- $args = func_get_args();
- $this->connect();
- $trans = new DibiTranslator($this->driver);
- $ok = $trans->translate($args);
- dibi::dump($trans->sql);
- return $ok;
- }
-
-
-
- /**
- * Executes the SQL query.
- *
- * @param string SQL statement.
- * @return DibiResult|NULL result set object (if any)
- * @throws DibiException
- */
- final public function nativeQuery($sql)
- {
- $this->connect();
-
- dibi::$numOfQueries++;
- dibi::$sql = $sql;
- dibi::$elapsedTime = FALSE;
- $time = -microtime(TRUE);
- dibi::notify($this, 'beforeQuery', $sql);
-
- if ($res = $this->driver->query($sql)) { // intentionally =
- $res = new DibiResult($res, $this->config);
- }
-
- $time += microtime(TRUE);
- dibi::$elapsedTime = $time;
- dibi::$totalTime += $time;
- dibi::notify($this, 'afterQuery', $res);
-
- return $res;
- }
-
-
-
- /**
- * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
- *
- * @return int number of rows
- * @throws DibiException
- */
- public function affectedRows()
- {
- $rows = $this->driver->affectedRows();
- if (!is_int($rows) || $rows < 0) throw new DibiException('Cannot retrieve number of affected rows.');
- return $rows;
- }
-
-
-
- /**
- * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
- *
- * @param string optional sequence name
- * @return int
- * @throws DibiException
- */
- public function insertId($sequence = NULL)
- {
- $id = $this->driver->insertId($sequence);
- if ($id < 1) throw new DibiException('Cannot retrieve last generated ID.');
- return (int) $id;
- }
-
-
-
- /**
- * Begins a transaction (if supported).
- * @return void
- */
- public function begin()
- {
- $this->connect();
- if ($this->inTxn) {
- throw new DibiException('There is already an active transaction.');
- }
- $this->driver->begin();
- $this->inTxn = TRUE;
- dibi::notify($this, 'begin');
- }
-
-
-
- /**
- * Commits statements in a transaction.
- * @return void
- */
- public function commit()
- {
- if (!$this->inTxn) {
- throw new DibiException('There is no active transaction.');
- }
- $this->driver->commit();
- $this->inTxn = FALSE;
- dibi::notify($this, 'commit');
- }
-
-
-
- /**
- * Rollback changes in a transaction.
- * @return void
- */
- public function rollback()
- {
- if (!$this->inTxn) {
- throw new DibiException('There is no active transaction.');
- }
- $this->driver->rollback();
- $this->inTxn = FALSE;
- dibi::notify($this, 'rollback');
- }
-
-
-
- /**
- * Encodes data for use in an SQL statement.
- *
- * @param string unescaped string
- * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
- * @return string escaped and quoted string
- */
- public function escape($value, $type = dibi::FIELD_TEXT)
- {
- $this->connect(); // MySQL & PDO require connection
- return $this->driver->escape($value, $type);
- }
-
-
-
- /**
- * Decodes data from result set.
- *
- * @param string value
- * @param string type (dibi::FIELD_BINARY)
- * @return string decoded value
- */
- public function unescape($value, $type = dibi::FIELD_BINARY)
- {
- return $this->driver->unescape($value, $type);
- }
-
-
-
- /**
- * Delimites identifier (table's or column's name, etc.).
- *
- * @param string identifier
- * @return string delimited identifier
- */
- public function delimite($value)
- {
- return $this->driver->escape($value, dibi::IDENTIFIER);
- }
-
-
-
- /**
- * Injects LIMIT/OFFSET to the SQL query.
- *
- * @param string &$sql The SQL query that will be modified.
- * @param int $limit
- * @param int $offset
- * @return void
- */
- public function applyLimit(&$sql, $limit, $offset)
- {
- $this->driver->applyLimit($sql, $limit, $offset);
- }
-
-
-
- /**
- * Import SQL dump from file - extreme fast!
- *
- * @param string filename
- * @return int count of sql commands
- */
- public function loadFile($file)
- {
- $this->connect();
-
- @set_time_limit(0); // intentionally @
-
- $handle = @fopen($file, 'r'); // intentionally @
- if (!$handle) {
- throw new FileNotFoundException("Cannot open file '$file'.");
- }
-
- $count = 0;
- $sql = '';
- while (!feof($handle)) {
- $s = fgets($handle);
- $sql .= $s;
- if (substr(rtrim($s), -1) === ';') {
- $this->driver->query($sql);
- $sql = '';
- $count++;
- }
- }
- fclose($handle);
- return $count;
- }
-
-
-
- /**
- * Gets a information of the current database.
- *
- * @return DibiReflection
- */
- public function getDibiReflection()
- {
- throw new NotImplementedException;
- }
-
-
-
- /**
- * Prevents unserialization.
- */
- public function __wakeup()
- {
- throw new NotSupportedException('You cannot serialize or unserialize ' . $this->getClass() . ' instances.');
- }
-
-
-
- /**
- * Prevents serialization.
- */
- public function __sleep()
- {
- throw new NotSupportedException('You cannot serialize or unserialize ' . $this->getClass() . ' instances.');
- }
-
-}
+config = $config;
+ $this->driver = new $class;
+
+ if (empty($config['lazy'])) {
+ $this->connect();
+ }
+ }
+
+
+
+ /**
+ * Automatically frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function __destruct()
+ {
+ // disconnects and rolls back transaction - do not rely on auto-disconnect and rollback!
+ $this->disconnect();
+ }
+
+
+
+ /**
+ * Connects to a database.
+ *
+ * @return void
+ */
+ final protected function connect()
+ {
+ if (!$this->connected) {
+ $this->driver->connect($this->config);
+ $this->connected = TRUE;
+ dibi::notify($this, 'connected');
+ }
+ }
+
+
+
+ /**
+ * Disconnects from a database.
+ *
+ * @return void
+ */
+ final public function disconnect()
+ {
+ if ($this->connected) {
+ if ($this->inTxn) {
+ $this->rollback();
+ }
+ $this->driver->disconnect();
+ $this->connected = FALSE;
+ dibi::notify($this, 'disconnected');
+ }
+ }
+
+
+
+ /**
+ * Returns TRUE when connection was established.
+ *
+ * @return bool
+ */
+ final public function isConnected()
+ {
+ return $this->connected;
+ }
+
+
+
+ /**
+ * Returns configuration variable. If no $key is passed, returns the entire array.
+ *
+ * @see self::__construct
+ * @param string
+ * @param mixed default value to use if key not found
+ * @return mixed
+ */
+ final public function getConfig($key = NULL, $default = NULL)
+ {
+ if ($key === NULL) {
+ return $this->config;
+
+ } elseif (isset($this->config[$key])) {
+ return $this->config[$key];
+
+ } else {
+ return $default;
+ }
+ }
+
+
+
+ /**
+ * Apply configuration alias or default values.
+ *
+ * @param array connect configuration
+ * @param string key
+ * @param string alias key
+ * @return void
+ */
+ public static function alias(&$config, $key, $alias=NULL)
+ {
+ if (isset($config[$key])) return;
+
+ if ($alias !== NULL && isset($config[$alias])) {
+ $config[$key] = $config[$alias];
+ unset($config[$alias]);
+ } else {
+ $config[$key] = NULL;
+ }
+ }
+
+
+
+ /**
+ * Returns the connection resource.
+ *
+ * @return resource
+ */
+ final public function getResource()
+ {
+ return $this->driver->getResource();
+ }
+
+
+
+ /**
+ * Generates (translates) and executes SQL query.
+ *
+ * @param array|mixed one or more arguments
+ * @return DibiResult|NULL result set object (if any)
+ * @throws DibiException
+ */
+ final public function query($args)
+ {
+ $args = func_get_args();
+ $this->connect();
+ $trans = new DibiTranslator($this->driver);
+ if ($trans->translate($args)) {
+ return $this->nativeQuery($trans->sql);
+ } else {
+ throw new DibiException('SQL translate error: ' . $trans->sql);
+ }
+ }
+
+
+
+ /**
+ * Generates and prints SQL query.
+ *
+ * @param array|mixed one or more arguments
+ * @return bool
+ */
+ final public function test($args)
+ {
+ $args = func_get_args();
+ $this->connect();
+ $trans = new DibiTranslator($this->driver);
+ $ok = $trans->translate($args);
+ dibi::dump($trans->sql);
+ return $ok;
+ }
+
+
+
+ /**
+ * Executes the SQL query.
+ *
+ * @param string SQL statement.
+ * @return DibiResult|NULL result set object (if any)
+ * @throws DibiException
+ */
+ final public function nativeQuery($sql)
+ {
+ $this->connect();
+
+ dibi::$numOfQueries++;
+ dibi::$sql = $sql;
+ dibi::$elapsedTime = FALSE;
+ $time = -microtime(TRUE);
+ dibi::notify($this, 'beforeQuery', $sql);
+
+ if ($res = $this->driver->query($sql)) { // intentionally =
+ $res = new DibiResult($res, $this->config);
+ }
+
+ $time += microtime(TRUE);
+ dibi::$elapsedTime = $time;
+ dibi::$totalTime += $time;
+ dibi::notify($this, 'afterQuery', $res);
+
+ return $res;
+ }
+
+
+
+ /**
+ * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
+ *
+ * @return int number of rows
+ * @throws DibiException
+ */
+ public function affectedRows()
+ {
+ $rows = $this->driver->affectedRows();
+ if (!is_int($rows) || $rows < 0) throw new DibiException('Cannot retrieve number of affected rows.');
+ return $rows;
+ }
+
+
+
+ /**
+ * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
+ *
+ * @param string optional sequence name
+ * @return int
+ * @throws DibiException
+ */
+ public function insertId($sequence = NULL)
+ {
+ $id = $this->driver->insertId($sequence);
+ if ($id < 1) throw new DibiException('Cannot retrieve last generated ID.');
+ return (int) $id;
+ }
+
+
+
+ /**
+ * Begins a transaction (if supported).
+ * @return void
+ */
+ public function begin()
+ {
+ $this->connect();
+ if ($this->inTxn) {
+ throw new DibiException('There is already an active transaction.');
+ }
+ $this->driver->begin();
+ $this->inTxn = TRUE;
+ dibi::notify($this, 'begin');
+ }
+
+
+
+ /**
+ * Commits statements in a transaction.
+ * @return void
+ */
+ public function commit()
+ {
+ if (!$this->inTxn) {
+ throw new DibiException('There is no active transaction.');
+ }
+ $this->driver->commit();
+ $this->inTxn = FALSE;
+ dibi::notify($this, 'commit');
+ }
+
+
+
+ /**
+ * Rollback changes in a transaction.
+ * @return void
+ */
+ public function rollback()
+ {
+ if (!$this->inTxn) {
+ throw new DibiException('There is no active transaction.');
+ }
+ $this->driver->rollback();
+ $this->inTxn = FALSE;
+ dibi::notify($this, 'rollback');
+ }
+
+
+
+ /**
+ * Encodes data for use in an SQL statement.
+ *
+ * @param string unescaped string
+ * @param string type (dibi::FIELD_TEXT, dibi::FIELD_BOOL, ...)
+ * @return string escaped and quoted string
+ */
+ public function escape($value, $type = dibi::FIELD_TEXT)
+ {
+ $this->connect(); // MySQL & PDO require connection
+ return $this->driver->escape($value, $type);
+ }
+
+
+
+ /**
+ * Decodes data from result set.
+ *
+ * @param string value
+ * @param string type (dibi::FIELD_BINARY)
+ * @return string decoded value
+ */
+ public function unescape($value, $type = dibi::FIELD_BINARY)
+ {
+ return $this->driver->unescape($value, $type);
+ }
+
+
+
+ /**
+ * Delimites identifier (table's or column's name, etc.).
+ *
+ * @param string identifier
+ * @return string delimited identifier
+ */
+ public function delimite($value)
+ {
+ return $this->driver->escape($value, dibi::IDENTIFIER);
+ }
+
+
+
+ /**
+ * Injects LIMIT/OFFSET to the SQL query.
+ *
+ * @param string &$sql The SQL query that will be modified.
+ * @param int $limit
+ * @param int $offset
+ * @return void
+ */
+ public function applyLimit(&$sql, $limit, $offset)
+ {
+ $this->driver->applyLimit($sql, $limit, $offset);
+ }
+
+
+
+ /**
+ * Import SQL dump from file - extreme fast!
+ *
+ * @param string filename
+ * @return int count of sql commands
+ */
+ public function loadFile($file)
+ {
+ $this->connect();
+
+ @set_time_limit(0); // intentionally @
+
+ $handle = @fopen($file, 'r'); // intentionally @
+ if (!$handle) {
+ throw new FileNotFoundException("Cannot open file '$file'.");
+ }
+
+ $count = 0;
+ $sql = '';
+ while (!feof($handle)) {
+ $s = fgets($handle);
+ $sql .= $s;
+ if (substr(rtrim($s), -1) === ';') {
+ $this->driver->query($sql);
+ $sql = '';
+ $count++;
+ }
+ }
+ fclose($handle);
+ return $count;
+ }
+
+
+
+ /**
+ * Gets a information of the current database.
+ *
+ * @return DibiReflection
+ */
+ public function getDibiReflection()
+ {
+ throw new NotImplementedException;
+ }
+
+
+
+ /**
+ * Prevents unserialization.
+ */
+ public function __wakeup()
+ {
+ throw new NotSupportedException('You cannot serialize or unserialize ' . $this->getClass() . ' instances.');
+ }
+
+
+
+ /**
+ * Prevents serialization.
+ */
+ public function __sleep()
+ {
+ throw new NotSupportedException('You cannot serialize or unserialize ' . $this->getClass() . ' instances.');
+ }
+
+}
diff --git a/dibi/libs/DibiDataSource.php b/dibi/libs/DibiDataSource.php
index 70f385a5..afd68bbf 100644
--- a/dibi/libs/DibiDataSource.php
+++ b/dibi/libs/DibiDataSource.php
@@ -1,92 +1,92 @@
-sql = $sql;
- } else {
- // SQL command
- $this->sql = '(' . $sql . ') AS [source]';
- }
-
- $this->connection = $connection === NULL ? dibi::getConnection() : $connection;
- }
-
-
-
- /**
- * @param int offset
- * @param int limit
- * @param array columns
- * @return ArrayIterator
- */
- public function getIterator($offset = NULL, $limit = NULL, $cols = NULL)
- {
- return $this->connection->query('
- SELECT *
- FROM', $this->sql, '
- %ofs %lmt', $offset, $limit
- );
- }
-
-
-
- /**
- * @return int
- */
- public function count()
- {
- if ($this->count === NULL) {
- $this->count = $this->connection->query('
- SELECT COUNT(*) FROM', $this->sql
- )->fetchSingle();
- }
- return $this->count;
- }
-
-}
+sql = $sql;
+ } else {
+ // SQL command
+ $this->sql = '(' . $sql . ') AS [source]';
+ }
+
+ $this->connection = $connection === NULL ? dibi::getConnection() : $connection;
+ }
+
+
+
+ /**
+ * @param int offset
+ * @param int limit
+ * @param array columns
+ * @return ArrayIterator
+ */
+ public function getIterator($offset = NULL, $limit = NULL, $cols = NULL)
+ {
+ return $this->connection->query('
+ SELECT *
+ FROM', $this->sql, '
+ %ofs %lmt', $offset, $limit
+ );
+ }
+
+
+
+ /**
+ * @return int
+ */
+ public function count()
+ {
+ if ($this->count === NULL) {
+ $this->count = $this->connection->query('
+ SELECT COUNT(*) FROM', $this->sql
+ )->fetchSingle();
+ }
+ return $this->count;
+ }
+
+}
diff --git a/dibi/libs/DibiException.php b/dibi/libs/DibiException.php
index 18b077c8..6ef95fda 100644
--- a/dibi/libs/DibiException.php
+++ b/dibi/libs/DibiException.php
@@ -1,159 +1,158 @@
-sql = $sql;
- dibi::notify(NULL, 'exception', $this);
- }
-
-
-
- /**
- * @return string The SQL passed to the constructor
- */
- final public function getSql()
- {
- return $this->sql;
- }
-
-
-
- /**
- * @return string string represenation of exception with SQL command
- */
- public function __toString()
- {
- return parent::__toString() . ($this->sql ? "\nSQL: " . $this->sql : '');
- }
-
-
-
- /********************* interface Nette::IDebuggable ****************d*g**/
-
-
- /**
- * Returns custom panels.
- * @return array
- */
- public function getPanels()
- {
- $panels = array();
- if ($this->sql !== NULL) {
- $panels['SQL'] = array(
- 'expanded' => TRUE,
- 'content' => dibi::dump($this->sql, TRUE),
- );
- }
- return $panels;
- }
-
-
-
- /********************* error catching ****************d*g**/
-
-
-
- /**
- * Starts catching potential errors/warnings
- *
- * @return void
- */
- public static function tryError()
- {
- set_error_handler(array(__CLASS__, '_errorHandler'), E_ALL);
- self::$errorMsg = NULL;
- }
-
-
-
- /**
- * Returns catched error/warning message.
- *
- * @param string catched message
- * @return bool
- */
- public static function catchError(& $message)
- {
- restore_error_handler();
- $message = self::$errorMsg;
- self::$errorMsg = NULL;
- return $message !== NULL;
- }
-
-
-
- /**
- * Internal error handler. Do not call directly.
- */
- public static function _errorHandler($code, $message)
- {
- restore_error_handler();
-
- if (ini_get('html_errors')) {
- $message = strip_tags($message);
- $message = html_entity_decode($message);
- }
-
- self::$errorMsg = $message;
- }
-
+sql = $sql;
+ dibi::notify(NULL, 'exception', $this);
+ }
+
+
+
+ /**
+ * @return string The SQL passed to the constructor
+ */
+ final public function getSql()
+ {
+ return $this->sql;
+ }
+
+
+
+ /**
+ * @return string string represenation of exception with SQL command
+ */
+ public function __toString()
+ {
+ return parent::__toString() . ($this->sql ? "\nSQL: " . $this->sql : '');
+ }
+
+
+
+ /********************* interface Nette::IDebuggable ****************d*g**/
+
+
+ /**
+ * Returns custom panels.
+ * @return array
+ */
+ public function getPanels()
+ {
+ $panels = array();
+ if ($this->sql !== NULL) {
+ $panels['SQL'] = array(
+ 'expanded' => TRUE,
+ 'content' => dibi::dump($this->sql, TRUE),
+ );
+ }
+ return $panels;
+ }
+
+
+
+ /********************* error catching ****************d*g**/
+
+
+
+ /**
+ * Starts catching potential errors/warnings
+ *
+ * @return void
+ */
+ public static function tryError()
+ {
+ set_error_handler(array(__CLASS__, '_errorHandler'), E_ALL);
+ self::$errorMsg = NULL;
+ }
+
+
+
+ /**
+ * Returns catched error/warning message.
+ *
+ * @param string catched message
+ * @return bool
+ */
+ public static function catchError(& $message)
+ {
+ restore_error_handler();
+ $message = self::$errorMsg;
+ self::$errorMsg = NULL;
+ return $message !== NULL;
+ }
+
+
+
+ /**
+ * Internal error handler. Do not call directly.
+ */
+ public static function _errorHandler($code, $message)
+ {
+ restore_error_handler();
+
+ if (ini_get('html_errors')) {
+ $message = strip_tags($message);
+ $message = html_entity_decode($message);
+ }
+
+ self::$errorMsg = $message;
+ }
+
}
\ No newline at end of file
diff --git a/dibi/libs/DibiFluent.php b/dibi/libs/DibiFluent.php
index d18a4e2d..43beabc6 100644
--- a/dibi/libs/DibiFluent.php
+++ b/dibi/libs/DibiFluent.php
@@ -1,329 +1,329 @@
- array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'GROUP BY',
- 'HAVING', 'ORDER BY', 'LIMIT', 'OFFSET', '%end'),
- 'UPDATE' => array('UPDATE', 'SET', 'WHERE', 'ORDER BY', 'LIMIT', '%end'),
- 'INSERT' => array('INSERT', 'INTO', 'VALUES', 'SELECT', '%end'),
- 'DELETE' => array('DELETE', 'FROM', 'USING', 'WHERE', 'ORDER BY', 'LIMIT', '%end'),
- );
-
- /** @var array */
- public static $separators = array(
- 'SELECT' => ',',
- 'FROM' => FALSE,
- 'WHERE' => 'AND',
- 'GROUP BY' => ',',
- 'HAVING' => 'AND',
- 'ORDER BY' => ',',
- 'LIMIT' => FALSE,
- 'OFFSET' => FALSE,
- 'SET' => ',',
- 'VALUES' => ',',
- 'INTO' => FALSE,
- );
-
- /** @var DibiConnection */
- private $connection;
-
- /** @var string */
- private $command;
-
- /** @var array */
- private $clauses = array();
-
- /** @var array */
- private $flags = array();
-
- /** @var array */
- private $cursor;
-
-
-
- /**
- * @param DibiConnection
- */
- public function __construct(DibiConnection $connection)
- {
- $this->connection = $connection;
- }
-
-
-
- /**
- * Appends new argument to the clause.
- * @param string clause name
- * @param array arguments
- * @return DibiFluent provides a fluent interface
- */
- public function __call($clause, $args)
- {
- $clause = self::_clause($clause);
-
- // lazy initialization
- if ($this->command === NULL) {
- if (isset(self::$masks[$clause])) {
- $this->clauses = array_fill_keys(self::$masks[$clause], NULL);
- }
- $this->cursor = & $this->clauses[$clause];
- $this->cursor = array();
- $this->command = $clause;
- }
-
- // special types or argument
- if (count($args) === 1) {
- $arg = $args[0];
- // TODO: really ignore TRUE?
- if ($arg === TRUE) {
- $args = array();
-
- } elseif (is_string($arg) && preg_match('#^[a-z][a-z0-9_.]*$#i', $arg)) {
- $args = array('%n', $arg);
- }
- }
-
- if (array_key_exists($clause, $this->clauses)) {
- // append to clause
- $this->cursor = & $this->clauses[$clause];
-
- // TODO: really delete?
- if ($args === array(FALSE)) {
- $this->cursor = NULL;
- return $this;
- }
-
- if (isset(self::$separators[$clause])) {
- $sep = self::$separators[$clause];
- if ($sep === FALSE) {
- $this->cursor = array();
-
- } elseif (!empty($this->cursor)) {
- $this->cursor[] = $sep;
- }
- }
-
- } else {
- // append to currect flow
- if ($args === array(FALSE)) {
- return $this;
- }
-
- $this->cursor[] = $clause;
- }
-
- if ($this->cursor === NULL) {
- $this->cursor = array();
- }
-
- array_splice($this->cursor, count($this->cursor), 0, $args);
- return $this;
- }
-
-
-
- /**
- * Switch to a clause.
- * @param string clause name
- * @return DibiFluent provides a fluent interface
- */
- public function clause($clause, $remove = FALSE)
- {
- $this->cursor = & $this->clauses[self::_clause($clause)];
-
- if ($remove) {
- $this->cursor = NULL;
-
- } elseif ($this->cursor === NULL) {
- $this->cursor = array();
- }
-
- return $this;
- }
-
-
-
- /**
- * Change a SQL flag.
- * @param string flag name
- * @param bool value
- * @return DibiFluent provides a fluent interface
- */
- public function setFlag($flag, $value = TRUE)
- {
- $flag = strtoupper($flag);
- if ($value) {
- $this->flags[$flag] = TRUE;
- } else {
- unset($this->flags[$flag]);
- }
- return $this;
- }
-
-
-
- /**
- * Is a flag set?
- * @param string flag name
- * @return bool
- */
- final public function getFlag($flag, $value = TRUE)
- {
- return isset($this->flags[strtoupper($flag)]);
- }
-
-
-
- /**
- * Returns SQL command.
- * @return string
- */
- final public function getCommand()
- {
- return $this->command;
- }
-
-
-
- /**
- * Generates and executes SQL query.
- * @return DibiResult|NULL result set object (if any)
- * @throws DibiException
- */
- public function execute()
- {
- return $this->connection->query($this->_export());
- }
-
-
-
- /**
- * Generates, executes SQL query and fetches the single row.
- * @return array|FALSE array on success, FALSE if no next record
- * @throws DibiException
- */
- public function fetch()
- {
- if ($this->command === 'SELECT') {
- $this->clauses['LIMIT'] = array(1);
- }
- return $this->connection->query($this->_export())->fetch();
- }
-
-
-
- /**
- * Generates and prints SQL query or it's part.
- * @param string clause name
- * @return bool
- */
- public function test($clause = NULL)
- {
- return $this->connection->test($this->_export($clause));
- }
-
-
-
- /**
- * Generates parameters for DibiTranslator.
- * @param string clause name
- * @return array
- */
- protected function _export($clause = NULL)
- {
- if ($clause === NULL) {
- $data = $this->clauses;
-
- } else {
- $clause = self::_clause($clause);
- if (array_key_exists($clause, $this->clauses)) {
- $data = array($clause => $this->clauses[$clause]);
- } else {
- return array();
- }
- }
-
- $args = array();
- foreach ($data as $clause => $statement) {
- if ($statement !== NULL) {
- if ($clause[0] !== '%') {
- $args[] = $clause;
- if ($clause === $this->command) {
- $args[] = implode(' ', array_keys($this->flags));
- }
- }
- array_splice($args, count($args), 0, $statement);
- }
- }
- return $args;
- }
-
-
-
- /**
- * Format camelCase clause name to UPPER CASE.
- * @param string
- * @return string
- */
- private static function _clause($s)
- {
- if ($s === 'order' || $s === 'group') {
- $s .= 'By';
- trigger_error("Did you mean '$s'?", E_USER_NOTICE);
- }
- return strtoupper(preg_replace('#[A-Z]#', ' $0', $s));
-
- }
-
-
-
- /**
- * Returns (highlighted) SQL query.
- * @return string
- */
- final public function __toString()
- {
- ob_start();
- $this->test();
- return ob_get_clean();
- }
-
-}
-
-
-// PHP < 5.2 compatibility
-if (!function_exists('array_fill_keys')) {
- function array_fill_keys($keys, $value)
- {
- return array_combine($keys, array_fill(0, count($keys), $value));
- }
-}
+ array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'GROUP BY',
+ 'HAVING', 'ORDER BY', 'LIMIT', 'OFFSET', '%end'),
+ 'UPDATE' => array('UPDATE', 'SET', 'WHERE', 'ORDER BY', 'LIMIT', '%end'),
+ 'INSERT' => array('INSERT', 'INTO', 'VALUES', 'SELECT', '%end'),
+ 'DELETE' => array('DELETE', 'FROM', 'USING', 'WHERE', 'ORDER BY', 'LIMIT', '%end'),
+ );
+
+ /** @var array */
+ public static $separators = array(
+ 'SELECT' => ',',
+ 'FROM' => FALSE,
+ 'WHERE' => 'AND',
+ 'GROUP BY' => ',',
+ 'HAVING' => 'AND',
+ 'ORDER BY' => ',',
+ 'LIMIT' => FALSE,
+ 'OFFSET' => FALSE,
+ 'SET' => ',',
+ 'VALUES' => ',',
+ 'INTO' => FALSE,
+ );
+
+ /** @var DibiConnection */
+ private $connection;
+
+ /** @var string */
+ private $command;
+
+ /** @var array */
+ private $clauses = array();
+
+ /** @var array */
+ private $flags = array();
+
+ /** @var array */
+ private $cursor;
+
+
+
+ /**
+ * @param DibiConnection
+ */
+ public function __construct(DibiConnection $connection)
+ {
+ $this->connection = $connection;
+ }
+
+
+
+ /**
+ * Appends new argument to the clause.
+ * @param string clause name
+ * @param array arguments
+ * @return DibiFluent provides a fluent interface
+ */
+ public function __call($clause, $args)
+ {
+ $clause = self::_clause($clause);
+
+ // lazy initialization
+ if ($this->command === NULL) {
+ if (isset(self::$masks[$clause])) {
+ $this->clauses = array_fill_keys(self::$masks[$clause], NULL);
+ }
+ $this->cursor = & $this->clauses[$clause];
+ $this->cursor = array();
+ $this->command = $clause;
+ }
+
+ // special types or argument
+ if (count($args) === 1) {
+ $arg = $args[0];
+ // TODO: really ignore TRUE?
+ if ($arg === TRUE) {
+ $args = array();
+
+ } elseif (is_string($arg) && preg_match('#^[a-z][a-z0-9_.]*$#i', $arg)) {
+ $args = array('%n', $arg);
+ }
+ }
+
+ if (array_key_exists($clause, $this->clauses)) {
+ // append to clause
+ $this->cursor = & $this->clauses[$clause];
+
+ // TODO: really delete?
+ if ($args === array(FALSE)) {
+ $this->cursor = NULL;
+ return $this;
+ }
+
+ if (isset(self::$separators[$clause])) {
+ $sep = self::$separators[$clause];
+ if ($sep === FALSE) {
+ $this->cursor = array();
+
+ } elseif (!empty($this->cursor)) {
+ $this->cursor[] = $sep;
+ }
+ }
+
+ } else {
+ // append to currect flow
+ if ($args === array(FALSE)) {
+ return $this;
+ }
+
+ $this->cursor[] = $clause;
+ }
+
+ if ($this->cursor === NULL) {
+ $this->cursor = array();
+ }
+
+ array_splice($this->cursor, count($this->cursor), 0, $args);
+ return $this;
+ }
+
+
+
+ /**
+ * Switch to a clause.
+ * @param string clause name
+ * @return DibiFluent provides a fluent interface
+ */
+ public function clause($clause, $remove = FALSE)
+ {
+ $this->cursor = & $this->clauses[self::_clause($clause)];
+
+ if ($remove) {
+ $this->cursor = NULL;
+
+ } elseif ($this->cursor === NULL) {
+ $this->cursor = array();
+ }
+
+ return $this;
+ }
+
+
+
+ /**
+ * Change a SQL flag.
+ * @param string flag name
+ * @param bool value
+ * @return DibiFluent provides a fluent interface
+ */
+ public function setFlag($flag, $value = TRUE)
+ {
+ $flag = strtoupper($flag);
+ if ($value) {
+ $this->flags[$flag] = TRUE;
+ } else {
+ unset($this->flags[$flag]);
+ }
+ return $this;
+ }
+
+
+
+ /**
+ * Is a flag set?
+ * @param string flag name
+ * @return bool
+ */
+ final public function getFlag($flag, $value = TRUE)
+ {
+ return isset($this->flags[strtoupper($flag)]);
+ }
+
+
+
+ /**
+ * Returns SQL command.
+ * @return string
+ */
+ final public function getCommand()
+ {
+ return $this->command;
+ }
+
+
+
+ /**
+ * Generates and executes SQL query.
+ * @return DibiResult|NULL result set object (if any)
+ * @throws DibiException
+ */
+ public function execute()
+ {
+ return $this->connection->query($this->_export());
+ }
+
+
+
+ /**
+ * Generates, executes SQL query and fetches the single row.
+ * @return array|FALSE array on success, FALSE if no next record
+ * @throws DibiException
+ */
+ public function fetch()
+ {
+ if ($this->command === 'SELECT') {
+ $this->clauses['LIMIT'] = array(1);
+ }
+ return $this->connection->query($this->_export())->fetch();
+ }
+
+
+
+ /**
+ * Generates and prints SQL query or it's part.
+ * @param string clause name
+ * @return bool
+ */
+ public function test($clause = NULL)
+ {
+ return $this->connection->test($this->_export($clause));
+ }
+
+
+
+ /**
+ * Generates parameters for DibiTranslator.
+ * @param string clause name
+ * @return array
+ */
+ protected function _export($clause = NULL)
+ {
+ if ($clause === NULL) {
+ $data = $this->clauses;
+
+ } else {
+ $clause = self::_clause($clause);
+ if (array_key_exists($clause, $this->clauses)) {
+ $data = array($clause => $this->clauses[$clause]);
+ } else {
+ return array();
+ }
+ }
+
+ $args = array();
+ foreach ($data as $clause => $statement) {
+ if ($statement !== NULL) {
+ if ($clause[0] !== '%') {
+ $args[] = $clause;
+ if ($clause === $this->command) {
+ $args[] = implode(' ', array_keys($this->flags));
+ }
+ }
+ array_splice($args, count($args), 0, $statement);
+ }
+ }
+ return $args;
+ }
+
+
+
+ /**
+ * Format camelCase clause name to UPPER CASE.
+ * @param string
+ * @return string
+ */
+ private static function _clause($s)
+ {
+ if ($s === 'order' || $s === 'group') {
+ $s .= 'By';
+ trigger_error("Did you mean '$s'?", E_USER_NOTICE);
+ }
+ return strtoupper(preg_replace('#[A-Z]#', ' $0', $s));
+
+ }
+
+
+
+ /**
+ * Returns (highlighted) SQL query.
+ * @return string
+ */
+ final public function __toString()
+ {
+ ob_start();
+ $this->test();
+ return ob_get_clean();
+ }
+
+}
+
+
+// PHP < 5.2 compatibility
+if (!function_exists('array_fill_keys')) {
+ function array_fill_keys($keys, $value)
+ {
+ return array_combine($keys, array_fill(0, count($keys), $value));
+ }
+}
diff --git a/dibi/libs/DibiLogger.php b/dibi/libs/DibiLogger.php
index c864cb92..a72aa81b 100644
--- a/dibi/libs/DibiLogger.php
+++ b/dibi/libs/DibiLogger.php
@@ -1,106 +1,106 @@
-file = $file;
- }
-
-
-
- /**
- * Event handler (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback).
- *
- * @param DibiConnection
- * @param string event name
- * @param mixed
- * @return void
- */
- public function handler($connection, $event, $arg)
- {
- if ($event === 'afterQuery' && $this->logQueries) {
- $this->write(
- "OK: " . dibi::$sql
- . ($arg instanceof DibiResult ? ";\n-- rows: " . count($arg) : '')
- . "\n-- takes: " . sprintf('%0.3f', dibi::$elapsedTime * 1000) . ' ms'
- . "\n-- driver: " . $connection->getConfig('driver')
- . "\n-- " . date('Y-m-d H:i:s')
- . "\n\n"
- );
- return;
- }
-
- if ($event === 'exception' && $this->logErrors) {
- // $arg is DibiDriverException
- $message = $arg->getMessage();
- $code = $arg->getCode();
- if ($code) {
- $message = "[$code] $message";
- }
-
- $this->write(
- "ERROR: $message"
- . "\n-- SQL: " . dibi::$sql
- . "\n-- driver: " //. $connection->getConfig('driver')
- . ";\n-- " . date('Y-m-d H:i:s')
- . "\n\n"
- );
- return;
- }
- }
-
-
-
- private function write($message)
- {
- $handle = fopen($this->file, 'a');
- if (!$handle) return; // or throw exception?
-
- flock($handle, LOCK_EX);
- fwrite($handle, $message);
- fclose($handle);
- }
-
-}
+file = $file;
+ }
+
+
+
+ /**
+ * Event handler (events: exception, connected, beforeQuery, afterQuery, begin, commit, rollback).
+ *
+ * @param DibiConnection
+ * @param string event name
+ * @param mixed
+ * @return void
+ */
+ public function handler($connection, $event, $arg)
+ {
+ if ($event === 'afterQuery' && $this->logQueries) {
+ $this->write(
+ "OK: " . dibi::$sql
+ . ($arg instanceof DibiResult ? ";\n-- rows: " . count($arg) : '')
+ . "\n-- takes: " . sprintf('%0.3f', dibi::$elapsedTime * 1000) . ' ms'
+ . "\n-- driver: " . $connection->getConfig('driver')
+ . "\n-- " . date('Y-m-d H:i:s')
+ . "\n\n"
+ );
+ return;
+ }
+
+ if ($event === 'exception' && $this->logErrors) {
+ // $arg is DibiDriverException
+ $message = $arg->getMessage();
+ $code = $arg->getCode();
+ if ($code) {
+ $message = "[$code] $message";
+ }
+
+ $this->write(
+ "ERROR: $message"
+ . "\n-- SQL: " . dibi::$sql
+ . "\n-- driver: " //. $connection->getConfig('driver')
+ . ";\n-- " . date('Y-m-d H:i:s')
+ . "\n\n"
+ );
+ return;
+ }
+ }
+
+
+
+ private function write($message)
+ {
+ $handle = fopen($this->file, 'a');
+ if (!$handle) return; // or throw exception?
+
+ flock($handle, LOCK_EX);
+ fwrite($handle, $message);
+ fclose($handle);
+ }
+
+}
diff --git a/dibi/libs/DibiResult.php b/dibi/libs/DibiResult.php
index 1696712f..3d241fc8 100644
--- a/dibi/libs/DibiResult.php
+++ b/dibi/libs/DibiResult.php
@@ -1,661 +1,661 @@
-
- * $result = dibi::query('SELECT * FROM [table]');
- *
- * $row = $result->fetch();
- * $obj = $result->fetch(TRUE);
- * $value = $result->fetchSingle();
- * $table = $result->fetchAll();
- * $pairs = $result->fetchPairs();
- * $assoc = $result->fetchAssoc('id');
- * $assoc = $result->fetchAssoc('active,#,id');
- *
- * unset($result);
- *
- *
- * @author David Grudl
- * @copyright Copyright (c) 2005, 2008 David Grudl
- * @package dibi
- * @version $Revision$ $Date$
- */
-class DibiResult extends /*Nette::*/Object implements IDataSource
-{
- /**
- * IDibiDriver.
- * @var array
- */
- private $driver;
-
- /**
- * Translate table.
- * @var array
- */
- private $xlat;
-
- /**
- * Cache for $driver->getColumnsMeta().
- * @var array
- */
- private $metaCache;
-
- /**
- * Already fetched? Used for allowance for first seek(0).
- * @var bool
- */
- private $fetched = FALSE;
-
- /**
- * Qualifiy each column name with the table name?
- * @var array|FALSE
- */
- private $withTables = FALSE;
-
- /**
- * Fetch as objects or arrays?
- * @var mixed TRUE | FALSE | class name
- */
- private $objects = FALSE;
-
-
-
- /**
- * @param IDibiDriver
- * @param array
- */
- public function __construct($driver, $config)
- {
- $this->driver = $driver;
-
- if (!empty($config['result:withtables'])) {
- $this->setWithTables(TRUE);
- }
-
- if (isset($config['result:objects'])) {
- $this->setObjects($config['result:objects']);
- }
- }
-
-
-
- /**
- * Automatically frees the resources allocated for this result set.
- *
- * @return void
- */
- public function __destruct()
- {
- @$this->free(); // intentionally @
- }
-
-
-
- /**
- * Returns the result set resource.
- *
- * @return mixed
- */
- final public function getResource()
- {
- return $this->getDriver()->getResultResource();
- }
-
-
-
- /**
- * Moves cursor position without fetching row.
- *
- * @param int the 0-based cursor pos to seek to
- * @return boolean TRUE on success, FALSE if unable to seek to specified record
- * @throws DibiException
- */
- final public function seek($row)
- {
- return ($row !== 0 || $this->fetched) ? (bool) $this->getDriver()->seek($row) : TRUE;
- }
-
-
-
- /**
- * Returns the number of rows in a result set.
- *
- * @return int
- */
- final public function rowCount()
- {
- return $this->getDriver()->rowCount();
- }
-
-
-
- /**
- * Frees the resources allocated for this result set.
- *
- * @return void
- */
- final public function free()
- {
- if ($this->driver !== NULL) {
- $this->driver->free();
- $this->driver = NULL;
- }
- }
-
-
-
- /**
- * Qualifiy each column name with the table name?
- *
- * @param bool
- * @return void
- * @throws DibiException
- */
- final public function setWithTables($val)
- {
- if ($val) {
- if ($this->metaCache === NULL) {
- $this->metaCache = $this->getDriver()->getColumnsMeta();
- }
-
- $cols = array();
- foreach ($this->metaCache as $col) {
- // intentional ==
- $name = $col['table'] == '' ? $col['name'] : ($col['table'] . '.' . $col['name']);
- if (isset($cols[$name])) {
- $fix = 1;
- while (isset($cols[$name . '#' . $fix])) $fix++;
- $name .= '#' . $fix;
- }
- $cols[$name] = TRUE;
- }
- $this->withTables = array_keys($cols);
-
- } else {
- $this->withTables = FALSE;
- }
- }
-
-
-
- /**
- * Qualifiy each key with the table name?
- *
- * @return bool
- */
- final public function getWithTables()
- {
- return (bool) $this->withTables;
- }
-
-
-
- /**
- * Returns rows as arrays or objects?
- *
- * @param mixed TRUE | FALSE | class name
- * @return void
- */
- public function setObjects($type)
- {
- $this->objects = $type;
- }
-
-
-
- /**
- * Returns rows as arrays or objects?
- *
- * @return mixed TRUE | FALSE | class name
- */
- public function getObjects()
- {
- return $this->objects;
- }
-
-
-
- /**
- * Fetches the row at current position, process optional type conversion.
- * and moves the internal cursor to the next position
- *
- * @param mixed fetch as object? Overrides $this->setObjects()
- * @return array|FALSE array on success, FALSE if no next record
- */
- final public function fetch($objects = NULL)
- {
- if ($this->withTables === FALSE) {
- $row = $this->getDriver()->fetch(TRUE);
- if (!is_array($row)) return FALSE;
-
- } else {
- $row = $this->getDriver()->fetch(FALSE);
- if (!is_array($row)) return FALSE;
- $row = array_combine($this->withTables, $row);
- }
-
- $this->fetched = TRUE;
-
- // types-converting?
- if ($this->xlat !== NULL) {
- foreach ($this->xlat as $col => $type) {
- if (isset($row[$col])) {
- $row[$col] = $this->convert($row[$col], $type[0], $type[1]);
- }
- }
- }
-
- if ($objects === NULL) {
- $objects = $this->objects;
- }
-
- if ($objects) {
- if ($objects === TRUE) {
- $row = (object) $row;
- } else {
- $row = new $objects($row);
- }
- }
-
- return $row;
- }
-
-
-
- /**
- * Like fetch(), but returns only first field.
- *
- * @return mixed value on success, FALSE if no next record
- */
- final function fetchSingle()
- {
- $row = $this->getDriver()->fetch(TRUE);
- if (!is_array($row)) return FALSE;
- $this->fetched = TRUE;
- $value = reset($row);
-
- // types-converting?
- $key = key($row);
- if (isset($this->xlat[$key])) {
- $type = $this->xlat[$key];
- return $this->convert($value, $type[0], $type[1]);
- }
-
- return $value;
- }
-
-
-
- /**
- * Fetches all records from table.
- *
- * @param int offset
- * @param int limit
- * @param bool simplify one-column result set?
- * @return array
- */
- final function fetchAll($offset = NULL, $limit = NULL, $simplify = TRUE)
- {
- $limit = $limit === NULL ? -1 : (int) $limit;
- $this->seek((int) $offset);
- $row = $this->fetch();
- if (!$row) return array(); // empty result set
-
- $data = array();
- if ($simplify && !$this->objects && count($row) === 1) {
- // special case: one-column result set
- $key = key($row);
- do {
- if ($limit === 0) break;
- $limit--;
- $data[] = $row[$key];
- } while ($row = $this->fetch());
-
- } else {
- do {
- if ($limit === 0) break;
- $limit--;
- $data[] = $row;
- } while ($row = $this->fetch());
- }
-
- return $data;
- }
-
-
-
- /**
- * Fetches all records from table and returns associative tree.
- * Associative descriptor: assoc1,#,assoc2,=,assoc3,@
- * builds a tree: $data[assoc1][index][assoc2]['assoc3']->value = {record}
- *
- * @param string associative descriptor
- * @return array
- * @throws InvalidArgumentException
- */
- final function fetchAssoc($assoc)
- {
- $this->seek(0);
- $row = $this->fetch(FALSE);
- if (!$row) return array(); // empty result set
-
- $data = NULL;
- $assoc = explode(',', $assoc);
-
- // check columns
- foreach ($assoc as $as) {
- if ($as !== '#' && $as !== '=' && $as !== '@' && !array_key_exists($as, $row)) {
- throw new InvalidArgumentException("Unknown column '$as' in associative descriptor.");
- }
- }
-
- // strip leading = and @
- $assoc[] = '='; // gap
- $last = count($assoc) - 1;
- while ($assoc[$last] === '=' || $assoc[$last] === '@') {
- $leaf = $assoc[$last];
- unset($assoc[$last]);
- $last--;
-
- if ($last < 0) {
- $assoc[] = '#';
- break;
- }
- }
-
- // make associative tree
- do {
- $x = & $data;
-
- // iterative deepening
- foreach ($assoc as $i => $as) {
- if ($as === '#') { // indexed-array node
- $x = & $x[];
-
- } elseif ($as === '=') { // "record" node
- if ($x === NULL) {
- $x = $row;
- $x = & $x[ $assoc[$i+1] ];
- $x = NULL; // prepare child node
- } else {
- $x = & $x[ $assoc[$i+1] ];
- }
-
- } elseif ($as === '@') { // "object" node
- if ($x === NULL) {
- $x = (object) $row;
- $x = & $x->{$assoc[$i+1]};
- $x = NULL; // prepare child node
- } else {
- $x = & $x->{$assoc[$i+1]};
- }
-
-
- } else { // associative-array node
- $x = & $x[ $row[ $as ] ];
- }
- }
-
- if ($x === NULL) { // build leaf
- if ($leaf === '=') $x = $row; else $x = (object) $row;
- }
-
- } while ($row = $this->fetch(FALSE));
-
- unset($x);
- return $data;
- }
-
-
-
- /**
- * Fetches all records from table like $key => $value pairs.
- *
- * @param string associative key
- * @param string value
- * @return array
- * @throws InvalidArgumentException
- */
- final function fetchPairs($key = NULL, $value = NULL)
- {
- $this->seek(0);
- $row = $this->fetch(FALSE);
- if (!$row) return array(); // empty result set
-
- $data = array();
-
- if ($value === NULL) {
- if ($key !== NULL) {
- throw new InvalidArgumentException("Either none or both columns must be specified.");
- }
-
- if (count($row) < 2) {
- throw new UnexpectedValueException("Result must have at least two columns.");
- }
-
- // autodetect
- $tmp = array_keys($row);
- $key = $tmp[0];
- $value = $tmp[1];
-
- } else {
- if (!array_key_exists($value, $row)) {
- throw new InvalidArgumentException("Unknown value column '$value'.");
- }
-
- if ($key === NULL) { // indexed-array
- do {
- $data[] = $row[$value];
- } while ($row = $this->fetch(FALSE));
- return $data;
- }
-
- if (!array_key_exists($key, $row)) {
- throw new InvalidArgumentException("Unknown key column '$key'.");
- }
- }
-
- do {
- $data[ $row[$key] ] = $row[$value];
- } while ($row = $this->fetch(FALSE));
-
- return $data;
- }
-
-
-
- /**
- * Define column type.
- * @param string column
- * @param string type (use constant Dibi::FIELD_*)
- * @param string optional format
- * @return void
- */
- final public function setType($col, $type, $format = NULL)
- {
- $this->xlat[$col] = array($type, $format);
- }
-
-
-
- /**
- * Define multiple columns types (for internal usage).
- * @param array
- * @return void
- */
- final public function setTypes(array $types)
- {
- $this->xlat = $types;
- }
-
-
-
- /**
- * Returns column type.
- * @return array ($type, $format)
- */
- final public function getType($col)
- {
- return isset($this->xlat[$col]) ? $this->xlat[$col] : NULL;
- }
-
-
-
- /**
- * Converts value to specified type and format
- * @return array ($type, $format)
- */
- final public function convert($value, $type, $format = NULL)
- {
- if ($value === NULL || $value === FALSE) {
- return $value;
- }
-
- switch ($type) {
- case dibi::FIELD_TEXT:
- return (string) $value;
-
- case dibi::FIELD_BINARY:
- return $this->getDriver()->unescape($value, $type);
-
- case dibi::FIELD_INTEGER:
- return (int) $value;
-
- case dibi::FIELD_FLOAT:
- return (float) $value;
-
- case dibi::FIELD_DATE:
- case dibi::FIELD_DATETIME:
- $value = strtotime($value);
- return $format === NULL ? $value : date($format, $value);
-
- case dibi::FIELD_BOOL:
- return ((bool) $value) && $value !== 'f' && $value !== 'F';
-
- default:
- return $value;
- }
- }
-
-
-
- /**
- * Gets an array of meta informations about column.
- *
- * @return array
- */
- final public function getColumnsMeta()
- {
- if ($this->metaCache === NULL) {
- $this->metaCache = $this->getDriver()->getColumnsMeta();
- }
-
- $cols = array();
- foreach ($this->metaCache as $col) {
- $name = (!$this->withTables || $col['table'] === NULL) ? $col['name'] : ($col['table'] . '.' . $col['name']);
- $cols[$name] = $col;
- }
- return $cols;
- }
-
-
-
- /**
- * Displays complete result-set as HTML table for debug purposes.
- *
- * @return void
- */
- final public function dump()
- {
- $none = TRUE;
- foreach ($this as $i => $row) {
- if ($none) {
- echo "\n\n\n\t
\n";
- }
- }
-
-
-
- /**
- * Required by the IteratorAggregate interface.
- * @param int offset
- * @param int limit
- * @return ArrayIterator
- */
- final public function getIterator($offset = NULL, $limit = NULL)
- {
- return new ArrayIterator($this->fetchAll($offset, $limit, FALSE));
- }
-
-
-
- /**
- * Required by the Countable interface.
- * @return int
- */
- final public function count()
- {
- return $this->rowCount();
- }
-
-
-
- /**
- * Safe access to property $driver.
- *
- * @return IDibiDriver
- * @throws InvalidStateException
- */
- private function getDriver()
- {
- if ($this->driver === NULL) {
- throw new InvalidStateException('Resultset was released from memory.');
- }
-
- return $this->driver;
- }
-
-
-}
+
+ * $result = dibi::query('SELECT * FROM [table]');
+ *
+ * $row = $result->fetch();
+ * $obj = $result->fetch(TRUE);
+ * $value = $result->fetchSingle();
+ * $table = $result->fetchAll();
+ * $pairs = $result->fetchPairs();
+ * $assoc = $result->fetchAssoc('id');
+ * $assoc = $result->fetchAssoc('active,#,id');
+ *
+ * unset($result);
+ *
+ *
+ * @author David Grudl
+ * @copyright Copyright (c) 2005, 2008 David Grudl
+ * @package dibi
+ */
+class DibiResult extends /*Nette::*/Object implements IDataSource
+{
+ /**
+ * IDibiDriver.
+ * @var array
+ */
+ private $driver;
+
+ /**
+ * Translate table.
+ * @var array
+ */
+ private $xlat;
+
+ /**
+ * Cache for $driver->getColumnsMeta().
+ * @var array
+ */
+ private $metaCache;
+
+ /**
+ * Already fetched? Used for allowance for first seek(0).
+ * @var bool
+ */
+ private $fetched = FALSE;
+
+ /**
+ * Qualifiy each column name with the table name?
+ * @var array|FALSE
+ */
+ private $withTables = FALSE;
+
+ /**
+ * Fetch as objects or arrays?
+ * @var mixed TRUE | FALSE | class name
+ */
+ private $objects = FALSE;
+
+
+
+ /**
+ * @param IDibiDriver
+ * @param array
+ */
+ public function __construct($driver, $config)
+ {
+ $this->driver = $driver;
+
+ if (!empty($config['result:withtables'])) {
+ $this->setWithTables(TRUE);
+ }
+
+ if (isset($config['result:objects'])) {
+ $this->setObjects($config['result:objects']);
+ }
+ }
+
+
+
+ /**
+ * Automatically frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ public function __destruct()
+ {
+ @$this->free(); // intentionally @
+ }
+
+
+
+ /**
+ * Returns the result set resource.
+ *
+ * @return mixed
+ */
+ final public function getResource()
+ {
+ return $this->getDriver()->getResultResource();
+ }
+
+
+
+ /**
+ * Moves cursor position without fetching row.
+ *
+ * @param int the 0-based cursor pos to seek to
+ * @return boolean TRUE on success, FALSE if unable to seek to specified record
+ * @throws DibiException
+ */
+ final public function seek($row)
+ {
+ return ($row !== 0 || $this->fetched) ? (bool) $this->getDriver()->seek($row) : TRUE;
+ }
+
+
+
+ /**
+ * Returns the number of rows in a result set.
+ *
+ * @return int
+ */
+ final public function rowCount()
+ {
+ return $this->getDriver()->rowCount();
+ }
+
+
+
+ /**
+ * Frees the resources allocated for this result set.
+ *
+ * @return void
+ */
+ final public function free()
+ {
+ if ($this->driver !== NULL) {
+ $this->driver->free();
+ $this->driver = NULL;
+ }
+ }
+
+
+
+ /**
+ * Qualifiy each column name with the table name?
+ *
+ * @param bool
+ * @return void
+ * @throws DibiException
+ */
+ final public function setWithTables($val)
+ {
+ if ($val) {
+ if ($this->metaCache === NULL) {
+ $this->metaCache = $this->getDriver()->getColumnsMeta();
+ }
+
+ $cols = array();
+ foreach ($this->metaCache as $col) {
+ // intentional ==
+ $name = $col['table'] == '' ? $col['name'] : ($col['table'] . '.' . $col['name']);
+ if (isset($cols[$name])) {
+ $fix = 1;
+ while (isset($cols[$name . '#' . $fix])) $fix++;
+ $name .= '#' . $fix;
+ }
+ $cols[$name] = TRUE;
+ }
+ $this->withTables = array_keys($cols);
+
+ } else {
+ $this->withTables = FALSE;
+ }
+ }
+
+
+
+ /**
+ * Qualifiy each key with the table name?
+ *
+ * @return bool
+ */
+ final public function getWithTables()
+ {
+ return (bool) $this->withTables;
+ }
+
+
+
+ /**
+ * Returns rows as arrays or objects?
+ *
+ * @param mixed TRUE | FALSE | class name
+ * @return void
+ */
+ public function setObjects($type)
+ {
+ $this->objects = $type;
+ }
+
+
+
+ /**
+ * Returns rows as arrays or objects?
+ *
+ * @return mixed TRUE | FALSE | class name
+ */
+ public function getObjects()
+ {
+ return $this->objects;
+ }
+
+
+
+ /**
+ * Fetches the row at current position, process optional type conversion.
+ * and moves the internal cursor to the next position
+ *
+ * @param mixed fetch as object? Overrides $this->setObjects()
+ * @return array|FALSE array on success, FALSE if no next record
+ */
+ final public function fetch($objects = NULL)
+ {
+ if ($this->withTables === FALSE) {
+ $row = $this->getDriver()->fetch(TRUE);
+ if (!is_array($row)) return FALSE;
+
+ } else {
+ $row = $this->getDriver()->fetch(FALSE);
+ if (!is_array($row)) return FALSE;
+ $row = array_combine($this->withTables, $row);
+ }
+
+ $this->fetched = TRUE;
+
+ // types-converting?
+ if ($this->xlat !== NULL) {
+ foreach ($this->xlat as $col => $type) {
+ if (isset($row[$col])) {
+ $row[$col] = $this->convert($row[$col], $type[0], $type[1]);
+ }
+ }
+ }
+
+ if ($objects === NULL) {
+ $objects = $this->objects;
+ }
+
+ if ($objects) {
+ if ($objects === TRUE) {
+ $row = (object) $row;
+ } else {
+ $row = new $objects($row);
+ }
+ }
+
+ return $row;
+ }
+
+
+
+ /**
+ * Like fetch(), but returns only first field.
+ *
+ * @return mixed value on success, FALSE if no next record
+ */
+ final function fetchSingle()
+ {
+ $row = $this->getDriver()->fetch(TRUE);
+ if (!is_array($row)) return FALSE;
+ $this->fetched = TRUE;
+ $value = reset($row);
+
+ // types-converting?
+ $key = key($row);
+ if (isset($this->xlat[$key])) {
+ $type = $this->xlat[$key];
+ return $this->convert($value, $type[0], $type[1]);
+ }
+
+ return $value;
+ }
+
+
+
+ /**
+ * Fetches all records from table.
+ *
+ * @param int offset
+ * @param int limit
+ * @param bool simplify one-column result set?
+ * @return array
+ */
+ final function fetchAll($offset = NULL, $limit = NULL, $simplify = TRUE)
+ {
+ $limit = $limit === NULL ? -1 : (int) $limit;
+ $this->seek((int) $offset);
+ $row = $this->fetch();
+ if (!$row) return array(); // empty result set
+
+ $data = array();
+ if ($simplify && !$this->objects && count($row) === 1) {
+ // special case: one-column result set
+ $key = key($row);
+ do {
+ if ($limit === 0) break;
+ $limit--;
+ $data[] = $row[$key];
+ } while ($row = $this->fetch());
+
+ } else {
+ do {
+ if ($limit === 0) break;
+ $limit--;
+ $data[] = $row;
+ } while ($row = $this->fetch());
+ }
+
+ return $data;
+ }
+
+
+
+ /**
+ * Fetches all records from table and returns associative tree.
+ * Associative descriptor: assoc1,#,assoc2,=,assoc3,@
+ * builds a tree: $data[assoc1][index][assoc2]['assoc3']->value = {record}
+ *
+ * @param string associative descriptor
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ final function fetchAssoc($assoc)
+ {
+ $this->seek(0);
+ $row = $this->fetch(FALSE);
+ if (!$row) return array(); // empty result set
+
+ $data = NULL;
+ $assoc = explode(',', $assoc);
+
+ // check columns
+ foreach ($assoc as $as) {
+ if ($as !== '#' && $as !== '=' && $as !== '@' && !array_key_exists($as, $row)) {
+ throw new InvalidArgumentException("Unknown column '$as' in associative descriptor.");
+ }
+ }
+
+ // strip leading = and @
+ $assoc[] = '='; // gap
+ $last = count($assoc) - 1;
+ while ($assoc[$last] === '=' || $assoc[$last] === '@') {
+ $leaf = $assoc[$last];
+ unset($assoc[$last]);
+ $last--;
+
+ if ($last < 0) {
+ $assoc[] = '#';
+ break;
+ }
+ }
+
+ // make associative tree
+ do {
+ $x = & $data;
+
+ // iterative deepening
+ foreach ($assoc as $i => $as) {
+ if ($as === '#') { // indexed-array node
+ $x = & $x[];
+
+ } elseif ($as === '=') { // "record" node
+ if ($x === NULL) {
+ $x = $row;
+ $x = & $x[ $assoc[$i+1] ];
+ $x = NULL; // prepare child node
+ } else {
+ $x = & $x[ $assoc[$i+1] ];
+ }
+
+ } elseif ($as === '@') { // "object" node
+ if ($x === NULL) {
+ $x = (object) $row;
+ $x = & $x->{$assoc[$i+1]};
+ $x = NULL; // prepare child node
+ } else {
+ $x = & $x->{$assoc[$i+1]};
+ }
+
+
+ } else { // associative-array node
+ $x = & $x[ $row[ $as ] ];
+ }
+ }
+
+ if ($x === NULL) { // build leaf
+ if ($leaf === '=') $x = $row; else $x = (object) $row;
+ }
+
+ } while ($row = $this->fetch(FALSE));
+
+ unset($x);
+ return $data;
+ }
+
+
+
+ /**
+ * Fetches all records from table like $key => $value pairs.
+ *
+ * @param string associative key
+ * @param string value
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ final function fetchPairs($key = NULL, $value = NULL)
+ {
+ $this->seek(0);
+ $row = $this->fetch(FALSE);
+ if (!$row) return array(); // empty result set
+
+ $data = array();
+
+ if ($value === NULL) {
+ if ($key !== NULL) {
+ throw new InvalidArgumentException("Either none or both columns must be specified.");
+ }
+
+ if (count($row) < 2) {
+ throw new UnexpectedValueException("Result must have at least two columns.");
+ }
+
+ // autodetect
+ $tmp = array_keys($row);
+ $key = $tmp[0];
+ $value = $tmp[1];
+
+ } else {
+ if (!array_key_exists($value, $row)) {
+ throw new InvalidArgumentException("Unknown value column '$value'.");
+ }
+
+ if ($key === NULL) { // indexed-array
+ do {
+ $data[] = $row[$value];
+ } while ($row = $this->fetch(FALSE));
+ return $data;
+ }
+
+ if (!array_key_exists($key, $row)) {
+ throw new InvalidArgumentException("Unknown key column '$key'.");
+ }
+ }
+
+ do {
+ $data[ $row[$key] ] = $row[$value];
+ } while ($row = $this->fetch(FALSE));
+
+ return $data;
+ }
+
+
+
+ /**
+ * Define column type.
+ * @param string column
+ * @param string type (use constant Dibi::FIELD_*)
+ * @param string optional format
+ * @return void
+ */
+ final public function setType($col, $type, $format = NULL)
+ {
+ $this->xlat[$col] = array($type, $format);
+ }
+
+
+
+ /**
+ * Define multiple columns types (for internal usage).
+ * @param array
+ * @return void
+ */
+ final public function setTypes(array $types)
+ {
+ $this->xlat = $types;
+ }
+
+
+
+ /**
+ * Returns column type.
+ * @return array ($type, $format)
+ */
+ final public function getType($col)
+ {
+ return isset($this->xlat[$col]) ? $this->xlat[$col] : NULL;
+ }
+
+
+
+ /**
+ * Converts value to specified type and format
+ * @return array ($type, $format)
+ */
+ final public function convert($value, $type, $format = NULL)
+ {
+ if ($value === NULL || $value === FALSE) {
+ return $value;
+ }
+
+ switch ($type) {
+ case dibi::FIELD_TEXT:
+ return (string) $value;
+
+ case dibi::FIELD_BINARY:
+ return $this->getDriver()->unescape($value, $type);
+
+ case dibi::FIELD_INTEGER:
+ return (int) $value;
+
+ case dibi::FIELD_FLOAT:
+ return (float) $value;
+
+ case dibi::FIELD_DATE:
+ case dibi::FIELD_DATETIME:
+ $value = strtotime($value);
+ return $format === NULL ? $value : date($format, $value);
+
+ case dibi::FIELD_BOOL:
+ return ((bool) $value) && $value !== 'f' && $value !== 'F';
+
+ default:
+ return $value;
+ }
+ }
+
+
+
+ /**
+ * Gets an array of meta informations about column.
+ *
+ * @return array
+ */
+ final public function getColumnsMeta()
+ {
+ if ($this->metaCache === NULL) {
+ $this->metaCache = $this->getDriver()->getColumnsMeta();
+ }
+
+ $cols = array();
+ foreach ($this->metaCache as $col) {
+ $name = (!$this->withTables || $col['table'] === NULL) ? $col['name'] : ($col['table'] . '.' . $col['name']);
+ $cols[$name] = $col;
+ }
+ return $cols;
+ }
+
+
+
+ /**
+ * Displays complete result-set as HTML table for debug purposes.
+ *
+ * @return void
+ */
+ final public function dump()
+ {
+ $none = TRUE;
+ foreach ($this as $i => $row) {
+ if ($none) {
+ echo "\n\n\t\t \n\n\n";
- $none = FALSE;
- }
-
- echo "\t#row \n";
-
- foreach ($row as $col => $foo) {
- echo "\t\t" . htmlSpecialChars($col) . " \n";
- }
-
- echo "\t\n\t\t \n";
- }
-
- if ($none) {
- echo '", $i, " \n";
- foreach ($row as $col) {
- //if (is_object($col)) $col = $col->__toString();
- echo "\t\t", htmlSpecialChars($col), " \n";
- }
- echo "\t\n\n\t
\n";
+ }
+ }
+
+
+
+ /**
+ * Required by the IteratorAggregate interface.
+ * @param int offset
+ * @param int limit
+ * @return ArrayIterator
+ */
+ final public function getIterator($offset = NULL, $limit = NULL)
+ {
+ return new ArrayIterator($this->fetchAll($offset, $limit, FALSE));
+ }
+
+
+
+ /**
+ * Required by the Countable interface.
+ * @return int
+ */
+ final public function count()
+ {
+ return $this->rowCount();
+ }
+
+
+
+ /**
+ * Safe access to property $driver.
+ *
+ * @return IDibiDriver
+ * @throws InvalidStateException
+ */
+ private function getDriver()
+ {
+ if ($this->driver === NULL) {
+ throw new InvalidStateException('Resultset was released from memory.');
+ }
+
+ return $this->driver;
+ }
+
+
+}
diff --git a/dibi/libs/DibiTable.php b/dibi/libs/DibiTable.php
index eaee3fcd..fc116527 100644
--- a/dibi/libs/DibiTable.php
+++ b/dibi/libs/DibiTable.php
@@ -1,290 +1,290 @@
-connection = $connection === NULL ? dibi::getConnection() : $connection;
- $this->setup();
- }
-
-
-
- /**
- * Returns the table name.
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
-
-
- /**
- * Returns the primary key name.
- * @return string
- */
- public function getPrimary()
- {
- return $this->primary;
- }
-
-
-
- /**
- * Returns the dibi connection.
- * @return DibiConnection
- */
- public function getConnection()
- {
- return $this->connection;
- }
-
-
-
- /**
- * Setup object.
- * @return void
- */
- protected function setup()
- {
- // autodetect table name
- if ($this->name === NULL) {
- $name = $this->getClass();
- if (FALSE !== ($pos = strrpos($name, ':'))) {
- $name = substr($name, $pos + 1);
- }
- if (self::$lowerCase) {
- $name = strtolower($name);
- }
- $this->name = $name;
- }
-
- // autodetect primary key name
- if ($this->primary === NULL) {
- $this->primary = str_replace(
- array('%p', '%s'),
- array($this->name, trim($this->name, 's')), // the simplest inflector in the world :-))
- self::$primaryMask
- );
- }
- }
-
-
-
- /**
- * Inserts row into a table.
- * @param array|object
- * @return int new primary key
- */
- public function insert($data)
- {
- $this->connection->query(
- 'INSERT INTO %n', $this->name, '%v', $this->prepare($data)
- );
- return $this->connection->insertId();
- }
-
-
-
- /**
- * Updates rows in a table.
- * @param mixed primary key value(s)
- * @param array|object
- * @return int number of updated rows
- */
- public function update($where, $data)
- {
- $this->connection->query(
- 'UPDATE %n', $this->name,
- 'SET %a', $this->prepare($data),
- 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
- );
- return $this->connection->affectedRows();
- }
-
-
-
- /**
- * Deletes rows from a table by primary key.
- * @param mixed primary key value(s)
- * @return int number of deleted rows
- */
- public function delete($where)
- {
- $this->connection->query(
- 'DELETE FROM %n', $this->name,
- 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
- );
- return $this->connection->affectedRows();
- }
-
-
-
- /**
- * Finds rows by primary key.
- * @param mixed primary key value(s)
- * @return DibiResult
- */
- public function find($what)
- {
- if (!is_array($what)) {
- $what = func_get_args();
- }
- return $this->complete($this->connection->query(
- 'SELECT * FROM %n', $this->name,
- 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $what, ')'
- ));
- }
-
-
-
- /**
- * Selects all rows.
- * @param string column to order by
- * @return DibiResult
- */
- public function findAll($order = NULL)
- {
- if ($order === NULL) {
- return $this->complete($this->connection->query(
- 'SELECT * FROM %n', $this->name
- ));
- } else {
- $order = func_get_args();
- return $this->complete($this->connection->query(
- 'SELECT * FROM %n', $this->name,
- 'ORDER BY %n', $order
- ));
- }
- }
-
-
-
- /**
- * Fetches single row.
- * @param scalar|array primary key value
- * @return array|object row
- */
- public function fetch($conditions)
- {
- if (is_array($conditions)) {
- return $this->complete($this->connection->query(
- 'SELECT * FROM %n', $this->name,
- 'WHERE %and', $conditions
- ))->fetch();
- }
- return $this->complete($this->connection->query(
- 'SELECT * FROM %n', $this->name,
- 'WHERE %n=' . $this->primaryModifier, $this->primary, $conditions
- ))->fetch();
- }
-
-
-
- /**
- * Returns a blank row (not fetched from database).
- * @return array|object
- */
- public function createBlank()
- {
- $row = $this->blankRow;
- $row[$this->primary] = NULL;
-
- if ($class = $this->connection->getConfig('result:objects')) {
- if ($class === TRUE) {
- $row = (object) $row;
- } else {
- $row = new $class($row);
- }
- }
-
- return $row;
- }
-
-
-
- /**
- * User data pre-processing.
- * @param array|object
- * @return array
- */
- protected function prepare($data)
- {
- if (is_object($data)) {
- return (array) $data;
- } elseif (is_array($data)) {
- return $data;
- }
-
- throw new InvalidArgumentException('Dataset must be array or anonymous object.');
- }
-
-
-
- /**
- * User DibiResult post-processing.
- * @param DibiResult
- * @return DibiResult
- */
- protected function complete($res)
- {
- return $res;
- }
-
-}
+connection = $connection === NULL ? dibi::getConnection() : $connection;
+ $this->setup();
+ }
+
+
+
+ /**
+ * Returns the table name.
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+
+
+ /**
+ * Returns the primary key name.
+ * @return string
+ */
+ public function getPrimary()
+ {
+ return $this->primary;
+ }
+
+
+
+ /**
+ * Returns the dibi connection.
+ * @return DibiConnection
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+
+
+
+ /**
+ * Setup object.
+ * @return void
+ */
+ protected function setup()
+ {
+ // autodetect table name
+ if ($this->name === NULL) {
+ $name = $this->getClass();
+ if (FALSE !== ($pos = strrpos($name, ':'))) {
+ $name = substr($name, $pos + 1);
+ }
+ if (self::$lowerCase) {
+ $name = strtolower($name);
+ }
+ $this->name = $name;
+ }
+
+ // autodetect primary key name
+ if ($this->primary === NULL) {
+ $this->primary = str_replace(
+ array('%p', '%s'),
+ array($this->name, trim($this->name, 's')), // the simplest inflector in the world :-))
+ self::$primaryMask
+ );
+ }
+ }
+
+
+
+ /**
+ * Inserts row into a table.
+ * @param array|object
+ * @return int new primary key
+ */
+ public function insert($data)
+ {
+ $this->connection->query(
+ 'INSERT INTO %n', $this->name, '%v', $this->prepare($data)
+ );
+ return $this->connection->insertId();
+ }
+
+
+
+ /**
+ * Updates rows in a table.
+ * @param mixed primary key value(s)
+ * @param array|object
+ * @return int number of updated rows
+ */
+ public function update($where, $data)
+ {
+ $this->connection->query(
+ 'UPDATE %n', $this->name,
+ 'SET %a', $this->prepare($data),
+ 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
+ );
+ return $this->connection->affectedRows();
+ }
+
+
+
+ /**
+ * Deletes rows from a table by primary key.
+ * @param mixed primary key value(s)
+ * @return int number of deleted rows
+ */
+ public function delete($where)
+ {
+ $this->connection->query(
+ 'DELETE FROM %n', $this->name,
+ 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
+ );
+ return $this->connection->affectedRows();
+ }
+
+
+
+ /**
+ * Finds rows by primary key.
+ * @param mixed primary key value(s)
+ * @return DibiResult
+ */
+ public function find($what)
+ {
+ if (!is_array($what)) {
+ $what = func_get_args();
+ }
+ return $this->complete($this->connection->query(
+ 'SELECT * FROM %n', $this->name,
+ 'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $what, ')'
+ ));
+ }
+
+
+
+ /**
+ * Selects all rows.
+ * @param string column to order by
+ * @return DibiResult
+ */
+ public function findAll($order = NULL)
+ {
+ if ($order === NULL) {
+ return $this->complete($this->connection->query(
+ 'SELECT * FROM %n', $this->name
+ ));
+ } else {
+ $order = func_get_args();
+ return $this->complete($this->connection->query(
+ 'SELECT * FROM %n', $this->name,
+ 'ORDER BY %n', $order
+ ));
+ }
+ }
+
+
+
+ /**
+ * Fetches single row.
+ * @param scalar|array primary key value
+ * @return array|object row
+ */
+ public function fetch($conditions)
+ {
+ if (is_array($conditions)) {
+ return $this->complete($this->connection->query(
+ 'SELECT * FROM %n', $this->name,
+ 'WHERE %and', $conditions
+ ))->fetch();
+ }
+ return $this->complete($this->connection->query(
+ 'SELECT * FROM %n', $this->name,
+ 'WHERE %n=' . $this->primaryModifier, $this->primary, $conditions
+ ))->fetch();
+ }
+
+
+
+ /**
+ * Returns a blank row (not fetched from database).
+ * @return array|object
+ */
+ public function createBlank()
+ {
+ $row = $this->blankRow;
+ $row[$this->primary] = NULL;
+
+ if ($class = $this->connection->getConfig('result:objects')) {
+ if ($class === TRUE) {
+ $row = (object) $row;
+ } else {
+ $row = new $class($row);
+ }
+ }
+
+ return $row;
+ }
+
+
+
+ /**
+ * User data pre-processing.
+ * @param array|object
+ * @return array
+ */
+ protected function prepare($data)
+ {
+ if (is_object($data)) {
+ return (array) $data;
+ } elseif (is_array($data)) {
+ return $data;
+ }
+
+ throw new InvalidArgumentException('Dataset must be array or anonymous object.');
+ }
+
+
+
+ /**
+ * User DibiResult post-processing.
+ * @param DibiResult
+ * @return DibiResult
+ */
+ protected function complete($res)
+ {
+ return $res;
+ }
+
+}
diff --git a/dibi/libs/DibiTranslator.php b/dibi/libs/DibiTranslator.php
index 65c6821d..9a3bab06 100644
--- a/dibi/libs/DibiTranslator.php
+++ b/dibi/libs/DibiTranslator.php
@@ -1,457 +1,457 @@
-driver = $driver;
- }
-
-
-
- /**
- * return IDibiDriver.
- */
- public function getDriver()
- {
- return $this->driver;
- }
-
-
-
- /**
- * Generates SQL.
- *
- * @param array
- * @return bool
- */
- public function translate(array $args)
- {
- $this->limit = -1;
- $this->offset = 0;
- $this->hasError = FALSE;
- $commandIns = NULL;
- $lastArr = NULL;
- // shortcuts
- $cursor = & $this->cursor;
- $cursor = 0;
- $this->args = array_values($args);
- $args = & $this->args;
-
- // conditional sql
- $this->ifLevel = $this->ifLevelStart = 0;
- $comment = & $this->comment;
- $comment = FALSE;
-
- // iterate
- $sql = array();
- while ($cursor < count($args))
- {
- $arg = $args[$cursor];
- $cursor++;
-
- // simple string means SQL
- if (is_string($arg)) {
- // speed-up - is regexp required?
- $toSkip = strcspn($arg, '`[\'"%');
-
- if (strlen($arg) === $toSkip) { // needn't be translated
- $sql[] = $arg;
- } else {
- $sql[] = substr($arg, 0, $toSkip)
-/*
- preg_replace_callback('/
- (?=`|\[|\'|"|%) ## speed-up
- (?:
- `(.+?)`| ## 1) `identifier`
- \[(.+?)\]| ## 2) [identifier]
- (\')((?:\'\'|[^\'])*)\'| ## 3,4) string
- (")((?:""|[^"])*)"| ## 5,6) "string"
- (\'|") ## 7) lone-quote
- %([a-zA-Z]{1,4})(?![a-zA-Z])|## 8) modifier
- )/xs',
-*/ // note: this can change $this->args & $this->cursor & ...
- . preg_replace_callback('/(?=`|\[|\'|"|%)(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|%([a-zA-Z]{1,4})(?![a-zA-Z]))/s',
- array($this, 'cb'),
- substr($arg, $toSkip)
- );
-
- }
- continue;
- }
-
- if ($comment) {
- $sql[] = '...';
- continue;
- }
-
- if (is_array($arg)) {
- if (is_string(key($arg))) {
- // associative array -> autoselect between SET or VALUES & LIST
- if ($commandIns === NULL) {
- $commandIns = strtoupper(substr(ltrim($args[0]), 0, 6));
- $commandIns = $commandIns === 'INSERT' || $commandIns === 'REPLAC';
- $sql[] = $this->formatValue($arg, $commandIns ? 'v' : 'a');
- } else {
- if ($lastArr === $cursor - 1) $sql[] = ',';
- $sql[] = $this->formatValue($arg, $commandIns ? 'l' : 'a');
- }
- $lastArr = $cursor;
- continue;
-
- } elseif ($cursor === 1) {
- // implicit array expansion
- $cursor = 0;
- array_splice($args, 0, 1, $arg);
- continue;
- }
- }
-
- // default processing
- $sql[] = $this->formatValue($arg, FALSE);
- } // while
-
-
- if ($comment) $sql[] = "*/";
-
- $sql = implode(' ', $sql);
-
- // apply limit
- if ($this->limit > -1 || $this->offset > 0) {
- $this->driver->applyLimit($sql, $this->limit, $this->offset);
- }
-
- $this->sql = $sql;
- return !$this->hasError;
- }
-
-
-
- /**
- * Apply modifier to single value.
- * @param mixed
- * @param string
- * @return string
- */
- public function formatValue($value, $modifier)
- {
- // array processing (with or without modifier)
- if (is_array($value)) {
-
- $vx = $kx = array();
- $separator = ', ';
- switch ($modifier) {
- case 'and':
- case 'or':
- $separator = ' ' . strtoupper($modifier) . ' ';
- if (!is_string(key($value))) {
- foreach ($value as $v) {
- $vx[] = $this->formatValue($v, 'sql');
- }
- return implode($separator, $vx);
- }
- // break intentionally omitted
- case 'a': // SET key=val, key=val, ...
- foreach ($value as $k => $v) {
- $pair = explode('%', $k, 2); // split into identifier & modifier
- $vx[] = $this->delimite($pair[0]) . '='
- . $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
- }
- return implode($separator, $vx);
-
-
- case 'l': // LIST (val, val, ...)
- foreach ($value as $k => $v) {
- $pair = explode('%', $k, 2); // split into identifier & modifier
- $vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
- }
- return '(' . implode(', ', $vx) . ')';
-
-
- case 'v': // (key, key, ...) VALUES (val, val, ...)
- foreach ($value as $k => $v) {
- $pair = explode('%', $k, 2); // split into identifier & modifier
- $kx[] = $this->delimite($pair[0]);
- $vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
- }
- return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
-
- default:
- foreach ($value as $v) {
- $vx[] = $this->formatValue($v, $modifier);
- }
- return implode(', ', $vx);
- }
- }
-
-
- // with modifier procession
- if ($modifier) {
- if ($value === NULL) {
- return 'NULL';
- }
-
- if ($value instanceof IDibiVariable) {
- return $value->toSql($this, $modifier);
- }
-
- if (!is_scalar($value)) { // array is already processed
- $this->hasError = TRUE;
- return '**Unexpected type ' . gettype($value) . '**';
- }
-
- switch ($modifier) {
- case 's': // string
- case 'bin':// binary
- case 'b': // boolean
- return $this->driver->escape($value, $modifier);
-
- case 'sn': // string or NULL
- return $value == '' ? 'NULL' : $this->driver->escape($value, dibi::FIELD_TEXT); // notice two equal signs
-
- case 'i': // signed int
- case 'u': // unsigned int, ignored
- // support for numbers - keep them unchanged
- if (is_string($value) && preg_match('#[+-]?\d+(e\d+)?$#A', $value)) {
- return $value;
- }
- return (string) (int) ($value + 0);
-
- case 'f': // float
- // support for numbers - keep them unchanged
- if (is_numeric($value) && (!is_string($value) || strpos($value, 'x') === FALSE)) {
- return $value; // something like -9E-005 is accepted by SQL, HEX values is not
- }
- return (string) ($value + 0);
-
- case 'd': // date
- case 't': // datetime
- return $this->driver->escape(is_string($value) ? strtotime($value) : $value, $modifier);
-
- case 'n': // identifier name
- return $this->delimite($value);
-
- case 'sql':// preserve as SQL
- $value = (string) $value;
- // speed-up - is regexp required?
- $toSkip = strcspn($value, '`[\'"');
- if (strlen($value) === $toSkip) { // needn't be translated
- return $value;
- } else {
- return substr($value, 0, $toSkip)
- . preg_replace_callback('/(?=`|\[|\'|")(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"(\'|"))/s',
- array($this, 'cb'),
- substr($value, $toSkip)
- );
- }
-
- case 'and':
- case 'or':
- case 'a':
- case 'l':
- case 'v':
- $this->hasError = TRUE;
- return '**Unexpected type ' . gettype($value) . '**';
-
- default:
- $this->hasError = TRUE;
- return "**Unknown or invalid modifier %$modifier**";
- }
- }
-
-
- // without modifier procession
- if (is_string($value))
- return $this->driver->escape($value, dibi::FIELD_TEXT);
-
- if (is_int($value) || is_float($value))
- return (string) $value; // something like -9E-005 is accepted by SQL
-
- if (is_bool($value))
- return $this->driver->escape($value, dibi::FIELD_BOOL);
-
- if ($value === NULL)
- return 'NULL';
-
- if ($value instanceof IDibiVariable)
- return $value->toSql($this, NULL);
-
- $this->hasError = TRUE;
- return '**Unexpected ' . gettype($value) . '**';
- }
-
-
-
- /**
- * PREG callback from translate() or formatValue().
- * @param array
- * @return string
- */
- private function cb($matches)
- {
- // [1] => `ident`
- // [2] => [ident]
- // [3] => '
- // [4] => string
- // [5] => "
- // [6] => string
- // [7] => lone-quote
- // [8] => modifier (when called from self::translate())
-
- if (!empty($matches[8])) { // modifier
- $mod = $matches[8];
- $cursor = & $this->cursor;
-
- if ($cursor >= count($this->args) && $mod !== 'else' && $mod !== 'end') {
- $this->hasError = TRUE;
- return "**Extra modifier %$mod**";
- }
-
- if ($mod === 'if') {
- $this->ifLevel++;
- $cursor++;
- if (!$this->comment && !$this->args[$cursor - 1]) {
- // open comment
- $this->ifLevelStart = $this->ifLevel;
- $this->comment = TRUE;
- return "/*";
- }
- return '';
-
- } elseif ($mod === 'else') {
- if ($this->ifLevelStart === $this->ifLevel) {
- $this->ifLevelStart = 0;
- $this->comment = FALSE;
- return "*/";
- } elseif (!$this->comment) {
- $this->ifLevelStart = $this->ifLevel;
- $this->comment = TRUE;
- return "/*";
- }
-
- } elseif ($mod === 'end') {
- $this->ifLevel--;
- if ($this->ifLevelStart === $this->ifLevel + 1) {
- // close comment
- $this->ifLevelStart = 0;
- $this->comment = FALSE;
- return "*/";
- }
- return '';
-
- } elseif ($mod === 'ex') { // array expansion
- array_splice($this->args, $cursor, 1, $this->args[$cursor]);
- return '';
-
- } elseif ($mod === 'lmt') { // apply limit
- if ($this->args[$cursor] !== NULL) $this->limit = (int) $this->args[$cursor];
- $cursor++;
- return '';
-
- } elseif ($mod === 'ofs') { // apply offset
- if ($this->args[$cursor] !== NULL) $this->offset = (int) $this->args[$cursor];
- $cursor++;
- return '';
-
- } else { // default processing
- $cursor++;
- return $this->formatValue($this->args[$cursor - 1], $mod);
- }
- }
-
- if ($this->comment) return '...';
-
- if ($matches[1]) // SQL identifiers: `ident`
- return $this->delimite($matches[1]);
-
- if ($matches[2]) // SQL identifiers: [ident]
- return $this->delimite($matches[2]);
-
- if ($matches[3]) // SQL strings: '...'
- return $this->driver->escape( str_replace("''", "'", $matches[4]), dibi::FIELD_TEXT);
-
- if ($matches[5]) // SQL strings: "..."
- return $this->driver->escape( str_replace('""', '"', $matches[6]), dibi::FIELD_TEXT);
-
- if ($matches[7]) { // string quote
- $this->hasError = TRUE;
- return '**Alone quote**';
- }
-
- die('this should be never executed');
- }
-
-
-
- /**
- * Apply substitutions to indentifier and delimites it.
- *
- * @param string indentifier
- * @return string
- */
- private function delimite($value)
- {
- return $this->driver->escape(dibi::substitute($value), dibi::IDENTIFIER);
- }
-
-
-} // class DibiTranslator
+driver = $driver;
+ }
+
+
+
+ /**
+ * return IDibiDriver.
+ */
+ public function getDriver()
+ {
+ return $this->driver;
+ }
+
+
+
+ /**
+ * Generates SQL.
+ *
+ * @param array
+ * @return bool
+ */
+ public function translate(array $args)
+ {
+ $this->limit = -1;
+ $this->offset = 0;
+ $this->hasError = FALSE;
+ $commandIns = NULL;
+ $lastArr = NULL;
+ // shortcuts
+ $cursor = & $this->cursor;
+ $cursor = 0;
+ $this->args = array_values($args);
+ $args = & $this->args;
+
+ // conditional sql
+ $this->ifLevel = $this->ifLevelStart = 0;
+ $comment = & $this->comment;
+ $comment = FALSE;
+
+ // iterate
+ $sql = array();
+ while ($cursor < count($args))
+ {
+ $arg = $args[$cursor];
+ $cursor++;
+
+ // simple string means SQL
+ if (is_string($arg)) {
+ // speed-up - is regexp required?
+ $toSkip = strcspn($arg, '`[\'"%');
+
+ if (strlen($arg) === $toSkip) { // needn't be translated
+ $sql[] = $arg;
+ } else {
+ $sql[] = substr($arg, 0, $toSkip)
+/*
+ preg_replace_callback('/
+ (?=`|\[|\'|"|%) ## speed-up
+ (?:
+ `(.+?)`| ## 1) `identifier`
+ \[(.+?)\]| ## 2) [identifier]
+ (\')((?:\'\'|[^\'])*)\'| ## 3,4) string
+ (")((?:""|[^"])*)"| ## 5,6) "string"
+ (\'|") ## 7) lone-quote
+ %([a-zA-Z]{1,4})(?![a-zA-Z])|## 8) modifier
+ )/xs',
+*/ // note: this can change $this->args & $this->cursor & ...
+ . preg_replace_callback('/(?=`|\[|\'|"|%)(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|%([a-zA-Z]{1,4})(?![a-zA-Z]))/s',
+ array($this, 'cb'),
+ substr($arg, $toSkip)
+ );
+
+ }
+ continue;
+ }
+
+ if ($comment) {
+ $sql[] = '...';
+ continue;
+ }
+
+ if (is_array($arg)) {
+ if (is_string(key($arg))) {
+ // associative array -> autoselect between SET or VALUES & LIST
+ if ($commandIns === NULL) {
+ $commandIns = strtoupper(substr(ltrim($args[0]), 0, 6));
+ $commandIns = $commandIns === 'INSERT' || $commandIns === 'REPLAC';
+ $sql[] = $this->formatValue($arg, $commandIns ? 'v' : 'a');
+ } else {
+ if ($lastArr === $cursor - 1) $sql[] = ',';
+ $sql[] = $this->formatValue($arg, $commandIns ? 'l' : 'a');
+ }
+ $lastArr = $cursor;
+ continue;
+
+ } elseif ($cursor === 1) {
+ // implicit array expansion
+ $cursor = 0;
+ array_splice($args, 0, 1, $arg);
+ continue;
+ }
+ }
+
+ // default processing
+ $sql[] = $this->formatValue($arg, FALSE);
+ } // while
+
+
+ if ($comment) $sql[] = "*/";
+
+ $sql = implode(' ', $sql);
+
+ // apply limit
+ if ($this->limit > -1 || $this->offset > 0) {
+ $this->driver->applyLimit($sql, $this->limit, $this->offset);
+ }
+
+ $this->sql = $sql;
+ return !$this->hasError;
+ }
+
+
+
+ /**
+ * Apply modifier to single value.
+ * @param mixed
+ * @param string
+ * @return string
+ */
+ public function formatValue($value, $modifier)
+ {
+ // array processing (with or without modifier)
+ if (is_array($value)) {
+
+ $vx = $kx = array();
+ $separator = ', ';
+ switch ($modifier) {
+ case 'and':
+ case 'or':
+ $separator = ' ' . strtoupper($modifier) . ' ';
+ if (!is_string(key($value))) {
+ foreach ($value as $v) {
+ $vx[] = $this->formatValue($v, 'sql');
+ }
+ return implode($separator, $vx);
+ }
+ // break intentionally omitted
+ case 'a': // SET key=val, key=val, ...
+ foreach ($value as $k => $v) {
+ $pair = explode('%', $k, 2); // split into identifier & modifier
+ $vx[] = $this->delimite($pair[0]) . '='
+ . $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
+ }
+ return implode($separator, $vx);
+
+
+ case 'l': // LIST (val, val, ...)
+ foreach ($value as $k => $v) {
+ $pair = explode('%', $k, 2); // split into identifier & modifier
+ $vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
+ }
+ return '(' . implode(', ', $vx) . ')';
+
+
+ case 'v': // (key, key, ...) VALUES (val, val, ...)
+ foreach ($value as $k => $v) {
+ $pair = explode('%', $k, 2); // split into identifier & modifier
+ $kx[] = $this->delimite($pair[0]);
+ $vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
+ }
+ return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
+
+ default:
+ foreach ($value as $v) {
+ $vx[] = $this->formatValue($v, $modifier);
+ }
+ return implode(', ', $vx);
+ }
+ }
+
+
+ // with modifier procession
+ if ($modifier) {
+ if ($value === NULL) {
+ return 'NULL';
+ }
+
+ if ($value instanceof IDibiVariable) {
+ return $value->toSql($this, $modifier);
+ }
+
+ if (!is_scalar($value)) { // array is already processed
+ $this->hasError = TRUE;
+ return '**Unexpected type ' . gettype($value) . '**';
+ }
+
+ switch ($modifier) {
+ case 's': // string
+ case 'bin':// binary
+ case 'b': // boolean
+ return $this->driver->escape($value, $modifier);
+
+ case 'sn': // string or NULL
+ return $value == '' ? 'NULL' : $this->driver->escape($value, dibi::FIELD_TEXT); // notice two equal signs
+
+ case 'i': // signed int
+ case 'u': // unsigned int, ignored
+ // support for numbers - keep them unchanged
+ if (is_string($value) && preg_match('#[+-]?\d+(e\d+)?$#A', $value)) {
+ return $value;
+ }
+ return (string) (int) ($value + 0);
+
+ case 'f': // float
+ // support for numbers - keep them unchanged
+ if (is_numeric($value) && (!is_string($value) || strpos($value, 'x') === FALSE)) {
+ return $value; // something like -9E-005 is accepted by SQL, HEX values is not
+ }
+ return (string) ($value + 0);
+
+ case 'd': // date
+ case 't': // datetime
+ return $this->driver->escape(is_string($value) ? strtotime($value) : $value, $modifier);
+
+ case 'n': // identifier name
+ return $this->delimite($value);
+
+ case 'sql':// preserve as SQL
+ $value = (string) $value;
+ // speed-up - is regexp required?
+ $toSkip = strcspn($value, '`[\'"');
+ if (strlen($value) === $toSkip) { // needn't be translated
+ return $value;
+ } else {
+ return substr($value, 0, $toSkip)
+ . preg_replace_callback('/(?=`|\[|\'|")(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"(\'|"))/s',
+ array($this, 'cb'),
+ substr($value, $toSkip)
+ );
+ }
+
+ case 'and':
+ case 'or':
+ case 'a':
+ case 'l':
+ case 'v':
+ $this->hasError = TRUE;
+ return '**Unexpected type ' . gettype($value) . '**';
+
+ default:
+ $this->hasError = TRUE;
+ return "**Unknown or invalid modifier %$modifier**";
+ }
+ }
+
+
+ // without modifier procession
+ if (is_string($value))
+ return $this->driver->escape($value, dibi::FIELD_TEXT);
+
+ if (is_int($value) || is_float($value))
+ return (string) $value; // something like -9E-005 is accepted by SQL
+
+ if (is_bool($value))
+ return $this->driver->escape($value, dibi::FIELD_BOOL);
+
+ if ($value === NULL)
+ return 'NULL';
+
+ if ($value instanceof IDibiVariable)
+ return $value->toSql($this, NULL);
+
+ $this->hasError = TRUE;
+ return '**Unexpected ' . gettype($value) . '**';
+ }
+
+
+
+ /**
+ * PREG callback from translate() or formatValue().
+ * @param array
+ * @return string
+ */
+ private function cb($matches)
+ {
+ // [1] => `ident`
+ // [2] => [ident]
+ // [3] => '
+ // [4] => string
+ // [5] => "
+ // [6] => string
+ // [7] => lone-quote
+ // [8] => modifier (when called from self::translate())
+
+ if (!empty($matches[8])) { // modifier
+ $mod = $matches[8];
+ $cursor = & $this->cursor;
+
+ if ($cursor >= count($this->args) && $mod !== 'else' && $mod !== 'end') {
+ $this->hasError = TRUE;
+ return "**Extra modifier %$mod**";
+ }
+
+ if ($mod === 'if') {
+ $this->ifLevel++;
+ $cursor++;
+ if (!$this->comment && !$this->args[$cursor - 1]) {
+ // open comment
+ $this->ifLevelStart = $this->ifLevel;
+ $this->comment = TRUE;
+ return "/*";
+ }
+ return '';
+
+ } elseif ($mod === 'else') {
+ if ($this->ifLevelStart === $this->ifLevel) {
+ $this->ifLevelStart = 0;
+ $this->comment = FALSE;
+ return "*/";
+ } elseif (!$this->comment) {
+ $this->ifLevelStart = $this->ifLevel;
+ $this->comment = TRUE;
+ return "/*";
+ }
+
+ } elseif ($mod === 'end') {
+ $this->ifLevel--;
+ if ($this->ifLevelStart === $this->ifLevel + 1) {
+ // close comment
+ $this->ifLevelStart = 0;
+ $this->comment = FALSE;
+ return "*/";
+ }
+ return '';
+
+ } elseif ($mod === 'ex') { // array expansion
+ array_splice($this->args, $cursor, 1, $this->args[$cursor]);
+ return '';
+
+ } elseif ($mod === 'lmt') { // apply limit
+ if ($this->args[$cursor] !== NULL) $this->limit = (int) $this->args[$cursor];
+ $cursor++;
+ return '';
+
+ } elseif ($mod === 'ofs') { // apply offset
+ if ($this->args[$cursor] !== NULL) $this->offset = (int) $this->args[$cursor];
+ $cursor++;
+ return '';
+
+ } else { // default processing
+ $cursor++;
+ return $this->formatValue($this->args[$cursor - 1], $mod);
+ }
+ }
+
+ if ($this->comment) return '...';
+
+ if ($matches[1]) // SQL identifiers: `ident`
+ return $this->delimite($matches[1]);
+
+ if ($matches[2]) // SQL identifiers: [ident]
+ return $this->delimite($matches[2]);
+
+ if ($matches[3]) // SQL strings: '...'
+ return $this->driver->escape( str_replace("''", "'", $matches[4]), dibi::FIELD_TEXT);
+
+ if ($matches[5]) // SQL strings: "..."
+ return $this->driver->escape( str_replace('""', '"', $matches[6]), dibi::FIELD_TEXT);
+
+ if ($matches[7]) { // string quote
+ $this->hasError = TRUE;
+ return '**Alone quote**';
+ }
+
+ die('this should be never executed');
+ }
+
+
+
+ /**
+ * Apply substitutions to indentifier and delimites it.
+ *
+ * @param string indentifier
+ * @return string
+ */
+ private function delimite($value)
+ {
+ return $this->driver->escape(dibi::substitute($value), dibi::IDENTIFIER);
+ }
+
+
+} // class DibiTranslator
diff --git a/dibi/libs/DibiVariable.php b/dibi/libs/DibiVariable.php
index 0620e693..00e07ad6 100644
--- a/dibi/libs/DibiVariable.php
+++ b/dibi/libs/DibiVariable.php
@@ -1,48 +1,49 @@
-value = $value;
- $this->modifier = $modifier;
- }
-
-
-
- public function toSql(DibiTranslator $translator, $modifier)
- {
- return $translator->formatValue($this->value, $this->modifier);
- }
-
+value = $value;
+ $this->modifier = $modifier;
+ }
+
+
+
+ public function toSql(DibiTranslator $translator, $modifier)
+ {
+ return $translator->formatValue($this->value, $this->modifier);
+ }
+
}
\ No newline at end of file
diff --git a/dibi/libs/interfaces.php b/dibi/libs/interfaces.php
index dd4dc940..8bc8a4fe 100644
--- a/dibi/libs/interfaces.php
+++ b/dibi/libs/interfaces.php
@@ -1,256 +1,256 @@
-dibi apply limit/offset example
-\n\t\t \n\n\n";
+ $none = FALSE;
+ }
+
+ echo "\t#row \n";
+
+ foreach ($row as $col => $foo) {
+ echo "\t\t" . htmlSpecialChars($col) . " \n";
+ }
+
+ echo "\t\n\t\t \n";
+ }
+
+ if ($none) {
+ echo '", $i, " \n";
+ foreach ($row as $col) {
+ //if (is_object($col)) $col = $col->__toString();
+ echo "\t\t", htmlSpecialChars($col), " \n";
+ }
+ echo "\t
- 'sqlite',
- 'database' => 'sample.sdb',
-));
-
-
-// no limit
-$res = dibi::query('SELECT * FROM [products]');
-foreach ($res as $n => $row) {
- print_r($row);
-}
-
-echo '
';
-
-// with limit = 2
-$res = dibi::query('SELECT * FROM [products] %lmt', 2);
-foreach ($res as $n => $row) {
- print_r($row);
-}
-
-echo '
';
-
-// with limit = 2, offset = 1
-$res = dibi::query('SELECT * FROM [products] %lmt %ofs', 2, 1);
-foreach ($res as $n => $row) {
- print_r($row);
-}
+dibi apply limit/offset example
+
+ 'sqlite',
+ 'database' => 'sample.sdb',
+));
+
+
+// no limit
+$res = dibi::query('SELECT * FROM [products]');
+foreach ($res as $n => $row) {
+ print_r($row);
+}
+
+echo '
';
+
+// with limit = 2
+$res = dibi::query('SELECT * FROM [products] %lmt', 2);
+foreach ($res as $n => $row) {
+ print_r($row);
+}
+
+echo '
';
+
+// with limit = 2, offset = 1
+$res = dibi::query('SELECT * FROM [products] %lmt %ofs', 2, 1);
+foreach ($res as $n => $row) {
+ print_r($row);
+}
diff --git a/examples/connect.php b/examples/connect.php
index 88279e12..62414272 100644
--- a/examples/connect.php
+++ b/examples/connect.php
@@ -1,145 +1,145 @@
-dibi::connect() example
-Connecting to Sqlite: ';
-try {
- dibi::connect(array(
- 'driver' => 'sqlite',
- 'database' => 'sample.sdb',
- 'result:objects' => TRUE, // fetch rows as objects
- ));
- echo 'OK';
-
-} catch (DibiException $e) {
- echo get_class($e), ': ', $e->getMessage(), "\n";
-}
-echo "
Connecting to MySQL: '; -try { - dibi::connect('driver=mysql&host=localhost&username=root&password=xxx&database=test&charset=utf8'); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - - -// connects to MySQLi using array -echo 'Connecting to MySQL: '; -try { - dibi::connect(array( - 'driver' => 'mysqli', - 'host' => 'localhost', - 'username' => 'root', - 'password' => 'xxx', - 'database' => 'dibi', - 'charset' => 'utf8', - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - - -// connects to ODBC -echo 'Connecting to ODBC: '; -try { - dibi::connect(array( - 'driver' => 'odbc', - 'username' => 'root', - 'password' => '***', - 'dsn' => 'Driver={Microsoft Access Driver (*.mdb)};Dbq='.dirname(__FILE__).'/sample.mdb', - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - - -// connects to PostgreSql -echo 'Connecting to PostgreSql: '; -try { - dibi::connect(array( - 'driver' => 'postgre', - 'string' => 'host=localhost port=5432 dbname=mary', - 'persistent' => TRUE, - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - - -// connects to PDO -echo 'Connecting to Sqlite via PDO: '; -try { - dibi::connect(array( - 'driver' => 'pdo', - 'dsn' => 'sqlite2::memory:', - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - -// connects to MS SQL -echo 'Connecting to MS SQL: '; -try { - dibi::connect(array( - 'driver' => 'mssql', - 'host' => 'localhost', - 'username' => 'root', - 'password' => 'xxx', - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} -echo "
\n"; - - - -// connects to Oracle -echo 'Connecting to Oracle: '; -try { - dibi::connect(array( - 'driver' => 'oracle', - 'username' => 'root', - 'password' => 'xxx', - 'database' => 'db', - )); - echo 'OK'; - -} catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; -} +
Connecting to MySQL: '; +try { + dibi::connect('driver=mysql&host=localhost&username=root&password=xxx&database=test&charset=utf8'); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + + +// connects to MySQLi using array +echo 'Connecting to MySQL: '; +try { + dibi::connect(array( + 'driver' => 'mysqli', + 'host' => 'localhost', + 'username' => 'root', + 'password' => 'xxx', + 'database' => 'dibi', + 'charset' => 'utf8', + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + + +// connects to ODBC +echo 'Connecting to ODBC: '; +try { + dibi::connect(array( + 'driver' => 'odbc', + 'username' => 'root', + 'password' => '***', + 'dsn' => 'Driver={Microsoft Access Driver (*.mdb)};Dbq='.dirname(__FILE__).'/sample.mdb', + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + + +// connects to PostgreSql +echo 'Connecting to PostgreSql: '; +try { + dibi::connect(array( + 'driver' => 'postgre', + 'string' => 'host=localhost port=5432 dbname=mary', + 'persistent' => TRUE, + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + + +// connects to PDO +echo 'Connecting to Sqlite via PDO: '; +try { + dibi::connect(array( + 'driver' => 'pdo', + 'dsn' => 'sqlite2::memory:', + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + +// connects to MS SQL +echo 'Connecting to MS SQL: '; +try { + dibi::connect(array( + 'driver' => 'mssql', + 'host' => 'localhost', + 'username' => 'root', + 'password' => 'xxx', + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} +echo "
\n"; + + + +// connects to Oracle +echo 'Connecting to Oracle: '; +try { + dibi::connect(array( + 'driver' => 'oracle', + 'username' => 'root', + 'password' => 'xxx', + 'database' => 'db', + )); + echo 'OK'; + +} catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; +} echo "
\n"; \ No newline at end of file diff --git a/examples/datetime.demo.php b/examples/datetime.demo.php index 9b1535cd..978414a8 100644 --- a/examples/datetime.demo.php +++ b/examples/datetime.demo.php @@ -1,28 +1,28 @@ -- 'sqlite', - 'database' => 'sample.sdb', -)); - -dibi::begin(); - - -// autodetection: primary keys are customer_id, order_id, ... -DibiTable::$primaryMask = '%s_id'; - - -// table products -class Products extends DibiTable -{ -// rely on autodetection... -// protected $name = 'products'; -// protected $primary = 'product_id'; - -} - - - - - -// create table object -$products = new Products(); - -echo "Table name: $products->name\n"; -echo "Primary key: $products->primary\n"; - - -// Finds rows by primary key -foreach ($products->find(1, 3) as $row) { - print_r($row); -} - - -// select all -$products->findAll()->dump(); - - -// select all, order by title, product_id -$products->findAll('title', $products->primary)->dump(); - - -// fetches single row with id 3 -$row = $products->fetch(3); - - -// deletes row from a table -$count = $products->delete(1); - -// deletes multiple rows -$count = $products->delete(array(1, 2, 3)); -var_dump($count); // number of deleted rows - - -// update row #2 in a table -$data = (object) NULL; -$data->title = 'New title'; -$count = $products->update(2, $data); -var_dump($count); // number of updated rows - - -// update multiple rows in a table -$count = $products->update(array(3, 5), $data); -var_dump($count); // number of updated rows - - -// inserts row into a table -$data = array(); -$data['title'] = 'New product'; -$id = $products->insert($data); -var_dump($id); // generated id - - -// is absolutely SQL injection safe -$key = '3 OR 1=1'; -$products->delete($key); -// --> DELETE FROM [products] WHERE [product_id] IN ( 3 ) +DibiTable demo
++ 'sqlite', + 'database' => 'sample.sdb', +)); + +dibi::begin(); + + +// autodetection: primary keys are customer_id, order_id, ... +DibiTable::$primaryMask = '%s_id'; + + +// table products +class Products extends DibiTable +{ +// rely on autodetection... +// protected $name = 'products'; +// protected $primary = 'product_id'; + +} + + + + + +// create table object +$products = new Products(); + +echo "Table name: $products->name\n"; +echo "Primary key: $products->primary\n"; + + +// Finds rows by primary key +foreach ($products->find(1, 3) as $row) { + print_r($row); +} + + +// select all +$products->findAll()->dump(); + + +// select all, order by title, product_id +$products->findAll('title', $products->primary)->dump(); + + +// fetches single row with id 3 +$row = $products->fetch(3); + + +// deletes row from a table +$count = $products->delete(1); + +// deletes multiple rows +$count = $products->delete(array(1, 2, 3)); +var_dump($count); // number of deleted rows + + +// update row #2 in a table +$data = (object) NULL; +$data->title = 'New title'; +$count = $products->update(2, $data); +var_dump($count); // number of updated rows + + +// update multiple rows in a table +$count = $products->update(array(3, 5), $data); +var_dump($count); // number of updated rows + + +// inserts row into a table +$data = array(); +$data['title'] = 'New product'; +$id = $products->insert($data); +var_dump($id); // generated id + + +// is absolutely SQL injection safe +$key = '3 OR 1=1'; +$products->delete($key); +// --> DELETE FROM [products] WHERE [product_id] IN ( 3 ) diff --git a/examples/dump.php b/examples/dump.php index b3f2648e..30ed2d19 100644 --- a/examples/dump.php +++ b/examples/dump.php @@ -1,30 +1,30 @@ -dibi dump example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - - -$res = dibi::query(' -SELECT * FROM [products] -INNER JOIN [orders] USING ([product_id]) -INNER JOIN [customers] USING ([customer_id]) -'); - - -echo 'dibi::dump()
'; - -// dump last query (dibi::$sql) -dibi::dump(); - - -// dump result table -echo 'DibiResult::dump()
'; - -$res->dump(); +dibi dump example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + + +$res = dibi::query(' +SELECT * FROM [products] +INNER JOIN [orders] USING ([product_id]) +INNER JOIN [customers] USING ([customer_id]) +'); + + +echo 'dibi::dump()
'; + +// dump last query (dibi::$sql) +dibi::dump(); + + +// dump result table +echo 'DibiResult::dump()
'; + +$res->dump(); diff --git a/examples/extension.method.php b/examples/extension.method.php index 964a7d0a..7612e83e 100644 --- a/examples/extension.method.php +++ b/examples/extension.method.php @@ -1,27 +1,27 @@ -dibi extension method example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - - -// using the "prototype" to add custom method to class DibiResult -function DibiResult_prototype_fetchShuffle(DibiResult $obj) -{ - $all = $obj->fetchAll(); - shuffle($all); - return $all; -} - - -// fetch complete result set shuffled -$res = dibi::query('SELECT * FROM [customers]'); -$all = $res->fetchShuffle(); -print_r($all); +dibi extension method example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + + +// using the "prototype" to add custom method to class DibiResult +function DibiResult_prototype_fetchShuffle(DibiResult $obj) +{ + $all = $obj->fetchAll(); + shuffle($all); + return $all; +} + + +// fetch complete result set shuffled +$res = dibi::query('SELECT * FROM [customers]'); +$all = $res->fetchShuffle(); +print_r($all); diff --git a/examples/fetch.php b/examples/fetch.php index ce098aba..dd7a5150 100644 --- a/examples/fetch.php +++ b/examples/fetch.php @@ -1,93 +1,93 @@ -dibi fetch example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -/* -TABLE products - -product_id | title ------------+---------- - 1 | Chair - 2 | Table - 3 | Computer - -*/ - - -// fetch a single row -$row = dibi::fetch('SELECT title FROM [products]'); -print_r($row); // Chair -echo '
'; - - -// fetch a single value -$value = dibi::fetchSingle('SELECT [title] FROM [products]'); -print_r($value); // Chair -echo '
'; - - -// fetch complete result set -$all = dibi::fetchAll('SELECT * FROM [products]'); -print_r($all); -echo '
'; - - -// fetch complete result set like association array -$res = dibi::query('SELECT * FROM [products]'); -$assoc = $res->fetchAssoc('title'); // key -print_r($assoc); -echo '
'; - - -// fetch complete result set like pairs key => value -$pairs = $res->fetchPairs('product_id', 'title'); -print_r($pairs); -echo '
'; - - -// fetch row by row -foreach ($res as $n => $row) { - print_r($row); -} -echo '
'; - - -// fetch row by row with defined offset -foreach ($res->getIterator(2) as $n => $row) { - print_r($row); -} - -// fetch row by row with defined offset and limit -foreach ($res->getIterator(2, 1) as $n => $row) { - print_r($row); -} - - -// more complex association array -$res = dibi::query(' -SELECT * -FROM [products] -INNER JOIN [orders] USING ([product_id]) -INNER JOIN [customers] USING ([customer_id]) -'); - -$assoc = $res->fetchAssoc('customers.name,products.title'); // key -print_r($assoc); -echo '
'; - -$assoc = $res->fetchAssoc('customers.name,#,products.title'); // key -print_r($assoc); -echo '
'; - -$assoc = $res->fetchAssoc('customers.name,=,products.title'); // key -print_r($assoc); -echo '
'; +dibi fetch example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +/* +TABLE products + +product_id | title +-----------+---------- + 1 | Chair + 2 | Table + 3 | Computer + +*/ + + +// fetch a single row +$row = dibi::fetch('SELECT title FROM [products]'); +print_r($row); // Chair +echo '
'; + + +// fetch a single value +$value = dibi::fetchSingle('SELECT [title] FROM [products]'); +print_r($value); // Chair +echo '
'; + + +// fetch complete result set +$all = dibi::fetchAll('SELECT * FROM [products]'); +print_r($all); +echo '
'; + + +// fetch complete result set like association array +$res = dibi::query('SELECT * FROM [products]'); +$assoc = $res->fetchAssoc('title'); // key +print_r($assoc); +echo '
'; + + +// fetch complete result set like pairs key => value +$pairs = $res->fetchPairs('product_id', 'title'); +print_r($pairs); +echo '
'; + + +// fetch row by row +foreach ($res as $n => $row) { + print_r($row); +} +echo '
'; + + +// fetch row by row with defined offset +foreach ($res->getIterator(2) as $n => $row) { + print_r($row); +} + +// fetch row by row with defined offset and limit +foreach ($res->getIterator(2, 1) as $n => $row) { + print_r($row); +} + + +// more complex association array +$res = dibi::query(' +SELECT * +FROM [products] +INNER JOIN [orders] USING ([product_id]) +INNER JOIN [customers] USING ([customer_id]) +'); + +$assoc = $res->fetchAssoc('customers.name,products.title'); // key +print_r($assoc); +echo '
'; + +$assoc = $res->fetchAssoc('customers.name,#,products.title'); // key +print_r($assoc); +echo '
'; + +$assoc = $res->fetchAssoc('customers.name,=,products.title'); // key +print_r($assoc); +echo '
'; diff --git a/examples/fluent.test.php b/examples/fluent.test.php index 0126f625..374a6363 100644 --- a/examples/fluent.test.php +++ b/examples/fluent.test.php @@ -1,63 +1,63 @@ -dibi dump example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - -$id = 10; -$record = array( - 'title' => 'Drtička na trávu', - 'price' => 318, - 'active' => TRUE, -); - -// SELECT ... -dibi::select('product_id')->as('id') - ->select('title') - ->from('products') - ->innerJoin('orders')->using('(product_id)') - ->innerJoin('customers USING (customer_id)') - ->orderBy('title') - ->test(); - -echo "\n"; - -// INSERT ... -dibi::insert('products', $record) - ->setFlag('IGNORE') - ->test(); - -echo "\n"; - -// UPDATE ... -dibi::update('products', $record) - ->where('product_id = %d', $id) - ->test(); - -echo "\n"; - -// DELETE ... -dibi::delete('products') - ->where('product_id = %d', $id) - ->test(); - -echo "\n"; - -// custom commands -dibi::command() - ->update('products') - ->where('product_id = %d', $id) - ->set($record) - ->test(); - -echo "\n"; - -dibi::command() - ->truncate('products') - ->test(); +dibi dump example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + +$id = 10; +$record = array( + 'title' => 'Drtička na trávu', + 'price' => 318, + 'active' => TRUE, +); + +// SELECT ... +dibi::select('product_id')->as('id') + ->select('title') + ->from('products') + ->innerJoin('orders')->using('(product_id)') + ->innerJoin('customers USING (customer_id)') + ->orderBy('title') + ->test(); + +echo "\n"; + +// INSERT ... +dibi::insert('products', $record) + ->setFlag('IGNORE') + ->test(); + +echo "\n"; + +// UPDATE ... +dibi::update('products', $record) + ->where('product_id = %d', $id) + ->test(); + +echo "\n"; + +// DELETE ... +dibi::delete('products') + ->where('product_id = %d', $id) + ->test(); + +echo "\n"; + +// custom commands +dibi::command() + ->update('products') + ->where('product_id = %d', $id) + ->set($record) + ->test(); + +echo "\n"; + +dibi::command() + ->truncate('products') + ->test(); diff --git a/examples/load-sql-dump.php b/examples/load-sql-dump.php index 5eedc6b5..07071372 100644 --- a/examples/load-sql-dump.php +++ b/examples/load-sql-dump.php @@ -1,16 +1,16 @@ -dibi import SQL dump example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -$count = dibi::loadFile('compress.zlib://dump.sql.gz'); - +dibi import SQL dump example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +$count = dibi::loadFile('compress.zlib://dump.sql.gz'); + echo 'Number of SQL commands:', $count; \ No newline at end of file diff --git a/examples/logger.php b/examples/logger.php index 0a291865..306ac821 100644 --- a/examples/logger.php +++ b/examples/logger.php @@ -1,32 +1,32 @@ -dibi logger example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - - -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 '', get_class($e), ': ', $e->getMessage(), '
'; -} - - -echo "File log.sql:
"; - -echo '', file_get_contents('log.sql'), ''; +dibi logger example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + + +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 '', get_class($e), ': ', $e->getMessage(), '
'; +} + + +echo "File log.sql:
"; + +echo '', file_get_contents('log.sql'), ''; diff --git a/examples/metatypes.php b/examples/metatypes.php index d77f5b42..5e4484ff 100644 --- a/examples/metatypes.php +++ b/examples/metatypes.php @@ -1,21 +1,21 @@ -dibi metatypes example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -$res = dibi::query('SELECT * FROM [customers]'); - -// auto-convert this column to integer -$res->setType('customer_id', Dibi::FIELD_INTEGER); -$res->setType('added', Dibi::FIELD_DATETIME, 'H:i j.n.Y'); - -$row = $res->fetch(); -var_dump($row); +dibi metatypes example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +$res = dibi::query('SELECT * FROM [customers]'); + +// auto-convert this column to integer +$res->setType('customer_id', Dibi::FIELD_INTEGER); +$res->setType('added', Dibi::FIELD_DATETIME, 'H:i j.n.Y'); + +$row = $res->fetch(); +var_dump($row); diff --git a/examples/nette-debug.php b/examples/nette-debug.php index ae73c5c9..c26c41e7 100644 --- a/examples/nette-debug.php +++ b/examples/nette-debug.php @@ -1,19 +1,19 @@ -Nette::Debug && dibi example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - - -// throws error -dibi::query('SELECT FROM [customers] WHERE [customer_id] < %i', 38); +Nette::Debug && dibi example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + + +// throws error +dibi::query('SELECT FROM [customers] WHERE [customer_id] < %i', 38); diff --git a/examples/profiler.php b/examples/profiler.php index fede2305..4e762240 100644 --- a/examples/profiler.php +++ b/examples/profiler.php @@ -1,25 +1,25 @@ -Dibi profiler example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - -for ($i=0; $i<20; $i++) { - $res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < %i', $i); -} - -?> - -Last query:
- -Number of queries:
- -Elapsed time for last query: ms
- -Total elapsed time: ms
+Dibi profiler example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + +for ($i=0; $i<20; $i++) { + $res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < %i', $i); +} + +?> + +Last query:
+ +Number of queries:
+ +Elapsed time for last query: ms
+ +Total elapsed time: ms
diff --git a/examples/sql-builder.php b/examples/sql-builder.php index e9fcb777..256c8dcf 100644 --- a/examples/sql-builder.php +++ b/examples/sql-builder.php @@ -1,66 +1,66 @@ - -dibi SQL builder example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -// dibi detects INSERT or REPLACE command -dibi::test(' -REPLACE INTO [products]', array( - 'title' => 'Drtika na trvu', - 'price' => 318, - 'active' => TRUE, -)); - - -// multiple INSERT command -$array = array( - 'title' => 'Super Product', - 'price' => 12, - 'brand' => NULL, - 'created' => dibi::datetime(), -); -dibi::test("INSERT INTO [products]", $array, $array, $array); - - -// dibi detects UPDATE command -dibi::test(" -UPDATE [colors] SET", array( - 'color' => 'blue', - 'order' => 12, -), " -WHERE [id]=%i", 123); - - -// SELECT -$ipMask = '192.168.%'; -$timestamp = mktime(0, 0, 0, 10, 13, 1997); - -dibi::test(' -SELECT COUNT(*) as [count] -FROM [comments] -WHERE [ip] LIKE %s', $ipMask, ' -AND [date] > ', dibi::date($timestamp) -); - - -// IN array -$array = array(1, 2, 3); -dibi::test(" -SELECT * -FROM [people] -WHERE [id] IN (", $array, ") -"); + +dibi SQL builder example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +// dibi detects INSERT or REPLACE command +dibi::test(' +REPLACE INTO [products]', array( + 'title' => 'Drtika na trvu', + 'price' => 318, + 'active' => TRUE, +)); + + +// multiple INSERT command +$array = array( + 'title' => 'Super Product', + 'price' => 12, + 'brand' => NULL, + 'created' => dibi::datetime(), +); +dibi::test("INSERT INTO [products]", $array, $array, $array); + + +// dibi detects UPDATE command +dibi::test(" +UPDATE [colors] SET", array( + 'color' => 'blue', + 'order' => 12, +), " +WHERE [id]=%i", 123); + + +// SELECT +$ipMask = '192.168.%'; +$timestamp = mktime(0, 0, 0, 10, 13, 1997); + +dibi::test(' +SELECT COUNT(*) as [count] +FROM [comments] +WHERE [ip] LIKE %s', $ipMask, ' +AND [date] > ', dibi::date($timestamp) +); + + +// IN array +$array = array(1, 2, 3); +dibi::test(" +SELECT * +FROM [people] +WHERE [id] IN (", $array, ") +"); diff --git a/examples/sql-condition.php b/examples/sql-condition.php index 4c373c8a..f17cf123 100644 --- a/examples/sql-condition.php +++ b/examples/sql-condition.php @@ -1,51 +1,51 @@ - -dibi conditional SQL example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -$cond1 = rand(0,2) < 1; -$cond2 = rand(0,2) < 1; -$foo = -1; -$bar = 2; - - -$name = $cond1 ? 'K%' : NULL; - -// if & end -dibi::test(' -SELECT * -FROM [customers] -%if', isset($name), 'WHERE [name] LIKE %s', $name, '%end' -); - - -// if & else & (optional) end -dibi::test(" -SELECT * -FROM [people] -WHERE [id] > 0 - %if", ($foo > 0), "AND [foo]=%i", $foo, " - %else %if", ($bar > 0), "AND [bar]=%i", $bar, " -"); - - -// nested condition -dibi::test(' -SELECT * -FROM [customers] -WHERE - %if', isset($name), '[name] LIKE %s', $name, ' - %if', $cond2, 'AND [admin]=1 %end - %else 1 LIMIT 10 %end' -); + +dibi conditional SQL example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +$cond1 = rand(0,2) < 1; +$cond2 = rand(0,2) < 1; +$foo = -1; +$bar = 2; + + +$name = $cond1 ? 'K%' : NULL; + +// if & end +dibi::test(' +SELECT * +FROM [customers] +%if', isset($name), 'WHERE [name] LIKE %s', $name, '%end' +); + + +// if & else & (optional) end +dibi::test(" +SELECT * +FROM [people] +WHERE [id] > 0 + %if", ($foo > 0), "AND [foo]=%i", $foo, " + %else %if", ($bar > 0), "AND [bar]=%i", $bar, " +"); + + +// nested condition +dibi::test(' +SELECT * +FROM [customers] +WHERE + %if', isset($name), '[name] LIKE %s', $name, ' + %if', $cond2, 'AND [admin]=1 %end + %else 1 LIMIT 10 %end' +); diff --git a/examples/table-prefix.php b/examples/table-prefix.php index 9a36ceae..fc13185c 100644 --- a/examples/table-prefix.php +++ b/examples/table-prefix.php @@ -1,44 +1,44 @@ -dibi prefix & substitute example
- 'sqlite', - 'database' => 'sample.sdb', -)); - - -// create new substitution :blog: ==> wp_ -dibi::addSubst('blog', 'wp_'); - - -// generate and dump SQL -dibi::test("UPDATE [:blog:items] SET [text]='Hello World'"); - - - - -// create new substitution :: (empty) ==> my_ -dibi::addSubst('', 'my_'); - - -// generate and dump SQL -dibi::test("UPDATE [database.::table] SET [text]='Hello World'"); - - - - - -function substFallBack($expr) -{ - return 'the_' . $expr; -} - -// create substitution fallback -dibi::setSubstFallBack('substFallBack'); - - -// generate and dump SQL -dibi::test("UPDATE [:account:user] SET [name]='John Doe'"); +dibi prefix & substitute example
+ 'sqlite', + 'database' => 'sample.sdb', +)); + + +// create new substitution :blog: ==> wp_ +dibi::addSubst('blog', 'wp_'); + + +// generate and dump SQL +dibi::test("UPDATE [:blog:items] SET [text]='Hello World'"); + + + + +// create new substitution :: (empty) ==> my_ +dibi::addSubst('', 'my_'); + + +// generate and dump SQL +dibi::test("UPDATE [database.::table] SET [text]='Hello World'"); + + + + + +function substFallBack($expr) +{ + return 'the_' . $expr; +} + +// create substitution fallback +dibi::setSubstFallBack('substFallBack'); + + +// generate and dump SQL +dibi::test("UPDATE [:account:user] SET [name]='John Doe'"); diff --git a/examples/transaction.php b/examples/transaction.php index 7b316e8b..14f43443 100644 --- a/examples/transaction.php +++ b/examples/transaction.php @@ -1,28 +1,28 @@ -dibi transaction example
-- 'sqlite', - 'database' => 'sample.sdb', -)); - - -echo "Before:
\n"; -dibi::query('SELECT * FROM [products]')->dump(); - - - -dibi::begin(); -dibi::query('INSERT INTO [products]', array( - 'title' => 'Test product', -)); -dibi::rollback(); // or dibi::commit(); - - - -echo "After:
\n"; +dibi transaction example
++ 'sqlite', + 'database' => 'sample.sdb', +)); + + +echo "Before:
\n"; +dibi::query('SELECT * FROM [products]')->dump(); + + + +dibi::begin(); +dibi::query('INSERT INTO [products]', array( + 'title' => 'Test product', +)); +dibi::rollback(); // or dibi::commit(); + + + +echo "After:
\n"; dibi::query('SELECT * FROM [products]')->dump(); \ No newline at end of file diff --git a/icons/example.html b/icons/example.html index 80cfd835..f6e0e7f2 100644 --- a/icons/example.html +++ b/icons/example.html @@ -1,2 +1,2 @@ -+
diff --git a/license.cs.txt b/license.cs.txt index 1c73580d..9f7bb367 100644 --- a/license.cs.txt +++ b/license.cs.txt @@ -1,69 +1,69 @@ ----------------------------------------------------------------------------------- -Tento text je NEOFICILNM pekladem "Dibi license". Nevyjaduje prvn podstatu -podmnek pro en tohoto softwaru - k tomuto elu slou vhradn pvodn -anglick verze licence. ----------------------------------------------------------------------------------- - - -Dibi Licence, verze 1 -====================== - -Copyright (c) 2005, 2008 David Grudl (http://davidgrudl.com) -Vechna prva vyhrazena. - -Tato licence je prvn ujednn mezi vmi a Davidem Grudlem (dle Author) -pro poteby pouit "dibi" (dle "Software"). Zsknm, pouitm -a/nebo zkoprovnm Software projevujete souhlas s tm, e jste peetli, -porozumli a budete jednat v souladu s podmnkami tto licence. - - -POVOLEN POUIT ----------------- - -Je povoleno pouvat, koprovat, modifikovat a distribuovat Software -a jeho dokumentaci, v pvodnm i upravovanm tvaru, pro jakkoliv el, -za pedpokladu, e jsou splnny tyto podmnky: - -1. Kopie tto licenn smlouvy mus bt soust distribuce. - -2. en zdrojov kd mus zachovat ve uvedenou informaci o autorskch - prvech ve vech souborech zdrojovho kdu. - -3. en binrn tvar mus reprodukovat ve uvedenou informaci o autorskch - prvech v dokumentaci a/nebo jinch materilech poskytovanch s distribuc. - -4. Produkty odvozen od Software mus obsahovat potvrzen, e jsou odvozen - od "dibi", ve sv dokumentaci a/nebo jinch materilech - poskytovanch s distribuc. - -5. Nzev "dibi" nesm bt pouit pi podpoe nebo propagaci produkt - odvozenmi ze Software bez pedchozho psemnho souhlasu Autora. - -6. Produkty odvozen od Software nesm bt nazvny "dibi", - ani se nesm "dibi" objevit v jejich nzvu bez pedchozho - psemnho souhlasu Autora. - - -ZBAVEN ZODPOVDNOSTI ---------------------- - -Souhlaste se zbavenm zodpovdnosti a krytm Autora a pispvatel vi -jakmkoliv pmm, nepmm, nhodnm nebo nslednm odjinud pochzejcm kodm, -alobm nebo sporm, jako i ped vemi souvisejcmi nklady, zvazky, -odkodnnmi, hradami nebo poplatky vyplvajcch z pouvn nebo -nesprvnho uit Software, nebo z poruen podmnek tto licence. - - -ZRUKA SE NEPOSKYTUJE ---------------------- - -TENTO SOFTWARE JE POSKYTOVN DRITELEM LICENCE A JEHO PISPVATELI "JAK STOJ A LE" -A JAKKOLIV VSLOVN NEBO PEDPOKLDAN ZRUKY VETN, ALE NEJEN, PEDPOKLDANCH -OBCHODNCH ZRUK A ZRUKY VHODNOSTI PRO JAKKOLIV EL JSOU POPENY. -DRITEL, ANI PISPVATEL NEBUDOU V DNM PPAD ODPOVDNI ZA JAKKOLIV PM, -NEPM, NHODN, ZVLTN, PKLADN NEBO VYPLVAJC KODY (VETN, ALE NEJEN, -KOD VZNIKLCH NARUENM DODVEK ZBO NEBO SLUEB; ZTRTOU POUITELNOSTI, -DAT NEBO ZISK; NEBO PERUENM OBCHODN INNOSTI) JAKKOLIV ZPSOBEN NA ZKLAD -JAKKOLIV TEORIE O ZODPOVDNOSTI, A U PLYNOUC Z JINHO SMLUVNHO VZTAHU, -URIT ZODPOVDNOSTI NEBO PEINU (VETN NEDBALOSTI) NA JAKMKOLIV ZPSOBU POUIT +---------------------------------------------------------------------------------- +Tento text je NEOFICILNM pekladem "Dibi license". Nevyjaduje prvn podstatu +podmnek pro en tohoto softwaru - k tomuto elu slou vhradn pvodn +anglick verze licence. +---------------------------------------------------------------------------------- + + +Dibi Licence, verze 1 +====================== + +Copyright (c) 2005, 2008 David Grudl (http://davidgrudl.com) +Vechna prva vyhrazena. + +Tato licence je prvn ujednn mezi vmi a Davidem Grudlem (dle Author) +pro poteby pouit "dibi" (dle "Software"). Zsknm, pouitm +a/nebo zkoprovnm Software projevujete souhlas s tm, e jste peetli, +porozumli a budete jednat v souladu s podmnkami tto licence. + + +POVOLEN POUIT +---------------- + +Je povoleno pouvat, koprovat, modifikovat a distribuovat Software +a jeho dokumentaci, v pvodnm i upravovanm tvaru, pro jakkoliv el, +za pedpokladu, e jsou splnny tyto podmnky: + +1. Kopie tto licenn smlouvy mus bt soust distribuce. + +2. en zdrojov kd mus zachovat ve uvedenou informaci o autorskch + prvech ve vech souborech zdrojovho kdu. + +3. en binrn tvar mus reprodukovat ve uvedenou informaci o autorskch + prvech v dokumentaci a/nebo jinch materilech poskytovanch s distribuc. + +4. Produkty odvozen od Software mus obsahovat potvrzen, e jsou odvozen + od "dibi", ve sv dokumentaci a/nebo jinch materilech + poskytovanch s distribuc. + +5. Nzev "dibi" nesm bt pouit pi podpoe nebo propagaci produkt + odvozenmi ze Software bez pedchozho psemnho souhlasu Autora. + +6. Produkty odvozen od Software nesm bt nazvny "dibi", + ani se nesm "dibi" objevit v jejich nzvu bez pedchozho + psemnho souhlasu Autora. + + +ZBAVEN ZODPOVDNOSTI +--------------------- + +Souhlaste se zbavenm zodpovdnosti a krytm Autora a pispvatel vi +jakmkoliv pmm, nepmm, nhodnm nebo nslednm odjinud pochzejcm kodm, +alobm nebo sporm, jako i ped vemi souvisejcmi nklady, zvazky, +odkodnnmi, hradami nebo poplatky vyplvajcch z pouvn nebo +nesprvnho uit Software, nebo z poruen podmnek tto licence. + + +ZRUKA SE NEPOSKYTUJE +--------------------- + +TENTO SOFTWARE JE POSKYTOVN DRITELEM LICENCE A JEHO PISPVATELI "JAK STOJ A LE" +A JAKKOLIV VSLOVN NEBO PEDPOKLDAN ZRUKY VETN, ALE NEJEN, PEDPOKLDANCH +OBCHODNCH ZRUK A ZRUKY VHODNOSTI PRO JAKKOLIV EL JSOU POPENY. +DRITEL, ANI PISPVATEL NEBUDOU V DNM PPAD ODPOVDNI ZA JAKKOLIV PM, +NEPM, NHODN, ZVLTN, PKLADN NEBO VYPLVAJC KODY (VETN, ALE NEJEN, +KOD VZNIKLCH NARUENM DODVEK ZBO NEBO SLUEB; ZTRTOU POUITELNOSTI, +DAT NEBO ZISK; NEBO PERUENM OBCHODN INNOSTI) JAKKOLIV ZPSOBEN NA ZKLAD +JAKKOLIV TEORIE O ZODPOVDNOSTI, A U PLYNOUC Z JINHO SMLUVNHO VZTAHU, +URIT ZODPOVDNOSTI NEBO PEINU (VETN NEDBALOSTI) NA JAKMKOLIV ZPSOBU POUIT TOHOTO SOFTWARE, I V PPAD, E DRITEL PRV BYL UPOZORNN NA MONOST TAKOVCH KOD. \ No newline at end of file diff --git a/license.txt b/license.txt index 5d95148f..40e698dd 100644 --- a/license.txt +++ b/license.txt @@ -1,62 +1,62 @@ -The Dibi License, Version 1 -============================ - -Copyright (c) 2005, 2008 David Grudl (http://davidgrudl.com) -All rights reserved. - -This license is a legal agreement between you and David Grudl (the "Author") -for the use of "dibi" (the "Software"). By obtaining, using and/or -copying the Software, you agree that you have read, understood, and will -comply with the terms and conditions of this license. - - -PERMITTED USE -------------- - -You are permitted to use, copy, modify, and distribute the Software and its -documentation, with or without modification, for any purpose, provided that -the following conditions are met: - -1. A copy of this license agreement must be included with the distribution. - -2. Redistributions of source code must retain the above copyright notice in - all source code files. - -3. Redistributions in binary form must reproduce the above copyright notice - in the documentation and/or other materials provided with the distribution. - -4. Products derived from the Software must include an acknowledgment that - they are derived from "dibi" in their documentation and/or other - materials provided with the distribution. - -5. The name "dibi" must not be used to endorse or promote products - derived from the Software without prior written permission from Author. - -6. Products derived from the Software may not be called "dibi", - nor may "dibi" appear in their name, without prior written - permission from Author. - - -INDEMNITY ---------- - -You agree to indemnify and hold harmless the Author and any contributors -for any direct, indirect, incidental, or consequential third-party claims, -actions or suits, as well as any related expenses, liabilities, damages, -settlements or fees arising from your use or misuse of the Software, -or a violation of any terms of this license. - - -DISCLAIMER OF WARRANTY ----------------------- - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The Dibi License, Version 1 +============================ + +Copyright (c) 2005, 2008 David Grudl (http://davidgrudl.com) +All rights reserved. + +This license is a legal agreement between you and David Grudl (the "Author") +for the use of "dibi" (the "Software"). By obtaining, using and/or +copying the Software, you agree that you have read, understood, and will +comply with the terms and conditions of this license. + + +PERMITTED USE +------------- + +You are permitted to use, copy, modify, and distribute the Software and its +documentation, with or without modification, for any purpose, provided that +the following conditions are met: + +1. A copy of this license agreement must be included with the distribution. + +2. Redistributions of source code must retain the above copyright notice in + all source code files. + +3. Redistributions in binary form must reproduce the above copyright notice + in the documentation and/or other materials provided with the distribution. + +4. Products derived from the Software must include an acknowledgment that + they are derived from "dibi" in their documentation and/or other + materials provided with the distribution. + +5. The name "dibi" must not be used to endorse or promote products + derived from the Software without prior written permission from Author. + +6. Products derived from the Software may not be called "dibi", + nor may "dibi" appear in their name, without prior written + permission from Author. + + +INDEMNITY +--------- + +You agree to indemnify and hold harmless the Author and any contributors +for any direct, indirect, incidental, or consequential third-party claims, +actions or suits, as well as any related expenses, liabilities, damages, +settlements or fees arising from your use or misuse of the Software, +or a violation of any terms of this license. + + +DISCLAIMER OF WARRANTY +---------------------- + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/readme.txt b/readme.txt index d394c60f..8c55f45d 100644 --- a/readme.txt +++ b/readme.txt @@ -1,41 +1,41 @@ -Dibi (c) David Grudl, 2005-2008 (http://davidgrudl.com) - - - -Introduction ------------- - -Thank you for downloading Dibi! - -Database access functions in PHP are not standardised. This is class library -to hide the differences between the different databases access. - -The files in this archive are released under the Dibi license. -See license.txt in this directory for a copy of the license. - - - -Documentation and Examples --------------------------- - -Refer to the 'examples' directory for examples. Dibi documentation is -available on the homepage: - -http://dibiphp.com - - - -Dibi.compact ------------- - -This is shrinked single-file version of whole Dibi, useful when you don't -want to modify library, but just use it. - -This is exactly the same as normal version, just only comments and -whitespaces are removed. - - - ------ -For more information, visit the author's weblog (in czech language): -http://phpfashion.com +Dibi (c) David Grudl, 2005-2008 (http://davidgrudl.com) + + + +Introduction +------------ + +Thank you for downloading Dibi! + +Database access functions in PHP are not standardised. This is class library +to hide the differences between the different databases access. + +The files in this archive are released under the Dibi license. +See license.txt in this directory for a copy of the license. + + + +Documentation and Examples +-------------------------- + +Refer to the 'examples' directory for examples. Dibi documentation is +available on the homepage: + +http://dibiphp.com + + + +Dibi.compact +------------ + +This is shrinked single-file version of whole Dibi, useful when you don't +want to modify library, but just use it. + +This is exactly the same as normal version, just only comments and +whitespaces are removed. + + + +----- +For more information, visit the author's weblog (in czech language): +http://phpfashion.com diff --git a/version.txt b/version.txt index a89c6c34..a111776a 100644 --- a/version.txt +++ b/version.txt @@ -1,4 +1,3 @@ -Dibi version 0.9 - -Revision: $WCREV$ -Date: $WCDATE$ +Dibi 0.9 (revision $WCREV$) + +Released on $WCDATE$