Created
March 3, 2016 19:21
-
-
Save audinue/3392690cd1ce376123cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SDO { | |
private $pdo; | |
function __construct(PDO $pdo) { | |
$this->pdo = $pdo; | |
} | |
function pdo() { | |
return $this->pdo; | |
} | |
function execute($sql, $args = array()) { | |
$pdo = $this->pdo; | |
$statement = $pdo->prepare($sql); | |
$error = $pdo->errorInfo(); | |
if($error[0] != '00000') { | |
throw new Exception($error[2]); | |
} | |
$statement->execute($args);; | |
$error = $pdo->errorInfo(); | |
if($error[0] != '00000') { | |
throw new Exception($error[2]); | |
} | |
return $statement; | |
} | |
function cell($sql, $args = array()) { | |
return $this->execute($sql, $args)->fetchColumn(); | |
} | |
function row($sql, $args = array(), $class = 'stdClass', $ctorArgs = array()) { | |
return $this->execute($sql, $args)->fetchObject($class, $ctorArgs); | |
} | |
function rows($sql, $args = array(), $class = 'stdClass', $ctorArgs = array()) { | |
return $this->execute($sql, $args)->fetchAll(PDO::FETCH_CLASS, $class, $ctorArgs); | |
} | |
function column($sql, $args = array()) { | |
$column = array(); | |
foreach($this->execute($sql, $args)->fetchAll() as $row) { | |
$column []= current($row); | |
} | |
return $column; | |
} | |
function insert($table, $row) { | |
return $this->execute('INSERT INTO ' . $table . ' (' . implode(', ', array_keys($row)) . ') VALUES (' . implode(', ', array_fill(0, count($row), '?')) . ')', array_values($row))->rowCount(); | |
} | |
function update($table, $row, $keys) { | |
return $this->execute('UPDATE ' . $table . ' SET ' . implode(' = ?, ', array_keys($row)) . ' = ? WHERE ' . implode(' = ?, ', array_keys($keys)) . ' = ?', array_merge(array_values($row), array_values($keys)))->rowCount(); | |
} | |
function delete($table, $keys) { | |
return $this->execute('DELETE FROM ' . $table . ' WHERE ' . implode(' = ?, ', array_keys($keys)) . ' = ?', array_values($keys))->rowCount(); | |
} | |
function lastId() { | |
return $this->pdo->lastInsertId(); | |
} | |
function begin() { | |
$this->pdo->beginTransaction(); | |
return $this; | |
} | |
function commit() { | |
$this->pdo->commit(); | |
return $this; | |
} | |
function rollBack() { | |
$this->pdo->rollBack(); | |
return $this; | |
} | |
function __get($name) { | |
return new SDORowSet($this, $name); | |
} | |
} | |
class SDORowSet implements IteratorAggregate { | |
private $sdo; | |
private $table; | |
private $parentKey; | |
private $parentValue; | |
private $select; | |
private $where; | |
private $group; | |
private $having; | |
private $order; | |
private $limit; | |
private $offset; | |
private $args; | |
function __construct(SDO $sdo, $table, $parentKey = NULL, $parentValue = NULL) { | |
$this->sdo = $sdo; | |
$this->table = $table; | |
$this->parentKey = $parentKey; | |
$this->parentValue = $parentValue; | |
} | |
function sdo() { | |
return $this->sdo; | |
} | |
function table() { | |
return $this->table; | |
} | |
function parentKey() { | |
return $this->parentKey; | |
} | |
function parentValue() { | |
return $this->parentValue; | |
} | |
function select($select = NULL) { | |
if(func_num_args()) { | |
$this->select = $select; | |
return $this; | |
} | |
return $this->select; | |
} | |
function where($where = NULL, $args = NULL) { | |
switch(func_num_args()) { | |
case 0: | |
return $this->where; | |
case 1: | |
$this->where = $where; | |
return $this; | |
case 2: | |
$this->where = $where; | |
$this->args = $args; | |
return $this; | |
} | |
} | |
function group($group = NULL) { | |
if(func_num_args()) { | |
$this->group = $group; | |
return $this; | |
} | |
return $this->group; | |
} | |
function having($having = NULL) { | |
if(func_num_args()) { | |
$this->having = $having; | |
return $this; | |
} | |
return $this->having; | |
} | |
function order($order = NULL) { | |
if(func_num_args()) { | |
$this->order = $order; | |
return $this; | |
} | |
return $this->order; | |
} | |
function limit($limit = NULL) { | |
if(func_num_args()) { | |
$this->limit = $limit; | |
return $this; | |
} | |
return $this->limit; | |
} | |
function offset($offset = NULL) { | |
if(func_num_args()) { | |
$this->offset = $offset; | |
return $this; | |
} | |
return $this->offset; | |
} | |
function args($args = NULL) { | |
if(func_num_args()) { | |
$this->args = $args; | |
return $this; | |
} | |
if(is_null($this->args)) { | |
$this->args = array(); | |
} | |
return $this->args; | |
} | |
private function sql() { | |
$sql = 'SELECT '; | |
if(!is_null($this->select)) { | |
$sql .= $this->select; | |
} else { | |
$sql .= '*'; | |
} | |
$sql .= ' FROM ' . $this->table . ' WHERE 1'; | |
if($this->parentKey) { | |
$sql .= ' AND ' . $this->parentKey . ' = ' . $this->parentValue; | |
} | |
if(!is_null($this->where)) { | |
$sql .= ' AND (' . $this->where . ')'; | |
} | |
if(!is_null($this->group)) { | |
$sql .= ' GROUP BY ' . $this->group; | |
} | |
if(!is_null($this->having)) { | |
$sql .= ' HAVING ' . $this->having; | |
} | |
if(!is_null($this->order)) { | |
$sql .= ' ORDER BY ' . $this->order; | |
} | |
if(!is_null($this->limit)) { | |
$sql .= ' LIMIT ' . $this->limit; | |
if(!is_null($this->offset)) { | |
$sql .= ' OFFSET ' . $this->offset; | |
} | |
} | |
return $sql; | |
} | |
function count() { | |
$sql = 'SELECT COUNT(*) FROM ' . $this->table . ' WHERE 1'; | |
if($this->parentKey) { | |
$sql .= ' AND ' . $this->parentKey . ' = ' . $this->parentValue; | |
} | |
if(!is_null($this->where)) { | |
$sql .= ' AND (' . $this->where . ')'; | |
} | |
if(!is_null($this->group)) { | |
$sql .= ' GROUP BY ' . $this->group; | |
} | |
if(!is_null($this->having)) { | |
$sql .= ' HAVING ' . $this->having; | |
} | |
return $this->sdo->cell($sql, $this->args()); | |
} | |
function exists() { | |
$sql = 'SELECT 1 FROM ' . $this->table . ' WHERE 1'; | |
if($this->parentKey) { | |
$sql .= ' AND ' . $this->parentKey . ' = ' . $this->parentValue; | |
} | |
if(!is_null($this->where)) { | |
$sql .= ' AND (' . $this->where . ')'; | |
} | |
if(!is_null($this->group)) { | |
$sql .= ' GROUP BY ' . $this->group; | |
} | |
if(!is_null($this->having)) { | |
$sql .= ' HAVING ' . $this->having; | |
} | |
return $this->sdo->cell($sql, $this->args()) == 1; | |
} | |
function row() { | |
return $this->sdo->row($this->sql(), $this->args(), 'SDORow', array($this)); | |
} | |
function getIterator() { | |
return new ArrayIterator($this->sdo->rows($this->sql(), $this->args(), 'SDORow', array($this))); | |
} | |
} | |
class SDORow { | |
private $rowSet; | |
function __construct(SDORowSet $rowSet) { | |
$this->rowSet = $rowSet; | |
} | |
function rowSet() { | |
return $this->rowSet; | |
} | |
private function primaryKey($table) { | |
foreach($this->rowSet->sdo()->rows('PRAGMA table_info(' . $table . ')') as $row) { | |
if($row->pk) { | |
return $row->name; | |
} | |
} | |
throw new Exception('Primary key not found.'); | |
} | |
function parent($table, $reference = NULL) { | |
$primaryKey = $this->primaryKey($table); | |
if(is_null($reference)) { | |
$reference = $primaryKey; | |
} | |
$rowSet = new SDORowSet($this->rowSet->sdo(), $table, $primaryKey, $this->{$reference}); | |
return $rowSet->row(); | |
} | |
function child($table, $reference = NULL) { | |
$primaryKey = $this->primaryKey($this->rowSet->table()); | |
if(is_null($reference)) { | |
$reference = $primaryKey; | |
} | |
return new SDORowSet($this->rowSet->sdo(), $table, $reference, $this->{$primaryKey}); | |
} | |
private function tableExists($name) { | |
return $this->rowSet->sdo()->cell("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '$name'") == 1; | |
} | |
private function tableByPrimaryKey($primaryKey) { | |
foreach($this->rowSet->sdo()->rows("SELECT name FROM sqlite_master WHERE type = 'table'") as $row) { | |
foreach($this->rowSet->sdo()->rows('PRAGMA table_info(' . $row->name . ')') as $row2) { | |
if($row2->name == $primaryKey && $row2->pk) { | |
return $row->name; | |
} | |
} | |
} | |
throw new Exception('Table not found.'); | |
} | |
function __get($name) { | |
if($this->tableExists($name)) { | |
return $this->child($name); | |
} | |
if(isset($this->{$name . '_id'})) { | |
return $this->parent($this->tableByPrimaryKey($name . '_id')); | |
} | |
throw new Exception('Property not found.'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment