dblayer : add a Singleton to not reconnect each time we need to access the same database.
dblayer : add a method to disconnect the database engine dblayer : add the transactions methods, linke in PDO dblayer : remove the extension of PDO git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@2259 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
159
dblayer.php
159
dblayer.php
@@ -36,7 +36,7 @@ Optionnaly, you can add the
|
||||
require_once ("domframework/verify.php");
|
||||
|
||||
/** Permit abstraction on the differents SQL databases available */
|
||||
class dblayer extends PDO
|
||||
class dblayer
|
||||
{
|
||||
/** The table name to use */
|
||||
public $table = null;
|
||||
@@ -84,7 +84,8 @@ class dblayer extends PDO
|
||||
the table, and re-import the datas (http://www.sqlite.org/omitted.html) */
|
||||
|
||||
/** Limit to one instance of the connection to the same database */
|
||||
private static $instance = null;
|
||||
// Based on an idea of http://tonylandis.com/php/php5-pdo-singleton-class/
|
||||
private static $instance = array ();
|
||||
|
||||
/** Connection to the database engine
|
||||
See http://fr2.php.net/manual/en/pdo.construct.php for the $dsn format
|
||||
@@ -99,6 +100,7 @@ class dblayer extends PDO
|
||||
if (! isset ($driver[0]))
|
||||
throw new Exception (_("No valid DSN provided"), 500);
|
||||
// Force specifics initialisations
|
||||
$this->dsn = $dsn;
|
||||
switch ($driver[0])
|
||||
{
|
||||
case "sqlite":
|
||||
@@ -116,56 +118,76 @@ class dblayer extends PDO
|
||||
file_exists ($file) &&
|
||||
fileowner ($file) === posix_getuid ())
|
||||
chmod ($file, 0666);
|
||||
try
|
||||
// Print the instances of PDO objects stored :
|
||||
// var_dump (self::$instance);
|
||||
if (! array_key_exists ($this->dsn, self::$instance))
|
||||
{
|
||||
parent::__construct ($dsn, $username, $password, $driver_options);
|
||||
parent::setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
if ($this->debug) echo "CONNECT TO DATABASE\n";
|
||||
try
|
||||
{
|
||||
self::$instance[$this->dsn] = new PDO ($dsn, $username, $password,
|
||||
$driver_options);
|
||||
self::$instance[$this->dsn]->setAttribute (PDO::ATTR_ERRMODE,
|
||||
PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Force ForeignKeys support (disabled by default)
|
||||
$this->exec("PRAGMA foreign_keys = ON");
|
||||
self::$instance[$this->dsn]->exec ("PRAGMA foreign_keys = ON");
|
||||
$this->sep = "`";
|
||||
break;
|
||||
case "mysql":
|
||||
try
|
||||
if (! array_key_exists ($this->dsn, self::$instance))
|
||||
{
|
||||
$driver_options[PDO::MYSQL_ATTR_FOUND_ROWS] = 1;
|
||||
parent::__construct ($dsn, $username, $password, $driver_options);
|
||||
parent::setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
if ($this->debug) echo "CONNECT TO DATABASE\n";
|
||||
try
|
||||
{
|
||||
$driver_options[PDO::MYSQL_ATTR_FOUND_ROWS] = 1;
|
||||
self::$instance[$this->dsn] = new PDO ($dsn, $username, $password,
|
||||
$driver_options);
|
||||
self::$instance[$this->dsn]->setAttribute (PDO::ATTR_ERRMODE,
|
||||
PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the coding to UTF8
|
||||
$this->exec("SET CHARACTER SET utf8");
|
||||
self::$instance[$this->dsn]->exec ("SET CHARACTER SET utf8");
|
||||
$this->sep = "`";
|
||||
break;
|
||||
case "pgsql":
|
||||
try
|
||||
if (! array_key_exists ($this->dsn, self::$instance))
|
||||
{
|
||||
parent::__construct ($dsn, $username, $password, $driver_options);
|
||||
parent::setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
if ($this->debug) echo "CONNECT TO DATABASE\n";
|
||||
try
|
||||
{
|
||||
self::$instance[$this->dsn] = new PDO ($dsn, $username, $password,
|
||||
$driver_options);
|
||||
self::$instance[$this->dsn]->setAttribute (PDO::ATTR_ERRMODE,
|
||||
PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ("PDO error : ".$e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the coding to UTF8
|
||||
$this->exec("SET NAMES 'utf8'");
|
||||
self::$instance[$this->dsn]->exec ("SET NAMES 'utf8'");
|
||||
$this->sep = "\"";
|
||||
break;
|
||||
default:
|
||||
throw new Exception (dgettext("domframework",
|
||||
"Unknown PDO driver provided"), 500);
|
||||
}
|
||||
$this->dsn = $dsn;
|
||||
return self::$instance[$this->dsn];
|
||||
}
|
||||
|
||||
/** Return the connected database name from DSN used to connect */
|
||||
@@ -192,11 +214,11 @@ class dblayer extends PDO
|
||||
if ($this->sep === "")
|
||||
throw new Exception (dgettext("domframework", "Database not connected"),
|
||||
500);
|
||||
switch ($this->getAttribute(PDO::ATTR_DRIVER_NAME))
|
||||
switch (self::$instance[$this->dsn]->getAttribute(PDO::ATTR_DRIVER_NAME))
|
||||
{
|
||||
case "sqlite":
|
||||
$req = "SELECT name FROM sqlite_master WHERE type='table'";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
$st->execute ();
|
||||
$res = array ();
|
||||
while ($d = $st->fetch (PDO::FETCH_ASSOC))
|
||||
@@ -206,7 +228,7 @@ class dblayer extends PDO
|
||||
$req = "SELECT TABLE_NAME
|
||||
FROM information_schema.tables
|
||||
WHERE TABLE_SCHEMA='".$this->databasename()."'";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
$st->execute ();
|
||||
$res = array ();
|
||||
while ($d = $st->fetch (PDO::FETCH_ASSOC))
|
||||
@@ -216,7 +238,7 @@ class dblayer extends PDO
|
||||
$req = "SELECT *
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public'";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
$st->execute ();
|
||||
$res = array ();
|
||||
while ($d = $st->fetch (PDO::FETCH_ASSOC))
|
||||
@@ -230,7 +252,7 @@ class dblayer extends PDO
|
||||
}
|
||||
|
||||
/** Verify if the provided datas can be inserted/updated in the database.
|
||||
@param $datas An array containing the datas to verify with keys
|
||||
@param $datas An array containing the datas to verify with keys
|
||||
@param $updatekey the key to update
|
||||
@return an array with the errors in array($key=>array($priority,$message))
|
||||
*/
|
||||
@@ -275,7 +297,7 @@ class dblayer extends PDO
|
||||
//." ". dgettext("domframework","in")." ".$key);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Check for type inconsistencies if the value is provided
|
||||
if (is_null ($datas[$key]))
|
||||
{
|
||||
@@ -286,7 +308,7 @@ class dblayer extends PDO
|
||||
{
|
||||
$errors[$key] = array ("error", sprintf (
|
||||
dgettext("domframework",
|
||||
"Errors in consistency : '%s' is not an integer or a string [is %s]"),
|
||||
"Errors in consistency : '%s' is not an integer or a string [is %s]"),
|
||||
$key, gettype ($datas[$key])));
|
||||
continue;
|
||||
}
|
||||
@@ -400,12 +422,12 @@ class dblayer extends PDO
|
||||
$this->unique = array ($this->primary);
|
||||
// TODO : If Unique is not defined nor primary
|
||||
// FIXME : If unique is defined, could I test if the primary key is defined
|
||||
// in a parameter of the unique and if it is not add it automatically
|
||||
// in a parameter of the unique and if it is not add it automatically
|
||||
foreach ($this->unique as $k=>$columns)
|
||||
{
|
||||
if ($this->primary === null)
|
||||
{
|
||||
return array (dgettext("domframework",
|
||||
return array (dgettext("domframework",
|
||||
"No field primary defined for tests in primary"));
|
||||
}
|
||||
|
||||
@@ -491,7 +513,7 @@ class dblayer extends PDO
|
||||
"FROM $this->sep$this->tableprefix$table$this->sep ".
|
||||
"WHERE $this->sep$column$this->sep=:".md5 ($column);
|
||||
if ($this->debug) echo "DEBUG : $req\n";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
$val = $datas[$foreign];
|
||||
$key = $column;
|
||||
if ($this->debug) echo "DEBUG BIND : ".$this->fields[$foreign][0]."\n";
|
||||
@@ -584,7 +606,7 @@ class dblayer extends PDO
|
||||
$req .= " VALUES ";
|
||||
$req .= "(:".implode (",:", $binds).")";
|
||||
if ($this->debug) echo "DEBUG : $req\n";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
foreach ($datasOK as $key=>$val)
|
||||
{
|
||||
if ($this->debug) echo "DEBUG BIND : $key(".md5 ($key).")->".
|
||||
@@ -612,7 +634,7 @@ class dblayer extends PDO
|
||||
echo "dblayer execute exception : ".$e->getMessage()."\n";
|
||||
exit;
|
||||
}
|
||||
$lastID = $this->lastInsertId();
|
||||
$lastID = self::$instance[$this->dsn]->lastInsertId();
|
||||
$lastID = $this->hookpostinsert ($datasOK, $lastID);
|
||||
return $lastID;
|
||||
}
|
||||
@@ -741,13 +763,13 @@ class dblayer extends PDO
|
||||
if ($this->debug) echo "DEBUG : $req\n";
|
||||
try
|
||||
{
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
if ($this->debug) echo "DEBUG : PREPARE ERROR ! Return FALSE".
|
||||
$e->getMessage()."\n";
|
||||
throw new Exception ($e->getMessage(), 500);
|
||||
throw new Exception ($e->getMessage(), 500);
|
||||
}
|
||||
|
||||
if ($select !== NULL)
|
||||
@@ -784,7 +806,7 @@ class dblayer extends PDO
|
||||
Return the number of rows modified
|
||||
@param string|integer $updatekey The key applied on primary key to be
|
||||
updated
|
||||
@param array $datas The values to be updated
|
||||
@param array $datas The values to be updated
|
||||
@return the number of lines modified */
|
||||
public function update ($updatekey, $datas)
|
||||
{
|
||||
@@ -826,7 +848,7 @@ class dblayer extends PDO
|
||||
$req .= " WHERE $this->sep$this->primary$this->sep=:".
|
||||
md5 ("PRIMARY".$this->primary);
|
||||
if ($this->debug) echo "DEBUG : $req\n";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
// Add the primary key to field list temporaly. It will permit to update the
|
||||
// primary key
|
||||
$fields = $this->fields;
|
||||
@@ -886,7 +908,7 @@ class dblayer extends PDO
|
||||
$deletekey = $this->hookpredelete ($deletekey);
|
||||
$req = "DELETE FROM $this->sep$this->tableprefix$this->table$this->sep ";
|
||||
$req .= "WHERE $this->primary = :primary";
|
||||
$st = $this->prepare ($req);
|
||||
$st = self::$instance[$this->dsn]->prepare ($req);
|
||||
if ($this->debug) echo "DEBUG : $req\n";
|
||||
if ($this->debug) echo "DEBUG BIND : primary->".
|
||||
var_export ($deletekey, TRUE)."\n";
|
||||
@@ -926,7 +948,7 @@ class dblayer extends PDO
|
||||
$sql = "DROP TABLE $this->sep$this->tableprefix$this->table$this->sep";
|
||||
if ($this->debug)
|
||||
echo "$sql\n";
|
||||
return $this->exec($sql);
|
||||
return self::$instance[$this->dsn]->exec ($sql);
|
||||
}
|
||||
|
||||
/** Create the table defined by the differents fields.
|
||||
@@ -953,7 +975,7 @@ class dblayer extends PDO
|
||||
500);
|
||||
if (count ($this->fields) === 0)
|
||||
throw new Exception (dgettext("domframework", "No Field defined"), 500);
|
||||
switch ($this->getAttribute(PDO::ATTR_DRIVER_NAME))
|
||||
switch (self::$instance[$this->dsn]->getAttribute(PDO::ATTR_DRIVER_NAME))
|
||||
{
|
||||
case "sqlite":
|
||||
$sql = "CREATE TABLE IF NOT EXISTS ".
|
||||
@@ -1248,7 +1270,7 @@ class dblayer extends PDO
|
||||
|
||||
if ($this->debug)
|
||||
echo "$sql\n";
|
||||
return $this->exec($sql);
|
||||
return self::$instance[$this->dsn]->exec ($sql);
|
||||
}
|
||||
|
||||
/** This function permit to send a SQL request to the database to do a SELECT
|
||||
@@ -1256,7 +1278,7 @@ class dblayer extends PDO
|
||||
public function directRead ($sql)
|
||||
{
|
||||
if ($this->debug) echo "== Entering directRead\n";
|
||||
$st = $this->prepare ($sql);
|
||||
$st = self::$instance[$this->dsn]->prepare ($sql);
|
||||
$st->execute ();
|
||||
$res = array ();
|
||||
while ($d = $st->fetch (PDO::FETCH_ASSOC))
|
||||
@@ -1264,9 +1286,40 @@ class dblayer extends PDO
|
||||
return $res;
|
||||
}
|
||||
|
||||
/** This function disconnect the database. It is normally only used in phpunit
|
||||
unit tests */
|
||||
public function disconnect ()
|
||||
{
|
||||
unset (self::$instance[$this->dsn]);
|
||||
}
|
||||
|
||||
/** The prepare method */
|
||||
public function prepare ($statement, $driver_options = array())
|
||||
{
|
||||
return self::$instance[$this->dsn]->prepare ($statement, $driver_options);
|
||||
}
|
||||
|
||||
/** Start a new Transaction */
|
||||
public function beginTransaction ()
|
||||
{
|
||||
return self::$instance[$this->dsn]->beginTransaction ();
|
||||
}
|
||||
|
||||
/** Commit (validate) a transaction */
|
||||
public function commit ()
|
||||
{
|
||||
return self::$instance[$this->dsn]->commit ();
|
||||
}
|
||||
|
||||
/** RollBack a transaction */
|
||||
public function rollback ()
|
||||
{
|
||||
return self::$instance[$this->dsn]->rollback ();
|
||||
}
|
||||
|
||||
/** Hook preinsert
|
||||
This hook is run before inserting a new data in the database, after the
|
||||
verification
|
||||
This hook is run before inserting a new data in the database, after the
|
||||
verification
|
||||
@param array the data to insert in the database
|
||||
@return the modified datas */
|
||||
public function hookpreinsert ($data)
|
||||
@@ -1283,8 +1336,8 @@ class dblayer extends PDO
|
||||
}
|
||||
|
||||
/** Hook preupdate
|
||||
This hook is run before updating a data in the database, after the
|
||||
verification
|
||||
This hook is run before updating a data in the database, after the
|
||||
verification
|
||||
@return the modified datas */
|
||||
public function hookpreupdate ($updatekey, $data)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user