Files
DomFramework/dblayer.php
Dominique Fournier 383e831ff3 Add support to read in dblayer with order and colmuns displayed
Return the number of deleted rows in delete


git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@1223 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
2014-03-18 18:35:48 +00:00

275 lines
9.2 KiB
PHP

<?php
// dblayer.php
/* Documentation :
The dbLayer provide an abstraction layer on PDO to be easier on all the CRUD
(Create, Read, Update, Delete) operations, accross all the databases engines.
To use it, extends in your code this class, and define the attributes :
- protected $table : name of the table you want to use
- protected $fields : description of all the fields in the database like :
protected $fields = array (
"id"=>array ("integer", "not null", "autoincrement"),
"zone"=>array ("varchar", "255", "not null"),
"viewname"=>array ("varchar", "255"),
"viewclients"=>array ("varchar", "255"),
"comment"=>array ("varchar", "1024"),
"opendate"=>array ("datetime", "not null"),
"closedate"=>array ("datetime"),
);
- protected $primary = "id" ; the primary key of the table (in text). Actually
the dbLayer abstraction don't supports primary key on multiples columns
Optionnaly, you can add the
- protected $debug = TRUE : enable the debug on screen (NOT FOR PROD !!)
*/
/** Permit abstraction on the differents SQL databases available */
class dblayer extends PDO
{
protected $fields = array ();
protected $primary = null;
protected $db = null;
public $debug = FALSE;
/** Return all the tables available in the database */
function listTables ()
{
$driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME);
$rc = @include_once ("dbLayer".ucfirst ($driver).".php");
if ($rc === FALSE)
throw new Exception ("dbLayer driver $driver not available");
}
// TODO !!
/** Create Table creation from $this->fields with engine abstraction
Example in sqlite3 id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
in MySQL id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, */
// TODO !!
/** Create automatic creation of $fields from .schema of sqlite3/
show create table `NomTable`; for MySQL
SQLite3 : PRAGMA TABLE_INFO('yourtable');
MYSQL : SHOW COLUMNS FROM yourtable;*/
/** Connection to the database engine
See http://fr2.php.net/manual/en/pdo.construct.php for the $dsn format */
function __construct ($dsn, $username=null, $password=null,
$driver_options=null)
{
$this->db = new PDO ($dsn, $username, $password, $driver_options);
$this->db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
/** Create a new entry in the table. Datas must be an indexed array */
function create ($datas)
{
if ($this->db === null)
throw new Exception ("Database not connected");
$datasOK = array ();
// Check for missing parameters
foreach ($this->fields as $key=>$params)
{
if (in_array ("autoincrement", $params))
$datas[$key] = null;
if (in_array ("not null", $params) && !array_key_exists ($key, $datas))
throw new Exception ("Mandatory field '$key' not provided");
// TODO : Check for type inconsistancies before create $datasOK
if (array_key_exists ($key, $datas))
$datasOK[$key] = $datas[$key];
}
$req = "INSERT INTO `".$this->table."` ";
$req .= "(".implode (",", array_keys ($datasOK)).")";
$req .= " VALUES ";
$req .= "(:".implode (",:", array_keys ($datasOK)).")";
if ($this->debug) echo "DEBUG : $req\n";
$st = $this->db->prepare ($req);
foreach ($datasOK as $key=>$val)
{
if ($this->debug) echo "DEBUG BIND : $key->".var_export ($val, TRUE)."\n";
if ($val === null)
$st->bindValue (":$key", $val, PDO::PARAM_NULL);
elseif ($this->fields[$key][0] === "integer")
$st->bindValue (":$key", $val, PDO::PARAM_INT);
elseif ($this->fields[$key][0] === "varchar")
$st->bindValue (":$key", $val, PDO::PARAM_STR);
elseif ($this->fields[$key][0] === "datetime")
$st->bindValue (":$key", $val, PDO::PARAM_STR);
else
throw new Exception ("TO BE DEVELOPPED : ".$this->fields[$key][0]);
}
$st->execute ();
return $this->db->lastInsertId();
}
/** Read the table content based on a select filter, ordered by order
operator and the associated select value
- $select = array (array ($key, $val, $operator), ...)
$key=>column, $val=>value to found, $operator=>'LIKE', =...
- $display = array ($col1, $col2...);
Columns displayed
- $order = array (array ($key, $orientation), ...)
$key=>column, $orientation=ASC/DESC
*/
function read ($select=null, $display=null, $order=null)
{
if ($this->db === null)
throw new Exception ("Database not connected");
if ($display !== null)
{
foreach ($display as $f)
{
if (!in_array ($f, array_keys ($this->fields)))
throw new Exception ("Field $f not allowed");
}
}
$req = "SELECT ";
$req .= implode (",", array_keys ($this->fields));
$req .= " FROM `".$this->table."`";
if ($select !== null)
{
$req .= " WHERE ";
foreach ($select as $n=>$s)
{
if ($n > 0)
$req .= " AND";
if (!isset ($s[2]))
$s[2] = "=";
$req .= " ".$s[0]." ".$s[2]." :".$s[0];
}
}
if ($order !== null)
{
$req .= " ORDER BY ";
foreach ($order as $n=>$o)
{
if ($n > 0)
$req .= ",";
$req .= $o[0];
if (isset ($o[1]) && $o[1] === "DESC")
$req .= " DESC";
else
$req .= " ASC";
}
}
if ($this->debug) echo "DEBUG : $req\n";
$st = $this->db->prepare ($req);
if ($select !== NULL)
{
foreach ($select as $s)
{
if ($this->debug) echo "DEBUG BIND : ".$s[0]."->".
var_export ($s[1], TRUE)."\n";
$st->bindValue (":".$s[0], $s[1]);
}
}
$st->execute ();
$res = array ();
while ($d = $st->fetch (PDO::FETCH_ASSOC))
$res[] = $d;
return $res;
}
/** Update the key tuple with the provided datas */
function update ($updatekey, $datas)
{
if ($this->db === null)
throw new Exception ("Database not connected");
$datasOK = array ();
// Check for missing parameters
foreach ($this->fields as $key=>$params)
{
// TODO : Check for type inconsistancies before create $datasOK
if (array_key_exists ($key, $datas))
$datasOK[$key] = $datas[$key];
}
$req = "UPDATE `".$this->table."` SET ";
$i = 0;
foreach ($datasOK as $key=>$val)
{
if ($i>0) $req .= ",";
$req .= "$key=:$key";
$i++;
}
$req .= " WHERE $this->primary=:primary";
if ($this->debug) echo "DEBUG : $req\n";
$st = $this->db->prepare ($req);
if ($this->debug) echo "DEBUG BIND : primary->".
var_export ($updatekey, TRUE)."\n";
$st->bindValue (":primary", $updatekey);
foreach ($datasOK as $key=>$val)
{
if ($this->debug) echo "DEBUG BIND : $key->".var_export ($val, TRUE)."\n";
if ($val === null)
$st->bindValue (":$key", $val, PDO::PARAM_NULL);
elseif ($this->fields[$key][0] === "integer")
$st->bindValue (":$key", $val, PDO::PARAM_INT);
elseif ($this->fields[$key][0] === "varchar")
$st->bindValue (":$key", $val, PDO::PARAM_STR);
elseif ($this->fields[$key][0] === "datetime")
$st->bindValue (":$key", $val, PDO::PARAM_STR);
else
throw new Exception ("TO BE DEVELOPPED : ".$this->fields[$key][0]);
}
$st->execute ();
}
/** Delete a tuple identified by its primary key
Return the number of deleted rows (can be 0 !) */
function delete ($deletekey)
{
if ($this->db === null)
throw new Exception ("Database not connected");
$req = "DELETE FROM `".$this->table."` ";
$req .= "WHERE $this->primary = :primary";
$st = $this->db->prepare ($req);
if ($this->debug) echo "DEBUG : $req\n";
if ($this->debug) echo "DEBUG BIND : primary->".
var_export ($deletekey, TRUE)."\n";
$st->bindValue (":primary", $deletekey);
$st->execute ();
return $st->rowCount();
}
}
/** POC :
error_reporting (E_ALL);
require_once ("domframework/dbLayer.php");
class zone extends dbLayer
{
// The database must be initialized with
// CREATE TABLE `dns_zones` (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
// zone VARCHAR(255) NOT NULL,
// viewname VARCHAR(255),
// viewclients VARCHAR(255),
// comment VARCHAR(1024),
// opendate DATETIME NOT NULL,
// closedate DATETIME,
// UNIQUE (zone,viewname));
protected $table = "dns_zones";
protected $fields = array (
"id"=>array ("integer", "not null", "autoincrement"),
"zone"=>array ("varchar", "255", "not null"),
"viewname"=>array ("varchar", "255"),
"viewclients"=>array ("varchar", "255"),
"comment"=>array ("varchar", "1024"),
"opendate"=>array ("datetime", "not null"),
"closedate"=>array ("datetime"),
);
protected $primary = "id";
}
ini_set ("date.timezone", "Europe/Paris");
$zone = new zone ("sqlite:datas/database.db");
$last = $zone->create (array ("zone"=>"testZone", "opendate"=>date("Y-m-d H:i:s")));
//print_r ($zone->read ());
$zone->update (2040, array ("zone"=>"testZone2"));
print_r ($zone->delete ($last));
*/