modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2025-04-11 18:20:27 +04:00
parent ebbd9e06c0
commit 64c872cf3f
9 changed files with 136 additions and 111 deletions

View File

@ -15,5 +15,9 @@ interface IDatabase extends ITransactor {
function one($query, ?array $params=null): ?array;
/**
* si $primaryKeys est fourni, le résultat est indexé sur la(es) colonne(s)
* spécifiée(s)
*/
function all($query, ?array $params=null, $primaryKeys=null): iterable;
}

View File

@ -6,7 +6,51 @@ use nulib\str;
use nulib\ValueException;
abstract class _base extends _common {
abstract protected static function verifix(&$sql, ?array &$bindings=null, ?array &$meta=null): void;
protected static function verifix(&$sql, ?array &$bindings=null, ?array &$meta=null): void {
if (is_array($sql)) {
$prefix = $sql[0] ?? null;
if ($prefix === null) {
throw new ValueException("requête invalide");
} elseif (_create::isa($prefix)) {
$sql = _create::parse($sql, $bindings);
$meta = ["isa" => "create", "type" => "ddl"];
} elseif (_select::isa($prefix)) {
$sql = _select::parse($sql, $bindings);
$meta = ["isa" => "select", "type" => "dql"];
} elseif (_insert::isa($prefix)) {
$sql = _insert::parse($sql, $bindings);
$meta = ["isa" => "insert", "type" => "dml"];
} elseif (_update::isa($prefix)) {
$sql = _update::parse($sql, $bindings);
$meta = ["isa" => "update", "type" => "dml"];
} elseif (_delete::isa($prefix)) {
$sql = _delete::parse($sql, $bindings);
$meta = ["isa" => "delete", "type" => "dml"];
} elseif (_generic::isa($prefix)) {
$sql = _generic::parse($sql, $bindings);
$meta = ["isa" => "generic", "type" => null];
} else {
throw ValueException::invalid_kind($sql, "query");
}
} else {
if (!is_string($sql)) $sql = strval($sql);
if (_create::isa($sql)) {
$meta = ["isa" => "create", "type" => "ddl"];
} elseif (_select::isa($sql)) {
$meta = ["isa" => "select", "type" => "dql"];
} elseif (_insert::isa($sql)) {
$meta = ["isa" => "insert", "type" => "dml"];
} elseif (_update::isa($sql)) {
$meta = ["isa" => "update", "type" => "dml"];
} elseif (_delete::isa($sql)) {
$meta = ["isa" => "delete", "type" => "dml"];
} elseif (_generic::isa($sql)) {
$meta = ["isa" => "generic", "type" => null];
} else {
$meta = ["isa" => "generic", "type" => null];
}
}
}
static function with($sql, ?array $params=null): array {
static::verifix($sql, $params);

View File

@ -143,11 +143,6 @@ class Pdo implements IDatabase {
return $this->db()->exec($query);
}
private static function is_insert(?string $sql): bool {
if ($sql === null) return false;
return preg_match('/^\s*insert\b/i', $sql);
}
function exec($query, ?array $params=null) {
$db = $this->db();
$query = new query($query, $params);
@ -157,7 +152,7 @@ class Pdo implements IDatabase {
else return $stmt->rowCount();
} else {
$rowCount = $db->exec($sql);
if (self::is_insert($sql)) return $db->lastInsertId();
if ($query->isInsert()) return $db->lastInsertId();
else return $rowCount;
}
}
@ -245,11 +240,7 @@ class Pdo implements IDatabase {
return $this->get($query, $params, true);
}
/**
* si $primaryKeys est fourni, le résultat est indexé sur la(es) colonne(s)
* spécifiée(s)
*/
function all($query, ?array $params=null, $primaryKeys=null): Generator {
function all($query, ?array $params=null, $primaryKeys=null): iterable {
$db = $this->db();
$query = new query($query, $params);
$stmt = null;
@ -260,7 +251,7 @@ class Pdo implements IDatabase {
} else {
$stmt = $db->query($sql);
}
if ($primaryKeys !== null) $primaryKeys = cl::with($primaryKeys);
$primaryKeys = cl::withn($primaryKeys);
while (($row = $stmt->fetch(\PDO::FETCH_ASSOC)) !== false) {
$this->verifixRow($row);
if ($primaryKeys !== null) {

View File

@ -2,64 +2,11 @@
namespace nulib\db\pdo;
use nulib\db\_private\_base;
use nulib\db\_private\_create;
use nulib\db\_private\_delete;
use nulib\db\_private\_generic;
use nulib\db\_private\_insert;
use nulib\db\_private\_select;
use nulib\db\_private\_update;
use nulib\db\_private\Tbindings;
use nulib\ValueException;
class query extends _base {
use Tbindings;
protected static function verifix(&$sql, ?array &$bindings=null, ?array &$meta=null): void {
if (is_array($sql)) {
$prefix = $sql[0] ?? null;
if ($prefix === null) {
throw new ValueException("requête invalide");
} elseif (_create::isa($prefix)) {
$sql = _create::parse($sql, $bindings);
$meta = ["isa" => "create", "type" => "ddl"];
} elseif (_select::isa($prefix)) {
$sql = _select::parse($sql, $bindings);
$meta = ["isa" => "select", "type" => "dql"];
} elseif (_insert::isa($prefix)) {
$sql = _insert::parse($sql, $bindings);
$meta = ["isa" => "insert", "type" => "dml"];
} elseif (_update::isa($prefix)) {
$sql = _update::parse($sql, $bindings);
$meta = ["isa" => "update", "type" => "dml"];
} elseif (_delete::isa($prefix)) {
$sql = _delete::parse($sql, $bindings);
$meta = ["isa" => "delete", "type" => "dml"];
} elseif (_generic::isa($prefix)) {
$sql = _generic::parse($sql, $bindings);
$meta = ["isa" => "generic", "type" => null];
} else {
throw ValueException::invalid_kind($sql, "query");
}
} else {
if (!is_string($sql)) $sql = strval($sql);
if (_create::isa($sql)) {
$meta = ["isa" => "create", "type" => "ddl"];
} elseif (_select::isa($sql)) {
$meta = ["isa" => "select", "type" => "dql"];
} elseif (_insert::isa($sql)) {
$meta = ["isa" => "insert", "type" => "dml"];
} elseif (_update::isa($sql)) {
$meta = ["isa" => "update", "type" => "dml"];
} elseif (_delete::isa($sql)) {
$meta = ["isa" => "delete", "type" => "dml"];
} elseif (_generic::isa($sql)) {
$meta = ["isa" => "generic", "type" => null];
} else {
$meta = ["isa" => "generic", "type" => null];
}
}
}
const DEBUG_QUERIES = false;
function useStmt(\PDO $db, ?\PDOStatement &$stmt=null, ?string &$sql=null): bool {

View File

@ -164,15 +164,27 @@ class Pgsql implements IDatabase {
return $this->db;
}
/**
* @return resource|false
*/
function _exec(string $query) {
return pg_query($this->db(), $query);
function _exec(string $query): bool {
$result = pg_query($this->db(), $query);
if ($result === false) return false;
pg_free_result($result);
return true;
}
function exec($query, ?array $params=null) {
// TODO: Implement exec() method.
$db = $this->db();
$query = new query($query, $params);
$result = $query->_exec($db);
if ($query->isInsert()) {
$result = @pg_query($db, "select lastval()");
if ($result === false) return false;
$lastInsertId = pg_fetch_row($result)[0];
pg_free_result($result);
return $lastInsertId;
}
$affected_rows = pg_affected_rows($result);
pg_free_result($result);
return $affected_rows;
}
/** @var ITransactor[] */
@ -243,14 +255,35 @@ class Pgsql implements IDatabase {
}
function get($query, ?array $params=null, bool $entireRow=false) {
// TODO: Implement get() method.
$db = $this->db();
$query = new query($query, $params);
$result = $query->_exec($db);
$row = pg_fetch_assoc($result);
pg_free_result($result);
if ($row === false) return null;
$this->verifixRow($row);
if ($entireRow) return $row;
else return cl::first($row);
}
function one($query, ?array $params=null): ?array {
// TODO: Implement one() method.
return $this->get($query, $params, true);
}
function all($query, ?array $params=null, $primaryKeys=null): iterable {
// TODO: Implement all() method.
$db = $this->db();
$query = new query($query, $params);
$result = $query->_exec($db);
$primaryKeys = cl::withn($primaryKeys);
while (($row = pg_fetch_assoc($result)) !== false) {
$this->verifixRow($row);
if ($primaryKeys !== null) {
$key = implode("-", cl::select($row, $primaryKeys));
yield $key => $row;
} else {
yield $row;
}
}
pg_free_result($result);
}
}

View File

@ -6,6 +6,10 @@ use RuntimeException;
use SQLite3;
class PgsqlException extends RuntimeException {
static final function last_error($db): self {
return new static(pg_last_error($db));
}
static final function wrap(Exception $e): self {
return new static($e->getMessage(), $e->getCode(), $e);
}

View File

@ -0,0 +1,36 @@
<?php
namespace nulib\db\pgsql;
use nulib\db\_private\_base;
use nulib\db\_private\_create;
use nulib\db\_private\_delete;
use nulib\db\_private\_generic;
use nulib\db\_private\_insert;
use nulib\db\_private\_select;
use nulib\db\_private\_update;
use nulib\db\_private\Tbindings;
use nulib\ValueException;
class query extends _base {
use Tbindings;
const DEBUG_QUERIES = false;
/**
* @return resource
*/
function _exec($db) {
if (static::DEBUG_QUERIES) { #XXX
error_log($this->sql);
//error_log(var_export($this->bindings, true));
}
if ($this->bindings !== null) {
#XXX corriger les bindings et la requête *dans le constructeur*
$result = pg_query_params($db, $this->sql, $this->bindings);
} else {
$result = pg_query($db, $this->sql);
}
if ($result === false) throw PgsqlException::last_error($db);
return $result;
}
}

View File

@ -181,11 +181,6 @@ class Sqlite implements IDatabase {
return $this->db()->exec($query);
}
private static function is_insert(?string $sql): bool {
if ($sql === null) return false;
return preg_match('/^\s*insert\b/i', $sql);
}
function exec($query, ?array $params=null) {
$db = $this->db();
$query = new query($query, $params);
@ -202,7 +197,7 @@ class Sqlite implements IDatabase {
} else {
$result = $db->exec($sql);
if ($result === false) return false;
if (self::is_insert($sql)) return $db->lastInsertRowID();
if ($query->isInsert()) return $db->lastInsertRowID();
else return $db->changes();
}
}
@ -301,7 +296,7 @@ class Sqlite implements IDatabase {
}
protected function _fetchResult(SQLite3Result $result, ?SQLite3Stmt $stmt=null, $primaryKeys=null): Generator {
if ($primaryKeys !== null) $primaryKeys = cl::with($primaryKeys);
$primaryKeys = cl::withn($primaryKeys);
try {
while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) {
$this->verifixRow($row);
@ -318,10 +313,6 @@ class Sqlite implements IDatabase {
}
}
/**
* si $primaryKeys est fourni, le résultat est indexé sur la(es) colonne(s)
* spécifiée(s)
*/
function all($query, ?array $params=null, $primaryKeys=null): iterable {
$db = $this->db();
$query = new query($query, $params);

View File

@ -17,31 +17,6 @@ use SQLite3Stmt;
class query extends _base {
use Tbindings;
protected static function verifix(&$sql, ?array &$bindings=null, ?array &$meta=null): void {
if (is_array($sql)) {
$prefix = $sql[0] ?? null;
if ($prefix === null) {
throw new ValueException("requête invalide");
} elseif (_create::isa($prefix)) {
$sql = _create::parse($sql, $bindings);
} elseif (_select::isa($prefix)) {
$sql = _select::parse($sql, $bindings);
} elseif (_insert::isa($prefix)) {
$sql = _insert::parse($sql, $bindings);
} elseif (_update::isa($prefix)) {
$sql = _update::parse($sql, $bindings);
} elseif (_delete::isa($prefix)) {
$sql = _delete::parse($sql, $bindings);
} elseif (_generic::isa($prefix)) {
$sql = _generic::parse($sql, $bindings);
} else {
throw SqliteException::wrap(ValueException::invalid_kind($sql, "query"));
}
} elseif (!is_string($sql)) {
$sql = strval($sql);
}
}
const DEBUG_QUERIES = false;
function useStmt(SQLite3 $db, ?SQLite3Stmt &$stmt=null, ?string &$sql=null): bool {