X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=framework%2Fmain%2Fmiddleware%2Fdatabase%2Fclass_DatabaseConnection.php;h=f8b0187f0834640a74dd671c214425e009cd9455;hp=83b13eb5f9fd1bc71c183939f939c6ce3390f9e6;hb=refs%2Fheads%2Fmaster;hpb=a60894f1d6ef33613d2d0351075aa07aa257f304;ds=sidebyside diff --git a/framework/main/middleware/database/class_DatabaseConnection.php b/framework/main/middleware/database/class_DatabaseConnection.php index 83b13eb5..b64d5189 100644 --- a/framework/main/middleware/database/class_DatabaseConnection.php +++ b/framework/main/middleware/database/class_DatabaseConnection.php @@ -7,16 +7,22 @@ use Org\Mxchange\CoreFramework\Connector\Database\DatabaseConnector; use Org\Mxchange\CoreFramework\Criteria\Criteria; use Org\Mxchange\CoreFramework\Criteria\Storing\StoreableCriteria; use Org\Mxchange\CoreFramework\Database\Backend\DatabaseBackend; -use Org\Mxchange\CoreFramework\Registry\Registerable; +use Org\Mxchange\CoreFramework\Generic\FrameworkInterface; use Org\Mxchange\CoreFramework\Middleware\BaseMiddleware; -use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware; +use Org\Mxchange\CoreFramework\Registry\Registerable; +use Org\Mxchange\CoreFramework\Result\Database\BaseDatabaseResult; + +// Import SPL stuff +use \InvalidArgumentException; +use \OutOfBoundsException; +use \UnexpectedValueException; /** - * Database selector class + * Database connectivity class * * @author Roland Haeder * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team * @license GNU GPL 3.0 or any newer version * @link http://www.shipsimu.org * @@ -37,17 +43,17 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re /** * Array for connection data */ - private $connectData = array( + private $connectData = [ 'login' => '', 'pass' => '', 'dbase' => '', - 'host' => '' - ); + 'host' => '', + ]; /** * The real database layer */ - private $dbLayer = NULL; + private $backendInstance = NULL; /** * An instance of this class @@ -57,7 +63,7 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re /** * Protected constructor */ - protected function __construct () { + private function __construct () { // Call parent constructor parent::__construct(__CLASS__); } @@ -65,21 +71,22 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re /** * Creates a new database connection layer * - * @param $debugInstance An instance of a DebugMiddleware class - * @param $dbLayer An instance of a DatabaseBackend class + * @param $backendInstance An instance of a DatabaseBackend class * @todo $debugInstance is currently not used */ - public static final function createDatabaseConnection (DebugMiddleware $debugInstance, DatabaseBackend $dbLayer) { + public static final function createDatabaseConnection (DatabaseBackend $backendInstance) { // Get instance + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: backendInstance=%s - CALLED!', $backendInstance->__toString())); $databaseInstance = new DatabaseConnection(); // Set database layer - $databaseInstance->setDatabaseLayer($dbLayer); + $databaseInstance->setBackendInstance($backendInstance); // Set db instance self::$selfInstance = $databaseInstance; // Return instance + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: databaseInstance=%s - EXIT!', $databaseInstance->__toString())); return $databaseInstance; } @@ -92,6 +99,15 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re return self::$selfInstance; } + /** + * Setter for the real database layer + * @param $backendInstance An instance of a DatabaseBackend class + * @return void + */ + private final function setBackendInstance (DatabaseBackend $backendInstance) { + $this->backendInstance = $backendInstance; + } + /** * Setter for all database connection data. All these parameters may be * supported by the underlaying backend. @@ -101,13 +117,31 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * @param $dbase Name of used database * @param $host Host to connect to (default: 127.0.0.1) * @return void + * @throws InvalidArgumentException If a parameter is empty */ - public final function setConnectionData ($login, $pass, $dbase, $host = '127.0.0.1') { + public final function setConnectionData (string $login, string $pass, string $dbase, string $host = 'localhost') { + // Check parameter + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: login=%s,pass=%s,dbase=%s,host=%s CALLED!', $login, $pass, $dbase, $host)); + if (empty($login)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "login" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif (empty($dbase)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "dbase" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif (empty($host)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "host" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Transfer connection data - $this->connectData['login'] = (string) $login; - $this->connectData['pass'] = (string) $pass; - $this->connectData['dbase'] = (string) $dbase; - $this->connectData['host'] = (string) $host; + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('DATABASE-CONNECTION: Setting data ...'); + $this->connectData['login'] = $login; + $this->connectData['pass'] = $pass; + $this->connectData['dbase'] = $dbase; + $this->connectData['host'] = $host; + + // Trace message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: EXIT!'); } /** @@ -119,22 +153,13 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re return $this->connectData; } - /** - * Setter for the real database layer - * @param $dbLayer An instance of the real database layer - * @return void - */ - public final function setDatabaseLayer (DatabaseBackend $dbLayer) { - $this->dbLayer = $dbLayer; - } - /** * Getter for index key * * @return $indexKey Index key */ public final function getIndexKey () { - return $this->dbLayer->getIndexKey(); + return $this->backendInstance->getIndexKey(); } /** @@ -144,15 +169,43 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * @param $tableName Name of the 'table' we shall query * @param $criteriaInstance An instance of a Criteria class * @return $result The result as an array + * @throws InvalidArgumentException If a parameter is empty + * @throws OutOfBoundsException If important array elements are not present + * @throws UnexpectedValueException If $result['status'] is not 'ok' */ - public function doSelectByTableCriteria ($tableName, Criteria $criteriaInstance) { + public function doSelectByTableCriteria (string $tableName, Criteria $criteriaInstance) { + // Validate parameter + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: tableName=%s,criteriaInstance=%s - CALLED!', $tableName, $criteriaInstance->__toString())); + if (empty($tableName)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "tableName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: Invoking this->backendInstance->connectToDatabase() ...'); + $this->backendInstance->connectToDatabase(); // Get result from query - $result = $this->dbLayer->querySelect($tableName, $criteriaInstance); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: Invoking this->backendInstance->querySelect(%s,%s) ...', $tableName, $criteriaInstance->__toString())); + $result = $this->backendInstance->querySelect($tableName, $criteriaInstance); + + // Is a valid array returned? + if (!isset($result[BaseDatabaseResult::RESULT_NAME_STATUS])) { + // Missing element + throw new OutOfBoundsException(sprintf('result()=%d does not have element "%s"', count($result), BaseDatabaseResult::RESULT_NAME_STATUS), FrameworkInterface::EXCEPTION_OUT_OF_BOUNDS); + } elseif ($result[BaseDatabaseResult::RESULT_NAME_STATUS] != 'ok') { + // Is exception given? + if (isset($result[BaseDatabaseResult::RESULT_NAME_EXCEPTION])) { + // Attach it + throw new UnexpectedValueException(sprintf('result[%s]=%s is not "ok" with cause', BaseDatabaseResult::RESULT_NAME_STATUS), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT, BaseDatabaseResult::RESULT_NAME_EXCEPTION); + } else { + // No exception attached + throw new UnexpectedValueException(sprintf('result[%s]=%s is not "ok"', BaseDatabaseResult::RESULT_NAME_STATUS, $result[BaseDatabaseResult::RESULT_NAME_STATUS]), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + } // Return the result + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: result[]=%s - EXIT!', gettype($result))); return $result; } @@ -162,7 +215,12 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * @return $exceptionInstance Last thrown exception */ public final function getLastException () { - $exceptionInstance = $this->dbLayer->getLastException(); + // Get instance + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: CALLED!'); + $exceptionInstance = $this->backendInstance->getLastException(); + + // Return it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: exceptionInstance=%s - EXIT!', $exceptionInstance->__toString())); return $exceptionInstance; } @@ -174,10 +232,15 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re */ public function queryInsertDataSet (StoreableCriteria $dataSetInstance) { // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: dataSetInstance=%s - CALLED!', $dataSetInstance->__toString())); + $this->backendInstance->connectToDatabase(); // Ask the database layer - $this->dbLayer->queryInsertDataSet($dataSetInstance); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: Invoking this->backendInstance->queryInsertDataSet(%s) ...', $dataSetInstance->__toString())); + $this->backendInstance->queryInsertDataSet($dataSetInstance); + + // Trace message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: EXIT!'); } /** @@ -188,10 +251,15 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re */ public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: dataSetInstance=%s - CALLED!', $dataSetInstance->__toString())); + $this->backendInstance->connectToDatabase(); // Ask the database layer - $this->dbLayer->queryUpdateDataSet($dataSetInstance); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: Invoking this->backendInstance->queryUpdateDataSet(%s) ...', $dataSetInstance->__toString())); + $this->backendInstance->queryUpdateDataSet($dataSetInstance); + + // Trace message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: EXIT!'); } /** @@ -199,15 +267,26 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * * @param $tableName Name of table we need the primary key column from * @return $primaryKey Primary key column of requested table + * @throws InvalidArgumentException If a parameter is empty */ - public function getPrimaryKeyOfTable ($tableName) { + public function getPrimaryKeyOfTable (string $tableName) { + // Validate parameter + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: tableName=%s - CALLED!', $tableName)); + if (empty($tableName)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "tableName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: Invoking this->backendInstance->connectToDatabase() ...'); + $this->backendInstance->connectToDatabase(); // Ask the database layer - $primaryKey = $this->dbLayer->getPrimaryKeyOfTable($tableName); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: Invoking this->backendInstance->getPrimaryKeyOfTable(%s) ...', $tableName)); + $primaryKey = $this->backendInstance->getPrimaryKeyOfTable($tableName); // Return the value + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: primaryKey=%s - CALLED!', $primaryKey)); return $primaryKey; } @@ -216,16 +295,26 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * * @param $data An array with possible non-public data that needs to be removed. * @return $data A cleaned up array with only public data. + * @throws InvalidArgumentException If a parameter has an invalid value */ public function removeNonPublicDataFromArray (array $data) { + // Check parameter + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: data()=%d - CALLED!', count($data))); + if (count($data) == 0) { + // Throw IAE + throw new InvalidArgumentException('Parameter "data" is an empty array', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: Invoking this->backendInstance->connectToDatabase() ...'); + $this->backendInstance->connectToDatabase(); // Call database backend - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DB-CONNECTION[' . $this->__toString() . ']: Calling this->dbLayer->removeNonPublicDataFromArray(data) ...'); - $data = $this->dbLayer->removeNonPublicDataFromArray($data); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: Invoking this->backendInstance->removeNonPublicDataFromArray(data()=%d) ...', count($data))); + $data = $this->backendInstance->removeNonPublicDataFromArray($data); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DB-CONNECTION[' . $this->__toString() . ']: data[]=' . gettype($data)); + // Trace message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: data()=%d - EXIT!', count($data))); return $data; } @@ -234,15 +323,25 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re * * @param $tableName Table name * @return $count Total row count + * @throws InvalidArgumentException If a parameter is empty */ - public function countTotalRows ($tableName) { + public function countTotalRows (string $tableName) { + // Validate parameter + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: tableName=%s - CALLED!', $tableName)); + if (empty($tableName)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "tableName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Connect to the database - $this->dbLayer->connectToDatabase(); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('DATABASE-CONNECTION: Invoking this->backendInstance->connectToDatabase() ...'); + $this->backendInstance->connectToDatabase(); // Ask the database layer - $count = $this->dbLayer->countTotalRows($tableName); + $count = $this->backendInstance->countTotalRows($tableName); // Return the value + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DATABASE-CONNECTION: count=%d - CALLED!', $count)); return $count; }