From f2d6c72a2e31e9a381e77a9b55e832f17358dc52 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 3 May 2024 13:23:01 +0400 Subject: [PATCH] suite select --- src/db/sqlite/_Query.php | 74 ++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/src/db/sqlite/_Query.php b/src/db/sqlite/_Query.php index d66ae15..63236b9 100644 --- a/src/db/sqlite/_Query.php +++ b/src/db/sqlite/_Query.php @@ -79,22 +79,67 @@ class _Query { static function is_select(string $sql): bool { return false; } + + /** + * parser une chaine de la forme + * "select [COLS] [from TABLE] [where CONDS] [order by ORDERS] [group by GROUPS] [having CONDS]" + */ static function parse_select(array $query, ?array &$params=null): string { # fusionner d'abord toutes les parties séquentielles $usersql = $tmpsql = self::merge_seq($query); - # vérifier la présence des parties nécessaires + ## vérifier la présence des parties nécessaires $sql = []; if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix; + # select self::consume('select\s*', $tmpsql); $sql[] = "select"; - if (self::consume('(.*)\s*(?:\s+(from)\s*(?:\s+([a-z_][a-z0-9_]*)\s*(?:(\S+.*)\s*(?:\s+(where)\s*)?)?)?)?', $tmpsql, $ms)) { - $usercols = $ms[1]; - $userfrom = $ms[2]; - $usertable = $ms[3]; - $userjoins = $ms[4]; - $userwhere = $ms[5]; - } else { - throw new ValueException("expected select query: $usersql"); + # cols + $usercols = []; + if (self::consume('(.*)\s*(?<=$|\bfrom\b)', $tmpsql, $ms)) { + if ($ms[1]) $usercols[] = $ms[1]; } + $tmpcols = cl::withn($query["cols"] ?? null); + $schema = $query["schema"] ?? null; + if ($tmpcols !== null) { + $cols = []; + $index = 0; + foreach ($tmpcols as $key => $col) { + if ($key === $index) { + $index++; + $cols[] = $col; + $usercols[] = $col; + } else { + $cols[] = $key; + $usercols[] = "$col as $key"; + } + } + } else { + $cols = null; + if ($schema && is_array($schema)) { + $cols = array_keys($schema); + $usercols = array_merge($usercols, $cols); + } + } + $sql[] = implode(" ", $usercols); + # from + $from = $query["from"] ?? null; + if (self::consume('from\s+([a-z_][a-z0-9_]*)\s*(?<=;?\s*$|\bwhere\b)', $tmpsql, $ms)) { + if ($from === null) $from = $ms[1]; + $sql[] = $from; + } elseif ($from !== null) { + $sql[] = $from; + } else { + throw new ValueException("expected table name: $usersql"); + } + # where + $userwhere = []; + if (self::consume('where\s*(.*)(?<=;?\s*$|\border\s+by\b)', $tmpsql, $ms)) { + if ($ms[1]) $userwhere[] = $ms[1]; + } + $where = cl::withn($query["where"] ?? null); + + # order by + # group by + # having self::consume(';\s*', $tmpsql); if ($tmpsql) { throw new ValueException("unexpected value at end: $usersql"); @@ -112,6 +157,11 @@ class _Query { static function is_insert(string $sql): bool { return preg_match("/^insert\b/i", $sql); } + + /** + * parser une chaine de la forme + * "insert [into] [TABLE] [(COLS)] [values (VALUES)]" + */ static function parse_insert(array $query, ?array &$params=null): string { # fusionner d'abord toutes les parties séquentielles $usersql = $tmpsql = self::merge_seq($query); @@ -120,9 +170,11 @@ class _Query { if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix; self::consume('insert\s*', $tmpsql); $sql[] = "insert"; self::consume('into\s*', $tmpsql); $sql[] = "into"; + $into = $query["into"] ?? null; if (self::consume('([a-z_][a-z0-9_]*)\s*', $tmpsql, $ms)) { - $sql[] = $ms[1]; - } elseif (($into = $query["into"] ?? null) !== null) { + if ($into === null) $into = $ms[1]; + $sql[] = $into; + } elseif ($into !== null) { $sql[] = $into; } else { throw new ValueException("expected table name: $usersql");