From: Roland Haeder Date: Fri, 6 Mar 2015 23:19:12 +0000 (+0100) Subject: Renamed some paths and a class for better understanding them: X-Git-Url: https://git.mxchange.org/?p=core.git;a=commitdiff_plain;h=5b0d513d846a787285baa062db26da2879077df6 Renamed some paths and a class for better understanding them: - Classes in 'databases' were backend classes (doing the hard work) so it got renamed to 'backend' - Classes in 'wrapper' were frontend classes (which classes from e.g. the "business logic" may use) so it got renamed to 'frontend' - To both above renames there are already proper "base" classes - Renamed 'LocalFileDatabase' to 'CachedLocalFileDatabase' as the entire (!) result is stored in $resultData. This is maybe fine for small tables but never good for tables with a lot rows (I don't want to name a number here). - TODOs.txt updated Signed-off-by: Roland Häder --- diff --git a/docs/TODOs.txt b/docs/TODOs.txt index ae078e4d..48f5efec 100644 --- a/docs/TODOs.txt +++ b/docs/TODOs.txt @@ -31,8 +31,8 @@ ./inc/classes/main/controller/web/class_WebStatusController.php:10: * @todo This controller shall still provide some headlines for sidebars ./inc/classes/main/criteria/search/class_SearchCriteria.php:102: * @todo Find a nice casting here. (int) allows until and including 32766. ./inc/classes/main/criteria/search/class_SearchCriteria.php:70: * @todo Find a nice casting here. (int) allows until and including 32766. -./inc/classes/main/database/databases/class_LocalFileDatabase.php:327: * @todo Do some checks on the database directory and files here -./inc/classes/main/database/databases/class_LocalFileDatabase.php:616: * @todo Add more generic non-public data for removal +./inc/classes/main/database/backend/class_CachedLocalFileDatabase.php:327: * @todo Do some checks on the database directory and files here +./inc/classes/main/database/backend/class_CachedLocalFileDatabase.php:616: * @todo Add more generic non-public data for removal ./inc/classes/main/decorator/template/class_XmlRewriterTemplateDecorator.php:427: * @todo Find something useful with this! ./inc/classes/main/discovery/payment/class_LocalPaymentDiscovery.php:85: * @todo 0% done ./inc/classes/main/file_directories/class_BaseFile.php:135: * @todo ~10% done? diff --git a/inc/classes/main/database/backend/.htaccess b/inc/classes/main/database/backend/.htaccess new file mode 100644 index 00000000..3a428827 --- /dev/null +++ b/inc/classes/main/database/backend/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/main/database/backend/class_CachedLocalFileDatabase.php b/inc/classes/main/database/backend/class_CachedLocalFileDatabase.php new file mode 100644 index 00000000..63f8b21d --- /dev/null +++ b/inc/classes/main/database/backend/class_CachedLocalFileDatabase.php @@ -0,0 +1,629 @@ + + * @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 CachedLocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { + /** + * The file's extension + */ + private $fileExtension = 'serialized'; + + /** + * The last read file's name + */ + private $lastFile = ''; + + /** + * The last read file's content including header information + */ + private $lastContents = array(); + + /** + * Whether the "connection is already up + */ + private $alreadyConnected = FALSE; + + /** + * Table information array + */ + private $tableInfo = array(); + + /** + * Element for index + */ + private $indexKey = '__idx'; + + /** + * The protected constructor. Do never instance from outside! You need to + * set a local file path. The class will then validate it. + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Create an object of CachedLocalFileDatabase and set the save path from + * configuration for local files. + * + * @return $databaseInstance An instance of CachedLocalFileDatabase + */ + public static final function createCachedLocalFileDatabase () { + // Get an instance + $databaseInstance = new CachedLocalFileDatabase(); + + // Get a new compressor channel instance + $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class'); + + // Set the compressor channel + $databaseInstance->setCompressorChannel($compressorInstance); + + // Get a file IO handler + $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class'); + + // ... and set it + $databaseInstance->setFileIoInstance($fileIoInstance); + + // "Connect" to the database + $databaseInstance->connectToDatabase(); + + // Return database instance + return $databaseInstance; + } + + /** + * Setter for the last read file + * + * @param $fqfn The FQFN of the last read file + * @return void + */ + private final function setLastFile ($fqfn) { + // Cast string and set it + $this->lastFile = (string) $fqfn; + } + + /** + * Getter for last read file + * + * @return $lastFile The last read file's name with full path + */ + public final function getLastFile () { + return $this->lastFile; + } + + /** + * Setter for contents of the last read file + * + * @param $contents An array with header and data elements + * @return void + */ + private final function setLastFileContents (array $contents) { + // Set array + $this->lastContents = $contents; + } + + /** + * Getter for last read file's content as an array + * + * @return $lastContent The array with elements 'header' and 'data'. + */ + public final function getLastContents () { + return $this->lastContents; + } + + /** + * Getter for file extension + * + * @return $fileExtension The array with elements 'header' and 'data'. + */ + public final function getFileExtension () { + return $this->fileExtension; + } + + /** + * Getter for index key + * + * @return $indexKey Index key + */ + public final function getIndexKey () { + return $this->indexKey; + } + + /** + * Reads a local data file and returns it's contents in an array + * + * @param $fqfn The FQFN for the requested file + * @return $dataArray + */ + private function getDataArrayFromFile ($fqfn) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); + + // Init compressed data + $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); + $compressedData = $compressedData['data']; + + // Close the file and throw the instance away + unset($fileInstance); + + // Decompress it + $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); + + // Unserialize it + $dataArray = unserialize($serializedData); + + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Read ' . count($dataArray) . ' elements from database file ' . $fqfn . '.'); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE)); + + // Finally return it + return $dataArray; + } + + /** + * Writes data array to local file + * + * @param $fqfn The FQFN of the local file + * @param $dataArray An array with all the data we shall write + * @return void + */ + private function writeDataArrayToFqfn ($fqfn, array $dataArray) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file ' . $fqfn . ' ...'); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE)); + + // Serialize and compress it + $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray)); + + // Write data + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...'); + + // Write this data BASE64 encoded to the file + $this->getFileIoInstance()->saveStreamToFile($fqfn, $compressedData, $this); + + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); + } + + /** + * Getter for table information file contents or an empty if info file was not created + * + * @param $dataSetInstance An instance of a database set class + * @return $infoArray An array with all table informations + */ + private function getContentsFromTableInfoFile (StoreableCriteria $dataSetInstance) { + // Default content is no data + $infoArray = array(); + + // Create FQFN for getting the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the file contents + try { + $infoArray = $this->getDataArrayFromFile($fqfn); + } catch (FileIoException $e) { + // Not found, so ignore it here + } + + // ... and return it + return $infoArray; + } + + /** + * Generates an FQFN from given dataset instance and string + * + * @param $dataSetInstance An instance of a database set class + * @param $rowName Name of the row + * @return $fqfn The FQFN for this row + */ + private function generateFqfnFromDataSet (Criteria $dataSetInstance, $rowName) { + // This is the FQFN + $fqfn = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/' . $rowName . '.' . $this->getFileExtension(); + + // Return it + return $fqfn; + } + + /** + * Creates the table info file from given dataset instance + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function createTableInfoFile (StoreableCriteria $dataSetInstance) { + // Create FQFN for creating the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the data out from dataset in a local array + $this->tableInfo[$dataSetInstance->getTableName()] = array( + 'primary' => $dataSetInstance->getPrimaryKey(), + 'created' => time(), + 'last_updated' => time() + ); + + // Write the data to the file + $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]); + } + + /** + * Updates the table info file from given dataset instance + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function updateTableInfoFile (StoreableCriteria $dataSetInstance) { + // "Cache" table name + $tableName = $dataSetInstance->getTableName(); + + // Create FQFN for creating the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the data out from dataset in a local array + $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); + $this->tableInfo[$tableName]['last_updated'] = time(); + + // Write the data to the file + $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$tableName]); + } + + /** + * Updates the primary key information or creates the table info file if not found + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function updatePrimaryKey (StoreableCriteria $dataSetInstance) { + // "Cache" table name + $tableName = $dataSetInstance->getTableName(); + + // Get the information array from lower method + $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance); + + // Is the primary key there? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: tableInfo=' . print_r($this->tableInfo, TRUE)); + if (!isset($this->tableInfo[$tableName]['primary'])) { + // Then create the info file + $this->createTableInfoFile($dataSetInstance); + } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) { + // Set the array element + $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); + + // Update the entry + $this->updateTableInfoFile($dataSetInstance); + } + } + + /** + * Makes sure that the database connection is alive + * + * @return void + * @todo Do some checks on the database directory and files here + */ + public function connectToDatabase () { + } + + /** + * Starts a SELECT query on the database by given return type, table name + * and search criteria + * + * @param $tableName Name of the database table + * @param $searchInstance Local search criteria class + * @return $resultData Result data of the query + * @throws UnsupportedCriteriaException If the criteria is unsupported + * @throws SqlException If an 'SQL error' occurs + */ + public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); + + // The result is null by any errors + $resultData = NULL; + + // Create full path name + $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $tableName . '/'; + + /* + * A 'select' query is not that easy on local files, so first try to + * find the 'table' which is in fact a directory on the server + */ + try { + // Get a directory pointer instance + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); + + // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read + $resultData = array( + BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY, + BaseDatabaseBackend::RESULT_INDEX_ROWS => array() + ); + + // Initialize limit/skip + $limitFound = 0; + $skipFound = 0; + $idx = 1; + + // Read the directory with some exceptions + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',this->getFileExtension()=' . $this->getFileExtension()); + + // Does the extension match? + if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { + // Skip this file! + continue; + } // END - if + + // Read the file + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE)); + + // Is this an array? + if (is_array($dataArray)) { + // Default is nothing found + $isFound = TRUE; + + // Search in the criteria with FMFW (First Matches, First Wins) + foreach ($dataArray as $key => $value) { + // Make sure value is not bool + assert(!is_bool($value)); + + // Found one entry? + $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value))); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: key=' . $key . ',value=' . $value . ',isFound=' . intval($isFound)); + } // END - foreach + + // Is all found? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: isFound=' . intval($isFound) . ',limitFound=' . $limitFound . ',limit=' . $searchInstance->getLimit()); + if ($isFound === TRUE) { + // Shall we skip this entry? + if ($searchInstance->getSkip() > 0) { + // We shall skip some entries + if ($skipFound < $searchInstance->getSkip()) { + // Skip this entry + $skipFound++; + break; + } // END - if + } // END - if + + // Set id number + $dataArray[$this->getIndexKey()] = $idx; + + // Entry found! + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, TRUE)); + array_push($resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS], $dataArray); + + // Count found entries up + $limitFound++; + } // END - if + } else { + // Throw an exception here + throw new SqlException(array($this, sprintf('File '%s' contains invalid data.', $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY); + } + + // Count entry up + $idx++; + } // END - while + + // Close directory and throw the instance away + $directoryInstance->closeDirectory(); + unset($directoryInstance); + + // Reset last exception + $this->resetLastException(); + } catch (PathIsNoDirectoryException $e) { + // Path not found means "table not found" for real databases... + $this->setLastException($e); + + // So throw an SqlException here with faked error message + throw new SqlException (array($this, sprintf('Table '%s' not found', $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + } + + // Return the gathered result + return $resultData; + } + + /** + * "Inserts" a data set instance into a local file database folder + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + public function queryInsertDataSet (StoreableCriteria $dataSetInstance) { + // Try to save the request away + try { + // Create full path name + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, md5($dataSetInstance->getUniqueValue())); + + // Write the data away + $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); + + // Update the primary key + $this->updatePrimaryKey($dataSetInstance); + + // Reset last exception + $this->resetLastException(); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + + // Throw an SQL exception + throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); + } + } + + /** + * "Updates" a data set instance with a database layer + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { + // Create full path name + $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/'; + + // Try all the requests + try { + // Get a file pointer instance + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); + + // Initialize limit/skip + $limitFound = 0; + $skipFound = 0; + + // Get the criteria array from the dataset + $searchArray = $dataSetInstance->getCriteriaArray(); + + // Get search criteria + $searchInstance = $dataSetInstance->getSearchInstance(); + + // Read the directory with some exceptions + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + // Does the extension match? + if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); + // Skip this file! + continue; + } // END - if + + // Open this file for reading + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE)); + + // Is this an array? + if (is_array($dataArray)) { + // Default is nothing found + $isFound = TRUE; + + // Search in the criteria with FMFW (First Matches, First Wins) + foreach ($dataArray as $key => $value) { + // Make sure value is not bool + assert(!is_bool($value)); + + // Found one entry? + $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value))); + } // END - foreach + + // Is all found? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: isFound=' . intval($isFound)); + if ($isFound === TRUE) { + // Shall we skip this entry? + if ($searchInstance->getSkip() > 0) { + // We shall skip some entries + if ($skipFound < $searchInstance->getSkip()) { + // Skip this entry + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Found entry, but skipping ...'); + $skipFound++; + break; + } // END - if + } // END - if + + // Entry found, so update it + foreach ($searchArray as $searchKey => $searchValue) { + // Make sure the value is not bool again + assert(!is_bool($searchValue)); + assert($searchKey != $this->indexKey); + + // Debug message + add/update it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue); + $dataArray[$searchKey] = $searchValue; + } // END - foreach + + // Write the data to a local file + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing dataArray()=' . count($dataArray) . ' to ' . $dataFile . ' ...'); + $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); + + // Count found entries up + $limitFound++; + } // END - if + } // END - if + } // END - while + + // Close the file pointer + $directoryInstance->closeDirectory(); + + // Update the primary key + $this->updatePrimaryKey($dataSetInstance); + + // Reset last exception + $this->resetLastException(); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + + // Throw an SQL exception + throw new SqlException(array($this, sprintf("Cannot write data to table '%s', is the table created?", $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); + } + } + + /** + * Getter for primary key of specified table or if not found null will be + * returned. This must be database-specific. + * + * @param $tableName Name of the table we need the primary key from + * @return $primaryKey Primary key column of the given table + */ + public function getPrimaryKeyOfTable ($tableName) { + // Default key is null + $primaryKey = NULL; + + // Does the table information exist? + if (isset($this->tableInfo[$tableName])) { + // Then return the primary key + $primaryKey = $this->tableInfo[$tableName]['primary']; + } // END - if + + // Return the column + return $primaryKey; + } + + /** + * 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. + * @todo Add more generic non-public data for removal + */ + public function removeNonPublicDataFromArray (array $data) { + // Remove '__idx' + unset($data[$this->indexKey]); + + // Return it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: data[' . gettype($data) . ']='.print_r($data, TRUE)); + return $data; + } +} + +// [EOF] +?> diff --git a/inc/classes/main/database/databases/.htaccess b/inc/classes/main/database/databases/.htaccess deleted file mode 100644 index 3a428827..00000000 --- a/inc/classes/main/database/databases/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php deleted file mode 100644 index 7f23e2ad..00000000 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ /dev/null @@ -1,629 +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 LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { - /** - * The file's extension - */ - private $fileExtension = 'serialized'; - - /** - * The last read file's name - */ - private $lastFile = ''; - - /** - * The last read file's content including header information - */ - private $lastContents = array(); - - /** - * Whether the "connection is already up - */ - private $alreadyConnected = FALSE; - - /** - * Table information array - */ - private $tableInfo = array(); - - /** - * Element for index - */ - private $indexKey = '__idx'; - - /** - * The protected constructor. Do never instance from outside! You need to - * set a local file path. The class will then validate it. - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Create an object of LocalFileDatabase and set the save path from - * configuration for local files. - * - * @return $databaseInstance An instance of LocalFileDatabase - */ - public static final function createLocalFileDatabase () { - // Get an instance - $databaseInstance = new LocalFileDatabase(); - - // Get a new compressor channel instance - $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class'); - - // Set the compressor channel - $databaseInstance->setCompressorChannel($compressorInstance); - - // Get a file IO handler - $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class'); - - // ... and set it - $databaseInstance->setFileIoInstance($fileIoInstance); - - // "Connect" to the database - $databaseInstance->connectToDatabase(); - - // Return database instance - return $databaseInstance; - } - - /** - * Setter for the last read file - * - * @param $fqfn The FQFN of the last read file - * @return void - */ - private final function setLastFile ($fqfn) { - // Cast string and set it - $this->lastFile = (string) $fqfn; - } - - /** - * Getter for last read file - * - * @return $lastFile The last read file's name with full path - */ - public final function getLastFile () { - return $this->lastFile; - } - - /** - * Setter for contents of the last read file - * - * @param $contents An array with header and data elements - * @return void - */ - private final function setLastFileContents (array $contents) { - // Set array - $this->lastContents = $contents; - } - - /** - * Getter for last read file's content as an array - * - * @return $lastContent The array with elements 'header' and 'data'. - */ - public final function getLastContents () { - return $this->lastContents; - } - - /** - * Getter for file extension - * - * @return $fileExtension The array with elements 'header' and 'data'. - */ - public final function getFileExtension () { - return $this->fileExtension; - } - - /** - * Getter for index key - * - * @return $indexKey Index key - */ - public final function getIndexKey () { - return $this->indexKey; - } - - /** - * Reads a local data file and returns it's contents in an array - * - * @param $fqfn The FQFN for the requested file - * @return $dataArray - */ - private function getDataArrayFromFile ($fqfn) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); - - // Init compressed data - $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); - $compressedData = $compressedData['data']; - - // Close the file and throw the instance away - unset($fileInstance); - - // Decompress it - $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); - - // Unserialize it - $dataArray = unserialize($serializedData); - - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Read ' . count($dataArray) . ' elements from database file ' . $fqfn . '.'); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE)); - - // Finally return it - return $dataArray; - } - - /** - * Writes data array to local file - * - * @param $fqfn The FQFN of the local file - * @param $dataArray An array with all the data we shall write - * @return void - */ - private function writeDataArrayToFqfn ($fqfn, array $dataArray) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file ' . $fqfn . ' ...'); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE)); - - // Serialize and compress it - $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray)); - - // Write data - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...'); - - // Write this data BASE64 encoded to the file - $this->getFileIoInstance()->saveStreamToFile($fqfn, $compressedData, $this); - - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); - } - - /** - * Getter for table information file contents or an empty if info file was not created - * - * @param $dataSetInstance An instance of a database set class - * @return $infoArray An array with all table informations - */ - private function getContentsFromTableInfoFile (StoreableCriteria $dataSetInstance) { - // Default content is no data - $infoArray = array(); - - // Create FQFN for getting the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the file contents - try { - $infoArray = $this->getDataArrayFromFile($fqfn); - } catch (FileIoException $e) { - // Not found, so ignore it here - } - - // ... and return it - return $infoArray; - } - - /** - * Generates an FQFN from given dataset instance and string - * - * @param $dataSetInstance An instance of a database set class - * @param $rowName Name of the row - * @return $fqfn The FQFN for this row - */ - private function generateFqfnFromDataSet (Criteria $dataSetInstance, $rowName) { - // This is the FQFN - $fqfn = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/' . $rowName . '.' . $this->getFileExtension(); - - // Return it - return $fqfn; - } - - /** - * Creates the table info file from given dataset instance - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function createTableInfoFile (StoreableCriteria $dataSetInstance) { - // Create FQFN for creating the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the data out from dataset in a local array - $this->tableInfo[$dataSetInstance->getTableName()] = array( - 'primary' => $dataSetInstance->getPrimaryKey(), - 'created' => time(), - 'last_updated' => time() - ); - - // Write the data to the file - $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]); - } - - /** - * Updates the table info file from given dataset instance - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function updateTableInfoFile (StoreableCriteria $dataSetInstance) { - // "Cache" table name - $tableName = $dataSetInstance->getTableName(); - - // Create FQFN for creating the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the data out from dataset in a local array - $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); - $this->tableInfo[$tableName]['last_updated'] = time(); - - // Write the data to the file - $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$tableName]); - } - - /** - * Updates the primary key information or creates the table info file if not found - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function updatePrimaryKey (StoreableCriteria $dataSetInstance) { - // "Cache" table name - $tableName = $dataSetInstance->getTableName(); - - // Get the information array from lower method - $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance); - - // Is the primary key there? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: tableInfo=' . print_r($this->tableInfo, TRUE)); - if (!isset($this->tableInfo[$tableName]['primary'])) { - // Then create the info file - $this->createTableInfoFile($dataSetInstance); - } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) { - // Set the array element - $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); - - // Update the entry - $this->updateTableInfoFile($dataSetInstance); - } - } - - /** - * Makes sure that the database connection is alive - * - * @return void - * @todo Do some checks on the database directory and files here - */ - public function connectToDatabase () { - } - - /** - * Starts a SELECT query on the database by given return type, table name - * and search criteria - * - * @param $tableName Name of the database table - * @param $searchInstance Local search criteria class - * @return $resultData Result data of the query - * @throws UnsupportedCriteriaException If the criteria is unsupported - * @throws SqlException If an 'SQL error' occurs - */ - public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); - - // The result is null by any errors - $resultData = NULL; - - // Create full path name - $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $tableName . '/'; - - /* - * A 'select' query is not that easy on local files, so first try to - * find the 'table' which is in fact a directory on the server - */ - try { - // Get a directory pointer instance - $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); - - // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read - $resultData = array( - BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY, - BaseDatabaseBackend::RESULT_INDEX_ROWS => array() - ); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - $idx = 1; - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',this->getFileExtension()=' . $this->getFileExtension()); - - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Skip this file! - continue; - } // END - if - - // Read the file - $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE)); - - // Is this an array? - if (is_array($dataArray)) { - // Default is nothing found - $isFound = TRUE; - - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Make sure value is not bool - assert(!is_bool($value)); - - // Found one entry? - $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value))); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: key=' . $key . ',value=' . $value . ',isFound=' . intval($isFound)); - } // END - foreach - - // Is all found? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: isFound=' . intval($isFound) . ',limitFound=' . $limitFound . ',limit=' . $searchInstance->getLimit()); - if ($isFound === TRUE) { - // Shall we skip this entry? - if ($searchInstance->getSkip() > 0) { - // We shall skip some entries - if ($skipFound < $searchInstance->getSkip()) { - // Skip this entry - $skipFound++; - break; - } // END - if - } // END - if - - // Set id number - $dataArray[$this->getIndexKey()] = $idx; - - // Entry found! - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, TRUE)); - array_push($resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS], $dataArray); - - // Count found entries up - $limitFound++; - } // END - if - } else { - // Throw an exception here - throw new SqlException(array($this, sprintf('File '%s' contains invalid data.', $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY); - } - - // Count entry up - $idx++; - } // END - while - - // Close directory and throw the instance away - $directoryInstance->closeDirectory(); - unset($directoryInstance); - - // Reset last exception - $this->resetLastException(); - } catch (PathIsNoDirectoryException $e) { - // Path not found means "table not found" for real databases... - $this->setLastException($e); - - // So throw an SqlException here with faked error message - throw new SqlException (array($this, sprintf('Table '%s' not found', $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - } - - // Return the gathered result - return $resultData; - } - - /** - * "Inserts" a data set instance into a local file database folder - * - * @param $dataSetInstance A storeable data set - * @return void - * @throws SqlException If an SQL error occurs - */ - public function queryInsertDataSet (StoreableCriteria $dataSetInstance) { - // Try to save the request away - try { - // Create full path name - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, md5($dataSetInstance->getUniqueValue())); - - // Write the data away - $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last exception - $this->resetLastException(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - - // Throw an SQL exception - throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); - } - } - - /** - * "Updates" a data set instance with a database layer - * - * @param $dataSetInstance A storeable data set - * @return void - * @throws SqlException If an SQL error occurs - */ - public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { - // Create full path name - $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/'; - - // Try all the requests - try { - // Get a file pointer instance - $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - - // Get the criteria array from the dataset - $searchArray = $dataSetInstance->getCriteriaArray(); - - // Get search criteria - $searchInstance = $dataSetInstance->getSearchInstance(); - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); - // Skip this file! - continue; - } // END - if - - // Open this file for reading - $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE)); - - // Is this an array? - if (is_array($dataArray)) { - // Default is nothing found - $isFound = TRUE; - - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Make sure value is not bool - assert(!is_bool($value)); - - // Found one entry? - $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value))); - } // END - foreach - - // Is all found? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: isFound=' . intval($isFound)); - if ($isFound === TRUE) { - // Shall we skip this entry? - if ($searchInstance->getSkip() > 0) { - // We shall skip some entries - if ($skipFound < $searchInstance->getSkip()) { - // Skip this entry - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Found entry, but skipping ...'); - $skipFound++; - break; - } // END - if - } // END - if - - // Entry found, so update it - foreach ($searchArray as $searchKey => $searchValue) { - // Make sure the value is not bool again - assert(!is_bool($searchValue)); - assert($searchKey != $this->indexKey); - - // Debug message + add/update it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue); - $dataArray[$searchKey] = $searchValue; - } // END - foreach - - // Write the data to a local file - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing dataArray()=' . count($dataArray) . ' to ' . $dataFile . ' ...'); - $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); - - // Count found entries up - $limitFound++; - } // END - if - } // END - if - } // END - while - - // Close the file pointer - $directoryInstance->closeDirectory(); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last exception - $this->resetLastException(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - - // Throw an SQL exception - throw new SqlException(array($this, sprintf("Cannot write data to table '%s', is the table created?", $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); - } - } - - /** - * Getter for primary key of specified table or if not found null will be - * returned. This must be database-specific. - * - * @param $tableName Name of the table we need the primary key from - * @return $primaryKey Primary key column of the given table - */ - public function getPrimaryKeyOfTable ($tableName) { - // Default key is null - $primaryKey = NULL; - - // Does the table information exist? - if (isset($this->tableInfo[$tableName])) { - // Then return the primary key - $primaryKey = $this->tableInfo[$tableName]['primary']; - } // END - if - - // Return the column - return $primaryKey; - } - - /** - * 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. - * @todo Add more generic non-public data for removal - */ - public function removeNonPublicDataFromArray (array $data) { - // Remove '__idx' - unset($data[$this->indexKey]); - - // Return it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: data[' . gettype($data) . ']='.print_r($data, TRUE)); - return $data; - } -} - -// [EOF] -?> diff --git a/inc/classes/main/database/frontend/.htaccess b/inc/classes/main/database/frontend/.htaccess new file mode 100644 index 00000000..3a428827 --- /dev/null +++ b/inc/classes/main/database/frontend/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/main/database/frontend/class_NewsDatabaseWrapper.php b/inc/classes/main/database/frontend/class_NewsDatabaseWrapper.php new file mode 100644 index 00000000..5a983028 --- /dev/null +++ b/inc/classes/main/database/frontend/class_NewsDatabaseWrapper.php @@ -0,0 +1,56 @@ + + * @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 NewsDatabaseWrapper extends BaseDatabaseWrapper { + // Constants for database table names + const DB_TABLE_NEWS = 'news'; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this database wrapper by a provided user class + * + * @return $wrapperInstance An instance of the created wrapper class + */ + public static final function createNewsDatabaseWrapper () { + // Get a new instance + $wrapperInstance = new NewsDatabaseWrapper(); + + // Set (primary!) table name + $wrapperInstance->setTableName(self::DB_TABLE_NEWS); + + // Return the instance + return $wrapperInstance; + } +} + +// [EOF] +?> diff --git a/inc/classes/main/database/frontend/class_PaymentsDatabaseWrapper.php b/inc/classes/main/database/frontend/class_PaymentsDatabaseWrapper.php new file mode 100644 index 00000000..59e92fcc --- /dev/null +++ b/inc/classes/main/database/frontend/class_PaymentsDatabaseWrapper.php @@ -0,0 +1,59 @@ + + * @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 PaymentsDatabaseWrapper extends BaseDatabaseWrapper { + // Constants for exceptions + const EXCEPTION_CLIENT_USERNAME_NOT_FOUND = 0x180; + + // Constants for database table names + const DB_TABLE_PAYMENTS = 'payments'; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this database wrapper by a provided user class + * + * @return $wrapperInstance An instance of the created wrapper class + */ + public static final function createPaymentsDatabaseWrapper () { + // Get a new instance + $wrapperInstance = new PaymentsDatabaseWrapper(); + + // Set (primary!) table name + $wrapperInstance->setTableName(self::DB_TABLE_PAYMENTS); + + // Return the instance + return $wrapperInstance; + } +} + +// [EOF] +?> diff --git a/inc/classes/main/database/frontend/class_UserDatabaseWrapper.php b/inc/classes/main/database/frontend/class_UserDatabaseWrapper.php new file mode 100644 index 00000000..d68f2883 --- /dev/null +++ b/inc/classes/main/database/frontend/class_UserDatabaseWrapper.php @@ -0,0 +1,134 @@ + + * @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 UserDatabaseWrapper extends BaseDatabaseWrapper implements ManageableAccountWrapper { + // Constants for exceptions + const EXCEPTION_CLIENT_USERNAME_NOT_FOUND = 0x180; + + // Constants for database columns + const DB_COLUMN_USERID = 'userid'; + const DB_COLUMN_USERNAME = 'username'; + const DB_COLUMN_EMAIL = 'email'; + const DB_COLUMN_CONFIRM_HASH = 'confirm_hash'; + const DB_COLUMN_USER_STATUS = 'user_status'; + + // Constants for database table names + const DB_TABLE_USER = 'user'; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this database wrapper by a provided user class + * + * @return $wrapperInstance An instance of the created wrapper class + */ + public static final function createUserDatabaseWrapper () { + // Get a new instance + $wrapperInstance = new UserDatabaseWrapper(); + + // Set (primary!) table name + $wrapperInstance->setTableName(self::DB_TABLE_USER); + + // Return the instance + return $wrapperInstance; + } + + /** + * Handles inserting the registration data from a registration instance into the database + * + * @param $registrationInstance An instance of a registration class + * @return void + */ + public function insertRegistrationObject (UserRegister $registrationInstance) { + // Generate a data set for the request + $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER)); + + // Set the primary key + $dataSetInstance->setUniqueKey(self::DB_COLUMN_USERNAME); + + // Add registration elements to the dataset + $registrationInstance->addElementsToDataSet($dataSetInstance, NULL); + + // "Insert" this request instance completely into the database + $this->queryInsertDataSet($dataSetInstance); + } + + /** + * Updates an user database entry with given result + * + * @param $resultInstance An instance of a Updateable database result + * @return void + * @throws NullPointerException If $updateInstance or $searchInstance is null + */ + public function doUpdateByResult (UpdateableResult $resultInstance) { + // Get the search instance from result + $searchInstance = $resultInstance->getSearchInstance(); + + // Is this null? + if (is_null($searchInstance)) { + // Get the update instance + $updateInstance = $resultInstance->getUpdateInstance(); + + // Is this null? + if (is_null($updateInstance)) { + // Throw an exception here + throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); + } // END - if + + // Get search instance from update instance + $searchInstance = $updateInstance->getSearchInstance(); + + // Is it still null? + if (is_null($searchInstance)) { + // Throw an exception here + throw new NullPointerException($updateInstance, self::EXCEPTION_IS_NULL_POINTER); + } // END - if + } // END - if + + // Generate a data set object + $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER)); + + // Add seach criteria + $dataSetInstance->setSearchInstance($searchInstance); + + // Set the primary key + $dataSetInstance->setUniqueKey(self::DB_COLUMN_USERNAME); + + // Add all update criteria to the database set + $resultInstance->addElementsToDataSet($dataSetInstance, NULL); + + // "Update" this request with the database + $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/database/frontend/class_UserPointsDatabaseWrapper.php b/inc/classes/main/database/frontend/class_UserPointsDatabaseWrapper.php new file mode 100644 index 00000000..5f01b299 --- /dev/null +++ b/inc/classes/main/database/frontend/class_UserPointsDatabaseWrapper.php @@ -0,0 +1,111 @@ + + * @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 UserPointsDatabaseWrapper extends BaseDatabaseWrapper implements BookablePointsWrapper { + /** + * Constants for database table names + */ + const DB_TABLE_USER_POINTS = 'user_points'; + + /** + * Name of the user->points column + */ + const DB_COLUMN_POINTS_UID = 'points_uid'; + + /** + * Name of the points column + */ + const DB_COLUMN_POINTS = 'points'; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this database wrapper by a provided user class + * + * @return $wrapperInstance An instance of the created wrapper class + */ + public static final function createUserPointsDatabaseWrapper () { + // Get a new instance + $wrapperInstance = new UserPointsDatabaseWrapper(); + + // Set (primary!) table name + $wrapperInstance->setTableName(self::DB_TABLE_USER_POINTS); + + // Return the instance + return $wrapperInstance; + } + + /** + * Inserts the given points for the given user in the database + * + * @param $pointsInstance An instance of a user class + * @return void + */ + public function insertUserPoints (BookablePoints $pointsInstance) { + // Generate a data set for the request + $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER_POINTS)); + + // Set the primary key + $dataSetInstance->setUniqueKey(self::DB_COLUMN_POINTS_UID); + + // Add registration elements to the dataset + $pointsInstance->addElementsToDataSet($dataSetInstance, NULL); + + // "Insert" this request instance completely into the database + $this->queryInsertDataSet($dataSetInstance); + } + + /** + * Updates an user database entry with given result + * + * @param $resultInstance An instance of a Updateable database result + * @return void + */ + public function doUpdateByResult (UpdateableResult $resultInstance) { + // Generate a data set object + $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER_POINTS)); + + // Add all update criteria to the database set + $resultInstance->addElementsToDataSet($dataSetInstance, NULL); + + // Add seach criteria + $dataSetInstance->setSearchInstance($resultInstance->getUpdateInstance()->getSearchInstance()); + + // Set the primary key + $dataSetInstance->setUniqueKey(self::DB_COLUMN_POINTS_UID); + + // "Update" this request with the database + $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance); + } +} + +// [EOF] +?> diff --git a/inc/classes/main/database/wrapper/.htaccess b/inc/classes/main/database/wrapper/.htaccess deleted file mode 100644 index 3a428827..00000000 --- a/inc/classes/main/database/wrapper/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/inc/classes/main/database/wrapper/class_NewsDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_NewsDatabaseWrapper.php deleted file mode 100644 index 5a983028..00000000 --- a/inc/classes/main/database/wrapper/class_NewsDatabaseWrapper.php +++ /dev/null @@ -1,56 +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 NewsDatabaseWrapper extends BaseDatabaseWrapper { - // Constants for database table names - const DB_TABLE_NEWS = 'news'; - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Creates an instance of this database wrapper by a provided user class - * - * @return $wrapperInstance An instance of the created wrapper class - */ - public static final function createNewsDatabaseWrapper () { - // Get a new instance - $wrapperInstance = new NewsDatabaseWrapper(); - - // Set (primary!) table name - $wrapperInstance->setTableName(self::DB_TABLE_NEWS); - - // Return the instance - return $wrapperInstance; - } -} - -// [EOF] -?> diff --git a/inc/classes/main/database/wrapper/class_PaymentsDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_PaymentsDatabaseWrapper.php deleted file mode 100644 index 59e92fcc..00000000 --- a/inc/classes/main/database/wrapper/class_PaymentsDatabaseWrapper.php +++ /dev/null @@ -1,59 +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 PaymentsDatabaseWrapper extends BaseDatabaseWrapper { - // Constants for exceptions - const EXCEPTION_CLIENT_USERNAME_NOT_FOUND = 0x180; - - // Constants for database table names - const DB_TABLE_PAYMENTS = 'payments'; - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Creates an instance of this database wrapper by a provided user class - * - * @return $wrapperInstance An instance of the created wrapper class - */ - public static final function createPaymentsDatabaseWrapper () { - // Get a new instance - $wrapperInstance = new PaymentsDatabaseWrapper(); - - // Set (primary!) table name - $wrapperInstance->setTableName(self::DB_TABLE_PAYMENTS); - - // Return the instance - return $wrapperInstance; - } -} - -// [EOF] -?> diff --git a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php deleted file mode 100644 index d68f2883..00000000 --- a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php +++ /dev/null @@ -1,134 +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 UserDatabaseWrapper extends BaseDatabaseWrapper implements ManageableAccountWrapper { - // Constants for exceptions - const EXCEPTION_CLIENT_USERNAME_NOT_FOUND = 0x180; - - // Constants for database columns - const DB_COLUMN_USERID = 'userid'; - const DB_COLUMN_USERNAME = 'username'; - const DB_COLUMN_EMAIL = 'email'; - const DB_COLUMN_CONFIRM_HASH = 'confirm_hash'; - const DB_COLUMN_USER_STATUS = 'user_status'; - - // Constants for database table names - const DB_TABLE_USER = 'user'; - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Creates an instance of this database wrapper by a provided user class - * - * @return $wrapperInstance An instance of the created wrapper class - */ - public static final function createUserDatabaseWrapper () { - // Get a new instance - $wrapperInstance = new UserDatabaseWrapper(); - - // Set (primary!) table name - $wrapperInstance->setTableName(self::DB_TABLE_USER); - - // Return the instance - return $wrapperInstance; - } - - /** - * Handles inserting the registration data from a registration instance into the database - * - * @param $registrationInstance An instance of a registration class - * @return void - */ - public function insertRegistrationObject (UserRegister $registrationInstance) { - // Generate a data set for the request - $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER)); - - // Set the primary key - $dataSetInstance->setUniqueKey(self::DB_COLUMN_USERNAME); - - // Add registration elements to the dataset - $registrationInstance->addElementsToDataSet($dataSetInstance, NULL); - - // "Insert" this request instance completely into the database - $this->queryInsertDataSet($dataSetInstance); - } - - /** - * Updates an user database entry with given result - * - * @param $resultInstance An instance of a Updateable database result - * @return void - * @throws NullPointerException If $updateInstance or $searchInstance is null - */ - public function doUpdateByResult (UpdateableResult $resultInstance) { - // Get the search instance from result - $searchInstance = $resultInstance->getSearchInstance(); - - // Is this null? - if (is_null($searchInstance)) { - // Get the update instance - $updateInstance = $resultInstance->getUpdateInstance(); - - // Is this null? - if (is_null($updateInstance)) { - // Throw an exception here - throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); - } // END - if - - // Get search instance from update instance - $searchInstance = $updateInstance->getSearchInstance(); - - // Is it still null? - if (is_null($searchInstance)) { - // Throw an exception here - throw new NullPointerException($updateInstance, self::EXCEPTION_IS_NULL_POINTER); - } // END - if - } // END - if - - // Generate a data set object - $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER)); - - // Add seach criteria - $dataSetInstance->setSearchInstance($searchInstance); - - // Set the primary key - $dataSetInstance->setUniqueKey(self::DB_COLUMN_USERNAME); - - // Add all update criteria to the database set - $resultInstance->addElementsToDataSet($dataSetInstance, NULL); - - // "Update" this request with the database - $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance); - } -} - -// [EOF] -?> diff --git a/inc/classes/main/database/wrapper/class_UserPointsDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_UserPointsDatabaseWrapper.php deleted file mode 100644 index 5f01b299..00000000 --- a/inc/classes/main/database/wrapper/class_UserPointsDatabaseWrapper.php +++ /dev/null @@ -1,111 +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 UserPointsDatabaseWrapper extends BaseDatabaseWrapper implements BookablePointsWrapper { - /** - * Constants for database table names - */ - const DB_TABLE_USER_POINTS = 'user_points'; - - /** - * Name of the user->points column - */ - const DB_COLUMN_POINTS_UID = 'points_uid'; - - /** - * Name of the points column - */ - const DB_COLUMN_POINTS = 'points'; - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Creates an instance of this database wrapper by a provided user class - * - * @return $wrapperInstance An instance of the created wrapper class - */ - public static final function createUserPointsDatabaseWrapper () { - // Get a new instance - $wrapperInstance = new UserPointsDatabaseWrapper(); - - // Set (primary!) table name - $wrapperInstance->setTableName(self::DB_TABLE_USER_POINTS); - - // Return the instance - return $wrapperInstance; - } - - /** - * Inserts the given points for the given user in the database - * - * @param $pointsInstance An instance of a user class - * @return void - */ - public function insertUserPoints (BookablePoints $pointsInstance) { - // Generate a data set for the request - $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER_POINTS)); - - // Set the primary key - $dataSetInstance->setUniqueKey(self::DB_COLUMN_POINTS_UID); - - // Add registration elements to the dataset - $pointsInstance->addElementsToDataSet($dataSetInstance, NULL); - - // "Insert" this request instance completely into the database - $this->queryInsertDataSet($dataSetInstance); - } - - /** - * Updates an user database entry with given result - * - * @param $resultInstance An instance of a Updateable database result - * @return void - */ - public function doUpdateByResult (UpdateableResult $resultInstance) { - // Generate a data set object - $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_USER_POINTS)); - - // Add all update criteria to the database set - $resultInstance->addElementsToDataSet($dataSetInstance, NULL); - - // Add seach criteria - $dataSetInstance->setSearchInstance($resultInstance->getUpdateInstance()->getSearchInstance()); - - // Set the primary key - $dataSetInstance->setUniqueKey(self::DB_COLUMN_POINTS_UID); - - // "Update" this request with the database - $this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance); - } -} - -// [EOF] -?> diff --git a/inc/config.php b/inc/config.php index 1a855b97..900225cb 100644 --- a/inc/config.php +++ b/inc/config.php @@ -327,7 +327,7 @@ $cfg->setConfigEntry('stacker_generic_max_size', 100); $cfg->setConfigEntry('stacker_current_node_max_size', 20); // CFG: LOCAL-FILE-DATABASE-CLASS -$cfg->setConfigEntry('local_file_database_class', 'LocalFileDatabase'); +$cfg->setConfigEntry('local_file_database_class', 'CachedLocalFileDatabase'); // CFG: COMPRESSOR-CHANNEL-CLASS $cfg->setConfigEntry('compressor_channel_class', 'CompressorChannel');