Forked from
Stud.IP / Stud.IP
1002 commits behind the upstream repository.
-
Jan-Hendrik Willms authoredJan-Hendrik Willms authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
DBManager.class.php 6.61 KiB
<?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);
}
}