Database result added, SqlException added
authorRoland Häder <roland@mxchange.org>
Sun, 1 Jun 2008 10:23:10 +0000 (10:23 +0000)
committerRoland Häder <roland@mxchange.org>
Sun, 1 Jun 2008 10:23:10 +0000 (10:23 +0000)
17 files changed:
.gitattributes
inc/classes/exceptions/database/class_DatabaseException.php [new file with mode: 0644]
inc/classes/exceptions/database/general/.htaccess [new file with mode: 0644]
inc/classes/exceptions/database/general/class_SqlException.php [new file with mode: 0644]
inc/classes/exceptions/database/local_file/class_SavePathIsEmptyException.php
inc/classes/exceptions/database/local_file/class_SavePathIsNoDirectoryException.php
inc/classes/exceptions/database/local_file/class_SavePathReadProtectedException.php
inc/classes/exceptions/database/local_file/class_SavePathWriteProtectedException.php
inc/classes/exceptions/database/wrapper/class_WrapperUserNameNotFoundException.php
inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php
inc/classes/main/database/class_BaseDatabaseFrontend.php
inc/classes/main/database/databases/class_LocalFileDatabase.php
inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php
inc/classes/main/io/class_FrameworkDirectoryPointer.php
inc/classes/main/result/.htaccess [new file with mode: 0644]
inc/classes/main/result/class_DatabaseResult.php [new file with mode: 0644]
inc/classes/middleware/database/class_DatabaseConnection.php

index 5ad52fbe74a3efe44a004da2d7de85e37746d3c1..25f3a004126a13326783978cb29475efd8beada0 100644 (file)
@@ -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 (file)
index 0000000..6b713d2
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * A general database exception
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+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 (file)
index 0000000..3a42882
--- /dev/null
@@ -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 (file)
index 0000000..e39c1e2
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * A SQL exception thrown when an SQL error was detected.
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+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: <u>%s</u>, code: <u>0x%s</u>",
+                       $msgArray[0]->__toString(),
+                       $this->getLine(),
+                       $msgArray[1],
+                       dechex($msgArray[2])
+               );
+
+               // Call parent constructor
+               parent::__construct($message, $code);
+       }
+}
+
+// [EOF]
+?>
index a9172c0847643434c4c1b9e7e76ec38e36678e2d..dc5ed66beb0def355566d6652b9a1affa8b0883d 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-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) {
index 57536ab62e771f169b053f05da394bfdd5c15729..a8bcc6ed236a8d9a2ca89dd90e2b3b2cd5f6f552 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-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) {
index 23c99b6fbe340e764c3f2a0a31561625e83d39d8..ee1da7f48742b589fc1ce5d76df11c3dc35f4c9c 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-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) {
index 8a88b18b6aa137da577e268a16011d7f946a4af7..eb5417fe9611318cec346d88cbd8d0f0297eec5f 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-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) {
index 080480391e3eb18e3aa13de9148b24067822c8f9..6b38482df1a9df5d598a9035eea643dee179fd7b 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-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) {
index 14e89d99856885532bb5cb7e06a9a7be76ed7491..0b66c124ef0ccb7f6a3688f696e0122779c07d89 100644 (file)
@@ -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);
 }
index 3207831572231f672a0b4953472ae2adea42d22e..cdf894fc04a0428758b2274ec8e3665e59d7372b 100644 (file)
@@ -23,6 +23,9 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 abstract class BaseDatabaseFrontend extends BaseFrameworkSystem implements DatabaseFrontendInterface, LimitableObject {
+       // Constants for exceptions
+       const EXCEPTION_SQL_QUERY = 0xc00;
+
        /**
         * The limiter instance
         */
index 16314e1164e3557e7cd55f68bad8657b87340aea..56034fa0b62087794511527ca856538c8286b05a 100644 (file)
@@ -24,6 +24,9 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 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 &quot;tables&quot;");
+
+                       // 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 &#39;%s&#39; 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;
        }
 }
 
index c8eb465c2b3e313b29cb753dae071d0b832708f3..a9f64d8c0b54c40ad49e6d5225785485fffab231 100644 (file)
@@ -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
index f0f2dd8a9a5c0515f400468e23a3e529acab3f5a..7ce3c4ecb744e4639586a212cf90aa8edd6ec6fc 100644 (file)
@@ -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 (file)
index 0000000..3a42882
--- /dev/null
@@ -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 (file)
index 0000000..50f57e0
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * A database result class
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+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]
+?>
index ebb6933556de1731255326236e34a8b816da5217..74196bc628b37dc82d5e2e1245f6b033a582c073 100644 (file)
@@ -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]