From: Roland Haeder Date: Mon, 16 Mar 2015 18:57:33 +0000 (+0100) Subject: Renamed DatabaseResult to CachedDatabaseResult as it is actually "caching" the X-Git-Url: https://git.mxchange.org/?p=core.git;a=commitdiff_plain;h=36dfe2c7247a1e6460826b41ce2cc011bb2d4ef9 Renamed DatabaseResult to CachedDatabaseResult as it is actually "caching" the whole result. This means that the result is kept in array and this result can be used as an iterator to "walk" over the whole result. Later on if a non-cached version is coming the iteration will callback the backend for the actual iteration. Signed-off-by: Roland Häder --- diff --git a/inc/classes/main/class_BaseFrameworkSystem.php b/inc/classes/main/class_BaseFrameworkSystem.php index 94769e12..7829b368 100644 --- a/inc/classes/main/class_BaseFrameworkSystem.php +++ b/inc/classes/main/class_BaseFrameworkSystem.php @@ -1894,7 +1894,8 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface { // Do we have an entry? if ($this->getResultInstance()->valid() === FALSE) { - throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT); + // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available + throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT); } // END - if // Get next entry diff --git a/inc/classes/main/database/class_BaseDatabaseWrapper.php b/inc/classes/main/database/class_BaseDatabaseWrapper.php index 7653f4d2..77e530fd 100644 --- a/inc/classes/main/database/class_BaseDatabaseWrapper.php +++ b/inc/classes/main/database/class_BaseDatabaseWrapper.php @@ -194,7 +194,8 @@ class BaseDatabaseWrapper extends BaseFrameworkSystem { } } - // Create an instance of a DatabaseResult class with the given result + // Create an instance of a CachedDatabaseResult class with the given result + // @TODO Minor: Update above comment to e.g. BaseDatabaseResult $resultInstance = ObjectFactory::createObjectByConfiguredName('database_result_class', array($result)); // And return the instance diff --git a/inc/classes/main/result/class_CachedDatabaseResult.php b/inc/classes/main/result/class_CachedDatabaseResult.php new file mode 100644 index 00000000..b0076ffc --- /dev/null +++ b/inc/classes/main/result/class_CachedDatabaseResult.php @@ -0,0 +1,419 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.shipsimu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class CachedDatabaseResult extends BaseFrameworkSystem implements SearchableResult, UpdateableResult, SeekableIterator { + // Exception constants + const EXCEPTION_INVALID_DATABASE_RESULT = 0x1c0; + const EXCEPTION_RESULT_UPDATE_FAILED = 0x1c1; + + /** + * Current position in array + */ + private $currentPos = -1; + + /** + * Current row + */ + private $currentRow = NULL; + + /** + * Result array + */ + private $resultArray = array(); + + /** + * Array of out-dated entries + */ + private $outDated = array(); + + /** + * Affected rows + */ + private $affectedRows = 0; + + /** + * Found value + */ + private $foundValue = ''; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this result by a provided result array + * + * @param $resultArray The array holding the result from query + * @return $resultInstance An instance of this class + */ + public static final function createCachedDatabaseResult (array $resultArray) { + // Get a new instance + $resultInstance = new CachedDatabaseResult(); + + // Set the result array + $resultInstance->setResultArray($resultArray); + + // Set affected rows + $resultInstance->setAffectedRows(count($resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS])); + + // Return the instance + return $resultInstance; + } + + /** + * Setter for result array + * + * @param $resultArray The array holding the result from query + * @return void + */ + protected final function setResultArray (array $resultArray) { + $this->resultArray = $resultArray; + } + + /** + * Updates the current entry by given update criteria + * + * @param $updateInstance An instance of an Updateable criteria + * @return void + */ + private function updateCurrentEntryByCriteria (LocalUpdateCriteria $updateInstance) { + // Get the current entry key + $entryKey = $this->key(); + + // Now get the update criteria array and update all entries + foreach ($updateInstance->getUpdateCriteria() as $criteriaKey => $criteriaValue) { + // Update data + $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$entryKey][$criteriaKey] = $criteriaValue; + + // Mark it as out-dated + $this->outDated[$criteriaKey] = 1; + } // END - foreach + } + + /** + * "Iterator" method next() to advance to the next valid entry. This method + * does also check if result is invalid + * + * @return $nextValid Whether the next entry is valid + */ + public function next () { + // Default is not valid + $nextValid = FALSE; + + // Is the result valid? + if ($this->valid()) { + // Next entry found, so count one up and cache it + $this->currentPos++; + $this->currentRow = $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos]; + $nextValid = TRUE; + } // END - if + + // Return the result + return $nextValid; + } + + /** + * Seeks for to a specified position + * + * @param $index Index to seek for + * @return void + */ + public function seek ($index) { + // Rewind to beginning + $this->rewind(); + + // Search for the entry + while (($this->currentPos < $index) && ($this->valid())) { + // Continue on + $this->next(); + } // END - while + } + + /** + * Gives back the current position or null if not found + * + * @return $current Current element to give back + */ + public function current () { + // Default is not found + $current = NULL; + + // Does the current enty exist? + if (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos])) { + // Then get it + $current = $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos]; + } // END - if + + // Return the result + return $current; + } + + /** + * Checks if next() and rewind will give a valid result + * + * @return $isValid Whether the next/rewind entry is valid + */ + public function valid () { + // By default nothing is valid + $isValid = FALSE; + + // Debug message + //*NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] this->currentPos=' . $this->currentPos); + + // Check if all is fine ... + if (($this->ifStatusIsOkay()) && (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][($this->currentPos + 1)])) && (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][0]))) { + // All fine! + $isValid = TRUE; + } // END - if + + // Return the result + return $isValid; + } + + /** + * Returns count of entries + * + * @return $isValid Whether the next/rewind entry is valid + */ + public function count () { + // Return it + return count($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS]); + } + + /** + * Determines whether the status of the query was fine (BaseDatabaseBackend::RESULT_OKAY) + * + * @return $ifStatusOkay Whether the status of the query was okay + */ + public function ifStatusIsOkay () { + $ifStatusOkay = ((isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_STATUS])) && ($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_STATUS] === BaseDatabaseBackend::RESULT_OKAY)); + //*NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] ifStatusOkay=' . intval($ifStatusOkay)); + return $ifStatusOkay; + } + + /** + * Gets the current key of iteration + * + * @return $currentPos Key from iterator + */ + public function key () { + return $this->currentPos; + } + + /** + * Rewind to the beginning and clear array $currentRow + * + * @return void + */ + public function rewind () { + $this->currentPos = -1; + $this->currentRow = array(); + } + + /** + * Searches for an entry in data result and returns it + * + * @param $criteriaInstance The criteria to look inside the data set + * @return $result Found result entry + * @todo 0% done + */ + public function searchEntry (LocalSearchCriteria $criteriaInstance) { + $this->debugBackTrace('[' . '[' . __METHOD__ . ':' . __LINE__ . ']: Unfinished!'); + } + + /** + * Adds an update request to the database result for writing it to the + * database layer + * + * @param $criteriaInstance An instance of a updateable criteria + * @return void + * @throws ResultUpdateException If no result was updated + */ + public function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance) { + // Rewind the pointer + $this->rewind(); + + // Get search criteria + $searchInstance = $criteriaInstance->getSearchInstance(); + + // And start looking for the result + $foundEntries = 0; + while (($this->valid()) && ($foundEntries < $searchInstance->getLimit())) { + // Get next entry + $this->next(); + $currentEntry = $this->current(); + + // Is this entry found? + if ($searchInstance->ifEntryMatches($currentEntry)) { + // Update this entry + $this->updateCurrentEntryByCriteria($criteriaInstance); + + // Count one up + $foundEntries++; + } // END - if + } // END - while + + // If no entry is found/updated throw an exception + if ($foundEntries == 0) { + // Throw an exception here + throw new ResultUpdateException($this, self::EXCEPTION_RESULT_UPDATE_FAILED); + } // END - if + + // Set affected rows + $this->setAffectedRows($foundEntries); + + // Set update instance + $this->setUpdateInstance($criteriaInstance); + } + + /** + * Setter for affected rows + * + * @param $rows Number of affected rows + * @return void + */ + public final function setAffectedRows ($rows) { + $this->affectedRows = $rows; + } + + /** + * Getter for affected rows + * + * @return $rows Number of affected rows + */ + public final function getAffectedRows () { + return $this->affectedRows; + } + + /** + * Getter for found value of previous found() call + * + * @return $foundValue Found value of previous found() call + */ + public final function getFoundValue () { + return $this->foundValue; + } + + /** + * Checks whether we have out-dated entries or not + * + * @return $needsUpdate Whether we have out-dated entries + */ + public function ifDataNeedsFlush () { + $needsUpdate = (count($this->outDated) > 0); + return $needsUpdate; + } + + /** + * Adds registration elements to a given dataset instance + * + * @param $criteriaInstance An instance of a StoreableCriteria class + * @param $requestInstance An instance of a Requestable class + * @return void + */ + public function addElementsToDataSet (StoreableCriteria $criteriaInstance, Requestable $requestInstance = NULL) { + // Walk only through out-dated columns + foreach ($this->outDated as $key => $dummy) { + // Does this key exist? + //* DEBUG: */ echo "outDated: {$key}
\n"; + if ($this->find($key)) { + // Then update it + $criteriaInstance->addCriteria($key, $this->getFoundValue()); + } // END - if + } // END - foreach + } + + /** + * Find a key inside the result array + * + * @param $key The key we shall find + * @return $found Whether the key was found or not + */ + public function find ($key) { + // By default nothing is found + $found = FALSE; + + // Rewind the pointer + $this->rewind(); + + // Walk through all entries + while ($this->valid()) { + // Advance to next entry + $this->next(); + + // Get the whole array + $currentEntry = $this->current(); + + // Is the element there? + if (isset($currentEntry[$key])) { + // Okay, found! + $found = TRUE; + + // So "cache" it + $this->foundValue = $currentEntry[$key]; + + // And stop searching + break; + } // END - if + } // END - while + + // Return the result + return $found; + } + + /** + * Solver for result index value with call-back method + * + * @param $databaseColumn Database column where the index might be found + * @param $wrapperInstance The wrapper instance to ask for array element + * @para $callBack Call-back object for setting the index; + * 0=object instance,1=method name + * @return void + * @todo Find a caching way without modifying the result array + */ + public function solveResultIndex ($databaseColumn, DatabaseWrapper $wrapperInstance, array $callBack) { + // By default nothing is found + $indexValue = 0; + + // Is the element in result itself found? + if ($this->find($databaseColumn)) { + // Use this value + $indexValue = $this->getFoundValue(); + } elseif ($this->find($wrapperInstance->getIndexKey())) { + // Use this value + $indexValue = $this->getFoundValue(); + } + + // Set the index + call_user_func_array($callBack, array($indexValue)); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/result/class_DatabaseResult.php b/inc/classes/main/result/class_DatabaseResult.php deleted file mode 100644 index 97bf28b4..00000000 --- a/inc/classes/main/result/class_DatabaseResult.php +++ /dev/null @@ -1,419 +0,0 @@ - - * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team - * @license GNU GPL 3.0 or any newer version - * @link http://www.shipsimu.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, UpdateableResult, SeekableIterator { - // Exception constants - const EXCEPTION_INVALID_DATABASE_RESULT = 0x1c0; - const EXCEPTION_RESULT_UPDATE_FAILED = 0x1c1; - - /** - * Current position in array - */ - private $currentPos = -1; - - /** - * Current row - */ - private $currentRow = NULL; - - /** - * Result array - */ - private $resultArray = array(); - - /** - * Array of out-dated entries - */ - private $outDated = array(); - - /** - * Affected rows - */ - private $affectedRows = 0; - - /** - * Found value - */ - private $foundValue = ''; - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Creates an instance of this result by a provided result array - * - * @param $resultArray The array holding the result from query - * @return $resultInstance An instance of this class - */ - public static final function createDatabaseResult (array $resultArray) { - // Get a new instance - $resultInstance = new DatabaseResult(); - - // Set the result array - $resultInstance->setResultArray($resultArray); - - // Set affected rows - $resultInstance->setAffectedRows(count($resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS])); - - // Return the instance - return $resultInstance; - } - - /** - * Setter for result array - * - * @param $resultArray The array holding the result from query - * @return void - */ - protected final function setResultArray (array $resultArray) { - $this->resultArray = $resultArray; - } - - /** - * Updates the current entry by given update criteria - * - * @param $updateInstance An instance of an Updateable criteria - * @return void - */ - private function updateCurrentEntryByCriteria (LocalUpdateCriteria $updateInstance) { - // Get the current entry key - $entryKey = $this->key(); - - // Now get the update criteria array and update all entries - foreach ($updateInstance->getUpdateCriteria() as $criteriaKey => $criteriaValue) { - // Update data - $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$entryKey][$criteriaKey] = $criteriaValue; - - // Mark it as out-dated - $this->outDated[$criteriaKey] = 1; - } // END - foreach - } - - /** - * "Iterator" method next() to advance to the next valid entry. This method - * does also check if result is invalid - * - * @return $nextValid Whether the next entry is valid - */ - public function next () { - // Default is not valid - $nextValid = FALSE; - - // Is the result valid? - if ($this->valid()) { - // Next entry found, so count one up and cache it - $this->currentPos++; - $this->currentRow = $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos]; - $nextValid = TRUE; - } // END - if - - // Return the result - return $nextValid; - } - - /** - * Seeks for to a specified position - * - * @param $index Index to seek for - * @return void - */ - public function seek ($index) { - // Rewind to beginning - $this->rewind(); - - // Search for the entry - while (($this->currentPos < $index) && ($this->valid())) { - // Continue on - $this->next(); - } // END - while - } - - /** - * Gives back the current position or null if not found - * - * @return $current Current element to give back - */ - public function current () { - // Default is not found - $current = NULL; - - // Does the current enty exist? - if (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos])) { - // Then get it - $current = $this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][$this->currentPos]; - } // END - if - - // Return the result - return $current; - } - - /** - * Checks if next() and rewind will give a valid result - * - * @return $isValid Whether the next/rewind entry is valid - */ - public function valid () { - // By default nothing is valid - $isValid = FALSE; - - // Debug message - //*NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] this->currentPos=' . $this->currentPos); - - // Check if all is fine ... - if (($this->ifStatusIsOkay()) && (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][($this->currentPos + 1)])) && (isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS][0]))) { - // All fine! - $isValid = TRUE; - } // END - if - - // Return the result - return $isValid; - } - - /** - * Returns count of entries - * - * @return $isValid Whether the next/rewind entry is valid - */ - public function count () { - // Return it - return count($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_ROWS]); - } - - /** - * Determines whether the status of the query was fine (BaseDatabaseBackend::RESULT_OKAY) - * - * @return $ifStatusOkay Whether the status of the query was okay - */ - public function ifStatusIsOkay () { - $ifStatusOkay = ((isset($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_STATUS])) && ($this->resultArray[BaseDatabaseBackend::RESULT_INDEX_STATUS] === BaseDatabaseBackend::RESULT_OKAY)); - //*NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] ifStatusOkay=' . intval($ifStatusOkay)); - return $ifStatusOkay; - } - - /** - * Gets the current key of iteration - * - * @return $currentPos Key from iterator - */ - public function key () { - return $this->currentPos; - } - - /** - * Rewind to the beginning and clear array $currentRow - * - * @return void - */ - public function rewind () { - $this->currentPos = -1; - $this->currentRow = array(); - } - - /** - * Searches for an entry in data result and returns it - * - * @param $criteriaInstance The criteria to look inside the data set - * @return $result Found result entry - * @todo 0% done - */ - public function searchEntry (LocalSearchCriteria $criteriaInstance) { - $this->debugBackTrace('[' . '[' . __METHOD__ . ':' . __LINE__ . ']: Unfinished!'); - } - - /** - * Adds an update request to the database result for writing it to the - * database layer - * - * @param $criteriaInstance An instance of a updateable criteria - * @return void - * @throws ResultUpdateException If no result was updated - */ - public function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance) { - // Rewind the pointer - $this->rewind(); - - // Get search criteria - $searchInstance = $criteriaInstance->getSearchInstance(); - - // And start looking for the result - $foundEntries = 0; - while (($this->valid()) && ($foundEntries < $searchInstance->getLimit())) { - // Get next entry - $this->next(); - $currentEntry = $this->current(); - - // Is this entry found? - if ($searchInstance->ifEntryMatches($currentEntry)) { - // Update this entry - $this->updateCurrentEntryByCriteria($criteriaInstance); - - // Count one up - $foundEntries++; - } // END - if - } // END - while - - // If no entry is found/updated throw an exception - if ($foundEntries == 0) { - // Throw an exception here - throw new ResultUpdateException($this, self::EXCEPTION_RESULT_UPDATE_FAILED); - } // END - if - - // Set affected rows - $this->setAffectedRows($foundEntries); - - // Set update instance - $this->setUpdateInstance($criteriaInstance); - } - - /** - * Setter for affected rows - * - * @param $rows Number of affected rows - * @return void - */ - public final function setAffectedRows ($rows) { - $this->affectedRows = $rows; - } - - /** - * Getter for affected rows - * - * @return $rows Number of affected rows - */ - public final function getAffectedRows () { - return $this->affectedRows; - } - - /** - * Getter for found value of previous found() call - * - * @return $foundValue Found value of previous found() call - */ - public final function getFoundValue () { - return $this->foundValue; - } - - /** - * Checks whether we have out-dated entries or not - * - * @return $needsUpdate Whether we have out-dated entries - */ - public function ifDataNeedsFlush () { - $needsUpdate = (count($this->outDated) > 0); - return $needsUpdate; - } - - /** - * Adds registration elements to a given dataset instance - * - * @param $criteriaInstance An instance of a StoreableCriteria class - * @param $requestInstance An instance of a Requestable class - * @return void - */ - public function addElementsToDataSet (StoreableCriteria $criteriaInstance, Requestable $requestInstance = NULL) { - // Walk only through out-dated columns - foreach ($this->outDated as $key => $dummy) { - // Does this key exist? - //* DEBUG: */ echo "outDated: {$key}
\n"; - if ($this->find($key)) { - // Then update it - $criteriaInstance->addCriteria($key, $this->getFoundValue()); - } // END - if - } // END - foreach - } - - /** - * Find a key inside the result array - * - * @param $key The key we shall find - * @return $found Whether the key was found or not - */ - public function find ($key) { - // By default nothing is found - $found = FALSE; - - // Rewind the pointer - $this->rewind(); - - // Walk through all entries - while ($this->valid()) { - // Advance to next entry - $this->next(); - - // Get the whole array - $currentEntry = $this->current(); - - // Is the element there? - if (isset($currentEntry[$key])) { - // Okay, found! - $found = TRUE; - - // So "cache" it - $this->foundValue = $currentEntry[$key]; - - // And stop searching - break; - } // END - if - } // END - while - - // Return the result - return $found; - } - - /** - * Solver for result index value with call-back method - * - * @param $databaseColumn Database column where the index might be found - * @param $wrapperInstance The wrapper instance to ask for array element - * @para $callBack Call-back object for setting the index; - * 0=object instance,1=method name - * @return void - * @todo Find a caching way without modifying the result array - */ - public function solveResultIndex ($databaseColumn, DatabaseWrapper $wrapperInstance, array $callBack) { - // By default nothing is found - $indexValue = 0; - - // Is the element in result itself found? - if ($this->find($databaseColumn)) { - // Use this value - $indexValue = $this->getFoundValue(); - } elseif ($this->find($wrapperInstance->getIndexKey())) { - // Use this value - $indexValue = $this->getFoundValue(); - } - - // Set the index - call_user_func_array($callBack, array($indexValue)); - } -} - -// [EOF] -?> diff --git a/inc/config.php b/inc/config.php index 900225cb..078542cc 100644 --- a/inc/config.php +++ b/inc/config.php @@ -171,7 +171,7 @@ $cfg->setConfigEntry('update_criteria_class', 'UpdateCriteria'); $cfg->setConfigEntry('file_io_class', 'FileIoHandler'); // CFG: DATABASE-RESULT-CLASS -$cfg->setConfigEntry('database_result_class', 'DatabaseResult'); +$cfg->setConfigEntry('database_result_class', 'CachedDatabaseResult'); // CFG: FILTER-CHAIN-CLASS $cfg->setConfigEntry('filter_chain_class', 'FilterChain');