Skip to content

Instantly share code, notes, and snippets.

@audinue
Created March 3, 2016 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audinue/3392690cd1ce376123cf to your computer and use it in GitHub Desktop.
Save audinue/3392690cd1ce376123cf to your computer and use it in GitHub Desktop.
<?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