Skip to content

Commit

Permalink
1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefano Azzolini committed Feb 26, 2016
1 parent 8b2545c commit 5105daf
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 74 deletions.
172 changes: 113 additions & 59 deletions classes/SQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,63 @@
* @copyright Caffeina srl - 2015 - http://caffeina.it
*/


class SQL {
use Module;
protected static $connections = [],
$current = 'default';

protected static $connection = [];
protected static $pdo = null;
protected static $queries = [];
protected static $last_exec_success = true;
public static function register($name, $dsn, $username=null, $password=null, $options=[]){
return self::$connections[$name] = new SQLConnection($dsn, $username, $password, $options);
}

public static function connect($dsn, $username=null, $password=null, $options=[]){
static::$connection = [
return self::register('default', $dsn, $username, $password, $options);
}

public static function defaultTo($name){
if (isset(self::$connections[$name])){
self::$current = $name;
return true;
} else return false;
}

public static function close($name=null){
if ($name === null) {
foreach (self::$connections as $conn) $conn->close();
return true;
} else if (isset(self::$connections[$name])){
self::$connections->close();
return true;
} else return false;
}

public static function using($name){
if (empty(self::$connections[$name])) throw new \Exception("[SQL] Unknown connection named '$name'.");
return self::$connections[$name];
}

public static function __callStatic($method, $args){
if (empty(self::$connections[self::$current])) throw new \Exception("[SQL] No default connection defined.");
return call_user_func_array([self::$connections[self::$current],$method],$args);
}

}

// Default connection to in-memory ephemeral database
SQL::connect('sqlite::memory:');


class SQLConnection {

protected $connection = [],
$queries = [],
$last_exec_success = true;

public function __construct($dsn, $username=null, $password=null, $options=[]){
$this->connection = [
'dsn' => $dsn,
'pdo' => null,
'username' => $username,
'password' => $password,
'options' => array_merge([
Expand All @@ -31,39 +77,47 @@ public static function connect($dsn, $username=null, $password=null, $options=[]
];
// "The auto-commit mode cannot be changed for this driver" SQLite workaround
if (strpos($dsn,'sqlite:') === 0) {
static::$connection['options'] = $options;
$this->connection['options'] = $options;
}
}

public static function & connection(){
if(null === static::$pdo) {
public function close(){
$this->connection['pdo'] = null;
}

public function onConnect($callbkack){
$this->connection['pdo'] = null;
}

public function connection(){
if(empty($this->connection['pdo'])) {
try {
static::$pdo = new PDO(
static::$connection['dsn'],
static::$connection['username'],
static::$connection['password'],
static::$connection['options']
$this->connection['pdo'] = new PDO(
$this->connection['dsn'],
$this->connection['username'],
$this->connection['password'],
$this->connection['options']

);
Event::trigger('core.sql.connect',$this);
} catch(Exception $e) {
static::$pdo = null;
$this->connection['pdo'] = null;
}
Event::triggerOnce('core.sql.connect',static::$connection,static::$pdo);
}
return static::$pdo;
return $this->connection['pdo'];
}

public static function prepare($query){
if(!static::connection()) return false;
return isset(static::$queries[$query]) ? static::$queries[$query] : (static::$queries[$query] = static::connection()->prepare($query));
public function prepare($query){
if(!$this->connection()) return false;
return isset($this->queries[$query]) ? $this->queries[$query] : ($this->queries[$query] = $this->connection()->prepare($query));
}

public static function exec($query, $params=[]){
if(!static::connection()) return false;
public function exec($query, $params=[]){
if(!$this->connection()) return false;

if (false==is_array($params)) $params = (array)$params;
$query = Filter::with('core.sql.query',$query);
if($statement = static::prepare($query)){
if($statement = $this->prepare($query)){
Event::trigger('core.sql.query',$query,$params,(bool)$statement);

foreach ($params as $key => $val) {
Expand All @@ -83,112 +137,112 @@ public static function exec($query, $params=[]){
return false;
}

static::$last_exec_success = $statement && $statement->execute();
$this->last_exec_success = $statement && $statement->execute();
return $statement;
}

public static function value($query, $params=[], $column=0){
if(!static::connection()) return false;
public function value($query, $params=[], $column=0){
if(!$this->connection()) return false;

$res = static::exec($query,$params);
$res = $this->exec($query,$params);
return $res ? $res->fetchColumn($column) : null;
}

public static function each($query, $params=[], callable $looper = null){
if(!static::connection()) return false;
public function each($query, $params=[], callable $looper = null){
if(!$this->connection()) return false;

// ($query,$looper) shorthand
if ($looper===null && is_callable($params)) {$looper = $params; $params = [];}
if( $res = static::exec($query,$params) ){
if( $res = $this->exec($query,$params) ){
if(is_callable($looper))
while ($row = $res->fetchObject()) $looper($row);
else
return $res->fetchAll(PDO::FETCH_CLASS);
}
}

public static function single($query, $params=[], callable $handler = null){
if(!static::connection()) return false;
public function single($query, $params=[], callable $handler = null){
if(!$this->connection()) return false;

// ($query,$handler) shorthand
if ($handler===null && is_callable($params)) {$handler = $params; $params = [];}
if( $res = static::exec($query,$params) ){
if( $res = $this->exec($query,$params) ){
if (is_callable($handler))
$handler($res->fetchObject());
else
return $res->fetchObject();
}
}

public static function run($script){
if(!static::connection()) return false;
public function run($script){
if(!$this->connection()) return false;

$sql_path = Options::get('database.sql.path',APP_DIR.'/sql');
$sql_sep = Options::get('database.sql.separator',';');
if (is_file($f = "$sql_path/$script.sql")){
$result = true;
foreach(explode($sql_sep,file_get_contents($f)) as $statement) {
$result = SQL::exec($statement);
$result = $this->exec($statement);
}
return $result;
} else return false;
}

public static function all($query, $params=[], callable $looper = null){
if(!static::connection()) return false;
return static::each($query,$params,$looper);
public function all($query, $params=[], callable $looper = null){
if(!$this->connection()) return false;
return $this->each($query,$params,$looper);
}

public static function delete($table, $pks=null, $pk='id', $inclusive=true){
if(!static::connection()) return false;
public function delete($table, $pks=null, $pk='id', $inclusive=true){
if(!$this->connection()) return false;

if (null===$pks) {
return static::exec("DELETE FROM `$table`");
return $this->exec("DELETE FROM `$table`");
} else {
return static::exec("DELETE FROM `$table` WHERE `$pk` ".($inclusive ? "" : "NOT " )."IN (" . implode( ',', array_fill_keys( (array)$pks, '?' ) ) . ")",(array)$pks);
return $this->exec("DELETE FROM `$table` WHERE `$pk` ".($inclusive ? "" : "NOT " )."IN (" . implode( ',', array_fill_keys( (array)$pks, '?' ) ) . ")",(array)$pks);
}
}

public static function insert($table, $data=[]){
if(!static::connection()) return false;
public function insert($table, $data=[]){
if(!$this->connection()) return false;

if (false==is_array($data)) $data = (array)$data;
$k = array_keys($data);
asort($k);
$pk = $k;
array_walk($pk,function(&$e){ $e = ':'.$e;});
$q = "INSERT INTO `$table` (`".implode('`,`',$k)."`) VALUES (".implode(',',$pk).")";
static::exec($q,$data);
return static::$last_exec_success ? static::connection()->lastInsertId() : false;
$this->exec($q,$data);
return $this->last_exec_success ? $this->connection()->lastInsertId() : false;
}

public static function updateWhere($table, $data=[], $where){
if(!static::connection()) return false;
public function updateWhere($table, $data=[], $where){
if(!$this->connection()) return false;

if (false==is_array($data)) $data = (array)$data;
if (empty($data)) return false;
$k = array_keys($data);
asort($k);
array_walk($k,function(&$e){ $e = "`$e`=:$e";});
$q = "UPDATE `$table` SET ".implode(', ',$k)." WHERE $where";
static::exec($q,$data);
return static::$last_exec_success;
$this->exec($q,$data);
return $this->last_exec_success;
}

public static function update($table, $data=[], $pk='id', $extra_where=''){
return static::updateWhere($table, $data, "`$pk`=:$pk $extra_where");
public function update($table, $data=[], $pk='id', $extra_where=''){
return $this->updateWhere($table, $data, "`$pk`=:$pk $extra_where");
}

public static function insertOrUpdate($table, $data=[], $pk='id', $extra_where=''){
if(!static::connection()) return false;
public function insertOrUpdate($table, $data=[], $pk='id', $extra_where=''){
if(!$this->connection()) return false;

if (false==is_array($data)) $data = (array)$data;
if (empty($data[$pk])) return static::insert($table, $data);
if( (string) static::value("SELECT `$pk` FROM `$table` WHERE `$pk`=? LIMIT 1", [$data[$pk]]) === (string) $data[$pk] ){
return static::update($table, $data, $pk, $extra_where);
if (empty($data[$pk])) return $this->insert($table, $data);
if( (string) $this->value("SELECT `$pk` FROM `$table` WHERE `$pk`=? LIMIT 1", [$data[$pk]]) === (string) $data[$pk] ){
return $this->update($table, $data, $pk, $extra_where);
} else {
return static::insert($table, $data);
return $this->insert($table, $data);
}
}

}

4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "caffeina-core/core",
"type": "library",
"description": "Caffeina - Core PHP Toolbox",
"description": "Components for rapid application development.",
"keywords": ["framework","core","sdk","toolbox"],
"homepage": "http://caffeina.com",
"version": "1.3.0",
"version": "1.4.0",
"license": "MIT",
"authors": [
{
Expand Down
17 changes: 8 additions & 9 deletions tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ class ModelTest extends PHPUnit_Framework_TestCase {
private $b1,$b2;

public function __construct(){
SQL::connect('sqlite::memory:');
SQL::exec("
CREATE TABLE `books` (
id integer primary key,
title text
);
");
SQL::connect('sqlite::memory:');
SQL::exec("CREATE TABLE books (
id integer primary key,
title text
);");

$this->b1 = Book::create([
'id' => 1,
Expand All @@ -28,20 +26,21 @@ public function __construct(){
}

public function testCreate(){
$results = SQL::value('select title from books where id=1');
$results = SQL::value('SELECT title from books where id=1');
$this->assertEquals('My book',$results);
}

public function testSave(){
$this->b1->title = "My Awesome Book";
$this->b1->save();
$results = SQL::value('select title from books where id=1');
$results = SQL::value('SELECT title from books where id=1');
$this->assertEquals('My Awesome Book',$results);
}

public function testLoad(){
$b2_loaded = Book::load(2);

$this->assertNotNull($b2_loaded);
$this->assertNotFalse($b2_loaded);
$this->assertEquals('Necronomicon',$b2_loaded->title);

Expand Down
Loading

0 comments on commit 5105daf

Please sign in to comment.