diff options
author | Frédéric Guillot <contact@fredericguillot.com> | 2014-01-25 14:56:02 -0500 |
---|---|---|
committer | Frédéric Guillot <contact@fredericguillot.com> | 2014-01-25 14:56:02 -0500 |
commit | 9383a15af699ede77142d040b65118e15754a2ca (patch) | |
tree | b550b5adf5bcf8f5a8793c188cc5630f26a27d49 /vendor/PicoDb |
First commit
Diffstat (limited to 'vendor/PicoDb')
-rw-r--r-- | vendor/PicoDb/Database.php | 108 | ||||
-rw-r--r-- | vendor/PicoDb/Drivers/Sqlite.php | 48 | ||||
-rw-r--r-- | vendor/PicoDb/Schema.php | 60 | ||||
-rw-r--r-- | vendor/PicoDb/Table.php | 430 |
4 files changed, 646 insertions, 0 deletions
diff --git a/vendor/PicoDb/Database.php b/vendor/PicoDb/Database.php new file mode 100644 index 00000000..c3405f72 --- /dev/null +++ b/vendor/PicoDb/Database.php @@ -0,0 +1,108 @@ +<?php + +namespace PicoDb; + +class Database +{ + private $logs = array(); + private $pdo; + + + public function __construct(array $settings) + { + if (! isset($settings['driver'])) { + + throw new \LogicException('You must define a database driver.'); + } + + switch ($settings['driver']) { + + case 'sqlite': + require_once __DIR__.'/Drivers/Sqlite.php'; + $this->pdo = new Sqlite($settings['filename']); + break; + + default: + throw new \LogicException('This database driver is not supported.'); + } + + $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + } + + + public function setLogMessage($message) + { + $this->logs[] = $message; + } + + + public function getLogMessages() + { + return $this->logs; + } + + + public function getConnection() + { + return $this->pdo; + } + + + public function escapeIdentifier($value) + { + return $this->pdo->escapeIdentifier($value); + } + + + public function execute($sql, array $values = array()) + { + try { + + $this->setLogMessage($sql); + $this->setLogMessage(implode(', ', $values)); + + $rq = $this->pdo->prepare($sql); + $rq->execute($values); + + return $rq; + } + catch (\PDOException $e) { + + if ($this->pdo->inTransaction()) $this->pdo->rollback(); + $this->setLogMessage($e->getMessage()); + return false; + } + } + + + public function startTransaction() + { + $this->pdo->beginTransaction(); + } + + + public function closeTransaction() + { + $this->pdo->commit(); + } + + + public function cancelTransaction() + { + $this->pdo->rollback(); + } + + + public function table($table_name) + { + require_once __DIR__.'/Table.php'; + return new Table($this, $table_name); + } + + + public function schema() + { + require_once __DIR__.'/Schema.php'; + return new Schema($this); + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Drivers/Sqlite.php b/vendor/PicoDb/Drivers/Sqlite.php new file mode 100644 index 00000000..6555e73d --- /dev/null +++ b/vendor/PicoDb/Drivers/Sqlite.php @@ -0,0 +1,48 @@ +<?php + +namespace PicoDb; + +class Sqlite extends \PDO { + + + public function __construct($filename) + { + parent::__construct('sqlite:'.$filename); + + $this->exec('PRAGMA foreign_keys = ON'); + } + + + public function getSchemaVersion() + { + $rq = $this->prepare('PRAGMA user_version'); + $rq->execute(); + $result = $rq->fetch(\PDO::FETCH_ASSOC); + + if (isset($result['user_version'])) { + + return $result['user_version']; + } + + return 0; + } + + + public function setSchemaVersion($version) + { + $this->exec('PRAGMA user_version='.$version); + } + + + public function getLastId() + { + return $this->lastInsertId(); + } + + + public function escapeIdentifier($value) + { + if (strpos($value, '.') !== false) return $value; + return '"'.$value.'"'; + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Schema.php b/vendor/PicoDb/Schema.php new file mode 100644 index 00000000..2f52b846 --- /dev/null +++ b/vendor/PicoDb/Schema.php @@ -0,0 +1,60 @@ +<?php + +namespace PicoDb; + +class Schema +{ + protected $db = null; + + + public function __construct(Database $db) + { + $this->db = $db; + } + + + public function check($last_version = 1) + { + $current_version = $this->db->getConnection()->getSchemaVersion(); + + if ($current_version < $last_version) { + + return $this->migrateTo($current_version, $last_version); + } + + return true; + } + + + public function migrateTo($current_version, $next_version) + { + try { + + $this->db->startTransaction(); + + for ($i = $current_version + 1; $i <= $next_version; $i++) { + + $function_name = '\Schema\version_'.$i; + + if (function_exists($function_name)) { + + call_user_func($function_name, $this->db->getConnection()); + $this->db->getConnection()->setSchemaVersion($i); + } + else { + + throw new \LogicException('To execute a database migration, you need to create this function: "'.$function_name.'".'); + } + } + + $this->db->closeTransaction(); + } + catch (\PDOException $e) { + + $this->db->cancelTransaction(); + return false; + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Table.php b/vendor/PicoDb/Table.php new file mode 100644 index 00000000..4cdf35f7 --- /dev/null +++ b/vendor/PicoDb/Table.php @@ -0,0 +1,430 @@ +<?php + +namespace PicoDb; + +class Table +{ + private $table_name = ''; + private $sql_limit = ''; + private $sql_offset = ''; + private $sql_order = ''; + private $joins = array(); + private $conditions = array(); + private $or_conditions = array(); + private $is_or_condition = false; + private $columns = array(); + private $values = array(); + private $distinct = false; + private $group_by = array(); + + private $db; + + + public function __construct(Database $db, $table_name) + { + $this->db = $db; + $this->table_name = $table_name; + + return $this; + } + + + public function save(array $data) + { + if (! empty($this->conditions)) { + + return $this->update($data); + } + else { + + return $this->insert($data); + } + } + + + public function update(array $data) + { + $columns = array(); + $values = array(); + + foreach ($data as $column => $value) { + + $columns[] = $this->db->escapeIdentifier($column).'=?'; + $values[] = $value; + } + + foreach ($this->values as $value) { + + $values[] = $value; + } + + $sql = sprintf( + 'UPDATE %s SET %s %s', + $this->db->escapeIdentifier($this->table_name), + implode(', ', $columns), + $this->conditions() + ); + + $result = $this->db->execute($sql, $values); + + if ($result !== false && $result->rowCount() > 0) { + + return true; + } + + return false; + } + + + public function insert(array $data) + { + $columns = array(); + + foreach ($data as $column => $value) { + + $columns[] = $this->db->escapeIdentifier($column); + } + + $sql = sprintf( + 'INSERT INTO %s (%s) VALUES (%s)', + $this->db->escapeIdentifier($this->table_name), + implode(', ', $columns), + implode(', ', array_fill(0, count($data), '?')) + ); + + return false !== $this->db->execute($sql, array_values($data)); + } + + + public function remove() + { + $sql = sprintf( + 'DELETE FROM %s %s', + $this->db->escapeIdentifier($this->table_name), + $this->conditions() + ); + + return false !== $this->db->execute($sql, $this->values); + } + + + public function listing($key, $value) + { + $this->columns($key, $value); + + $listing = array(); + $results = $this->findAll(); + + if ($results) { + + foreach ($results as $result) { + + $listing[$result[$key]] = $result[$value]; + } + } + + return $listing; + } + + + public function findAll() + { + $rq = $this->db->execute($this->buildSelectQuery(), $this->values); + if (false === $rq) return false; + + return $rq->fetchAll(\PDO::FETCH_ASSOC); + } + + + public function findAllByColumn($column) + { + $this->columns = array($column); + $rq = $this->db->execute($this->buildSelectQuery(), $this->values); + if (false === $rq) return false; + + return $rq->fetchAll(\PDO::FETCH_COLUMN, 0); + } + + + public function findOne() + { + $this->limit(1); + $result = $this->findAll(); + + return isset($result[0]) ? $result[0] : null; + } + + + public function findOneColumn($column) + { + $this->limit(1); + $this->columns = array($column); + + $rq = $this->db->execute($this->buildSelectQuery(), $this->values); + if (false === $rq) return false; + + return $rq->fetchColumn(); + } + + + public function buildSelectQuery() + { + return sprintf( + 'SELECT %s %s FROM %s %s %s %s %s %s %s', + $this->distinct ? 'DISTINCT' : '', + empty($this->columns) ? '*' : implode(', ', $this->columns), + $this->db->escapeIdentifier($this->table_name), + implode(' ', $this->joins), + $this->conditions(), + empty($this->group_by) ? '' : 'GROUP BY '.implode(', ', $this->group_by), + $this->sql_order, + $this->sql_limit, + $this->sql_offset + ); + } + + + public function count() + { + $sql = sprintf( + 'SELECT COUNT(*) FROM %s'.$this->conditions().$this->sql_order.$this->sql_limit.$this->sql_offset, + $this->db->escapeIdentifier($this->table_name) + ); + + $rq = $this->db->execute($sql, $this->values); + if (false === $rq) return false; + + $result = $rq->fetchColumn(); + return $result ? (int) $result : 0; + } + + + public function join($table, $foreign_column, $local_column) + { + $this->joins[] = sprintf( + 'LEFT JOIN %s ON %s=%s', + $this->db->escapeIdentifier($table), + $this->db->escapeIdentifier($table).'.'.$this->db->escapeIdentifier($foreign_column), + $this->db->escapeIdentifier($this->table_name).'.'.$this->db->escapeIdentifier($local_column) + ); + + return $this; + } + + + public function conditions() + { + if (! empty($this->conditions)) { + + return ' WHERE '.implode(' AND ', $this->conditions); + } + else { + + return ''; + } + } + + + public function addCondition($sql) + { + if ($this->is_or_condition) { + + $this->or_conditions[] = $sql; + } + else { + + $this->conditions[] = $sql; + } + } + + + public function beginOr() + { + $this->is_or_condition = true; + $this->or_conditions = array(); + + return $this; + } + + + public function closeOr() + { + $this->is_or_condition = false; + + if (! empty($this->or_conditions)) { + + $this->conditions[] = '('.implode(' OR ', $this->or_conditions).')'; + } + + return $this; + } + + + public function orderBy($column, $order = 'ASC') + { + $order = strtoupper($order); + $order = $order === 'ASC' || $order === 'DESC' ? $order : 'ASC'; + + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' '.$order; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' '.$order; + } + + return $this; + } + + + public function asc($column) + { + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' ASC'; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' ASC'; + } + + return $this; + } + + + public function desc($column) + { + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' DESC'; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' DESC'; + } + + return $this; + } + + + public function limit($value) + { + if (! is_null($value)) $this->sql_limit = ' LIMIT '.(int) $value; + return $this; + } + + + public function offset($value) + { + if (! is_null($value)) $this->sql_offset = ' OFFSET '.(int) $value; + return $this; + } + + + public function groupBy() + { + $this->group_by = \func_get_args(); + return $this; + } + + + public function columns() + { + $this->columns = \func_get_args(); + return $this; + } + + + public function distinct() + { + $this->columns = \func_get_args(); + $this->distinct = true; + return $this; + } + + + public function __call($name, array $arguments) + { + $column = $arguments[0]; + $sql = ''; + + switch (strtolower($name)) { + + case 'in': + if (isset($arguments[1]) && is_array($arguments[1])) { + + $sql = sprintf( + '%s IN (%s)', + $this->db->escapeIdentifier($column), + implode(', ', array_fill(0, count($arguments[1]), '?')) + ); + } + break; + + case 'notin': + if (isset($arguments[1]) && is_array($arguments[1])) { + + $sql = sprintf( + '%s NOT IN (%s)', + $this->db->escapeIdentifier($column), + implode(', ', array_fill(0, count($arguments[1]), '?')) + ); + } + break; + + case 'like': + $sql = sprintf('%s LIKE ?', $this->db->escapeIdentifier($column)); + break; + + case 'eq': + case 'equal': + case 'equals': + $sql = sprintf('%s = ?', $this->db->escapeIdentifier($column)); + break; + + case 'gt': + case 'greaterthan': + $sql = sprintf('%s > ?', $this->db->escapeIdentifier($column)); + break; + + case 'lt': + case 'lowerthan': + $sql = sprintf('%s < ?', $this->db->escapeIdentifier($column)); + break; + + case 'gte': + case 'greaterthanorequals': + $sql = sprintf('%s >= ?', $this->db->escapeIdentifier($column)); + break; + + case 'lte': + case 'lowerthanorequals': + $sql = sprintf('%s <= ?', $this->db->escapeIdentifier($column)); + break; + + case 'isnull': + $sql = sprintf('%s IS NULL', $this->db->escapeIdentifier($column)); + break; + + case 'notnull': + $sql = sprintf('%s IS NOT NULL', $this->db->escapeIdentifier($column)); + break; + } + + if ($sql !== '') { + + $this->addCondition($sql); + + if (isset($arguments[1])) { + + if (is_array($arguments[1])) { + + foreach ($arguments[1] as $value) { + $this->values[] = $value; + } + } + else { + + $this->values[] = $arguments[1]; + } + } + } + + return $this; + } +} |