From f952a5fb1fe821dd1ddca875f537dd680019371d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Sun, 1 Jun 2008 10:23:10 +0000 Subject: [PATCH] Database result added, SqlException added --- .gitattributes | 5 + .../database/class_DatabaseException.php | 39 ++++++ .../exceptions/database/general/.htaccess | 1 + .../database/general/class_SqlException.php | 47 ++++++++ .../class_SavePathIsEmptyException.php | 6 +- .../class_SavePathIsNoDirectoryException.php | 6 +- .../class_SavePathReadProtectedException.php | 6 +- .../class_SavePathWriteProtectedException.php | 6 +- ...class_WrapperUserNameNotFoundException.php | 6 +- .../class_DatabaseFrontendInterface.php | 4 +- .../database/class_BaseDatabaseFrontend.php | 3 + .../databases/class_LocalFileDatabase.php | 75 +++++++++++- .../wrapper/class_UserDatabaseWrapper.php | 13 +- .../io/class_FrameworkDirectoryPointer.php | 10 +- inc/classes/main/result/.htaccess | 1 + .../main/result/class_DatabaseResult.php | 114 ++++++++++++++++++ .../database/class_DatabaseConnection.php | 10 ++ 17 files changed, 327 insertions(+), 25 deletions(-) create mode 100644 inc/classes/exceptions/database/class_DatabaseException.php create mode 100644 inc/classes/exceptions/database/general/.htaccess create mode 100644 inc/classes/exceptions/database/general/class_SqlException.php create mode 100644 inc/classes/main/result/.htaccess create mode 100644 inc/classes/main/result/class_DatabaseResult.php diff --git a/.gitattributes b/.gitattributes index 5ad52fb..25f3a00 100644 --- a/.gitattributes +++ b/.gitattributes @@ -152,6 +152,9 @@ inc/classes/exceptions/controller/.htaccess -text inc/classes/exceptions/controller/class_DefaultControllerException.php -text inc/classes/exceptions/criteria/.htaccess -text inc/classes/exceptions/database/.htaccess -text +inc/classes/exceptions/database/class_DatabaseException.php -text +inc/classes/exceptions/database/general/.htaccess -text +inc/classes/exceptions/database/general/class_SqlException.php -text inc/classes/exceptions/database/local_file/.htaccess -text inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php -text inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php -text @@ -347,6 +350,8 @@ inc/classes/main/resolver/web/class_WebCommandResolver.php -text inc/classes/main/resolver/web/class_WebControllerResolver.php -text inc/classes/main/response/.htaccess -text inc/classes/main/response/class_HttpResponse.php -text +inc/classes/main/result/.htaccess -text +inc/classes/main/result/class_DatabaseResult.php -text inc/classes/main/template/.htaccess -text inc/classes/main/template/class_TemplateEngine.php -text inc/classes/main/user/.htaccess -text diff --git a/inc/classes/exceptions/database/class_DatabaseException.php b/inc/classes/exceptions/database/class_DatabaseException.php new file mode 100644 index 0000000..6b713d2 --- /dev/null +++ b/inc/classes/exceptions/database/class_DatabaseException.php @@ -0,0 +1,39 @@ + + * @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 DatabaseException extends FrameworkException { + /** + * The constructor + * + * @param $message Message from the exception + * @param $code Code number for the exception + * @return void + */ + public function __construct ($message, $code) { + // Just call the parent constructor + parent::__construct($message, $code); + } +} + +// [EOF] +?> diff --git a/inc/classes/exceptions/database/general/.htaccess b/inc/classes/exceptions/database/general/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/exceptions/database/general/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/exceptions/database/general/class_SqlException.php b/inc/classes/exceptions/database/general/class_SqlException.php new file mode 100644 index 0000000..e39c1e2 --- /dev/null +++ b/inc/classes/exceptions/database/general/class_SqlException.php @@ -0,0 +1,47 @@ + + * @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 SqlException extends DatabaseException { + /** + * The constructor + * + * @param $msgArray Message array + * @param $code Code number for the exception + * @return void + */ + public function __construct (array $msgArray, $code) { + // Construct the message + $message = sprintf("[%s:%d] SQL error detected. Message from database: %s, code: 0x%s", + $msgArray[0]->__toString(), + $this->getLine(), + $msgArray[1], + dechex($msgArray[2]) + ); + + // Call parent constructor + parent::__construct($message, $code); + } +} + +// [EOF] +?> diff --git a/inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php b/inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php index a9172c0..dc5ed66 100644 --- a/inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php +++ b/inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php @@ -21,12 +21,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class SavePathIsEmptyException extends FrameworkException { +class SavePathIsEmptyException extends DatabaseException { /** * The constructor * - * @param $message Message from the exception - * @param $code Code number for the exception + * @param $message Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct (BaseFrameworkSystem $class, $code) { diff --git a/inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php b/inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php index 57536ab..a8bcc6e 100644 --- a/inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php +++ b/inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php @@ -21,12 +21,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class SavePathIsNoDirectoryException extends FrameworkException { +class SavePathIsNoDirectoryException extends DatabaseException { /** * The constructor * - * @param $message Message from the exception - * @param $code Code number for the exception + * @param $message Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct ($path, $code) { diff --git a/inc/classes/exceptions/database/local_file/class_SavePathReadProtectedException.php b/inc/classes/exceptions/database/local_file/class_SavePathReadProtectedException.php index 23c99b6..ee1da7f 100644 --- a/inc/classes/exceptions/database/local_file/class_SavePathReadProtectedException.php +++ b/inc/classes/exceptions/database/local_file/class_SavePathReadProtectedException.php @@ -21,12 +21,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class SavePathReadProtectedException extends FrameworkException { +class SavePathReadProtectedException extends DatabaseException { /** * The constructor * - * @param $message Message from the exception - * @param $code Code number for the exception + * @param $message Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct ($path, $code) { diff --git a/inc/classes/exceptions/database/local_file/class_SavePathWriteProtectedException.php b/inc/classes/exceptions/database/local_file/class_SavePathWriteProtectedException.php index 8a88b18..eb5417f 100644 --- a/inc/classes/exceptions/database/local_file/class_SavePathWriteProtectedException.php +++ b/inc/classes/exceptions/database/local_file/class_SavePathWriteProtectedException.php @@ -21,12 +21,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class SavePathWriteProtectedException extends FrameworkException { +class SavePathWriteProtectedException extends DatabaseException { /** * The constructor * - * @param $message Message from the exception - * @param $code Code number for the exception + * @param $message Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct ($path, $code) { diff --git a/inc/classes/exceptions/database/wrapper/class_WrapperUserNameNotFoundException.php b/inc/classes/exceptions/database/wrapper/class_WrapperUserNameNotFoundException.php index 0804803..6b38482 100644 --- a/inc/classes/exceptions/database/wrapper/class_WrapperUserNameNotFoundException.php +++ b/inc/classes/exceptions/database/wrapper/class_WrapperUserNameNotFoundException.php @@ -21,12 +21,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class WrapperUserNameNotFoundException extends FrameworkException { +class WrapperUserNameNotFoundException extends DatabaseException { /** * The constructor * - * @param $msgArray Message from the exception - * @param $code Code number for the exception + * @param $msgArray Message from the exception + * @param $code Code number for the exception * @return void */ public function __construct (array $msgArray, $code) { diff --git a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php index 14e89d9..0b66c12 100644 --- a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php +++ b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php @@ -38,7 +38,7 @@ interface DatabaseFrontendInterface extends FrameworkDatabaseInterface { function loadObject (); /** - * Makes sure that the database connection is alive + * Makes sure that the database connection is up and alive * * @return void */ @@ -52,6 +52,8 @@ interface DatabaseFrontendInterface extends FrameworkDatabaseInterface { * @param $tableName Name of the database table * @param $criteria Search criteria class * @return $resultData Result data of the query + * @throws UnsupportedCriteriaException If the criteria is unsupported + * @throws SqlException If an SQL error occurs */ function querySelect ($resultType, $tableName, Criteria $criteriaInstance); } diff --git a/inc/classes/main/database/class_BaseDatabaseFrontend.php b/inc/classes/main/database/class_BaseDatabaseFrontend.php index 3207831..cdf894f 100644 --- a/inc/classes/main/database/class_BaseDatabaseFrontend.php +++ b/inc/classes/main/database/class_BaseDatabaseFrontend.php @@ -23,6 +23,9 @@ * along with this program. If not, see . */ abstract class BaseDatabaseFrontend extends BaseFrameworkSystem implements DatabaseFrontendInterface, LimitableObject { + // Constants for exceptions + const EXCEPTION_SQL_QUERY = 0xc00; + /** * The limiter instance */ diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php index 16314e1..56034fa 100644 --- a/inc/classes/main/database/databases/class_LocalFileDatabase.php +++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php @@ -24,6 +24,9 @@ * 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; + /** * Save path for "file database" */ @@ -49,6 +52,16 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend */ private $alreadyConnected = false; + /** + * Last error message + */ + private $lastError = ""; + + /** + * Last exception + */ + 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. @@ -116,6 +129,24 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend 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; + } + /** * Saves a given object to the local file system by serializing and * transparently compressing it @@ -284,6 +315,17 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend $this->lastFile = $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 * @@ -504,16 +546,45 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend * @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, Criteria $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); } - // A "select" query on local files is not that easy, so begin slowly with it... - $this->partialStub(sprintf("type=%s,table=%s,criteria=%s", $resultType, $tableName, $criteriaInstance)); + // 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 + $directoryPointer = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName); + $this->partialStub("Finish handling found "tables""); + + // 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; } } diff --git a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php index c8eb465..a9f64d8 100644 --- a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php +++ b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php @@ -103,8 +103,17 @@ class UserDatabaseWrapper extends BaseDatabaseWrapper { // Now it's time to ask the database layer for this select statement $result = $this->getDatabaseInstance()->doSelectByTableCriteria(self::DB_TABLE_USER, $criteriaInstance); - // Cache the result - $this->cacheInstance->offsetSet($cacheKey, $result); + // Cache the result if not null + if (!is_null($result)) { + // A valid result has returned from the database layer + $this->cacheInstance->offsetSet($cacheKey, $result); + } else { + // This invalid result must be wrapped + $result = array( + 'status' => "invalid", + 'exception' => $this->getDatabaseInstance()->getLastException() + ); + } } // Create an instance of a DatabaseResult class with the given result diff --git a/inc/classes/main/io/class_FrameworkDirectoryPointer.php b/inc/classes/main/io/class_FrameworkDirectoryPointer.php index f0f2dd8..7ce3c4e 100644 --- a/inc/classes/main/io/class_FrameworkDirectoryPointer.php +++ b/inc/classes/main/io/class_FrameworkDirectoryPointer.php @@ -67,11 +67,11 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { * Create a directory pointer based on the given path. The path will also * be verified here. * - * @param $pathName The path name we shall pass + * @param $pathName The path name we shall pass * to opendir() - * @param $inConstructor If we are in de/con-structor + * @param $inConstructor If we are in de/con-structor * or from somewhere else - * @throws PathIsEmptyException If the provided path name + * @throws PathIsEmptyException If the provided path name * is empty * @throws InvalidPathStringException If the provided path name is * not a string @@ -79,9 +79,9 @@ class FrameworkDirectoryPointer extends BaseFrameworkSystem { * not valid * @throws PathReadProtectedException If the provided path name is * read-protected - * @throws DirPointerNotOpened If opendir() returns not a + * @throws DirPointerNotOpened If opendir() returns not a * directory resource - * @return $pointerInstance A prepared instance of + * @return $pointerInstance A prepared instance of * FrameworkDirectoryPointer */ public final static function createFrameworkDirectoryPointer ($pathName, $inConstructor = false) { diff --git a/inc/classes/main/result/.htaccess b/inc/classes/main/result/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/inc/classes/main/result/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/inc/classes/main/result/class_DatabaseResult.php b/inc/classes/main/result/class_DatabaseResult.php new file mode 100644 index 0000000..50f57e0 --- /dev/null +++ b/inc/classes/main/result/class_DatabaseResult.php @@ -0,0 +1,114 @@ + + * @version 0.3.0 + * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software + * @license GNU GPL 3.0 or any newer version + * @link http://www.mxchange.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 DatabaseResult extends BaseFrameworkSystem { + /** + * Current position in array + */ + private $currentPos = -1; + + /** + * Current row + */ + private $currentRow = null; + + /** + * Result array + */ + private $resultArray = array(); + + /** + * Private constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set part description + $this->setObjectDescription("Database result"); + + // Create unique ID number + $this->createUniqueID(); + + // Clean up a little + $this->removeNumberFormaters(); + $this->removeSystemArray(); + } + + /** + * Creates an instance of this result by a provided result array + * + * @param $resultArray The array holding the result from query + * @return $resultInstance An instance of this class + */ + public final static function createDatabaseResult (array $resultArray) { + // Get a new instance + $resultInstance = new DatabaseResult(); + + // Set the result array + $resultInstance->setResultArray($resultArray); + + // Return the instance + return $resultInstance; + } + + /** + * Setter for result array + * + * @param $resultArray The array holding the result from query + * @return void + */ + protected final function setResultArray (array $resultArray) { + $this->resultArray = $resultArray; + } + + /** + * "Iterator" method next() to advance to the next valid entry. This method + * does also check if the result is invalid + * + * @return $nextValid Wether the next entry is valid + */ + public function next () { + // Default is not valid + $nextValid = false; + + // Is the result valid? + if ($this->resultArray['status'] === "ok") { + // The status is fine so let's have a look for the next entry + if (isset($this->resultArray['rows'][($this->currentPos + 1)])) { + // Next entry found, so count one up and cache it + $this->currentPos++; + $this->currentRow = $this->resultArray['rows'][$this->currentPos]; + $nextValid = true; + } // END - if + } // END - if + + // Return the result + return $nextValid; + } +} + +// [EOF] +?> diff --git a/inc/classes/middleware/database/class_DatabaseConnection.php b/inc/classes/middleware/database/class_DatabaseConnection.php index ebb6933..74196bc 100644 --- a/inc/classes/middleware/database/class_DatabaseConnection.php +++ b/inc/classes/middleware/database/class_DatabaseConnection.php @@ -180,6 +180,16 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Li // Return the result return $result; } + + /** + * Getter for last exception + * + * @return $exceptionInstance Last thrown exception + */ + public final function getLastException () { + $exceptionInstance = $this->dbLayer->getLastException(); + return $exceptionInstance; + } } // [EOF] -- 2.39.5