3 namespace Org\Mxchange\CoreFramework\Database\Frontend;
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Criteria\Criteria;
7 use Org\Mxchange\CoreFramework\Criteria\Storing\StoreableCriteria;
8 use Org\Mxchange\CoreFramework\Database\Backend\BaseDatabaseBackend;
9 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
10 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
13 * A generic database wrapper
15 * @author Roland Haeder <webmaster@shipsimu.org>
17 <<<<<<< HEAD:framework/main/classes/database/class_BaseDatabaseWrapper.php
18 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
20 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2016 Core Developer Team
21 >>>>>>> Some updates::inc/main/classes/database/class_BaseDatabaseWrapper.php
22 * @license GNU GPL 3.0 or any newer version
23 * @link http://www.shipsimu.org
25 * This program is free software: you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation, either version 3 of the License, or
28 * (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38 abstract class BaseDatabaseWrapper extends BaseFrameworkSystem {
42 private $cacheInstance = NULL;
45 * Current table name to use
47 private $tableName = 'unknown';
50 * Protected constructor
54 protected function __construct ($class) {
55 // Call parent constructor
56 parent::__construct($class);
58 // Initialize the cache instance
59 $this->initCacheInstance();
63 * Initializes the cache instance with a new object
67 private final function initCacheInstance () {
68 // Is the cache enabled?
69 if ($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) {
70 // Set the new instance
71 $this->cacheInstance = CacheFactory::getFactory()->createConfiguredCache();
76 * Setter for table name
78 * @param $tableName Name of table name to set
81 protected final function setTableName ($tableName) {
82 $this->tableName = (string) $tableName;
86 * Getter for table name
88 * @return $tableName Name of table name to set
90 protected final function getTableName () {
91 return $this->tableName;
95 * 'Inserts' a data set instance into a local file database folder
97 * @param $dataSetInstance A storeable data set
98 * @param $onlyKeys Only use these keys for a cache key
101 protected function queryInsertDataSet (StoreableCriteria $dataSetInstance, array $onlyKeys = array()) {
102 // Default cache key is NULL
106 if ($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) {
107 // First get a key suitable for our cache and extend it with this class name
108 $cacheKey = $this->getCacheKeyByCriteria($dataSetInstance, $onlyKeys);
109 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Using cache key ' . $cacheKey . ' for purging ...');
112 // Does this key exists in cache?
113 if (($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey))) {
115 $this->cacheInstance->purgeOffset($cacheKey);
118 // Handle it over to the middleware
119 $this->getDatabaseInstance()->queryInsertDataSet($dataSetInstance);
123 * 'Updates' a data set instance with a database layer
125 * @param $dataSetInstance A storeable data set
126 * @param $onlyKeys Only use these keys for a cache key
129 protected function queryUpdateDataSet (StoreableCriteria $dataSetInstance, array $onlyKeys = array()) {
134 if ($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) {
135 // First get a key suitable for our cache and extend it with this class name
136 $cacheKey = $this->getCacheKeyByCriteria($dataSetInstance, $onlyKeys);
137 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Using cache key ' . $cacheKey . ' for purging ...');
140 // Does this key exists in cache?
141 if (($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey))) {
143 $this->cacheInstance->purgeOffset($cacheKey);
146 // Handle it over to the middleware
147 $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance);
151 * Getter for index key
153 * @return $indexKey Index key
155 public final function getIndexKey () {
156 return $this->getDatabaseInstance()->getIndexKey();
160 * Getter for last exception
162 * @return $lastException Last exception or NULL if none occured
164 public final function getLastException () {
165 return $this->getDatabaseInstance()->getLastException();
169 * Do a "select" query on the current table with the given search criteria and
170 * store it in cache for later usage
172 * @param $criteriaInstance An instance of a Criteria class
173 * @param $onlyKeys Only use these keys for a cache key
174 * @return $resultInstance An instance of a database result class
176 public function doSelectByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
177 // Default cache key if cache is not enabled
180 // Is the cache enabled?
181 if ($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) {
182 // First get a key suitable for our cache and extend it with this class name
183 $cacheKey = $this->getCacheKeyByCriteria($criteriaInstance, $onlyKeys);
186 // Does this key exists in cache?
187 if (($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) && ($this->cacheInstance->offsetExists($cacheKey, BaseDatabaseBackend::RESULT_INDEX_ROWS, 1))) {
189 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Cache used for cacheKey=' . $cacheKey . ':' . print_r($this->cacheInstance->offsetGet($cacheKey), true));
191 // Then use this result
192 $result = $this->cacheInstance->offsetGet($cacheKey);
195 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: Quering database, cacheKey=' . $cacheKey);
197 // Now it's time to ask the database layer for this select statement
198 $result = $this->getDatabaseInstance()->doSelectByTableCriteria($this->getTableName(), $criteriaInstance);
199 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: result[]=' . gettype($result));
201 // Cache the result if not null
202 if (!is_null($result)) {
204 if ($this->getConfigInstance()->getConfigEntry('database_cache_enabled') === true) {
205 // A valid result has returned from the database layer
206 $this->cacheInstance->offsetSet($cacheKey, $result);
209 // This invalid result must be wrapped
211 BaseDatabaseBackend::RESULT_INDEX_STATUS => 'invalid',
212 BaseDatabaseBackend::RESULT_INDEX_EXCEPTION => $this->getDatabaseInstance()->getLastException()
217 // Create an instance of a CachedDatabaseResult class with the given result
218 // @TODO Minor: Update above comment to e.g. BaseDatabaseResult
219 $resultInstance = ObjectFactory::createObjectByConfiguredName('database_result_class', array($result));
221 // And return the instance
222 return $resultInstance;
226 * Count the numbers of rows we shall receive
228 * @param $criteriaInstance An instance of a Criteria class
229 * @param $onlyKeys Only use these keys for a cache key
230 * @return $numRows Numbers of rows of database entries
232 public function doSelectCountByCriteria (Criteria $criteriaInstance, $onlyKeys = array()) {
233 // Total numbers is -1 so we can distinglish between failed and valid queries
236 // Get the result from above method
237 $resultInstance = $this->doSelectByCriteria($criteriaInstance, $onlyKeys);
239 // Was that query fine?
240 if ($resultInstance->ifStatusIsOkay()) {
241 // Then get the number of rows
242 $numRows = $resultInstance->getAffectedRows();
245 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-WRAPPER: numRows=' . $numRows);
253 * Getter for primary key used in wrapped table
255 * @return $primaryKey Primary key used in wrapped table
257 public final function getPrimaryKeyValue () {
258 // Get the table name and a database instance and ask for it
259 $primaryKey = $this->getDatabaseInstance()->getPrimaryKeyOfTable($this->getTableName());
266 * Count rows of this table
268 * @return $count Count of total rows in this table
270 public final function countTotalRows () {
271 // Get the table name and a database instance and ask for it
272 $count = $this->getDatabaseInstance()->countTotalRows($this->getTableName());
279 * Removes non-public data from given array.
281 * @param $data An array with possible non-public data that needs to be removed.
282 * @return $data A cleaned up array with only public data.
284 public function removeNonPublicDataFromArray (array $data) {
285 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('WRAPPER[' . $this->__toString() . ']: Calling this->getDatabaseInstance()->removeNonPublicDataFromArray(data) ...');
286 $data = $this->getDatabaseInstance()->removeNonPublicDataFromArray($data);
288 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('WRAPPER[' . $this->__toString() . ']: data[]=' . gettype($data));