diff --git a/TODO.txt b/TODO.txt
index b7b97e96..65a6da10 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1 +1 @@
-- event, log, profiler
+- event, log, profiler
diff --git a/dibi/Nette/IDebuggable.php b/dibi/Nette/IDebuggable.php
index d4f96da4..2cfc2803 100644
--- a/dibi/Nette/IDebuggable.php
+++ b/dibi/Nette/IDebuggable.php
@@ -1,41 +1,40 @@
-
- * $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
- * @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
#row | \n"; - - foreach ($row as $col => $foo) { - echo "\t\t" . htmlSpecialChars($col) . " | \n"; - } - - echo "\t
---|---|
", $i, " | \n"; - foreach ($row as $col) { - //if (is_object($col)) $col = $col->__toString(); - echo "\t\t", htmlSpecialChars($col), " | \n"; - } - echo "\t
#row | \n"; + + foreach ($row as $col => $foo) { + echo "\t\t" . htmlSpecialChars($col) . " | \n"; + } + + echo "\t
---|---|
", $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 "\n"; - - - - -// connects to MySQL using DSN -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"; -} +
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 "\n"; + + + + +// connects to MySQL using DSN +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"; +} 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 @@ -IDibiVariable example
- 'sqlite', - 'database' => 'sample.sdb', - 'format:date' => "'Y-m-d'", - 'format:datetime' => "'Y-m-d H-i-s'", -)); - - - -// generate and dump SQL -dibi::test(" -INSERT INTO [mytable]", array( - 'id' => 123, - 'date' => dibi::date('12.3.2007'), - 'stamp' => dibi::dateTime('23.1.2007 10:23'), -)); +IDibiVariable example
+ 'sqlite', + 'database' => 'sample.sdb', + 'format:date' => "'Y-m-d'", + 'format:datetime' => "'Y-m-d H-i-s'", +)); + + + +// generate and dump SQL +dibi::test(" +INSERT INTO [mytable]", array( + 'id' => 123, + 'date' => dibi::date('12.3.2007'), + 'stamp' => dibi::dateTime('23.1.2007 10:23'), +)); diff --git a/examples/dibi.table.php b/examples/dibi.table.php index 5752a1b4..31cf2190 100644 --- a/examples/dibi.table.php +++ b/examples/dibi.table.php @@ -1,88 +1,88 @@ -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 ) +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$