From 5b24b2e44351b57afba72edd4294fe1dea4edc8a Mon Sep 17 00:00:00 2001 From: Tyler Antonio <tantonio@ualberta.ca> Date: Tue, 21 Jul 2015 16:02:06 -0600 Subject: [PATCH] Updated to use namespace and added documentation --- docs/simplesamlphp-database.txt | 91 +++++++++++++++++++ lib/SimpleSAML/Database.php | 25 ++--- .../Metadata/MetaDataStorageHandlerPdo.php | 2 +- tests/SimpleSAML/DatabaseTest.php | 68 +++++++------- 4 files changed, 139 insertions(+), 47 deletions(-) create mode 100644 docs/simplesamlphp-database.txt diff --git a/docs/simplesamlphp-database.txt b/docs/simplesamlphp-database.txt new file mode 100644 index 000000000..663fdce15 --- /dev/null +++ b/docs/simplesamlphp-database.txt @@ -0,0 +1,91 @@ +SimpleSAML\Database +============================= + +<!-- + This file is written in Markdown syntax. + For more information about how to use the Markdown syntax, read here: + http://daringfireball.net/projects/markdown/syntax +--> + + +<!-- {{TOC}} --> + +Purpose +------- +This document covers the SimpleSAML\Database class and is only relevant to anyone writing code for SimpleSAMLphp, including modules, that require a database connection. + +The Database class provides a single class that can be used to connect to a database which can be shared by anything within SimpleSAMLphp. + +Getting Started +--------------- +If you are just using the already configured database, which would normally be the case, all you need to do is get the global instance of the Database class. + + $db = SimpleSAML\Database::getInstance(); + +If there is a requirement to connect to an alternate database server (ex. authenticating users that exist on a different SQL server or database) you can specify an alternate configuration. + + $config = new SimpleSAML_Configuration($myconfigarray, "mymodule/lib/Auth/Source/myauth.php"); + $db = SimpleSAML\Database::getInstance($config); + +That will create a new instance of the database, separate from the global instance, specific to the configuration defined in $myconfigarray. If you are going to specify an alternate config, your configuration array must contain the same keys that exist in the master config (database.dsn, database.username, database.password, database.prefix, etc). + +Database Prefix +--------------- +Administrators can add a prefix to all the table names that this database classes accesses and you should take that in account when querying. Assuming that a prefix has been configured as "sp_": + + $table = $db->applyPrefix("saml20_idp_hosted"); + +$table would be set to "sp_saml20_idp_hosted" + +Querying The Database +--------------------- +You can query the database through two public functions read() and write() which are fairly self-explanitory when it comes to determining which one to use when querying. + +### Writing to The Database +Since the database class allows administrators to configure master and slave database servers, the write function will always use the master database connection. + +The write function takes 2 parameters: SQL, params. + + $table = $db->applyPrefix("test"); + $values = array( + 'id' => 20, + 'data' => 'Some data', + ); + + $query = $db->write("INSERT INTO $table (id, data) VALUES (:id, :data)", $values); + +The values specified in the $values array will be bound to the placeholders and will be executed on the master. By default, values are binded as PDO::PARAM_STR. If you need to override this, you can specify it in the values array. + + $table = $db->applyPrefix("test"); + $values = array( + 'id' => array(20, PDO::PARAM_INT), + 'data' => 'Some data', + ); + + $query = $db->write("INSERT INTO $table (id, data) VALUES (:id, :data)", $values); + +You can also skip usage of prepared statements. You should **only** use this if you have a statement that has no user input (ex. CREATE TABLE). If the params variable is explicity set to false, it will skip usage of prepared statements. This is only available when writing to the database. + + $table = $db->applyPrefix("test"); + $query = $db->write("CREATE TABLE IF NOT EXISTS $table (id INT(16) NOT NULL, data TEXT NOT NULL)", false); + +### Reading The Database +Since the database class allows administrators to configure master and slave database servers, the read function will randomly select a slave server to query. If no slaves are configured, it will read from the master. + +The read function takes 2 parameters: SQL, params. + + $table = $db->applyPrefix("test"); + $values = array( + 'id' => 20, + ); + + $query = $db->read("SELECT * FROM $table WHERE id = :id", $values); + +The values specified in the $values array will be bound to the placeholders and will be executed on the selected slave. By default, values are binded as PDO::PARAM_STR. If you need to override this, you can specify it in the values array. + + $table = $db->applyPrefix("test"); + $values = array( + 'id' => array(20, PDO::PARAM_INT), + ); + + $query = $db->read("SELECT * FROM $table WHERE id = :id", $values); diff --git a/lib/SimpleSAML/Database.php b/lib/SimpleSAML/Database.php index f490101b0..5889a17fa 100644 --- a/lib/SimpleSAML/Database.php +++ b/lib/SimpleSAML/Database.php @@ -1,4 +1,5 @@ <?php +namespace SimpleSAML; /** * This file implements functions to read and write to a group of database @@ -14,10 +15,10 @@ * such as sqlauth, an alternative config file can be provided. * * @author Tyler Antonio, University of Alberta. <tantonio@ualberta.ca> - * @package simpleSAMLphp + * @package SimpleSAMLphp */ -class SimpleSAML_Database { +class Database { /** * This variable holds the instance of the session - Singleton approach. @@ -47,7 +48,7 @@ class SimpleSAML_Database { * @return SimpleSAML_Database The shared database connection. */ public static function getInstance($altConfig = null) { - $config = ($altConfig)? $altConfig : SimpleSAML_Configuration::getInstance(); + $config = ($altConfig)? $altConfig : \SimpleSAML_Configuration::getInstance(); $instanceId = self::generateInstanceId($config); /* Check if we already have initialized the session. */ @@ -56,7 +57,7 @@ class SimpleSAML_Database { } /* Create a new session. */ - self::$instance[$instanceId] = new SimpleSAML_Database($config); + self::$instance[$instanceId] = new Database($config); return self::$instance[$instanceId]; } @@ -68,7 +69,7 @@ class SimpleSAML_Database { private function __construct($config) { $driverOptions = array(); if ($config->getBoolean('database.persistent', TRUE)) { - $driverOptions = array(PDO::ATTR_PERSISTENT => TRUE); + $driverOptions = array(\PDO::ATTR_PERSISTENT => TRUE); } // Connect to the master @@ -120,12 +121,12 @@ class SimpleSAML_Database { */ private function connect($dsn, $username, $password, $options){ try{ - $db = new PDO($dsn, $username, $password, $options); - $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $db = new \PDO($dsn, $username, $password, $options); + $db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); return $db; } catch(PDOException $e){ - throw new Exception("Database error: ". $e->getMessage()); + throw new DBException("Database error: ". $e->getMessage()); } } @@ -175,10 +176,10 @@ class SimpleSAML_Database { foreach ($params as $param => $value) { if(is_array($value)){ - $query->bindValue(":$param", $value[0], ($value[1])? $value[1] : PDO::PARAM_STR); + $query->bindValue(":$param", $value[0], ($value[1])? $value[1] : \PDO::PARAM_STR); } else{ - $query->bindValue(":$param", $value, PDO::PARAM_STR); + $query->bindValue(":$param", $value, \PDO::PARAM_STR); } } @@ -186,7 +187,7 @@ class SimpleSAML_Database { return $query; } catch (PDOException $e){ - throw new Exception("Database error: ". $e->getMessage()); + throw new DBException("Database error: ". $e->getMessage()); } } @@ -209,7 +210,7 @@ class SimpleSAML_Database { return $query; } catch (PDOException $e){ - throw new Exception("Database error: ". $e->getMessage()); + throw new DBException("Database error: ". $e->getMessage()); } } diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php index aeef17b51..5414279bf 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php @@ -70,7 +70,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_ assert('is_array($config)'); $globalConfig = SimpleSAML_Configuration::getInstance(); - $this->db = SimpleSAML_Database::getInstance(); + $this->db = SimpleSAML\Database::getInstance(); $cfgHelp = SimpleSAML_Configuration::loadFromArray($config, 'pdo metadata source'); } diff --git a/tests/SimpleSAML/DatabaseTest.php b/tests/SimpleSAML/DatabaseTest.php index 5f84f0723..6e6cb25b8 100644 --- a/tests/SimpleSAML/DatabaseTest.php +++ b/tests/SimpleSAML/DatabaseTest.php @@ -21,17 +21,17 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase * @requires PHP 5.3.2 */ protected static function getMethod($getMethod) { - $class = new ReflectionClass('SimpleSAML_Database'); + $class = new ReflectionClass('SimpleSAML\Database'); $method = $class->getMethod($getMethod); $method->setAccessible(true); return $method; } /** - * @covers SimpleSAML_Database::getInstance - * @covers SimpleSAML_Database::generateInstanceId - * @covers SimpleSAML_Database::__construct - * @covers SimpleSAML_Database::connect + * @covers SimpleSAML\Database::getInstance + * @covers SimpleSAML\Database::generateInstanceId + * @covers SimpleSAML\Database::__construct + * @covers SimpleSAML\Database::connect */ public function setUp() { @@ -50,17 +50,17 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase $this->assertInstanceOf('SimpleSAML_Configuration', $this->config); $this->assertEquals($config['database.dsn'], $this->config->getValue('database.dsn')); - $this->db = SimpleSAML_Database::getInstance($this->config); + $this->db = SimpleSAML\Database::getInstance($this->config); // Ensure that we have a functional database class. - $this->assertInstanceOf('SimpleSAML_Database', $this->db); + $this->assertInstanceOf('SimpleSAML\Database', $this->db); } /** - * @covers SimpleSAML_Database::getInstance - * @covers SimpleSAML_Database::generateInstanceId - * @covers SimpleSAML_Database::__construct - * @covers SimpleSAML_Database::connect + * @covers SimpleSAML\Database::getInstance + * @covers SimpleSAML\Database::generateInstanceId + * @covers SimpleSAML\Database::__construct + * @covers SimpleSAML\Database::connect * @expectedException Exception * @test */ @@ -76,14 +76,14 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase ); $this->config = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php"); - $db = SimpleSAML_Database::getInstance($this->config); + $db = SimpleSAML\Database::getInstance($this->config); } /** - * @covers SimpleSAML_Database::getInstance - * @covers SimpleSAML_Database::generateInstanceId - * @covers SimpleSAML_Database::__construct - * @covers SimpleSAML_Database::connect + * @covers SimpleSAML\Database::getInstance + * @covers SimpleSAML\Database::generateInstanceId + * @covers SimpleSAML\Database::__construct + * @covers SimpleSAML\Database::connect * @test */ public function Instances() @@ -109,9 +109,9 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase $config2 = new SimpleSAML_Configuration($config2, "test/SimpleSAML/DatabaseTest.php"); $config3 = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php"); - $db1 = SimpleSAML_Database::getInstance($config1); - $db2 = SimpleSAML_Database::getInstance($config2); - $db3 = SimpleSAML_Database::getInstance($config3); + $db1 = SimpleSAML\Database::getInstance($config1); + $db2 = SimpleSAML\Database::getInstance($config2); + $db3 = SimpleSAML\Database::getInstance($config3); $generateInstanceId = self::getMethod('generateInstanceId'); @@ -131,11 +131,11 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase } /** - * @covers SimpleSAML_Database::getInstance - * @covers SimpleSAML_Database::generateInstanceId - * @covers SimpleSAML_Database::__construct - * @covers SimpleSAML_Database::connect - * @covers SimpleSAML_Database::getSlave + * @covers SimpleSAML\Database::getInstance + * @covers SimpleSAML\Database::generateInstanceId + * @covers SimpleSAML\Database::__construct + * @covers SimpleSAML\Database::connect + * @covers SimpleSAML\Database::getSlave * @test */ public function Slaves(){ @@ -162,7 +162,7 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase ); $sspConfiguration = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php"); - $msdb = SimpleSAML_Database::getInstance($sspConfiguration); + $msdb = SimpleSAML\Database::getInstance($sspConfiguration); $slaves = PHPUnit_Framework_Assert::readAttribute($msdb, 'dbSlaves'); $gotSlave = spl_object_hash($getSlave->invokeArgs($msdb, array())); @@ -171,7 +171,7 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase } /** - * @covers SimpleSAML_Database::applyPrefix + * @covers SimpleSAML\Database::applyPrefix * @test */ public function prefix(){ @@ -183,10 +183,10 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase } /** - * @covers SimpleSAML_Database::write - * @covers SimpleSAML_Database::read - * @covers SimpleSAML_Database::exec - * @covers SimpleSAML_Database::query + * @covers SimpleSAML\Database::write + * @covers SimpleSAML\Database::read + * @covers SimpleSAML\Database::exec + * @covers SimpleSAML\Database::query * @test */ public function Querying() @@ -210,8 +210,8 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase } /** - * @covers SimpleSAML_Database::read - * @covers SimpleSAML_Database::query + * @covers SimpleSAML\Database::read + * @covers SimpleSAML\Database::query * @expectedException Exception * @test */ @@ -224,8 +224,8 @@ class SimpleSAML_DatabaseTest extends PHPUnit_Framework_TestCase } /** - * @covers SimpleSAML_Database::write - * @covers SimpleSAML_Database::exec + * @covers SimpleSAML\Database::write + * @covers SimpleSAML\Database::exec * @expectedException Exception * @test */ -- GitLab