\SQLITE3_NULL, "integer" => \SQLITE3_INTEGER, "float" => \SQLITE3_FLOAT, "date" => \SQLITE3_TEXT, "time" => \SQLITE3_TEXT, "datetime" => \SQLITE3_TEXT, "binary" => \SQLITE3_BLOB, "string" => \SQLITE3_TEXT, "boolean" => \SQLITE3_INTEGER, ]; protected $db; protected $st; public function __construct(\SQLite3 $db, \SQLite3Stmt $st, array $bindings = []) { $this->db = $db; $this->st = $st; $this->rebindArray($bindings); } public function __destruct() { try {$this->st->close();} catch(\Throwable $e) {} unset($this->st); } public static function dateFormat(int $part = self::TS_BOTH): string { return ([ self::TS_TIME => 'H:i:s', self::TS_DATE => 'Y-m-d', self::TS_BOTH => 'Y-m-d H:i:s', ])[$part]; } public function runArray(array $values = []): \JKingWeb\Arsse\Db\Result { $this->st->clear(); $this->bindValues($values); try { $r = $this->st->execute(); } catch(\Exception $e) { list($excClass, $excMsg, $excData) = $this->exceptionBuild(); throw new $excClass($excMsg, $excData); } $changes = $this->db->changes(); $lastId = $this->db->lastInsertRowID(); return new Result($r, [$changes, $lastId], $this); } protected function bindValues(array $values, int $offset = 0): int { $a = $offset; foreach($values as $value) { if(is_array($value)) { // recursively flatten any arrays, which may be provided for SET or IN() clauses $a += $this->bindValues($value, $a); } else if(array_key_exists($a,$this->types)) { // if the parameter type is something other than the known values, this is an error if(!array_key_exists($this->types[$a], self::BINDINGS)) throw new Exception("paramTypeUnknown", $this->types[$a]); // if the parameter type is null or the value is null (and the type is nullable), just bind null if($this->types[$a]=="null" || ($this->isNullable[$a] && is_null($value))) { $this->st->bindValue($a+1, null, \SQLITE3_NULL); } else { // otherwise cast the value to the right type and bind the result $type = self::BINDINGS[$this->types[$a]]; $value = $this->cast($value, $this->types[$a], $this->isNullable[$a]); // re-adjust for null casts if($value===null) $type = \SQLITE3_NULL; // perform binding $this->st->bindValue($a+1, $value, $type); } $a++; } else { throw new Exception("paramTypeMissing", $a+1); } } return $a - $offset; } }