171 lines
4.2 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|