Skip to content
Snippets Groups Projects
Select Git revision
  • 8f3ad43e9375a242f64a21d3c651834849db2d10
  • main default protected
  • studip-rector
  • ci-opt
  • course-members-export-as-word
  • data-vue-app
  • pipeline-improvements
  • webpack-optimizations
  • rector
  • icon-renewal
  • http-client-and-factories
  • jsonapi-atomic-operations
  • vueify-messages
  • tic-2341
  • 135-translatable-study-areas
  • extensible-sorm-action-parameters
  • sorm-configuration-trait
  • jsonapi-mvv-routes
  • docblocks-for-magic-methods
19 results

DBManager.class.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    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);
        }
    }