]> git.mxchange.org Git - core.git/blobdiff - framework/main/classes/database/frontend/class_BaseDatabaseFrontend.php
Continued:
[core.git] / framework / main / classes / database / frontend / class_BaseDatabaseFrontend.php
diff --git a/framework/main/classes/database/frontend/class_BaseDatabaseFrontend.php b/framework/main/classes/database/frontend/class_BaseDatabaseFrontend.php
new file mode 100644 (file)
index 0000000..0a5aba8
--- /dev/null
@@ -0,0 +1,297 @@
+<?php
+// Own namespace
+namespace Org\Mxchange\CoreFramework\Database\Frontend;
+
+// Import framework stuff
+use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
+use Org\Mxchange\CoreFramework\Criteria\Criteria;
+use Org\Mxchange\CoreFramework\Criteria\Storing\StoreableCriteria;
+use Org\Mxchange\CoreFramework\Database\Backend\BaseDatabaseBackend;
+use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
+
+/**
+ * A generic database frontend
+ *
+ * @author             Roland Haeder <webmaster@shipsimu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 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 <http://www.gnu.org/licenses/>.
+ */
+abstract class BaseDatabaseFrontend extends BaseFrameworkSystem {
+       /**
+        * Cache instance
+        */
+       private $cacheInstance = NULL;
+
+       /**
+        * Current table name to use
+        */
+       private $tableName = 'unknown';
+
+       /**
+        * Protected constructor
+        *
+        * @return      void
+        */
+       protected function __construct ($class) {
+               // Call parent constructor
+               parent::__construct($class);
+
+               // Initialize the cache instance
+               $this->initCacheInstance();
+       }
+
+       /**
+        * Initializes the cache instance with a new object
+        *
+        * @return      void
+        */
+       private final function initCacheInstance () {
+               // Is the cache enabled?
+               if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) {
+                       // Set the new instance
+                       $this->cacheInstance = CacheFactory::getFactory()->createConfiguredCache();
+               } // END - if
+       }
+
+       /**
+        * Setter for table name
+        *
+        * @param       $tableName      Name of table name to set
+        * @return      void
+        */
+       protected final function setTableName ($tableName) {
+               $this->tableName = (string) $tableName;
+       }
+
+       /**
+        * Getter for table name
+        *
+        * @return      $tableName      Name of table name to set
+        */
+       protected final function getTableName () {
+               return $this->tableName;
+       }
+
+       /**
+        * 'Inserts' a data set instance into a local file database folder
+        *
+        * @param       $dataSetInstance        A storeable data set
+        * @param       $onlyKeys                       Only use these keys for a cache key
+        * @return      void
+        */
+       protected function queryInsertDataSet (StoreableCriteria $dataSetInstance, array $onlyKeys = []) {
+               // Default cache key is NULL
+               //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: dataSetInstance=%s,onlyKeys()=%d - CALLED!', $dataSetInstance->__toString(), count($onlyKeys)));
+               $cacheKey = NULL;
+
+               // Is cache enabled?
+               if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) {
+                       // First get a key suitable for our cache and extend it with this class name
+                       $cacheKey = $this->getCacheKeyByCriteria($dataSetInstance, $onlyKeys);
+                       //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Using cache key ' . $cacheKey . ' for purging ...');
+               } // END - if
+
+               // Does this key exists in cache?
+               //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: cacheKey[%s]=%s', gettype($cacheKey), $cacheKey));
+               if ((FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey))) {
+                       // Purge the cache
+                       //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: Calling this->cacheInstance->purgeOffset(%s) ...', $cacheKey));
+                       $this->cacheInstance->purgeOffset($cacheKey);
+               } // END - if
+
+               // Handle it over to the middleware
+               FrameworkBootstrap::getDatabaseInstance()->queryInsertDataSet($dataSetInstance);
+
+               // Trace message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: EXIT!');
+       }
+
+       /**
+        * 'Updates' a data set instance with a database layer
+        *
+        * @param       $dataSetInstance        A storeable data set
+        * @param       $onlyKeys                       Only use these keys for a cache key
+        * @return      void
+        */
+       protected function queryUpdateDataSet (StoreableCriteria $dataSetInstance, array $onlyKeys = []) {
+               // Init cache key
+               $cacheKey = NULL;
+
+               // Is cache enabled?
+               if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) {
+                       // First get a key suitable for our cache and extend it with this class name
+                       $cacheKey = $this->getCacheKeyByCriteria($dataSetInstance, $onlyKeys);
+                       //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Using cache key ' . $cacheKey . ' for purging ...');
+               } // END - if
+
+               // Does this key exists in cache?
+               if ((FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey))) {
+                       // Purge the cache
+                       $this->cacheInstance->purgeOffset($cacheKey);
+               } // END - if
+
+               // Handle it over to the middleware
+               FrameworkBootstrap::getDatabaseInstance()->queryUpdateDataSet($dataSetInstance);
+       }
+
+       /**
+        * Getter for index key
+        *
+        * @return      $indexKey       Index key
+        */
+       public final function getIndexKey () {
+               return FrameworkBootstrap::getDatabaseInstance()->getIndexKey();
+       }
+
+       /**
+        * Getter for last exception
+        *
+        * @return      $lastException  Last exception or NULL if none occured
+        */
+       public final function getLastException () {
+               return FrameworkBootstrap::getDatabaseInstance()->getLastException();
+       }
+
+       /**
+        * Do a "select" query on the current table with the given search criteria and
+        * store it in cache for later usage
+        *
+        * @param       $criteriaInstance       An instance of a Criteria class
+        * @param       $onlyKeys                       Only use these keys for a cache key
+        * @return      $resultInstance         An instance of a database result class
+        */
+       public function doSelectByCriteria (Criteria $criteriaInstance, array $onlyKeys = []) {
+               // Default cache key if cache is not enabled
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: criteriaInstance=%s,onlyKeys()=%d - CALLED!', $criteriaInstance->__toString(), count($onlyKeys)));
+               $cacheKey = NULL;
+               $result = [];
+
+               // Is the cache enabled?
+               if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) {
+                       // First get a key suitable for our cache and extend it with this class name
+                       $cacheKey = $this->getCacheKeyByCriteria($criteriaInstance, $onlyKeys);
+               } // END - if
+
+               // Does this key exists in cache?
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: cacheKey[%s]=%s', gettype($cacheKey), $cacheKey));
+               if ((FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey, BaseDatabaseBackend::RESULT_INDEX_ROWS, 1))) {
+                       // Then use this result
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: Cache used for cacheKey=%s', $cacheKey));
+                       $result = $this->cacheInstance->offsetGet($cacheKey);
+               } else {
+                       // Now it's time to ask the database layer for this select statement
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: Quering database, cacheKey=%s ...', $cacheKey));
+                       $result = FrameworkBootstrap::getDatabaseInstance()->doSelectByTableCriteria($this->getTableName(), $criteriaInstance);
+
+                       // Cache the result if not null
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: result[]=%s', gettype($result)));
+                       if (!is_null($result)) {
+                               // Is cache enabled?
+                               if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('database_cache_enabled') === true) {
+                                       // A valid result has returned from the database layer
+                                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: Setting cacheKey=%s with result()=%d entries', $cacheKey, count($result)));
+                                       $this->cacheInstance->offsetSet($cacheKey, $result);
+                               } // END - if
+                       } else {
+                               // This invalid result must be wrapped
+                               $result = array(
+                                       BaseDatabaseBackend::RESULT_INDEX_STATUS    => 'invalid',
+                                       BaseDatabaseBackend::RESULT_INDEX_EXCEPTION => FrameworkBootstrap::getDatabaseInstance()->getLastException()
+                               );
+                       }
+               }
+
+               // Create an instance of a CachedDatabaseResult class with the given result
+               // @TODO Minor: Update above comment to e.g. BaseDatabaseResult
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: result[%s]=%s,result[%s]?=%d,result[%s]?=%d', BaseDatabaseBackend::RESULT_INDEX_STATUS, $result[BaseDatabaseBackend::RESULT_INDEX_STATUS], BaseDatabaseBackend::RESULT_INDEX_ROWS, isset($result[BaseDatabaseBackend::RESULT_INDEX_ROWS]), BaseDatabaseBackend::RESULT_INDEX_EXCEPTION, isset($result[BaseDatabaseBackend::RESULT_INDEX_EXCEPTION])));
+               $resultInstance = ObjectFactory::createObjectByConfiguredName('database_result_class', array($result));
+
+               // And return the instance
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-WRAPPER: resultInstance=%s - EXIT!', $resultInstance->__toString()));
+               return $resultInstance;
+       }
+
+       /**
+        * Count the numbers of rows we shall receive
+        *
+        * @param       $criteriaInstance       An instance of a Criteria class
+        * @param       $onlyKeys                       Only use these keys for a cache key
+        * @return      $numRows                        Numbers of rows of database entries
+        */
+       public function doSelectCountByCriteria (Criteria $criteriaInstance, array $onlyKeys = []) {
+               // Total numbers is -1 so we can distinglish between failed and valid queries
+               $numRows = 0;
+
+               // Get the result from above method
+               $resultInstance = $this->doSelectByCriteria($criteriaInstance, $onlyKeys);
+
+               // Was that query fine?
+               if ($resultInstance->ifStatusIsOkay()) {
+                       // Then get the number of rows
+                       $numRows = $resultInstance->getAffectedRows();
+
+                       // Debug message
+                       //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: numRows=' . $numRows);
+               } // END - if
+
+               // Return the result
+               return $numRows;
+       }
+
+       /**
+        * Getter for primary key used in wrapped table
+        *
+        * @return      $primaryKey             Primary key used in wrapped table
+        */
+       public final function getPrimaryKeyValue () {
+               // Get the table name and a database instance and ask for it
+               $primaryKey = FrameworkBootstrap::getDatabaseInstance()->getPrimaryKeyOfTable($this->getTableName());
+
+               // Return value
+               return $primaryKey;
+       }
+
+       /**
+        * Count rows of this table
+        *
+        * @return      $count  Count of total rows in this table
+        */
+       public final function countTotalRows () {
+               // Get the table name and a database instance and ask for it
+               $count = FrameworkBootstrap::getDatabaseInstance()->countTotalRows($this->getTableName());
+
+               // Return value
+               return $count;
+       }
+
+       /**
+        * Removes non-public data from given array.
+        *
+        * @param       $data   An array with possible non-public data that needs to be removed.
+        * @return      $data   A cleaned up array with only public data.
+        */
+       public function removeNonPublicDataFromArray (array $data) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('WRAPPER[' . $this->__toString() . ']: Calling FrameworkBootstrap::getDatabaseInstance()->removeNonPublicDataFromArray(data) ...');
+               $data = FrameworkBootstrap::getDatabaseInstance()->removeNonPublicDataFromArray($data);
+
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('WRAPPER[' . $this->__toString() . ']: data[]=' . gettype($data));
+               return $data;
+       }
+
+}