implémenter insert
This commit is contained in:
parent
2d8a19e232
commit
bdc0ce23ed
|
@ -93,14 +93,14 @@ class Sqlite {
|
||||||
return SqliteException::check($this->db, $result);
|
return SqliteException::check($this->db, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _exec(string $sql): bool {
|
function _exec(string $query): bool {
|
||||||
$this->open();
|
$this->open();
|
||||||
return $this->db->exec($sql);
|
return $this->db->exec($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exec($sql, ?array $params=null): bool {
|
function exec($query, ?array $params=null): bool {
|
||||||
$this->open();
|
$this->open();
|
||||||
$query = new _Query($sql, $params);
|
$query = new _Query($query, $params);
|
||||||
$db = $this->db;
|
$db = $this->db;
|
||||||
if ($query->useStmt($db, $stmt, $sql)) {
|
if ($query->useStmt($db, $stmt, $sql)) {
|
||||||
try {
|
try {
|
||||||
|
@ -113,14 +113,14 @@ class Sqlite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _get(string $sql, bool $entireRow=false) {
|
function _get(string $query, bool $entireRow=false) {
|
||||||
$this->open();
|
$this->open();
|
||||||
return $this->db->querySingle($sql, $entireRow);
|
return $this->db->querySingle($query, $entireRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get($sql, ?array $params=null, bool $entireRow=false) {
|
function get($query, ?array $params=null, bool $entireRow=false) {
|
||||||
$this->open();
|
$this->open();
|
||||||
$query = new _Query($sql, $params);
|
$query = new _Query($query, $params);
|
||||||
$db = $this->db;
|
$db = $this->db;
|
||||||
if ($query->useStmt($db, $stmt, $sql)) {
|
if ($query->useStmt($db, $stmt, $sql)) {
|
||||||
try {
|
try {
|
||||||
|
@ -151,9 +151,9 @@ class Sqlite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function all($sql, ?array $params=null): iterable {
|
function all($query, ?array $params=null): iterable {
|
||||||
$this->open();
|
$this->open();
|
||||||
$query = new _Query($sql, $params);
|
$query = new _Query($query, $params);
|
||||||
$db = $this->db;
|
$db = $this->db;
|
||||||
if ($query->useStmt($db, $stmt, $sql)) {
|
if ($query->useStmt($db, $stmt, $sql)) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -25,10 +25,11 @@ class _Config {
|
||||||
|
|
||||||
function configure(Sqlite $sqlite): void {
|
function configure(Sqlite $sqlite): void {
|
||||||
foreach ($this->configs as $key => $config) {
|
foreach ($this->configs as $key => $config) {
|
||||||
if (is_callable($config)) {
|
if (is_string($config) && !func::is_method($config)) {
|
||||||
func::call($config, $sqlite, $key, $this);
|
|
||||||
} else {
|
|
||||||
$sqlite->exec($config);
|
$sqlite->exec($config);
|
||||||
|
} else {
|
||||||
|
func::ensure_func($config, $this, $args);
|
||||||
|
func::call($config, $sqlite, $key, ...$args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,11 @@ class _Migration {
|
||||||
"value" => $migration,
|
"value" => $migration,
|
||||||
"done" => 0,
|
"done" => 0,
|
||||||
]);
|
]);
|
||||||
if (is_callable($migration)) {
|
if (is_string($migration) && !func::is_method($migration)) {
|
||||||
func::call($migration, $sqlite, $key, $this);
|
|
||||||
} else {
|
|
||||||
$sqlite->exec($migration);
|
$sqlite->exec($migration);
|
||||||
|
} else {
|
||||||
|
func::ensure_func($migration, $this, $args);
|
||||||
|
func::call($migration, $sqlite, $key, ...$args);
|
||||||
}
|
}
|
||||||
$sqlite->exec("update _migration set done = 1 where key = :key", [
|
$sqlite->exec("update _migration set done = 1 where key = :key", [
|
||||||
"key" => $key,
|
"key" => $key,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\db\sqlite;
|
namespace nur\sery\db\sqlite;
|
||||||
|
|
||||||
use nur\sery\StateException;
|
use nur\sery\cl;
|
||||||
|
use nur\sery\str;
|
||||||
use nur\sery\ValueException;
|
use nur\sery\ValueException;
|
||||||
use SQLite3;
|
use SQLite3;
|
||||||
use SQLite3Stmt;
|
use SQLite3Stmt;
|
||||||
|
@ -9,7 +10,6 @@ use SQLite3Stmt;
|
||||||
class _Query {
|
class _Query {
|
||||||
static function verifix(&$query, ?array &$params=null): void {
|
static function verifix(&$query, ?array &$params=null): void {
|
||||||
if (is_array($query)) {
|
if (is_array($query)) {
|
||||||
throw StateException::not_implemented(); #XXX
|
|
||||||
$prefix = $query[0] ?? null;
|
$prefix = $query[0] ?? null;
|
||||||
if ($prefix === null) {
|
if ($prefix === null) {
|
||||||
throw new ValueException("requête invalide");
|
throw new ValueException("requête invalide");
|
||||||
|
@ -31,19 +31,28 @@ class _Query {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function consume(string $pattern, string &$string, ?array &$ms=null): bool {
|
||||||
|
if (!preg_match("/^$pattern/i", $string, $ms)) return false;
|
||||||
|
$string = substr($string, strlen($ms[0]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const create_SCHEMA = [
|
const create_SCHEMA = [
|
||||||
"prefix" => "string",
|
"prefix" => "string",
|
||||||
"table" => "string",
|
"table" => "string",
|
||||||
"cols" => "array",
|
"schema" => "?array",
|
||||||
|
"cols" => "?array",
|
||||||
"suffix" => "?string",
|
"suffix" => "?string",
|
||||||
];
|
];
|
||||||
static function is_create(string $sql): bool {
|
static function is_create(string $sql): bool {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
static function parse_create(array $query, ?array &$params=null): string {
|
static function parse_create(array $query, ?array &$params=null): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const select_SCHEMA = [
|
const select_SCHEMA = [
|
||||||
"prefix" => "string",
|
"prefix" => "string",
|
||||||
|
"schema" => "?array",
|
||||||
"cols" => "?array",
|
"cols" => "?array",
|
||||||
"from" => "?string",
|
"from" => "?string",
|
||||||
"where" => "?array",
|
"where" => "?array",
|
||||||
|
@ -52,6 +61,7 @@ class _Query {
|
||||||
"having" => "?array",
|
"having" => "?array",
|
||||||
];
|
];
|
||||||
static function is_select(string $sql): bool {
|
static function is_select(string $sql): bool {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
static function parse_select(array $query, ?array &$params=null): string {
|
static function parse_select(array $query, ?array &$params=null): string {
|
||||||
}
|
}
|
||||||
|
@ -59,22 +69,90 @@ class _Query {
|
||||||
const insert_SCHEMA = [
|
const insert_SCHEMA = [
|
||||||
"prefix" => "string",
|
"prefix" => "string",
|
||||||
"into" => "?string",
|
"into" => "?string",
|
||||||
|
"schema" => "?array",
|
||||||
"cols" => "?array",
|
"cols" => "?array",
|
||||||
"values" => "?array",
|
"values" => "?array",
|
||||||
];
|
];
|
||||||
static function is_insert(string $sql): bool {
|
static function is_insert(string $sql): bool {
|
||||||
|
return preg_match("/^insert\b/i", $sql);
|
||||||
}
|
}
|
||||||
static function parse_insert(array $query, ?array &$params=null): string {
|
static function parse_insert(array $query, ?array &$params=null): string {
|
||||||
|
# fusionner d'abord toutes les parties séquentielles
|
||||||
|
$index = 0;
|
||||||
|
$tmpsql = "";
|
||||||
|
foreach ($query as $key => $value) {
|
||||||
|
if ($key === $index) {
|
||||||
|
$index++;
|
||||||
|
if ($tmpsql && !str::ends_with(" ", $tmpsql) && !str::starts_with(" ", $value)) {
|
||||||
|
$tmpsql .= " ";
|
||||||
|
}
|
||||||
|
$tmpsql .= $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$usersql = $tmpsql;
|
||||||
|
# vérifier la présence des parties nécessaires
|
||||||
|
$sql = [];
|
||||||
|
if (($prefix = $query["prefix"] ?? null) !== null) {
|
||||||
|
$sql["prefix"] = $prefix;
|
||||||
|
}
|
||||||
|
self::consume('insert\s*', $tmpsql); $sql[] = "insert";
|
||||||
|
self::consume('into\s*', $tmpsql); $sql[] = "into";
|
||||||
|
if (self::consume('([a-z_][a-z0-9_]*)\s*', $tmpsql, $ms)) {
|
||||||
|
$sql[] = $ms[1];
|
||||||
|
} elseif (($into = $query["into"] ?? null) !== null) {
|
||||||
|
$sql[] = $into;
|
||||||
|
} else {
|
||||||
|
throw new ValueException("expected table name: $usersql");
|
||||||
|
}
|
||||||
|
$xcols = [];
|
||||||
|
$xvalues = [];
|
||||||
|
if (self::consume('\(([^)]*)\)\s*', $tmpsql, $ms)) {
|
||||||
|
$xcols = array_merge($xcols, preg_split("/\s*,\s*/", $ms[1]));
|
||||||
|
}
|
||||||
|
$cols = cl::withn($query["cols"] ?? null);
|
||||||
|
$values = cl::withn($query["values"] ?? null);
|
||||||
|
$schema = $query["schema"] ?? null;
|
||||||
|
if ($cols === null) {
|
||||||
|
if ($xcols) {
|
||||||
|
$cols = $xcols;
|
||||||
|
} elseif ($values) {
|
||||||
|
$cols = array_keys($values);
|
||||||
|
$xcols = array_merge($xcols, $cols);
|
||||||
|
} elseif ($schema && is_array($schema)) {
|
||||||
|
#XXX implémenter support AssocSchema
|
||||||
|
$cols = array_keys($schema);
|
||||||
|
$xcols = array_merge($xcols, $cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self::consume('values\s+\(\s*(.*)\s*\)\s*', $tmpsql, $ms)) {
|
||||||
|
if ($ms[1]) $xvalues[] = $ms[1];
|
||||||
|
}
|
||||||
|
self::consume(';\s*', $tmpsql);
|
||||||
|
if ($tmpsql) {
|
||||||
|
throw new ValueException("unexpected value at end: $usersql");
|
||||||
|
}
|
||||||
|
if ($cols !== null && !$xvalues) {
|
||||||
|
if (!$xcols) $xcols = $cols;
|
||||||
|
foreach ($cols as $col) {
|
||||||
|
$xvalues[] = ":$col";
|
||||||
|
$params[$col] = $values[$col] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql[] = "(".implode(", ", $xcols).")";
|
||||||
|
$sql[] = "values (".implode(", ", $xvalues).")";
|
||||||
|
return implode(" ", $sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
const update_SCHEMA = [
|
const update_SCHEMA = [
|
||||||
"prefix" => "string",
|
"prefix" => "string",
|
||||||
"table" => "?string",
|
"table" => "?string",
|
||||||
|
"schema" => "?array",
|
||||||
"cols" => "?array",
|
"cols" => "?array",
|
||||||
"values" => "?array",
|
"values" => "?array",
|
||||||
"where" => "?array",
|
"where" => "?array",
|
||||||
];
|
];
|
||||||
static function is_update(string $sql): bool {
|
static function is_update(string $sql): bool {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
static function parse_update(array $query, ?array &$params=null): string {
|
static function parse_update(array $query, ?array &$params=null): string {
|
||||||
}
|
}
|
||||||
|
@ -85,6 +163,7 @@ class _Query {
|
||||||
"where" => "?array",
|
"where" => "?array",
|
||||||
];
|
];
|
||||||
static function is_delete(string $sql): bool {
|
static function is_delete(string $sql): bool {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
static function parse_delete(array $query, ?array &$params=null): string {
|
static function parse_delete(array $query, ?array &$params=null): string {
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,4 +33,33 @@ class SqliteTest extends TestCase {
|
||||||
["key" => "1", "value" => self::INSERT_JEPHTE, "done" => 1],
|
["key" => "1", "value" => self::INSERT_JEPHTE, "done" => 1],
|
||||||
], iterator_to_array($sqlite->all("select key, value, done from _migration")));
|
], iterator_to_array($sqlite->all("select key, value, done from _migration")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testInsert() {
|
||||||
|
$sqlite = new Sqlite(":memory:", [
|
||||||
|
"migrate" => "create table mapping (i integer, s varchar)"
|
||||||
|
]);
|
||||||
|
$sqlite->exec(["insert into mapping", "values" => ["i" => 1, "s" => "un"]]);
|
||||||
|
$sqlite->exec(["insert mapping", "values" => ["i" => 2, "s" => "deux"]]);
|
||||||
|
$sqlite->exec(["insert into", "into" => "mapping", "values" => ["i" => 3, "s" => "trois"]]);
|
||||||
|
$sqlite->exec(["insert", "into" => "mapping", "values" => ["i" => 4, "s" => "quatre"]]);
|
||||||
|
$sqlite->exec(["insert into mapping(i)", "values" => ["i" => 5, "s" => "cinq"]]);
|
||||||
|
$sqlite->exec(["insert into (i)", "into" => "mapping", "values" => ["i" => 6, "s" => "six"]]);
|
||||||
|
$sqlite->exec(["insert into mapping(i) values ()", "values" => ["i" => 7, "s" => "sept"]]);
|
||||||
|
$sqlite->exec(["insert into mapping(i) values (8)", "values" => ["i" => 42, "s" => "whatever"]]);
|
||||||
|
$sqlite->exec(["insert into mapping(i, s) values (9, 'neuf')", "values" => ["i" => 43, "s" => "garbage"]]);
|
||||||
|
$sqlite->exec(["insert into mapping", "cols" => ["i"], "values" => ["i" => 10, "s" => "dix"]]);
|
||||||
|
|
||||||
|
self::assertSame([
|
||||||
|
["i" => 1, "s" => "un"],
|
||||||
|
["i" => 2, "s" => "deux"],
|
||||||
|
["i" => 3, "s" => "trois"],
|
||||||
|
["i" => 4, "s" => "quatre"],
|
||||||
|
["i" => 5, "s" => null/*"cinq"*/],
|
||||||
|
["i" => 6, "s" => null/*"six"*/],
|
||||||
|
["i" => 7, "s" => null/*"sept"*/],
|
||||||
|
["i" => 8, "s" => null/*"huit"*/],
|
||||||
|
["i" => 9, "s" => "neuf"],
|
||||||
|
["i" => 10, "s" => null/*"dix"*/],
|
||||||
|
], iterator_to_array($sqlite->all("select * from mapping")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue