diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /lib/classes/DBManager.php | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/classes/DBManager.php')
| -rw-r--r-- | lib/classes/DBManager.php | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/lib/classes/DBManager.php b/lib/classes/DBManager.php new file mode 100644 index 0000000..7854cff --- /dev/null +++ b/lib/classes/DBManager.php @@ -0,0 +1,250 @@ +<?php +# Lifter010: TODO + +/* + * Copyright (C) 2007 - Marcus Lunzenauer <mlunzena@uos.de> + * + * 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 2 of + * the License, or (at your option) any later version. + */ + +/** + * This class provides a singleton instance that is used to manage PDO database + * connections. + * + * Example of use: + * @code + * # get hold of the DBManager's singleton + * $manager = DBManager::getInstance(); + * + * # set PDO connections using a DSN + * $manager->setConnection('example', + * 'mysql:host=localhost;dbname=example', + * 'root', ''); + * # or an existing instance of PDO + * $manager->setConnection('example2', $existingPdo); + * + * # retrieve a PDO connection later in your code + * $db = $manager->getConnection("studip"); + * + * # or as a shortcut + * $db = DBManager::get("studip"); + * + * # or even shorter ("studip" is the default key) + * $db = DBManager::get(); + * + * # and use the connection + * $db->query('SELECT * FROM user_info'); + * + * # you may even alias connections + * $manager->aliasConnection("studip", "studip-slave"); + * + * # but this is just sugar for + * $studip = $manager->getConnection("studip"); + * $manager->setConnection("studip-slave", $studip); + * + * @endcode + */ +class DBManager +{ + + + /** + * the singleton instance + * + * @access private + * @var DBManager + */ + static private $instance; + + + /** + * an array of connections of the singleton instance + * + * @access private + * @var array + */ + private $connections; + + + /** + * @access private + * + * @return void + */ + private function __construct() + { + $this->connections = []; + } + + + /** + * This method returns the singleton instance of this class. + * + * @return DBManager the singleton instance + */ + static public function getInstance() + { + if (is_null(DBManager::$instance)) { + DBManager::$instance = new DBManager(); + } + return DBManager::$instance; + } + + + /** + * This method returns the database connection to the given key. Throws a + * DBManagerException if there is no such connection. + * + * Example usage: + * @code + * try { + * $db = DBManager::getInstance()->getConnection("foo"); + * $db->exec($sql); + * } catch (DBManagerException $e) { + * echo "oops"; + * } + * @endcode + * + * @param string the key + * + * @throw DBManagerException + * + * @return PDO the database connection + */ + public function getConnection($database) + { + + if (!isset($this->connections[$database])) { + throw new DBManagerException('Database connection: "'.$database. + '" does not exist.'); + } + + return $this->connections[$database]; + } + + + /** + * This method maps the specified key to the specified database connection. + * + * You can either use an instance of class PDO or specify a DSN (optionally + * with username/password). + * + * The (possibly newly created) connection is configured to throw exceptions + * and to buffer queries if it is a MySQL connection. + * + * Examples: + * @code + * $dbManager = DBManager::getInstance(); + * + * // using an existing PDO connection + * $existingPdo = new LoggingPDO($dsn); + * $dbManager->setConnection('studip', $pdo); + * + * // using a DSN with username and password + * $dbManager->setConnection('studip', $dsn , $username, $password); + * @endcode + * + * @param string the key + * @param string|PDO either a DSN or an existing PDO connection + * @param string (optional) the connection's username + * @param array (optional) the connection's password + * + * @return DBManager this instance, useful for cascading method calls + */ + public function setConnection($database, $dsnOrConnection, $user = NULL, + $pass = NULL) + { + $connection = $dsnOrConnection instanceof PDO + ? $dsnOrConnection + : new StudipPDO($dsnOrConnection, $user, $pass); + + $this->configureConnection($connection); + $this->connections[$database] = $connection; + + return $this; + } + + + // PDO connection should throw exceptions and use buffered queries + private function configureConnection($connection) + { + + $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + if ($connection->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { + $connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + // $connection->exec('SET CHARACTER SET latin1'); + } + } + + /** + * This method creates an alias for a database connection. + * + * This is useful if you want to use different keys but access the same + * database, e.g. if you want to use master-slave replication in the future + * + * @param string the old key of the database connection + * @param string the new key of the database connection + * + * @return DBManager this instance, useful for cascading method calls + */ + public function aliasConnection($old, $new) + { + + if (!isset($this->connections[$old])) { + throw new DBManagerException('No database found using key: ' . $old); + } + + $this->connections[$new] = $this->connections[$old]; + + return $this; + } + + + /** + * Shortcut static method to retrieve the database connection for a given + * key. + * + * Example usage: + * @code + * // instead of + * $db = DBManager::getInstance()->getConnection("studip"); + * + * // this can be shortened to + * $db = DBManager::get("studip"); + * + * // or in this case (as "studip" is the default key) + * $db = DBManager::get(); + * @endcode + * + * @param string the key + * + * @return StudipPDO the database connection + */ + static public function get($database = 'studip') + { + $manager = DBManager::getInstance(); + return $manager->getConnection($database); + } +} + + +/** + * The DBManager throws this exception if it cannot find a connection using + * a non existant key. + */ +class DBManagerException extends Exception +{ + + /** + * @param string the message of this exception + * + * @return void + */ + public function __construct($message) + { + parent::__construct($message); + } +} |
