|
|
@ -1,13 +1,14 @@ |
|
|
|
<?php |
|
|
|
declare(strict_types=1); |
|
|
|
namespace JKingWeb\NewsSync\Db; |
|
|
|
use JKingWeb\NewsSync\Db\DriverSQLite3 as Driver; |
|
|
|
|
|
|
|
class StatementSQLite3 implements Statement { |
|
|
|
protected $db; |
|
|
|
protected $st; |
|
|
|
protected $types; |
|
|
|
|
|
|
|
public function __construct($db, $st, array $bindings = []) { |
|
|
|
public function __construct(\SQLite3 $db, \SQLite3Stmt $st, array $bindings = []) { |
|
|
|
$this->db = $db; |
|
|
|
$this->st = $st; |
|
|
|
$this->rebindArray($bindings); |
|
|
@ -18,10 +19,6 @@ class StatementSQLite3 implements Statement { |
|
|
|
unset($this->st); |
|
|
|
} |
|
|
|
|
|
|
|
public function __invoke(...$values) { |
|
|
|
return $this->runArray($values); |
|
|
|
} |
|
|
|
|
|
|
|
public function run(...$values): Result { |
|
|
|
return $this->runArray($values); |
|
|
|
} |
|
|
@ -30,56 +27,81 @@ class StatementSQLite3 implements Statement { |
|
|
|
$this->st->clear(); |
|
|
|
$l = sizeof($values); |
|
|
|
for($a = 0; $a < $l; $a++) { |
|
|
|
// find the right SQLite binding type for the value/specified type |
|
|
|
$type = null; |
|
|
|
if($values[$a]===null) { |
|
|
|
$type = \SQLITE3_NULL; |
|
|
|
} else if(array_key_exists($a,$this->types)) { |
|
|
|
$type = $this->translateType($this->types[$a]); |
|
|
|
} else { |
|
|
|
$type = (array_key_exists($a,$this->types)) ? $this->types[$a] : \SQLITE3_TEXT; |
|
|
|
$type = \SQLITE3_TEXT; |
|
|
|
} |
|
|
|
$this->st->bindParam($a+1, $values[$a], $type); |
|
|
|
} |
|
|
|
return new ResultSQLite3($this->st->execute(), $this->db->changes(), $this); |
|
|
|
} |
|
|
|
|
|
|
|
public function rebind(...$bindings): bool { |
|
|
|
return $this->rebindArray($bindings); |
|
|
|
} |
|
|
|
|
|
|
|
public function rebindArray(array $bindings): bool { |
|
|
|
$this->types = []; |
|
|
|
foreach($bindings as $binding) { |
|
|
|
switch(trim(strtolower($binding))) { |
|
|
|
// cast values if necessary |
|
|
|
switch($this->types[$a]) { |
|
|
|
case "null": |
|
|
|
case "nil": |
|
|
|
$this->types[] = \SQLITE3_NULL; break; |
|
|
|
case "int": |
|
|
|
$value = null; break; |
|
|
|
case "integer": |
|
|
|
$this->types[] = \SQLITE3_INTEGER; break; |
|
|
|
$value = (int) $values[$a]; break; |
|
|
|
case "float": |
|
|
|
case "double": |
|
|
|
case "real": |
|
|
|
case "numeric": |
|
|
|
$this->types[] = \SQLITE3_FLOAT; break; |
|
|
|
$value = (float) $values[$a]; break; |
|
|
|
case "date": |
|
|
|
$value = Driver::formatDate($values[$a], Driver::TS_DATE); break; |
|
|
|
case "time": |
|
|
|
$value = Driver::formatDate($values[$a], Driver::TS_TIME); break; |
|
|
|
case "datetime": |
|
|
|
case "timestamp": |
|
|
|
$this->types[] = \SQLITE3_TEXT; break; |
|
|
|
case "blob": |
|
|
|
case "bin": |
|
|
|
$value = Driver::formatDate($values[$a], Driver::TS_BOTH); break; |
|
|
|
case "binary": |
|
|
|
$this->types[] = \SQLITE3_BLOB; break; |
|
|
|
$value = (string) $values[$a]; break; |
|
|
|
case "text": |
|
|
|
case "string": |
|
|
|
case "str": |
|
|
|
$this->types[] = \SQLITE3_TEXT; break; |
|
|
|
case "bool": |
|
|
|
$value = $values[$a]; break; |
|
|
|
case "boolean": |
|
|
|
case "bit": |
|
|
|
$this->types[] = \SQLITE3_INTEGER; break; |
|
|
|
$value = (bool) $values[$a]; break; |
|
|
|
default: |
|
|
|
$this->types[] = \SQLITE3_TEXT; break; |
|
|
|
throw new Exception("paramTypeUnknown", $type); |
|
|
|
} |
|
|
|
if($type===null) { |
|
|
|
$this->st->bindParam($a+1, $value); |
|
|
|
} else { |
|
|
|
$this->st->bindParam($a+1, $value, $type); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return new ResultSQLite3($this->st->execute(), $this->db->changes(), $this); |
|
|
|
} |
|
|
|
|
|
|
|
public function rebind(...$bindings): bool { |
|
|
|
return $this->rebindArray($bindings); |
|
|
|
} |
|
|
|
|
|
|
|
protected function translateType(string $type) { |
|
|
|
switch($type) { |
|
|
|
case "null": |
|
|
|
return \SQLITE3_NULL; |
|
|
|
case "integer": |
|
|
|
return \SQLITE3_INTEGER; |
|
|
|
case "float": |
|
|
|
return \SQLITE3_FLOAT; |
|
|
|
case "date": |
|
|
|
case "time": |
|
|
|
case "datetime": |
|
|
|
return \SQLITE3_TEXT; |
|
|
|
case "binary": |
|
|
|
return \SQLITE3_BLOB; |
|
|
|
case "text": |
|
|
|
return \SQLITE3_TEXT; |
|
|
|
case "boolean": |
|
|
|
return \SQLITE3_INTEGER; |
|
|
|
default: |
|
|
|
throw new Db\Exception("paramTypeUnknown", $binding); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public function rebindArray(array $bindings): bool { |
|
|
|
$this->types = []; |
|
|
|
foreach($bindings as $binding) { |
|
|
|
$binding = trim(strtolower($binding)); |
|
|
|
if(!array_key_exists($binding, self::TYPES)) throw new Db\Exception("paramTypeInvalid", $binding); |
|
|
|
$this->types[] = self::TYPES[$binding]; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |