From 6a0838d4fa6baa96e5602a5689da787d09ec2e09 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 25 Apr 2024 00:26:40 +0400 Subject: [PATCH] =?UTF-8?q?d=C3=A9but=20query?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/sqlite/Sqlite.php | 120 ++++++++++++++--------------- src/db/sqlite/SqliteConfig.php | 2 +- src/db/sqlite/SqliteMigration.php | 2 +- src/db/sqlite/SqliteQuery.php | 123 ++++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+), 66 deletions(-) create mode 100644 src/db/sqlite/SqliteQuery.php diff --git a/src/db/sqlite/Sqlite.php b/src/db/sqlite/Sqlite.php index db7384b..226b45d 100644 --- a/src/db/sqlite/Sqlite.php +++ b/src/db/sqlite/Sqlite.php @@ -1,7 +1,7 @@ db->enableExceptions(true); } - static function verifix_query(&$query, ?array &$params=null): void { - if (is_array($query)) { - throw IllegalAccessException::not_implemented(); #XXX - } elseif (!is_string($query)) { - $query = strval($query); - } - } - const CONFIG = [ [self::class, "config_enableExceptions"], ]; @@ -61,12 +53,16 @@ class Sqlite { /** @var string */ protected $file; + /** @var int */ protected $flags; + /** @var string */ protected $encryptionKey; + /** @var array|string|callable */ protected $config; + /** @var array|string|callable */ protected $migration; @@ -76,8 +72,8 @@ class Sqlite { function open(): self { if ($this->db === null) { $this->db = new SQLite3($this->file, $this->flags, $this->encryptionKey); - SqliteConfig::with($this->config)->run($this); - SqliteMigration::with($this->migration)->run($this); + SqliteConfig::with($this->config)->configure($this); + SqliteMigration::with($this->migration)->migrate($this); } return $this; } @@ -89,43 +85,46 @@ class Sqlite { } } - function exec($query, ?array $params=null): bool { + 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 $sql): bool { $this->open(); - self::verifix_query($query, $params); + return $this->db->exec($sql); + } + + function exec($sql, ?array $params=null): bool { + $this->open(); + $query = new SqliteQuery($sql, $params); $db = $this->db; - if ($params === null) { - return $db->exec($query); - } else { - /** @var SQLite3Stmt $stmt */ - $stmt = SqliteException::check($db, $db->prepare($query)); + if ($query->useStmt($db, $stmt, $sql)) { try { - foreach ($params as $param => $value) { - SqliteException::check($db, $stmt->bindValue($param, $value)); - } - /** @var SQLite3Result $result */ - $result = SqliteException::check($db, $stmt->execute()); - return $result->finalize(); + return $stmt->execute()->finalize(); } finally { $stmt->close(); } + } else { + return $db->exec($sql); } } - function get($query, ?array $params=null, bool $entireRow=false) { + function _get(string $sql, bool $entireRow=false) { $this->open(); - self::verifix_query($query, $params); + return $this->db->querySingle($sql, $entireRow); + } + + function get($sql, ?array $params=null, bool $entireRow=false) { + $this->open(); + $query = new SqliteQuery($sql, $params); $db = $this->db; - if ($params === null) { - return $db->querySingle($query, $entireRow); - } else { - /** @var SQLite3Stmt $stmt */ - $stmt = SqliteException::check($db, $db->prepare($query)); + if ($query->useStmt($db, $stmt, $sql)) { try { - foreach ($params as $param => $value) { - SqliteException::check($db, $stmt->bindValue($param, $value)); - } - /** @var SQLite3Result $result */ - $result = SqliteException::check($db, $stmt->execute()); + $result = $this->checkResult($stmt->execute()); try { $row = $result->fetchArray(SQLITE3_ASSOC); if ($row === false) return null; @@ -137,42 +136,35 @@ class Sqlite { } finally { $stmt->close(); } + } else { + return $db->querySingle($sql, $entireRow); } } - function all($query, ?array $params=null): iterable { - $this->open(); - self::verifix_query($query, $params); - $db = $this->db; - if ($params === null) { - /** @var SQLite3Result $result */ - $result = SqliteException::check($db, $db->query($query)); - try { - while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) { - yield $row; - } - } finally { - $result->finalize(); + protected function _fetchResult(SQLite3Result $result): Generator { + try { + while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) { + yield $row; } - } else { - /** @var SQLite3Stmt $stmt */ - $stmt = SqliteException::check($db, $db->prepare($query)); + } finally { + $result->finalize(); + } + } + + function all($sql, ?array $params=null): iterable { + $this->open(); + $query = new SqliteQuery($sql, $params); + $db = $this->db; + if ($query->useStmt($db, $stmt, $sql)) { try { - foreach ($params as $param => $value) { - SqliteException::check($db, $stmt->bindValue($param, $value)); - } - /** @var SQLite3Result $result */ - $result = SqliteException::check($db, $stmt->execute()); - try { - while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) { - yield $row; - } - } finally { - $result->finalize(); - } + $result = $this->checkResult($stmt->execute()); + return $this->_fetchResult($result); } finally { $stmt->close(); } + } else { + $result = $this->checkResult($db->query($sql)); + return $this->_fetchResult($result); } } } diff --git a/src/db/sqlite/SqliteConfig.php b/src/db/sqlite/SqliteConfig.php index b5364cb..217c097 100644 --- a/src/db/sqlite/SqliteConfig.php +++ b/src/db/sqlite/SqliteConfig.php @@ -23,7 +23,7 @@ class SqliteConfig { /** @var array */ protected $configs; - function run(Sqlite $sqlite): void { + function configure(Sqlite $sqlite): void { foreach ($this->configs as $key => $config) { if (is_callable($config)) { func::call($config, $sqlite, $key, $this); diff --git a/src/db/sqlite/SqliteMigration.php b/src/db/sqlite/SqliteMigration.php index a315a28..1fc5e08 100644 --- a/src/db/sqlite/SqliteMigration.php +++ b/src/db/sqlite/SqliteMigration.php @@ -23,7 +23,7 @@ class SqliteMigration { /** @var callable[]|string[] */ protected $migrations; - function run(Sqlite $sqlite): void { + function migrate(Sqlite $sqlite): void { $sqlite->exec("create table if not exists _migration(key varchar primary key, value varchar not null, done integer default 0)"); foreach ($this->migrations as $key => $migration) { $exists = $sqlite->get("select 1 from _migration where key = :key and done = 1", [ diff --git a/src/db/sqlite/SqliteQuery.php b/src/db/sqlite/SqliteQuery.php new file mode 100644 index 0000000..5d2edf1 --- /dev/null +++ b/src/db/sqlite/SqliteQuery.php @@ -0,0 +1,123 @@ + "string", + "table" => "string", + "cols" => "array", + "suffix" => "?string", + ]; + static function is_create(string $sql): bool { + } + static function parse_create(array $query, ?array &$params=null): string { + } + + const select_SCHEMA = [ + "prefix" => "string", + "cols" => "?array", + "from" => "?string", + "where" => "?array", + "order by" => "?array", + "group by" => "?array", + "having" => "?array", + ]; + static function is_select(string $sql): bool { + } + static function parse_select(array $query, ?array &$params=null): string { + } + + const insert_SCHEMA = [ + "prefix" => "string", + "into" => "?string", + "cols" => "?array", + "values" => "?array", + ]; + static function is_insert(string $sql): bool { + } + static function parse_insert(array $query, ?array &$params=null): string { + } + + const update_SCHEMA = [ + "prefix" => "string", + "table" => "?string", + "cols" => "?array", + "values" => "?array", + "where" => "?array", + ]; + static function is_update(string $sql): bool { + } + static function parse_update(array $query, ?array &$params=null): string { + } + + const delete_SCHEMA = [ + "prefix" => "string", + "from" => "?string", + "where" => "?array", + ]; + static function is_delete(string $sql): bool { + } + static function parse_delete(array $query, ?array &$params=null): string { + } + + function __construct($sql, ?array $params=null) { + self::verifix($sql, $params); + $this->sql = $sql; + $this->params = $params; + } + + /** @var string */ + protected $sql; + + /** @var ?array */ + protected $params; + + function useStmt(SQLite3 $db, ?SQLite3Stmt &$stmt=null, ?string &$sql=null): bool { + if ($this->params !== null) { + /** @var SQLite3Stmt $stmt */ + $stmt = SqliteException::check($db, $db->prepare($this->sql)); + $close = true; + try { + foreach ($this->params as $param => $value) { + SqliteException::check($db, $stmt->bindValue($param, $value)); + } + $close = false; + return true; + } finally { + if ($close) $stmt->close(); + } + } else { + $sql = $this->sql; + return false; + } + } +}