nur-sery/src/db/sqlite/Sqlite.php
2024-04-25 08:20:33 +04:00

171 lines
4.2 KiB
PHP

<?php
namespace nur\sery\db\sqlite;
use Generator;
use nur\sery\cl;
use SQLite3;
use SQLite3Result;
use SQLite3Stmt;
/**
* Class Sqlite: frontend vers une base de données sqlite3
*/
class Sqlite {
static function config_enableExceptions(self $sqlite) {
$sqlite->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);
}
}
}