class_LocalFileDatabase.php
Go to the documentation of this file.00001 <?php
00026 class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontendInterface {
00027
00028
00029 const DB_CODE_TABLE_MISSING = 0x100;
00030 const DB_CODE_TABLE_UNWRITEABLE = 0x101;
00031 const DB_CODE_DATA_FILE_CORRUPT = 0x102;
00032
00036 private $savePath = "";
00037
00041 private $fileExtension = "serialized";
00042
00046 private $lastFile = "";
00047
00051 private $lastContents = array();
00052
00056 private $alreadyConnected = false;
00057
00061 private $lastError = "";
00062
00066 private $lastException = null;
00067
00071 private $tableInfo = array();
00072
00076 private $indexKey = "__idx";
00077
00084 protected function __construct() {
00085
00086 parent::__construct(__CLASS__);
00087
00088
00089 $this->removeNumberFormaters();
00090 $this->removeSystemArray();
00091 }
00092
00102 public final static function createLocalFileDatabase ($savePath, FileIoHandler $ioInstance) {
00103
00104 $dbInstance = new LocalFileDatabase();
00105
00106
00107 $dbInstance->setSavePath($savePath);
00108 $dbInstance->setFileIoInstance($ioInstance);
00109
00110
00111 $dbInstance->connectToDatabase();
00112
00113
00114 return $dbInstance;
00115 }
00116
00123 public final function setSavePath ($savePath) {
00124
00125 $savePath = (string) $savePath;
00126
00127
00128 $this->savePath = $savePath;
00129 }
00130
00136 public final function getSavePath () {
00137 return $this->savePath;
00138 }
00139
00145 public final function getLastError () {
00146 return $this->lastError;
00147 }
00148
00154 public final function getLastException () {
00155 return $this->lastException;
00156 }
00157
00164 private final function setLastFile ($fqfn) {
00165
00166 $this->lastFile = (string) $fqfn;
00167 }
00168
00175 private final function resetLastError () {
00176 $this->lastError = "";
00177 $this->lastException = null;
00178 }
00179
00185 public final function getLastFile () {
00186 return $this->lastFile;
00187 }
00188
00195 private final function setLastFileContents (array $contents) {
00196
00197 $this->lastContents = $contents;
00198 }
00199
00205 public final function getLastContents () {
00206 return $this->lastContents;
00207 }
00208
00214 public final function getFileExtension () {
00215 return $this->fileExtension;
00216 }
00217
00223 public final function getIndexKey () {
00224 return $this->indexKey;
00225 }
00226
00233 private function getDataArrayFromFile ($fqfn) {
00234
00235 $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
00236
00237
00238 $compressedData = base64_decode($fileInstance->readLinesFromFile());
00239
00240
00241 $fileInstance->closeFile();
00242 unset($fileInstance);
00243
00244
00245 $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData);
00246
00247
00248 $dataArray = unserialize($serializedData);
00249
00250
00251 return $dataArray;
00252 }
00253
00261 private function writeDataArrayToFqfn ($fqfn, array $dataArray) {
00262
00263 $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w');
00264
00265
00266 $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray));
00267
00268
00269 $fileInstance->writeToFile(base64_encode($compressedData));
00270
00271
00272 $fileInstance->closeFile();
00273 }
00274
00281 private function getContentsFromTableInfoFile (StoreableCriteria $dataSetInstance) {
00282
00283 $infoArray = array();
00284
00285
00286 $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension();
00287
00288
00289 try {
00290 $infoArray = $this->getDataArrayFromFile($fqfn);
00291 } catch (FileNotFoundException $e) {
00292
00293 }
00294
00295
00296 return $infoArray;
00297 }
00298
00305 private function createTableInfoFile (StoreableCriteria $dataSetInstance) {
00306
00307 $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension();
00308
00309
00310 $this->tableInfo[$dataSetInstance->getTableName()] = array(
00311 'primary' => $dataSetInstance->getPrimaryKey(),
00312 'created' => time(),
00313 'last_updated' => time()
00314 );
00315
00316
00317 $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]);
00318 }
00319
00326 private function updatePrimaryKey (StoreableCriteria $dataSetInstance) {
00327
00328 $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance);
00329
00330
00331 if (!isset($this->tableInfo['primary'])) {
00332
00333 $this->createTableInfoFile($dataSetInstance);
00334 } elseif (($this->getConfigInstance()->readConfig('db_update_primary_forced') === "Y") && ($dataSetInstance->getPrimaryKey() != $this->tableInfo['primary'])) {
00335
00336 $this->tableInfo[$dataSetInstance->getTableName()]['primary'] = $dataSetInstance->getPrimaryKey();
00337
00338
00339 $this->updateTableInfoFile($dataSetInstance);
00340 }
00341 }
00342
00349 public function connectToDatabase () {
00350 }
00351
00363 public function querySelect ($resultType, $tableName, LocalSearchCriteria $criteriaInstance) {
00364
00365 $resultData = null;
00366
00367
00368 $pathName = $this->getSavePath() . $tableName . '/';
00369
00370
00371
00372 try {
00373
00374 $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName);
00375
00376
00377 $resultData = array(
00378 'status' => "ok",
00379 'rows' => array()
00380 );
00381
00382
00383 $limitFound = 0;
00384 $skipFound = 0;
00385 $idx = 1;
00386
00387
00388 while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn", "info." . $this->getFileExtension()))) && ($limitFound < $criteriaInstance->getLimit())) {
00389
00390 if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) {
00391
00392 continue;
00393 }
00394
00395
00396 $dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
00397
00398
00399 if (is_array($dataArray)) {
00400
00401 foreach ($dataArray as $key => $value) {
00402
00403 $criteria = $criteriaInstance->getCriteriaElemnent($key);
00404
00405
00406 if ((!is_null($criteria)) && ($criteria == $value)) {
00407
00408
00409 if ($criteriaInstance->getSkip() > 0) {
00410
00411 if ($skipFound < $criteriaInstance->getSkip()) {
00412
00413 $skipFound++;
00414 break;
00415 }
00416 }
00417
00418
00419 $dataArray[$this->getIndexKey()] = $idx;
00420
00421
00422 $resultData['rows'][] = $dataArray;
00423
00424
00425 $limitFound++;
00426 break;
00427 }
00428 }
00429 } else {
00430
00431 throw new SqlException(array($this, sprintf("File '%s' contains invalid data.", $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY);
00432 }
00433
00434
00435 $idx++;
00436 }
00437
00438
00439 $directoryInstance->closeDirectory();
00440 unset($directoryInstance);
00441
00442
00443 $this->resetLastError();
00444 } catch (PathIsNoDirectoryException $e) {
00445
00446 $this->lastException = $e;
00447 $this->lastError = $e->getMessage();
00448
00449
00450 throw new SqlException (array($this, sprintf("Table '%s' not found", $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY);
00451 } catch (FrameworkException $e) {
00452
00453 $this->lastException = $e;
00454 $this->lastError = $e->getMessage();
00455 }
00456
00457
00458 return $resultData;
00459 }
00460
00468 public function queryInsertDataSet (StoreableCriteria $dataSetInstance) {
00469
00470 $fqfn = sprintf("%s%s/%s.%s",
00471 $this->getSavePath(),
00472 $dataSetInstance->getTableName(),
00473 md5($dataSetInstance->getUniqueValue()),
00474 $this->getFileExtension()
00475 );
00476
00477
00478 try {
00479
00480 $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray());
00481
00482
00483 $this->updatePrimaryKey($dataSetInstance);
00484
00485
00486 $this->resetLastError();
00487 } catch (FrameworkException $e) {
00488
00489 $this->lastException = $e;
00490 $this->lastError = $e->getMessage();
00491
00492
00493 throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $tableName), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
00494 }
00495 }
00496
00504 public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) {
00505
00506 $pathName = $this->getSavePath() . $dataSetInstance->getTableName() . '/';
00507
00508
00509 try {
00510
00511 $directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName);
00512
00513
00514 $limitFound = 0;
00515 $skipFound = 0;
00516
00517
00518 $criteriaArray = $dataSetInstance->getCriteriaArray();
00519
00520
00521 $searchInstance = $dataSetInstance->getSearchInstance();
00522
00523
00524 while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn", "info." . $this->getFileExtension()))) && ($limitFound < $searchInstance->getLimit())) {
00525
00526 if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) {
00527
00528 continue;
00529 }
00530
00531
00532 $dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
00533
00534
00535 if (is_array($dataArray)) {
00536
00537 foreach ($dataArray as $key => $value) {
00538
00539 $criteria = $searchInstance->getCriteriaElemnent($key);
00540
00541
00542 if ((!is_null($criteria)) && ($criteria == $value)) {
00543
00544
00545 if ($searchInstance->getSkip() > 0) {
00546
00547 if ($skipFound < $searchInstance->getSkip()) {
00548
00549 $skipFound++;
00550 break;
00551 }
00552 }
00553
00554
00555 foreach ($criteriaArray as $criteriaKey => $criteriaValue) {
00556 $dataArray[$criteriaKey] = $criteriaValue;
00557 }
00558
00559
00560 $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray);
00561
00562
00563 $limitFound++;
00564 break;
00565 }
00566 }
00567 }
00568 }
00569
00570
00571 $directoryInstance->closeDirectory();
00572
00573
00574 $this->updatePrimaryKey($dataSetInstance);
00575
00576
00577 $this->resetLastError();
00578 } catch (FrameworkException $e) {
00579
00580 $this->lastException = $e;
00581 $this->lastError = $e->getMessage();
00582
00583
00584 throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
00585 }
00586 }
00587
00595 public function getPrimaryKeyOfTable ($tableName) {
00596
00597 $primaryKey = null;
00598
00599
00600 if (isset($this->tableInfo[$tableName])) {
00601
00602 $primaryKey = $this->tableInfo[$tableName]['primary'];
00603 }
00604
00605
00606 return $primaryKey;
00607 }
00608 }
00609
00610
00611 ?>