X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=inc%2Fclasses%2Fmain%2Fdatabase%2Fdatabases%2Fclass_LocalFileDatabase.php;h=bf19a67ecdddba1c3c2b8c0c490ce3358ee9a247;hb=fd80d47afc96ae0c0759530800051a0f07eb9c92;hp=6133051540b7315978525a79864b22b1eee78524;hpb=11ca3d829702e770073051f728151754190572e8;p=shipsimu.git diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index 6133051..bf19a67 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -24,8 +24,10 @@ * 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 = 0x000; + const DB_CODE_TABLE_MISSING = 0x000; + const DB_CODE_TABLE_UNWRITEABLE = 0x001; /** * Save path for "file database" @@ -63,8 +65,8 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend private $lastException = null; /** - * The private constructor. Do never instance from outside! - * You need to set a local file path. The class will then validate it. + * The protected constructor. Do never instance from outside! You need to + * set a local file path. The class will then validate it. * * @return void */ @@ -76,7 +78,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $this->setObjectDescription("Class for local file databases"); // Create unique ID - $this->createUniqueID(); + $this->generateUniqueId(); // Clean up a little $this->removeSystemArray(); @@ -151,25 +153,10 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * Saves a given object to the local file system by serializing and * transparently compressing it * - * @param $object The object we shall save to the local file system + * @param $object The object we shall save to the local file system * @return void - * @throws NullPointerException If the object instance is null - * @throws NoObjectException If the parameter $object is not - * an object */ - public final function saveObject ($object) { - // Some tests on the parameter... - if (is_null($object)) { - // Is null, throw exception - throw new NullPointerException($object, self::EXCEPTION_IS_NULL_POINTER); - } elseif (!is_object($object)) { - // Is not an object, throw exception - throw new NoObjectException($object, self::EXCEPTION_IS_NO_OBJECT); - } elseif (!method_exists($object, '__toString')) { - // A highly required method was not found... :-( - throw new MissingMethodException(array($object, '__toString'), self::EXCEPTION_MISSING_METHOD); - } - + public final function saveObject (FrameworkInterface $object) { // Get a string containing the serialized object. We cannot exchange // $this and $object here because $object does not need to worry // about it's limitations... ;-) @@ -186,14 +173,14 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend /** * Get a serialized string from the given object * - * @param $object The object we want to serialize and transparently - * compress - * @return $serialized A string containing the serialzed/compressed object + * @param $object The object we want to serialize and transparently + * compress + * @return $serialized A string containing the serialzed/compressed object * @see ObjectLimits An object holding limition information * @see SerializationContainer A special container class for e.g. - * attributes from limited objects + * attributes from limited objects */ - private function serializeObject ($object) { + private function serializeObject (FrameworkInterface $object) { // If there is no limiter instance we serialize the whole object // otherwise only in the limiter object (ObjectLimits) specified // attributes summarized in a special container class @@ -218,13 +205,13 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * Analyses if a unique ID has already been used or not by search in the * local database folder. * - * @param $uniqueID A unique ID number which shall be checked - * before it will be used - * @param $inConstructor If we got called in a de/con-structor or - * from somewhere else + * @param $uniqueID A unique ID number which shall be checked + * before it will be used + * @param $inConstructor If we got called in a de/con-structor or + * from somewhere else * @return $isUnused true = The unique ID was not found in the database, - * false = It is already in use by an other object - * @throws NoArrayCreatedException If explode() fails to create an array + * false = It is already in use by an other object + * @throws NoArrayCreatedException If explode() fails to create an array * @throws InvalidArrayCountException If the array contains less or * more than two elements */ @@ -274,7 +261,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // Initialize the search loop $isValid = false; - while ($dataFile = $dirInstance->readDirectoryExcept(array(".", ".."))) { + while ($dataFile = $dirInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) { // Generate FQFN for testing $fqfn = sprintf("%s/%s", $pathName, $dataFile); $this->setLastFile($fqfn); @@ -548,16 +535,10 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @throws UnsupportedCriteriaException If the criteria is unsupported * @throws SqlException If an "SQL error" occurs */ - public function querySelect ($resultType, $tableName, Criteria $criteriaInstance) { + public function querySelect ($resultType, $tableName, LocalSearchCriteria $criteriaInstance) { // The result is null by any errors $resultData = null; - // Is this criteria supported? - if (!$criteriaInstance instanceof LocalCriteria) { - // Not supported by this database layer - throw new UnsupportedCriteriaException(array($this, $criteriaInstance), self::EXCEPTION_REQUIRED_INTERFACE_MISSING); - } - // Create full path name $pathName = $this->getSavePath() . $tableName . '/'; @@ -573,9 +554,54 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend 'rows' => array() ); + // Initialize limit/skip + $limitFound = 0; $skipFound = 0; + // Read the directory with some exceptions - while ($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess"))) { - $this->partialStub(sprintf("File %s found.", $dataFile)); + while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) && ($limitFound < $criteriaInstance->getLimit())) { + // Open this file for reading + $filePointer = FrameworkFileInputPointer::createFrameworkFileInputPointer($pathName . $dataFile); + + // Get the raw data and BASE64-decode it + $compressedData = base64_decode($filePointer->readLinesFromFile()); + + // Close the file and throw the instance away + $filePointer->closeFile(); + unset($filePointer); + + // Decompress it + $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); + + // Unserialize it + $dataArray = unserialize($serializedData); + + // 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 + + // Entry found! + $resultData['rows'][] = $dataArray; + $limitFound++; + break; + } // END - if + } // END - foreach + } // END - if } // END - while // Close directory and throw the instance away @@ -600,6 +626,51 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend // 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 { + // Get a file pointer instance + $filePointer = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w'); + + // Get the criteria array from the dataset + $criteriaArray = $dataSetInstance->getCriteriaArray(); + + // Serialize and compress it + $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($criteriaArray)); + + // Write this data BASE64 encoded to the file + $filePointer->writeToFile(base64_encode($compressedData)); + + // Close the file pointer + $filePointer->closeFile(); + + // 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); + } + } } // [EOF]