135 lines
4.2 KiB
PHP
135 lines
4.2 KiB
PHP
<?php
|
|
namespace nur\m\base;
|
|
|
|
use nur\A;
|
|
use nur\b\ValueException;
|
|
use nur\iter;
|
|
use nur\m\IConn;
|
|
|
|
abstract class EntityManager {
|
|
const TABLE_NAME = null;
|
|
const PK_KEY = null;
|
|
const PK_AUTO = null;
|
|
|
|
/**
|
|
* retourner les champs de la clé primaire
|
|
* - soit une valeur chaine si c'est une clé simple
|
|
* - soit un tableau si c'est une clé composite
|
|
*/
|
|
protected static function get_pk_key($row, $pk_key=null) {
|
|
if ($pk_key === null) $pk_key = static::PK_KEY;
|
|
if (is_array($pk_key) && count($pk_key) == 1) $pk_key = iter::first($pk_key);
|
|
if ($pk_key === false) {
|
|
# si $pk_key est false, alors toute la ligne est une clé: prendre les noms
|
|
# des colonnes
|
|
$pk_key = array_keys(A::with($row));
|
|
if (is_array($pk_key) && count($pk_key) == 1) $pk_key = iter::first($pk_key);
|
|
}
|
|
return $pk_key;
|
|
}
|
|
|
|
/**
|
|
* Obtenir la valeur de la clé primaire d'une ligne.
|
|
*
|
|
* - Si $pk_key vaut false, considérer que la clé est l'ensemble des colonnes.
|
|
* - Si la clé est composite, retourner un tableau associatif avec toutes les
|
|
* valeurs
|
|
* - Sinon retourner uniquement la valeur de la clé.
|
|
*/
|
|
protected static function get_pk_value($row, $pk_key=null) {
|
|
$pk_key = self::get_pk_key($row, $pk_key);
|
|
if (is_array($pk_key)) {
|
|
if (!is_array($row)) throw ValueException::invalid_value($row, "row");
|
|
$pk_value = [];
|
|
foreach ($pk_key as $col) {
|
|
$pk_value[$col] = A::get($row, $col);
|
|
}
|
|
return $pk_value;
|
|
} elseif (is_array($row)) {
|
|
return A::get($row, $pk_key);
|
|
} else {
|
|
return $row;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* obtenir un tableau bindings pour filtrer une table sur la valeur de la clé
|
|
* primaire
|
|
*/
|
|
protected static function get_pk_bindings($row, $pk_key=null): array {
|
|
$pk_value = self::get_pk_value($row, $pk_key);
|
|
if (is_array($pk_value)) return $pk_value;
|
|
$pk_key = self::get_pk_key($row, $pk_key);
|
|
return [$pk_key => $pk_value];
|
|
}
|
|
|
|
/**
|
|
* Obtenir la valeur de la clé primaire d'une ligne sous forme de chaine.
|
|
*
|
|
* Si la clé est composite, séparer chaque valeur par un tiret '-' pour faire
|
|
* une seule chaine.
|
|
*/
|
|
protected static function get_pk_string($row, $pk_key=null): string {
|
|
$pk_value = self::get_pk_value($row, $pk_key);
|
|
if (is_array($pk_value)) $pk_string = implode("-", $pk_value);
|
|
else $pk_string = strval($pk_value);
|
|
return $pk_string;
|
|
}
|
|
|
|
protected static function map_pks(iterable $rows, $pk_key=null): array {
|
|
$mapped_rows = [];
|
|
foreach ($rows as $row) {
|
|
$pk_string = self::get_pk_string($row, $pk_key);
|
|
$mapped_rows[$pk_string] = $row;
|
|
}
|
|
return $mapped_rows;
|
|
}
|
|
|
|
protected static function sql_select_all(&$filter=null): string {
|
|
$sql = "select * from ". static::TABLE_NAME;
|
|
if ($filter !== null) {
|
|
if (!is_array($filter)) $filter = self::get_pk_bindings($filter);
|
|
$and = " where";
|
|
foreach ($filter as $col => $value) {
|
|
$sql .= "$and $col = :$col";
|
|
$and = " and";
|
|
}
|
|
}
|
|
return $sql;
|
|
}
|
|
|
|
abstract static function conn(IConn $pdo=null): IConn;
|
|
|
|
static function select_all($filter=null, $map_key=null): array {
|
|
$sql = self::sql_select_all($filter);
|
|
$rows = static::conn()->query($sql, $filter)->execute();
|
|
return self::map_pks($rows, $map_key);
|
|
}
|
|
|
|
static function select_all_val(string $key, $filter=null): array {
|
|
$sql = self::sql_select_all($filter);
|
|
$rows = static::conn()->query($sql, $filter)->execute();
|
|
$vals = [];
|
|
foreach ($rows as $row) {
|
|
$vals[] = A::get($row, $key);
|
|
}
|
|
return $vals;
|
|
}
|
|
|
|
static function select_first($filter=null, $default=null) {
|
|
$sql = self::sql_select_all($filter);
|
|
return static::conn()->query($sql, $filter)->first($default);
|
|
}
|
|
|
|
static function select_first_val(string $key, $filter=null, $default=null) {
|
|
$sql = self::sql_select_all($filter);
|
|
$first = static::conn()->query($sql, $filter)->first($default);
|
|
return A::get($first, $key, $default);
|
|
}
|
|
|
|
static function select_one($filter=null, $default=null, ?bool $rewind=null): array {
|
|
$sql = self::sql_select_all($filter);
|
|
return static::conn()->query($sql, $filter)->one($default, $rewind);
|
|
}
|
|
}
|