1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-06 14:16:39 +02:00

- removed NException, ability of catching PHP error moved to DibiDriverException

This commit is contained in:
David Grudl
2008-03-04 14:01:22 +00:00
parent 1459c6c95d
commit 2632953541
8 changed files with 125 additions and 162 deletions

View File

@@ -0,0 +1,28 @@
<?php
/**
* Nette Framework
*
* Copyright (c) 2004, 2008 David Grudl (http://www.davidgrudl.com)
*
* This source file is subject to the "Nette license" that is bundled
* with this package in the file license.txt.
*
* For more information please see http://nettephp.com/
*
* @copyright Copyright (c) 2004, 2008 David Grudl
* @license http://nettephp.com/license Nette license
* @link http://nettephp.com/
* @category Nette
* @package Nette
*/
// namespace Nette;
/**
* Custom output for Nette::Debug.
*/
interface IDebuggable
{
}

View File

@@ -1,132 +0,0 @@
<?php
/**
* dibi - tiny'n'smart database abstraction layer
* ----------------------------------------------
*
* Copyright (c) 2005, 2008 David Grudl (http://www.davidgrudl.com)
*
* This source file is subject to the "dibi license" that is bundled
* with this package in the file license.txt.
*
* For more information please see http://dibiphp.com/
*
* @copyright Copyright (c) 2004, 2008 David Grudl
* @license http://nettephp.com/license Nette license
* @link http://nettephp.com/
* @package Nette
*/
// namespace Nette;
/**
* Nette Exception base class.
*
* @author David Grudl
* @copyright Copyright (c) 2004, 2008 David Grudl
* @license http://nettephp.com/license Nette license
* @link http://nettephp.com/
* @package Nette
*/
class NException extends Exception
{
/** @var Exception */
private $cause;
/** @var callback */
private static $oldHandler;
/** @var string */
private static $handlerClass;
/**
* Initializes the cause of this throwable to the specified value.
*
* @param Exception
* @return void
*/
public function initCause(Exception $cause)
{
if ($this->cause === NULL) {
$this->cause = $cause;
} else {
throw new InvalidStateException('Cause was already assigned.');
}
}
/**
* Gets the Exception instance that caused the current exception.
*
* @return Exception
*/
public function getCause()
{
return $this->cause;
}
/**
* Returns string represenation of exception.
*
* @return string
*/
public function __toString()
{
return parent::__toString() . ($this->cause === NULL ? '' : "\nCaused by " . $this->cause->__toString());
}
/**
* Enables converting all PHP errors to exceptions.
*
* @param Exception class to be thrown
* @return void
*/
public static function catchError($class = __CLASS__)
{
self::$oldHandler = set_error_handler(array(__CLASS__, '_errorHandler'), E_ALL);
self::$handlerClass = $class;
}
/**
* Disables converting errors to exceptions.
*
* @return void
*/
public static function restore()
{
if (self::$oldHandler !== NULL) {
set_error_handler(self::$oldHandler);
self::$oldHandler = NULL;
} else {
restore_error_handler();
}
}
/**
* Internal error handler.
*/
public static function _errorHandler($code, $message, $file, $line, $context)
{
self::restore();
if (ini_get('html_errors')) {
$message = strip_tags($message);
}
throw new self::$handlerClass($message, $code);
}
}

View File

