X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Fdatabase%2Fdatabases%2Fclass_LocalFileDatabase.php;h=ed849a99369afd61d633cd215b1783bec5b26e05;hp=78375f6612f579962883e85cc4c86a5945f848e7;hb=546959d365de1c4a499502b4d2f08ce06be69269;hpb=b9c18d6c24e3be4393bf41005aa4e428a0ea3218 diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index 78375f66..ed849a99 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -2,13 +2,17 @@ /** * Database backend class for storing objects in locally created files. * - * This class serializes objects and saves them to local files. + * This class serializes arrays stored in the dataset instance and saves them + * to local files. Every file (except 'info') represents a single line. Every + * directory within the 'db' (base) directory represents a table. * - * @author Roland Haeder + * A configurable 'file_io_class' is being used as "storage backend". + * + * @author Roland Haeder * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Core Developer Team + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team * @license GNU GPL 3.0 or any newer version - * @link http://www.ship-simu.org + * @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 @@ -23,20 +27,7 @@ * 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; - - // Status results - const RESULT_OKAY = 'ok'; - - /** - * Save path for "file database" - */ - private $savePath = ''; - +class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { /** * The file's extension */ @@ -53,19 +44,9 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend private $lastContents = array(); /** - * Wether the "connection is already up - */ - private $alreadyConnected = false; - - /** - * Last error message - */ - private $lastError = ''; - - /** - * Last exception + * Whether the "connection is already up */ - private $lastException = null; + private $alreadyConnected = FALSE; /** * Table information array @@ -75,7 +56,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend /** * Element for index */ - private $indexKey = "__idx"; + private $indexKey = '__idx'; /** * The protected constructor. Do never instance from outside! You need to @@ -83,78 +64,38 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * * @return void */ - protected function __construct() { + 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. + * Create an object of LocalFileDatabase and set the save path from + * configuration for local files. * - * @param $savePath The local file path string - * @param $ioInstance The input/output handler. This - * should be FileIoHandler - * @return $dbInstance An instance of LocalFileDatabase + * @return $databaseInstance An instance of LocalFileDatabase */ - public final static function createLocalFileDatabase ($savePath, FileIoHandler $ioInstance) { + public static final function createLocalFileDatabase () { // Get an instance - $dbInstance = new LocalFileDatabase(); - - // Set save path and IO instance - $dbInstance->setSavePath($savePath); - $dbInstance->setFileIoInstance($ioInstance); + $databaseInstance = new LocalFileDatabase(); - // "Connect" to the database - $dbInstance->connectToDatabase(); + // Get a new compressor channel instance + $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class'); - // Return database instance - return $dbInstance; - } + // Set the compressor channel + $databaseInstance->setCompressorChannel($compressorInstance); - /** - * 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; - } + // Get a file IO handler + $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class'); - /** - * Getter for save path - * - * @return $savePath The local save path where we shall put our serialized classes - */ - public final function getSavePath () { - return $this->savePath; - } + // ... and set it + $databaseInstance->setFileIoInstance($fileIoInstance); - /** - * Getter for last error message - * - * @return $lastError Last error message - */ - public final function getLastError () { - return $this->lastError; - } + // "Connect" to the database + $databaseInstance->connectToDatabase(); - /** - * Getter for last exception - * - * @return $lastException Last thrown exception - */ - public final function getLastException () { - return $this->lastException; + // Return database instance + return $databaseInstance; } /** @@ -168,21 +109,10 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $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 + * @return $lastFile The last read file's name with full path */ public final function getLastFile () { return $this->lastFile; @@ -191,7 +121,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend /** * Setter for contents of the last read file * - * @param $contents An array with header and data elements + * @param $contents An array with header and data elements * @return void */ private final function setLastFileContents (array $contents) { @@ -233,14 +163,14 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @return $dataArray */ private function getDataArrayFromFile ($fqfn) { - // Get a file pointer - $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn); + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); - // Get the raw data and BASE64-decode it - $compressedData = base64_decode($fileInstance->readLinesFromFile()); + // Init compressed data + $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); + $compressedData = $compressedData['data']; // Close the file and throw the instance away - $fileInstance->closeFile(); unset($fileInstance); // Decompress it @@ -249,6 +179,10 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // 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; } @@ -261,17 +195,21 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @return void */ private function writeDataArrayToFqfn ($fqfn, array $dataArray) { - // Get a file pointer instance - $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w'); + // 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 - $fileInstance->writeToFile(base64_encode($compressedData)); + $this->getFileIoInstance()->saveFile($fqfn, $compressedData, $this); - // Close the file pointer - $fileInstance->closeFile(); + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); } /** @@ -285,12 +223,12 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $infoArray = array(); // Create FQFN for getting the table information file - $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension(); + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); // Get the file contents try { $infoArray = $this->getDataArrayFromFile($fqfn); - } catch (FileNotFoundException $e) { + } catch (FileIoException $e) { // Not found, so ignore it here } @@ -298,6 +236,21 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend 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 * @@ -306,7 +259,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend */ private function createTableInfoFile (StoreableCriteria $dataSetInstance) { // Create FQFN for creating the table information file - $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension(); + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); // Get the data out from dataset in a local array $this->tableInfo[$dataSetInstance->getTableName()] = array( @@ -319,6 +272,27 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $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 * @@ -326,16 +300,20 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @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? - if (!isset($this->tableInfo['primary'])) { + //* 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['primary'])) { + } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) { // Set the array element - $this->tableInfo[$dataSetInstance->getTableName()]['primary'] = $dataSetInstance->getPrimaryKey(); + $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); // Update the entry $this->updateTableInfoFile($dataSetInstance); @@ -355,19 +333,18 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * 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 + * @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 ($resultType, $tableName, LocalSearchCriteria $criteriaInstance) { + public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { // The result is null by any errors - $resultData = null; + $resultData = NULL; // Create full path name - $pathName = $this->getSavePath() . $tableName . '/'; + $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 @@ -377,8 +354,8 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read $resultData = array( - 'status' => LocalfileDatabase::RESULT_OKAY, - 'rows' => array() + BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY, + BaseDatabaseBackend::RESULT_INDEX_ROWS => array() ); // Initialize limit/skip @@ -387,7 +364,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $idx = 1; // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', "info." . $this->getFileExtension()))) && ($limitFound < $criteriaInstance->getLimit())) { + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { // Does the extension match? if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { // Skip this file! @@ -396,41 +373,49 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // 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) { - // 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 + // 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; + // Set id number + $dataArray[$this->getIndexKey()] = $idx; - // Entry found! - $resultData['rows'][] = $dataArray; + // 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++; - break; - } // END - if - } // END - foreach + // 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); + 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 @@ -441,19 +426,17 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $directoryInstance->closeDirectory(); unset($directoryInstance); - // Reset last error message and exception - $this->resetLastError(); + // Reset last exception + $this->resetLastException(); } catch (PathIsNoDirectoryException $e) { // Path not found means "table not found" for real databases... - $this->lastException = $e; - $this->lastError = $e->getMessage(); + $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); + 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(); + $this->setLastException($e); } // Return the gathered result @@ -468,31 +451,25 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @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 { + // 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 error message and exception - $this->resetLastError(); + // Reset last exception + $this->resetLastException(); } catch (FrameworkException $e) { // Catch all exceptions and store them in last error - $this->lastException = $e; - $this->lastError = $e->getMessage(); + $this->setLastException($e); // 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); + 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); } } @@ -505,7 +482,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend */ public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { // Create full path name - $pathName = $this->getSavePath() . $dataSetInstance->getTableName() . '/'; + $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/'; // Try all the requests try { @@ -517,55 +494,68 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $skipFound = 0; // Get the criteria array from the dataset - $criteriaArray = $dataSetInstance->getCriteriaArray(); + $searchArray = $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())) { + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', '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) { - // 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 + // 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? + 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 - // Entry found, so update it - foreach ($criteriaArray as $criteriaKey => $criteriaValue) { - $dataArray[$criteriaKey] = $criteriaValue; - } // END - foreach + // 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); - // Write the data to a local file - $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); + // Debug message + add/update it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue); + $dataArray[$searchKey] = $searchValue; + } // END - foreach - // Count it - $limitFound++; - break; - } // END - if - } // END - foreach + // Write the data to a local file + $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); + + // Count found entries up + $limitFound++; + } // END - if } // END - if } // END - while @@ -575,15 +565,14 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // Update the primary key $this->updatePrimaryKey($dataSetInstance); - // Reset last error message and exception - $this->resetLastError(); + // Reset last exception + $this->resetLastException(); } catch (FrameworkException $e) { // Catch all exceptions and store them in last error - $this->lastException = $e; - $this->lastError = $e->getMessage(); + $this->setLastException($e); // 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); + 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); } } @@ -596,7 +585,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend */ public function getPrimaryKeyOfTable ($tableName) { // Default key is null - $primaryKey = null; + $primaryKey = NULL; // Does the table information exist? if (isset($this->tableInfo[$tableName])) { @@ -607,6 +596,22 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // 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]