nur-sery/nur_src/m/base/EntityManager.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);
}
}