@@ -1,19 +1,19 @@
<?php <?php
/** /**
* dibi - tiny'n'smart database abstraction layer * Nette Framework
* ----------------------------------------------
* *
* Copyright (c) 2005, 2008 David Grudl (http://www.davidgrudl.com) * Copyright (c) 2004, 2008 David Grudl (http://www.davidgrudl.com)
* *
* This source file is subject to the "dibi license" that is bundled * This source file is subject to the "Nette license" that is bundled
* with this package in the file license.txt. * with this package in the file license.txt.
* *
* For more information please see http://dibiphp.com/ * For more information please see http://nettephp.com/
* *
* @copyright Copyright (c) 2004, 2008 David Grudl * @copyright Copyright (c) 2004, 2008 David Grudl
* @license http://nettephp.com/license Nette license * @license http://nettephp.com/license Nette license
* @link http://nettephp.com/ * @link http://nettephp.com/
* @category Nette
* @package Nette * @package Nette
*/ */
@@ -21,7 +21,7 @@
/** /**
* NObject is the ultimate ancestor of all instantiable classes. * Nette::Object is the ultimate ancestor of all instantiable classes.
* *
* It defines some handful methods and enhances object core of PHP: * It defines some handful methods and enhances object core of PHP:
* - access to undeclared members throws exceptions * - access to undeclared members throws exceptions
@@ -58,9 +58,8 @@
* *
* @author David Grudl * @author David Grudl
* @copyright Copyright (c) 2004, 2008 David Grudl * @copyright Copyright (c) 2004, 2008 David Grudl
* @license http://nettephp.com/license Nette license
* @link http://nettephp.com/
* @package Nette * @package Nette
* @version $Revision$ $Date$
*/ */
abstract class NObject abstract class NObject
{ {
@@ -131,6 +130,22 @@ abstract class NObject
/**
* 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. * Returns property value. Do not call directly.
* *
@@ -149,7 +164,7 @@ abstract class NObject
$m = 'get' . $name; $m = 'get' . $name;
if (self::hasAccessor($class, $m)) { if (self::hasAccessor($class, $m)) {
// ampersands: // ampersands:
// - using &__get() because declaration should be forward compatible (e.g. with NHtml) // - using &__get() because declaration should be forward compatible (e.g. with Web::Html)
// - not using &$this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value'; // - not using &$this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
$val = $this->$m(); $val = $this->$m();
return $val; return $val;
@@ -232,7 +247,7 @@ abstract class NObject
{ {
static $cache; static $cache;
if (!isset($cache[$c])) { if (!isset($cache[$c])) {
// get_class_methods returns private, protected and public methods of NObject (doesn't matter) // get_class_methods returns private, protected and public methods of Object (doesn't matter)
// and ONLY PUBLIC methods of descendants (perfect!) // and ONLY PUBLIC methods of descendants (perfect!)
// but returns static methods too (nothing doing...) // but returns static methods too (nothing doing...)
// and is much faster than reflection // and is much faster than reflection

View File

@@ -32,8 +32,8 @@ if (version_compare(PHP_VERSION, '5.1.0', '<')) {
// nette libraries // nette libraries
if (!class_exists('NotImplementedException', FALSE)) { require_once dirname(__FILE__) . '/Nette/exceptions.php'; } if (!class_exists('NotImplementedException', FALSE)) { require_once dirname(__FILE__) . '/Nette/exceptions.php'; }
if (!class_exists('NObject', FALSE)) { require_once dirname(__FILE__) . '/Nette/NObject.php'; } if (!class_exists('NObject', FALSE)) { require_once dirname(__FILE__) . '/Nette/Object.php'; }
if (!class_exists('NException', FALSE)) { require_once dirname(__FILE__) . '/Nette/NException.php'; } if (!interface_exists('IDebuggable', FALSE)) { require_once dirname(__FILE__) . '/Nette/IDebuggable.php'; }
// dibi libraries // dibi libraries
require_once dirname(__FILE__) . '/libs/interfaces.php'; require_once dirname(__FILE__) . '/libs/interfaces.php';
@@ -164,7 +164,7 @@ class dibi
*/ */
public static function connect($config = array(), $name = 0) public static function connect($config = array(), $name = 0)
{ {
if (is_array($config)) { if (is_array($config) || $config instanceof IMap) {
$config['name'] = $name; $config['name'] = $name;
} else { } else {
$config .= '&name=' . urlencode($name); $config .= '&name=' . urlencode($name);
@@ -404,9 +404,9 @@ class dibi
/** /**
* Experimental; will be used in PHP 5.3. * Replacement for majority of dibi::methods() in future.
*/ */
public static function __callStatic($name, $args) protected static function __callStatic($name, $args)
{ {
return call_user_func_array(array(self::getConnection(), $name), $args); return call_user_func_array(array(self::getConnection(), $name), $args);
} }

View File

@@ -88,22 +88,26 @@ class DibiPostgreDriver extends NObject implements IDibiDriver
} }
} }
DibiDriverException::catchError(); DibiDriverException::tryError();
if (isset($config['persistent'])) { if (isset($config['persistent'])) {
$this->connection = @pg_connect($string, PGSQL_CONNECT_FORCE_NEW); $this->connection = pg_connect($string, PGSQL_CONNECT_FORCE_NEW);
} else { } else {
$this->connection = @pg_pconnect($string, PGSQL_CONNECT_FORCE_NEW); $this->connection = pg_pconnect($string, PGSQL_CONNECT_FORCE_NEW);
}
if (DibiDriverException::catchError($msg)) {
throw new DibiDriverException($msg, 0);
} }
DibiDriverException::restore();
if (!is_resource($this->connection)) { if (!is_resource($this->connection)) {
throw new DibiDriverException('Connecting error.'); throw new DibiDriverException('Connecting error.');
} }
if (isset($config['charset'])) { if (isset($config['charset'])) {
DibiDriverException::catchError(); DibiDriverException::tryError();
@pg_set_client_encoding($this->connection, $config['charset']); pg_set_client_encoding($this->connection, $config['charset']);
DibiDriverException::restore(); if (DibiDriverException::catchError($msg)) {
throw new DibiDriverException($msg, 0);
}
} }
if (isset($config['schema'])) { if (isset($config['schema'])) {

View File

@@ -127,13 +127,15 @@ class DibiSqliteDriver extends NObject implements IDibiDriver
*/ */
public function query($sql) public function query($sql)
{ {
DibiDriverException::catchError(); DibiDriverException::tryError();
if ($this->buffered) { if ($this->buffered) {
$this->resultset = sqlite_query($this->connection, $sql); $this->resultset = sqlite_query($this->connection, $sql);
} else { } else {
$this->resultset = sqlite_unbuffered_query($this->connection, $sql); $this->resultset = sqlite_unbuffered_query($this->connection, $sql);
} }
DibiDriverException::restore(); if (DibiDriverException::catchError($msg)) {
throw new DibiDriverException($msg, sqlite_last_error($this->connection), $sql);
}
return is_resource($this->resultset); return is_resource($this->resultset);
} }

View File

@@ -58,7 +58,7 @@ class DibiConnection extends NObject
/** /**
* Creates object and (optionally) connects to a database. * Creates object and (optionally) connects to a database.
* *
* @param array|string connection parameters * @param array|string|IMap connection parameters
* @throws DibiException * @throws DibiException
*/ */
public function __construct($config) public function __construct($config)
@@ -66,6 +66,9 @@ class DibiConnection extends NObject
// DSN string // DSN string
if (is_string($config)) { if (is_string($config)) {
parse_str($config, $config); parse_str($config, $config);
} elseif ($config instanceof IMap) {
$config = $config->toArray();
} }
if (!isset($config['driver'])) { if (!isset($config['driver'])) {

View File

@@ -27,7 +27,7 @@
* @package dibi * @package dibi
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
class DibiException extends NException class DibiException extends Exception
{ {
} }
@@ -42,8 +42,11 @@ class DibiException extends NException
* @package dibi * @package dibi
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
class DibiDriverException extends DibiException class DibiDriverException extends DibiException implements IDebuggable
{ {
/** @var string */
private static $errorMsg;
/** @var string */ /** @var string */
private $sql; private $sql;
@@ -84,12 +87,52 @@ class DibiDriverException extends DibiException
/********************* error catching ****************d*g**/
/** /**
* @see NException::catchError (this is Late static binding fix * Starts catching potential errors/warnings
*
* @return void
*/ */
public static function catchError($class = __CLASS__) public static function tryError()
{ {
parent::catchError($class); 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;
} }
} }