1 <?php 2 /* Copyright (c) 2012, Geert Bergman (geert@scrivo.nl) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. Neither the name of "Scrivo" nor the names of its contributors may be 14 * used to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id: PdoConnection.php 866 2013-08-25 16:22:35Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\PdoConnection class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * Class to manage the connection to the Scrivo database. 40 * 41 * This is simply a direct descendent of the \PDO class with a modified 42 * constructor that uses a Scrivo configuration object to open the connection. 43 * It also assures that the connection is configured correctly (uses exceptions 44 * and UTF-8). 45 * 46 * It is possible to store data of several instances (sites) in a single 47 * database. The instance data is identified by an instance id which is also 48 * defined in the configuration file and present a property of this class. 49 * 50 * Furthermore, Scrivo uses object ids instead of auto-numbering. Ids within 51 * a specific instance need to be unique. To achieve this this class also 52 * deals with the generation of unique ids. 53 * 54 * 55 */ 56 class PdoConnection extends \PDO { 57 58 /** 59 * The database instance id. 60 * @var int 61 */ 62 private $instId; 63 64 /** 65 * Construct a scrivo database connection using the setting in a Scrivo 66 * config file. The following settings are used: 67 * 68 * * DB_HOST 69 * * DB_NAME 70 * * DB_USER 71 * * DB_PASSWORD 72 * * INSTANCE_ID 73 * 74 * @param Config $config A Scrivo config object that contains the database 75 * settings. 76 */ 77 public function __construct(Config $config) { 78 79 parent::__construct( 80 "mysql:host={$config->DB_HOST};dbname={$config->DB_NAME}", 81 $config->DB_USER, $config->DB_PASSWORD, 82 array(\PDO::ATTR_PERSISTENT => true)); 83 $this->setAttribute( 84 \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); 85 $this->exec("SET NAMES utf8"); 86 87 $this->instId = $config->INSTANCE_ID; 88 89 } 90 91 /** 92 * Get the database instance id. 93 * 94 * @return int The database instance id. 95 */ 96 public function getInstanceId() { 97 return $this->instId; 98 } 99 100 /** 101 * Generate a new object id. 102 * 103 * For the generation of an object id in MySQL we use a table with one 104 * autoincrement column. 105 * 106 * TODO: setup a test to see how this holds in concurrency situations 107 * and document it (the behavoir not the test). 108 * 109 * @return int A new object id. 110 */ 111 public function generateId() { 112 113 $this->exec("LOCK TABLES seq WRITE"); 114 $this->exec("INSERT INTO seq VALUES ()"); 115 $sth = $this->prepare("SELECT LAST_INSERT_ID()"); 116 $sth->execute(); 117 $this->exec("UNLOCK TABLES"); 118 $newId = $sth->fetchColumn(); 119 120 $sth = $this->prepare("DELETE FROM seq WHERE seq < :newID"); 121 $sth->bindValue(":newID", $newId, \PDO::PARAM_INT); 122 $sth->execute(); 123 124 return intval($newId); 125 } 126 127 /** 128 * Convenience method for setting the instance variable in an prepared 129 * statment. This variable is usually named ":instId", but you can use an 130 * alternative name. 131 * 132 * @param \PDOStatement $sth The statement for which to set the instance id. 133 * @param string $label An optional alternative label for the instance id 134 * variable. 135 */ 136 public function bindInstance(\PDOStatement $sth, $label=":instId") { 137 $sth->bindValue($label, $this->instId, \PDO::PARAM_INT); 138 } 139 140 /** 141 * Implementation of the readable properties using the PHP magic 142 * method __get(). 143 * 144 * @param string $field The name of the property to get. 145 * 146 * @return mixed The value of the requested property. 147 */ 148 public function __get($field) { 149 if ($field == "instanceId") { 150 return $this->getInstanceId(); 151 } else { 152 throw new \Scrivo\SystemException("Property $field not found"); 153 } 154 } 155 156 /** 157 * Overloaded version of PDO::prepare, just to be able to do some query 158 * logging. 159 * 160 * @param string $statement An SQL statement. 161 * @param array $options Driver options. 162 * 163 * @return \PDOStatement A PDO statement. 164 */ 165 public function prepare($statement, $options=array()) { 166 //error_log("Prepare: $statement"); 167 return parent::prepare($statement, $options); 168 } 169 170 } 171 172 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013