92 lines
2.6 KiB
PHP
92 lines
2.6 KiB
PHP
<?php
|
|
namespace nulib\db\_private;
|
|
|
|
use nulib\cl;
|
|
use nulib\ValueException;
|
|
|
|
class _insert extends _common {
|
|
const SCHEMA = [
|
|
"prefix" => "?string",
|
|
"into" => "?string",
|
|
"schema" => "?array",
|
|
"cols" => "?array",
|
|
"values" => "?array",
|
|
"suffix" => "?string",
|
|
];
|
|
|
|
static function isa(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(array $query, ?array &$bindings=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
|
|
$sql = [];
|
|
if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix;
|
|
|
|
## insert
|
|
self::consume('(insert(?:\s+or\s+(?:ignore|replace))?)\s*', $tmpsql, $ms);
|
|
$sql[] = $ms[1];
|
|
|
|
## into
|
|
self::consume('into\s*', $tmpsql);
|
|
$sql[] = "into";
|
|
$into = $query["into"] ?? null;
|
|
if (self::consume('([a-z_][a-z0-9_]*)\s*', $tmpsql, $ms)) {
|
|
if ($into === null) $into = $ms[1];
|
|
$sql[] = $into;
|
|
} elseif ($into !== null) {
|
|
$sql[] = $into;
|
|
} else {
|
|
throw new ValueException("expected table name: $usersql");
|
|
}
|
|
|
|
## cols & values
|
|
$usercols = [];
|
|
$uservalues = [];
|
|
if (self::consume('\(([^)]*)\)\s*', $tmpsql, $ms)) {
|
|
$usercols = array_merge($usercols, 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 ($usercols) {
|
|
$cols = $usercols;
|
|
} elseif ($values) {
|
|
$cols = array_keys($values);
|
|
$usercols = array_merge($usercols, $cols);
|
|
} elseif ($schema && is_array($schema)) {
|
|
#XXX implémenter support AssocSchema
|
|
$cols = array_keys($schema);
|
|
$usercols = array_merge($usercols, $cols);
|
|
}
|
|
}
|
|
if (self::consume('values\s+\(\s*(.*)\s*\)\s*', $tmpsql, $ms)) {
|
|
if ($ms[1]) $uservalues[] = $ms[1];
|
|
}
|
|
if ($cols !== null && !$uservalues) {
|
|
if (!$usercols) $usercols = $cols;
|
|
foreach ($cols as $col) {
|
|
$uservalues[] = ":$col";
|
|
$bindings[$col] = $values[$col] ?? null;
|
|
}
|
|
}
|
|
$sql[] = "(" . implode(", ", $usercols) . ")";
|
|
$sql[] = "values (" . implode(", ", $uservalues) . ")";
|
|
|
|
## suffixe
|
|
if (($suffix = $query["suffix"] ?? null) !== null) $sql[] = $suffix;
|
|
|
|
## fin de la requête
|
|
self::check_eof($tmpsql, $usersql);
|
|
return implode(" ", $sql);
|
|
}
|
|
}
|