From a50a24435cf59529c5d97ca149abe2d51121e284 Mon Sep 17 00:00:00 2001 From: Andrey Kutejko Date: Sat, 8 Jun 2013 19:19:40 +0300 Subject: [PATCH] magic-call-based DB listeners --- ipf/orm.php | 1 - ipf/orm/configurable.php | 43 ------------------- ipf/orm/connection.php | 66 +++++++++++++++++------------ ipf/orm/connection/statement.php | 13 +++--- ipf/orm/eventlistener.php | 38 ----------------- ipf/orm/eventlistener/interface.php | 27 ------------ ipf/orm/manager.php | 2 +- ipf/orm/transaction.php | 30 ++++++------- ipf/project.php | 12 +++--- 9 files changed, 65 insertions(+), 167 deletions(-) delete mode 100644 ipf/orm/eventlistener.php delete mode 100644 ipf/orm/eventlistener/interface.php diff --git a/ipf/orm.php b/ipf/orm.php index 72bc2ce..348c236 100644 --- a/ipf/orm.php +++ b/ipf/orm.php @@ -98,7 +98,6 @@ final class IPF_ORM { const ATTR_STRINGIFY_FETCHES = 17; const ATTR_MAX_COLUMN_LEN = 18; - const ATTR_LISTENER = 100; const ATTR_QUOTE_IDENTIFIER = 101; const ATTR_FIELD_CASE = 102; const ATTR_IDXNAME_FORMAT = 103; diff --git a/ipf/orm/configurable.php b/ipf/orm/configurable.php index 81f5196..c7ca7fb 100644 --- a/ipf/orm/configurable.php +++ b/ipf/orm/configurable.php @@ -45,9 +45,6 @@ abstract class IPF_ORM_Configurable extends IPF_ORM_Locator_Injectable } switch ($attribute) { - case IPF_ORM::ATTR_LISTENER: - $this->setEventListener($value); - break; case IPF_ORM::ATTR_COLL_KEY: if ( ! ($this instanceof IPF_ORM_Table)) { throw new IPF_ORM_Exception("This attribute can only be set at table level."); @@ -186,11 +183,6 @@ abstract class IPF_ORM_Configurable extends IPF_ORM_Locator_Injectable return true; } - public function setEventListener($listener) - { - return $this->setListener($listener); - } - public function addRecordListener($listener, $name = null) { if ( ! isset($this->attributes[IPF_ORM::ATTR_RECORD_LISTENER]) || @@ -226,41 +218,6 @@ abstract class IPF_ORM_Configurable extends IPF_ORM_Locator_Injectable return $this; } - public function addListener($listener, $name = null) - { - if ( ! isset($this->attributes[IPF_ORM::ATTR_LISTENER]) || - ! ($this->attributes[IPF_ORM::ATTR_LISTENER] instanceof IPF_ORM_EventListener_Chain)) { - - $this->attributes[IPF_ORM::ATTR_LISTENER] = new IPF_ORM_EventListener_Chain(); - } - $this->attributes[IPF_ORM::ATTR_LISTENER]->add($listener, $name); - - return $this; - } - - public function getListener() - { - if ( ! isset($this->attributes[IPF_ORM::ATTR_LISTENER])) { - if (isset($this->parent)) { - return $this->parent->getListener(); - } - return null; - } - return $this->attributes[IPF_ORM::ATTR_LISTENER]; - } - - public function setListener($listener) - { - if ( ! ($listener instanceof IPF_ORM_EventListener_Interface) - && ! ($listener instanceof IPF_ORM_Overloadable) - ) { - throw new IPF_ORM_Exception("Couldn't set eventlistener. EventListeners should implement either IPF_ORM_EventListener_Interface or IPF_ORM_Overloadable"); - } - $this->attributes[IPF_ORM::ATTR_LISTENER] = $listener; - - return $this; - } - public function getAttribute($attribute) { if (is_string($attribute)) { diff --git a/ipf/orm/connection.php b/ipf/orm/connection.php index ab0d593..ce37457 100644 --- a/ipf/orm/connection.php +++ b/ipf/orm/connection.php @@ -45,6 +45,8 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta ); protected $_count = 0; + public $dbListeners = array(); + public function __construct(IPF_ORM_Manager $manager, $adapter, $user = null, $pass = null) { if (is_object($adapter)) { @@ -69,11 +71,12 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta } $this->setParent($manager); + $this->dbListeners = $manager->dbListeners; $this->setAttribute(IPF_ORM::ATTR_CASE, IPF_ORM::CASE_NATURAL); $this->setAttribute(IPF_ORM::ATTR_ERRMODE, IPF_ORM::ERRMODE_EXCEPTION); - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->onOpen($this); + $this->notifyDBListeners('onOpen', $this); } public function getOptions() @@ -213,21 +216,21 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_CONNECT); - $this->getListener()->preConnect($event); + $this->notifyDBListeners('preConnect', $event); $e = explode(':', $this->options['dsn']); $found = false; if (extension_loaded('pdo')) { if (in_array($e[0], PDO::getAvailableDrivers())) { - try { + try { $this->dbh = new PDO($this->options['dsn'], $this->options['username'], (!$this->options['password'] ? '':$this->options['password']), $this->options['other']); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - } catch (PDOException $e) { - throw new IPF_ORM_Exception('PDO Connection Error: ' . $e->getMessage()); - } + } catch (PDOException $e) { + throw new IPF_ORM_Exception('PDO Connection Error: ' . $e->getMessage()); + } $found = true; } } @@ -247,7 +250,7 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta $this->isConnected = true; - $this->getListener()->postConnect($event); + $this->notifyDBListeners('postConnect', $event); return true; } @@ -387,8 +390,7 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta foreach ($arr as $k => $v) { $arr[$k] = $this->quoteIdentifier($v, $checkOption); } - - return $arr; + return $arr; } public function convertBooleans($item) @@ -455,20 +457,21 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta try { $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_PREPARE, $statement); - - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->prePrepare($event); + + $this->notifyDBListeners('prePrepare', $event); $stmt = false; - + if ( ! $event->skipOperation) { $stmt = $this->dbh->prepare($statement); } - - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->postPrepare($event); - + + $this->notifyDBListeners('postPrepare', $event); + return new IPF_ORM_Connection_Statement($this, $stmt); - } catch(IPF_ORM_Exception_Adapter $e) { - } catch(PDOException $e) { } + } catch (IPF_ORM_Exception_Adapter $e) { + } catch (PDOException $e) { + } $this->rethrowException($e, $this); } @@ -510,18 +513,19 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta } else { $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_QUERY, $query, $params); - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->preQuery($event); + $this->notifyDBListeners('preQuery', $event); if ( ! $event->skipOperation) { $stmt = $this->dbh->query($query); $this->_count++; } - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->postQuery($event); + $this->notifyDBListeners('postQuery', $event); return $stmt; } } catch (IPF_ORM_Exception_Adapter $e) { - } catch (PDOException $e) { } + } catch (PDOException $e) { + } $this->rethrowException($e, $this); } @@ -539,13 +543,13 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta } else { $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_EXEC, $query, $params); - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->preExec($event); + $this->notifyDBListeners('preExec', $event); if ( ! $event->skipOperation) { $count = $this->dbh->exec($query); $this->_count++; } - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->postExec($event); + $this->notifyDBListeners('postExec', $event); return $count; } @@ -559,7 +563,7 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta { $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_ERROR); - $this->getListener()->preError($event); + $this->notifyDBListeners('preError', $event); $name = 'IPF_ORM_Exception_' . $this->driverName; @@ -573,7 +577,7 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta throw $exc; } - $this->getListener()->postError($event); + $this->notifyDBListeners('postError', $event); } public function hasTable($name) @@ -661,14 +665,14 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta { $event = new IPF_ORM_Event($this, IPF_ORM_Event::CONN_CLOSE); - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->preClose($event); + $this->notifyDBListeners('preClose', $event); $this->clear(); unset($this->dbh); $this->isConnected = false; - $this->getAttribute(IPF_ORM::ATTR_LISTENER)->postClose($event); + $this->notifyDBListeners('postClose', $event); } public function getTransactionLevel() @@ -817,7 +821,7 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta if ($info['unix_socket']) { $pdoDsn = $info['scheme'] . ':unix_socket=' . $info['unix_socket']; } else { - $pdoDsn = $info['scheme'] . ':host=' . $info['host']; + $pdoDsn = $info['scheme'] . ':host=' . $info['host']; } if (isset($this->export->tmpConnectionDatabase) && $this->export->tmpConnectionDatabase) { @@ -845,4 +849,12 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta { return IPF_ORM_Utils::getConnectionAsString($this); } + + public function notifyDBListeners($method, $event) + { + foreach ($this->dbListeners as $listener) + if (method_exists($listener, $method)) + $listener->$method($event); + } } + diff --git a/ipf/orm/connection/statement.php b/ipf/orm/connection/statement.php index d29432b..1657b88 100644 --- a/ipf/orm/connection/statement.php +++ b/ipf/orm/connection/statement.php @@ -78,7 +78,7 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac { try { $event = new IPF_ORM_Event($this, IPF_ORM_Event::STMT_EXECUTE, $this->getQuery(), $params); - $this->_conn->getListener()->preStmtExecute($event); + $this->_conn->notifyDBListeners('preStmtExecute', $event); $result = true; if ( ! $event->skipOperation) { @@ -86,7 +86,7 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac $this->_conn->incrementQueryCount(); } - $this->_conn->getListener()->postStmtExecute($event); + $this->_conn->notifyDBListeners('postStmtExecute', $event); return $result; } catch (PDOException $e) { @@ -108,13 +108,13 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac $event->cursorOrientation = $cursorOrientation; $event->cursorOffset = $cursorOffset; - $data = $this->_conn->getListener()->preFetch($event); + $data = $this->_conn->notifyDBListeners('preFetch', $event); if ( ! $event->skipOperation) { $data = $this->_stmt->fetch($fetchMode, $cursorOrientation, $cursorOffset); } - $this->_conn->getListener()->postFetch($event); + $this->_conn->notifyDBListeners('postFetch', $event); return $data; } @@ -126,7 +126,7 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac $event->fetchMode = $fetchMode; $event->columnIndex = $columnIndex; - $this->_conn->getListener()->preFetchAll($event); + $this->_conn->notifyDBListeners('preFetchAll', $event); if ( ! $event->skipOperation) { if ($columnIndex !== null) { @@ -138,7 +138,7 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac $event->data = $data; } - $this->_conn->getListener()->postFetchAll($event); + $this->_conn->notifyDBListeners('postFetchAll', $event); return $data; } @@ -183,3 +183,4 @@ class IPF_ORM_Connection_Statement implements IPF_ORM_Adapter_Statement_Interfac return $this->_stmt->setFetchMode($mode, $arg1, $arg2); } } + diff --git a/ipf/orm/eventlistener.php b/ipf/orm/eventlistener.php deleted file mode 100644 index 1aea865..0000000 --- a/ipf/orm/eventlistener.php +++ /dev/null @@ -1,38 +0,0 @@ - null, IPF_ORM::ATTR_QUERY_CACHE => null, IPF_ORM::ATTR_LOAD_REFERENCES => true, - IPF_ORM::ATTR_LISTENER => new IPF_ORM_EventListener(), IPF_ORM::ATTR_RECORD_LISTENER => new IPF_ORM_Record_Listener(), IPF_ORM::ATTR_THROW_EXCEPTIONS => true, IPF_ORM::ATTR_QUERY_LIMIT => IPF_ORM::LIMIT_RECORDS, diff --git a/ipf/orm/transaction.php b/ipf/orm/transaction.php index b4d08d6..c61c8c4 100644 --- a/ipf/orm/transaction.php +++ b/ipf/orm/transaction.php @@ -60,26 +60,24 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module public function beginTransaction($savepoint = null) { $this->conn->connect(); - $listener = $this->conn->getAttribute(IPF_ORM::ATTR_LISTENER); - if ( ! is_null($savepoint)) { $this->savePoints[] = $savepoint; $event = new IPF_ORM_Event($this, IPF_ORM_Event::SAVEPOINT_CREATE); - $listener->preSavepointCreate($event); + $this->conn->notifyDBListeners('preSavepointCreate', $event); if ( ! $event->skipOperation) { $this->createSavePoint($savepoint); } - $listener->postSavepointCreate($event); + $this->conn->notifyDBListeners('postSavepointCreate', $event); } else { if ($this->_nestingLevel == 0) { $event = new IPF_ORM_Event($this, IPF_ORM_Event::TX_BEGIN); - $listener->preTransactionBegin($event); + $this->conn->notifyDBListeners('preTransactionBegin', $event); if ( ! $event->skipOperation) { try { @@ -88,7 +86,7 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module throw new IPF_ORM_Exception($e->getMessage()); } } - $listener->postTransactionBegin($event); + $this->conn->notifyDBListeners('postTransactionBegin', $event); } } @@ -105,20 +103,18 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module $this->conn->connect(); - $listener = $this->conn->getAttribute(IPF_ORM::ATTR_LISTENER); - if ( ! is_null($savepoint)) { $this->_nestingLevel -= $this->removeSavePoints($savepoint); $event = new IPF_ORM_Event($this, IPF_ORM_Event::SAVEPOINT_COMMIT); - $listener->preSavepointCommit($event); + $this->conn->notifyDBListeners('preSavepointCommit', $event); if ( ! $event->skipOperation) { $this->releaseSavePoint($savepoint); } - $listener->postSavepointCommit($event); + $this->conn->notifyDBListeners('postSavepointCommit', $event); } else { if ($this->_nestingLevel == 1 || $this->_internalNestingLevel == 1) { @@ -141,11 +137,11 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module $event = new IPF_ORM_Event($this, IPF_ORM_Event::TX_COMMIT); - $listener->preTransactionCommit($event); + $this->conn->notifyDBListeners('preTransactionCommit', $event); if ( ! $event->skipOperation) { $this->_doCommit(); } - $listener->postTransactionCommit($event); + $this->conn->notifyDBListeners('postTransactionCommit', $event); } } @@ -174,24 +170,22 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module return false; } - $listener = $this->conn->getAttribute(IPF_ORM::ATTR_LISTENER); - if ( ! is_null($savepoint)) { $this->_nestingLevel -= $this->removeSavePoints($savepoint); $event = new IPF_ORM_Event($this, IPF_ORM_Event::SAVEPOINT_ROLLBACK); - $listener->preSavepointRollback($event); + $this->conn->notifyDBListeners('preSavepointRollback', $event); if ( ! $event->skipOperation) { $this->rollbackSavePoint($savepoint); } - $listener->postSavepointRollback($event); + $this->conn->notifyDBListeners('postSavepointRollback', $event); } else { $event = new IPF_ORM_Event($this, IPF_ORM_Event::TX_ROLLBACK); - $listener->preTransactionRollback($event); + $this->conn->notifyDBListeners('preTransactionRollback', $event); if ( ! $event->skipOperation) { $this->_nestingLevel = 0; @@ -203,7 +197,7 @@ class IPF_ORM_Transaction extends IPF_ORM_Connection_Module } } - $listener->postTransactionRollback($event); + $this->conn->notifyDBListeners('postTransactionRollback', $event); } return true; diff --git a/ipf/project.php b/ipf/project.php index cf34d40..4b7adec 100644 --- a/ipf/project.php +++ b/ipf/project.php @@ -114,18 +114,18 @@ final class IPF_Project{ $cli->run(); } - public function run(){ + public function run() { $dsn = IPF::get('dsn'); if ($dsn=='') throw new IPF_Exception_Panic('Specify dsn in config file'); - IPF_ORM_Manager::getInstance()->openConnection($dsn, null, true, IPF::get('db_persistent', false)); - - if (IPF::get('debug')){ + if (IPF::get('debug')) { $this->sqlProfiler = new IPF_ORM_Connection_Profiler(); - IPF_ORM_Manager::getInstance()->getCurrentConnection()->setListener($this->sqlProfiler); + IPF_ORM_Manager::getInstance()->dbListeners[] = $this->sqlProfiler; } - + + IPF_ORM_Manager::getInstance()->openConnection($dsn, null, true, IPF::get('db_persistent', false)); + if (php_sapi_name() == 'cli'){ $this->cli(); return true; -- 2.49.0