2017-03-02 23:42:19 +00:00
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
2017-03-28 04:12:12 +00:00
|
|
|
namespace JKingWeb\Arsse\Db;
|
2017-07-17 11:47:57 +00:00
|
|
|
use JKingWeb\Arsse\Misc\Date;
|
2017-03-02 23:42:19 +00:00
|
|
|
|
|
|
|
abstract class AbstractStatement implements Statement {
|
2017-07-07 19:25:47 +00:00
|
|
|
|
2017-05-04 23:12:33 +00:00
|
|
|
protected $types = [];
|
|
|
|
protected $isNullable = [];
|
2017-06-04 22:00:18 +00:00
|
|
|
protected $values = ['pre' => [], 'post' => []];
|
2017-03-02 23:42:19 +00:00
|
|
|
|
2017-06-04 22:00:18 +00:00
|
|
|
abstract function runArray(array $values = []): Result;
|
2017-03-02 23:42:19 +00:00
|
|
|
|
|
|
|
public function run(...$values): Result {
|
|
|
|
return $this->runArray($values);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function rebind(...$bindings): bool {
|
|
|
|
return $this->rebindArray($bindings);
|
|
|
|
}
|
|
|
|
|
2017-04-06 15:02:47 +00:00
|
|
|
public function rebindArray(array $bindings, bool $append = false): bool {
|
|
|
|
if(!$append) $this->types = [];
|
2017-03-02 23:42:19 +00:00
|
|
|
foreach($bindings as $binding) {
|
2017-04-06 15:02:47 +00:00
|
|
|
if(is_array($binding)) {
|
|
|
|
// recursively flatten any arrays, which may be provided for SET or IN() clauses
|
|
|
|
$this->rebindArray($binding, true);
|
|
|
|
} else {
|
|
|
|
$binding = trim(strtolower($binding));
|
2017-05-04 23:12:33 +00:00
|
|
|
if(strpos($binding, "strict ")===0) {
|
|
|
|
// "strict" types' values may never be null; null values will later be cast to the type specified
|
|
|
|
$this->isNullable[] = false;
|
|
|
|
$binding = substr($binding, 7);
|
|
|
|
} else {
|
|
|
|
$this->isNullable[] = true;
|
|
|
|
}
|
2017-04-06 15:02:47 +00:00
|
|
|
if(!array_key_exists($binding, self::TYPES)) throw new Exception("paramTypeInvalid", $binding);
|
|
|
|
$this->types[] = self::TYPES[$binding];
|
|
|
|
}
|
2017-03-02 23:42:19 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-04 23:12:33 +00:00
|
|
|
protected function cast($v, string $t, bool $nullable) {
|
2017-04-07 01:41:21 +00:00
|
|
|
switch($t) {
|
|
|
|
case "date":
|
2017-05-04 23:12:33 +00:00
|
|
|
if(is_null($v) && !$nullable) $v = 0;
|
2017-07-17 11:47:57 +00:00
|
|
|
return Date::transform($v, "date");
|
2017-04-07 01:41:21 +00:00
|
|
|
case "time":
|
2017-05-04 23:12:33 +00:00
|
|
|
if(is_null($v) && !$nullable) $v = 0;
|
2017-07-17 11:47:57 +00:00
|
|
|
return Date::transform($v, "time");
|
2017-04-07 01:41:21 +00:00
|
|
|
case "datetime":
|
2017-05-04 23:12:33 +00:00
|
|
|
if(is_null($v) && !$nullable) $v = 0;
|
2017-07-17 11:47:57 +00:00
|
|
|
return Date::transform($v, "sql");
|
2017-04-07 01:41:21 +00:00
|
|
|
case "null":
|
|
|
|
case "integer":
|
|
|
|
case "float":
|
|
|
|
case "binary":
|
|
|
|
case "string":
|
|
|
|
case "boolean":
|
|
|
|
if($t=="binary") $t = "string";
|
2017-07-08 01:06:38 +00:00
|
|
|
if($v instanceof \DateTimeInterface) {
|
|
|
|
if($t=="string") {
|
2017-07-17 11:47:57 +00:00
|
|
|
return Date::transform($v, "sql");
|
2017-04-07 01:41:21 +00:00
|
|
|
} else {
|
2017-07-08 01:06:38 +00:00
|
|
|
$v = $v->getTimestamp();
|
|
|
|
settype($v, $t);
|
2017-04-07 01:41:21 +00:00
|
|
|
}
|
2017-07-08 01:06:38 +00:00
|
|
|
} else {
|
|
|
|
settype($v, $t);
|
2017-04-07 01:41:21 +00:00
|
|
|
}
|
2017-07-08 01:06:38 +00:00
|
|
|
return $v;
|
2017-04-07 01:41:21 +00:00
|
|
|
default:
|
|
|
|
throw new Exception("paramTypeUnknown", $type);
|
|
|
|
}
|
|
|
|
}
|
2017-03-02 23:42:19 +00:00
|
|
|
}
|