db->enableExceptions(true); } const CONFIG = [ [self::class, "config_enableExceptions"], ]; const MIGRATE = null; const SCHEMA = [ "file" => ["string", ""], "flags" => ["int", SQLITE3_OPEN_READWRITE + SQLITE3_OPEN_CREATE], "encryption_key" => ["string", ""], "config" => ["?array|callable"], "migrate" => ["?array|string|callable"], "auto_open" => ["bool", true], ]; function __construct(?string $file=null, ?array $params=null) { if ($file !== null) $params["file"] = $file; ##schéma $default_file = self::SCHEMA["file"][1]; $this->file = strval($params["file"] ?? $default_file); # $default_flags = self::SCHEMA["flags"][1]; $this->flags = intval($params["flags"] ?? $default_flags); # $default_encryptionKey = self::SCHEMA["encryption_key"][1]; $this->encryptionKey = strval($params["encryption_key"] ?? $default_encryptionKey); # configuration $this->config = $params["config"] ?? static::CONFIG; # migrations $this->migration = $params["migrate"] ?? static::MIGRATE; # $default_autoOpen = self::SCHEMA["auto_open"][1]; if ($params["auto_open"] ?? $default_autoOpen) { $this->open(); } } /** @var string */ protected $file; /** @var int */ protected $flags; /** @var string */ protected $encryptionKey; /** @var array|string|callable */ protected $config; /** @var array|string|callable */ protected $migration; /** @var SQLite3 */ protected $db; function open(): self { if ($this->db === null) { $this->db = new SQLite3($this->file, $this->flags, $this->encryptionKey); _Config::with($this->config)->configure($this); _Migration::with($this->migration)->migrate($this); } return $this; } function close(): void { if ($this->db !== null) { $this->db->close(); $this->db = null; } } protected function checkStmt($stmt): SQLite3Stmt { return SqliteException::check($this->db, $stmt); } protected function checkResult($result): SQLite3Result { return SqliteException::check($this->db, $result); } function _exec(string $query): bool { $this->open(); return $this->db->exec($query); } function exec($query, ?array $params=null): bool { $this->open(); $query = new _Query($query, $params); $db = $this->db; if ($query->useStmt($db, $stmt, $sql)) { try { return $stmt->execute()->finalize(); } finally { $stmt->close(); } } else { return $db->exec($sql); } } function _get(string $query, bool $entireRow=false) { $this->open(); return $this->db->querySingle($query, $entireRow); } function get($query, ?array $params=null, bool $entireRow=false) { $this->open(); $query = new _Query($query, $params); $db = $this->db; if ($query->useStmt($db, $stmt, $sql)) { try { $result = $this->checkResult($stmt->execute()); try { $row = $result->fetchArray(SQLITE3_ASSOC); if ($row === false) return null; elseif ($entireRow) return $row; else return cl::first($row); } finally { $result->finalize(); } } finally { $stmt->close(); } } else { return $db->querySingle($sql, $entireRow); } } protected function _fetchResult(SQLite3Result $result): Generator { try { while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) { yield $row; } } finally { $result->finalize(); } } function all($query, ?array $params=null): iterable { $this->open(); $query = new _Query($query, $params); $db = $this->db; if ($query->useStmt($db, $stmt, $sql)) { try { $result = $this->checkResult($stmt->execute()); return $this->_fetchResult($result); } finally { $stmt->close(); } } else { $result = $this->checkResult($db->query($sql)); return $this->_fetchResult($result); } } }