X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Fdatabase%2Fdatabases%2Fclass_LocalFileDatabase.php;h=b3f018319c74050e5d3772f497553eab024fdfb3;hp=c6dfc0ee58625cf608fb3135babf752415e04fba;hb=1c379903c466fba5770c5f38b348915cee0f5854;hpb=6703da39c439aa4772df4c1b31aca50b577e1406 diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index c6dfc0ee..b3f01831 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -164,7 +164,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn */ private function getDataArrayFromFile ($fqfn) { // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); // Init compressed data $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); @@ -180,7 +180,8 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn $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: 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; @@ -196,6 +197,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn 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)); @@ -204,7 +206,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...'); // Write this data BASE64 encoded to the file - $this->getFileIoInstance()->saveFile($fqfn, $compressedData); + $this->getFileIoInstance()->saveFile($fqfn, $compressedData, $this); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); @@ -270,6 +272,27 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn $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 * @@ -277,16 +300,20 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn * @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); @@ -306,13 +333,13 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn * Starts a SELECT query on the database by given return type, table name * and search criteria * - * @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 ($tableName, LocalSearchCriteria $criteriaInstance) { + public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { // The result is null by any errors $resultData = NULL; @@ -337,7 +364,7 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn $idx = 1; // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $criteriaInstance->getLimit()) || ($criteriaInstance->getLimit() == 0))) { + 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! @@ -346,40 +373,46 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn // Read the file $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray,true)); + //* 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 or none set? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteria[' . gettype($criteria) . ']=' . $criteria . ';()=' . strlen($criteria) . ',criteriaInstance()=' . $criteriaInstance->count() . ',value(' . strlen($value) . ')=' . $value); - if (((!is_null($criteria)) && ($criteria == $value)) || ($criteriaInstance->count() == 0)) { - // 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! - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, true)); - $resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS][] = $dataArray; + // Entry found! + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, TRUE)); + $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); @@ -461,13 +494,13 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn $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 @@ -478,42 +511,51 @@ class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackendIn // Open this file for reading $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray,true)); + //* 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); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',key=' . $key . ',criteria=' . $criteria); - - // Is the criteria met? - if (((!is_null($criteria)) && ($criteria == $value)) || ($searchInstance->count() == 0)) { - // 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) { - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $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