X-Git-Url: https://git.mxchange.org/?p=hub.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Fdatabase%2Fdatabases%2Fclass_LocalFileDatabase.php;fp=inc%2Fclasses%2Fmain%2Fdatabase%2Fdatabases%2Fclass_LocalFileDatabase.php;h=0000000000000000000000000000000000000000;hp=dc4371efd13fcb5a08bbb64a1bb185ddcd5726fd;hb=7150c6d1a1e3c91d3cfd2e732b26bbe9f0dc4f57;hpb=12dbc1af8f0bc2981711b17c7c955f270c440b35 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 dc4371efd..000000000 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ /dev/null @@ -1,611 +0,0 @@ - - * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, this is free software - * @license GNU GPL 3.0 or any newer version - * @link http://www.ship-simu.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 BaseDatabaseFrontend implements DatabaseFrontendInterface { - - // Constants for MySQL backward-compatiblity (PLEASE FIX THEM!) - const DB_CODE_TABLE_MISSING = 0x100; - const DB_CODE_TABLE_UNWRITEABLE = 0x101; - const DB_CODE_DATA_FILE_CORRUPT = 0x102; - - /** - * Save path for "file database" - */ - private $savePath = ""; - - /** - * 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(); - - /** - * Wether the "connection is already up - */ - private $alreadyConnected = false; - - /** - * Last error message - */ - private $lastError = ""; - - /** - * Last exception - */ - private $lastException = null; - - /** - * 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__); - - // Clean up a little - $this->removeNumberFormaters(); - $this->removeSystemArray(); - } - - /** - * Create an object of LocalFileDatabase and set the save path for local files. - * This method also validates the given file path. - * - * @param $savePath The local file path string - * @param $ioInstance The input/output handler. This - * should be FileIoHandler - * @return $dbInstance An instance of LocalFileDatabase - */ - public final static function createLocalFileDatabase ($savePath, FileIoHandler $ioInstance) { - // Get an instance - $dbInstance = new LocalFileDatabase(); - - // Set save path and IO instance - $dbInstance->setSavePath($savePath); - $dbInstance->setFileIoInstance($ioInstance); - - // "Connect" to the database - $dbInstance->connectToDatabase(); - - // Return database instance - return $dbInstance; - } - - /** - * Setter for save path - * - * @param $savePath The local save path where we shall put our serialized classes - * @return void - */ - public final function setSavePath ($savePath) { - // Secure string - $savePath = (string) $savePath; - - // Set save path - $this->savePath = $savePath; - } - - /** - * Getter for save path - * - * @return $savePath The local save path where we shall put our serialized classes - */ - public final function getSavePath () { - return $this->savePath; - } - - /** - * Getter for last error message - * - * @return $lastError Last error message - */ - public final function getLastError () { - return $this->lastError; - } - - /** - * Getter for last exception - * - * @return $lastException Last thrown exception - */ - public final function getLastException () { - return $this->lastException; - } - - /** - * 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; - } - - /** - * Reset the last error and exception instance. This should be done after - * a successfull "query" - * - * @return void - */ - private final function resetLastError () { - $this->lastError = ""; - $this->lastException = null; - } - - /** - * 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) { - // Get a file pointer - $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn); - - // Get the raw data and BASE64-decode it - $compressedData = base64_decode($fileInstance->readLinesFromFile()); - - // Close the file and throw the instance away - $fileInstance->closeFile(); - unset($fileInstance); - - // Decompress it - $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); - - // Unserialize it - $dataArray = unserialize($serializedData); - - // 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) { - // Get a file pointer instance - $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w'); - - // Serialize and compress it - $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray)); - - // Write this data BASE64 encoded to the file - $fileInstance->writeToFile(base64_encode($compressedData)); - - // Close the file pointer - $fileInstance->closeFile(); - } - - /** - * 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->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension(); - - // Get the file contents - try { - $infoArray = $this->getDataArrayFromFile($fqfn); - } catch (FileNotFoundException $e) { - // Not found, so ignore it here - } - - // ... and return it - return $infoArray; - } - - /** - * 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->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension(); - - // 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 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) { - // Get the information array from lower method - $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance); - - // Is the primary key there? - if (!isset($this->tableInfo['primary'])) { - // Then create the info file - $this->createTableInfoFile($dataSetInstance); - } elseif (($this->getConfigInstance()->readConfig('db_update_primary_forced') === "Y") && ($dataSetInstance->getPrimaryKey() != $this->tableInfo['primary'])) { - // Set the array element - $this->tableInfo[$dataSetInstance->getTableName()]['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 $resultType Result type ("array", "object" and "indexed" are valid) - * @param $tableName Name of the database table - * @param $criteria 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 ($resultType, $tableName, LocalSearchCriteria $criteriaInstance) { - // The result is null by any errors - $resultData = null; - - // Create full path name - $pathName = $this->getSavePath() . $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 = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); - - // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read - $resultData = array( - 'status' => "ok", - 'rows' => array() - ); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - $idx = 1; - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn", "info." . $this->getFileExtension()))) && ($limitFound < $criteriaInstance->getLimit())) { - // 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); - - // Is this an array? - if (is_array($dataArray)) { - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Get criteria element - $criteria = $criteriaInstance->getCriteriaElemnent($key); - - // Is the criteria met? - if ((!is_null($criteria)) && ($criteria == $value)) { - - // Shall we skip this entry? - if ($criteriaInstance->getSkip() > 0) { - // We shall skip some entries - if ($skipFound < $criteriaInstance->getSkip()) { - // Skip this entry - $skipFound++; - break; - } // END - if - } // END - if - - // Set id number - $dataArray[$this->getIndexKey()] = $idx; - - // Entry found! - $resultData['rows'][] = $dataArray; - - // Count found entries up - $limitFound++; - break; - } // END - if - } // END - foreach - } 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 error message and exception - $this->resetLastError(); - } catch (PathIsNoDirectoryException $e) { - // Path not found means "table not found" for real databases... - $this->lastException = $e; - $this->lastError = $e->getMessage(); - - // 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->lastException = $e; - $this->lastError = $e->getMessage(); - } - - // 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) { - // Create full path name - $fqfn = sprintf("%s%s/%s.%s", - $this->getSavePath(), - $dataSetInstance->getTableName(), - md5($dataSetInstance->getUniqueValue()), - $this->getFileExtension() - ); - - // Try to save the request away - try { - // Write the data away - $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last error message and exception - $this->resetLastError(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->lastException = $e; - $this->lastError = $e->getMessage(); - - // Throw an SQL exception - throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $tableName), 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->getSavePath() . $dataSetInstance->getTableName() . '/'; - - // Try all the requests - try { - // Get a file pointer instance - $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - - // Get the criteria array from the dataset - $criteriaArray = $dataSetInstance->getCriteriaArray(); - - // Get search criteria - $searchInstance = $dataSetInstance->getSearchInstance(); - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn", "info." . $this->getFileExtension()))) && ($limitFound < $searchInstance->getLimit())) { - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Skip this file! - continue; - } - - // Open this file for reading - $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - - // Is this an array? - if (is_array($dataArray)) { - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Get criteria element - $criteria = $searchInstance->getCriteriaElemnent($key); - - // Is the criteria met? - if ((!is_null($criteria)) && ($criteria == $value)) { - - // 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 - - // Entry found, so update it - foreach ($criteriaArray as $criteriaKey => $criteriaValue) { - $dataArray[$criteriaKey] = $criteriaValue; - } // END - foreach - - // Write the data to a local file - $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); - - // Count it - $limitFound++; - break; - } // END - if - } // END - foreach - } // END - if - } // END - while - - // Close the file pointer - $directoryInstance->closeDirectory(); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last error message and exception - $this->resetLastError(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->lastException = $e; - $this->lastError = $e->getMessage(); - - // Throw an SQL exception - throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $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; - } -} - -// [EOF] -?>