DB: add support of joins in get_many() / get_one() helper methods
This commit is contained in:
parent
28e6397f58
commit
ea66e9d217
1 changed files with 107 additions and 28 deletions
135
src/Db.php
135
src/Db.php
|
@ -129,31 +129,29 @@ class Db {
|
|||
|
||||
/**
|
||||
* Helper to retreive one row from a table of the database
|
||||
* @param string $table The table name
|
||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
||||
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||
* array (optional, default: all table fields will be returned)
|
||||
* @param string $table The table name
|
||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
||||
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||
* array (optional, default: all table fields will be returned)
|
||||
* @param array<array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string}>|array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string} $joins Join specification as array (see apply_joins())
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_one($table, $where, $fields=null) {
|
||||
public function get_one($table, $where, $fields=null, $joins=null) {
|
||||
try {
|
||||
$query = $this -> fpdo -> from($table) -> where($where);
|
||||
if ($joins)
|
||||
self :: apply_joins($query, $joins);
|
||||
if ($fields)
|
||||
$query -> select(null) -> select($fields);
|
||||
if ($query->execute() === false) // @phpstan-ignore-line
|
||||
if ($query->execute() === false)
|
||||
return false;
|
||||
$return = $query->fetchAll();
|
||||
if (is_array($return) && count($return) == 1)
|
||||
return $return[0];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
Log :: error(
|
||||
"Error occured getting one row of the table %s in database (where %s): %s",
|
||||
$table,
|
||||
is_array($where)?
|
||||
preg_replace("/\n */", " ", print_r($where, true)):
|
||||
vardump($where),
|
||||
$e->getMessage()
|
||||
self :: _log_simple_select_query_error(
|
||||
false, $table, $e, $where, $fields, null, null, $joins
|
||||
);
|
||||
}
|
||||
return false;
|
||||
|
@ -162,44 +160,125 @@ class Db {
|
|||
|
||||
/**
|
||||
* Helper to retreive multiple rows from a table of the database
|
||||
* @param string $table The table name
|
||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
||||
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||
* array (optional, default: all table fields will be returned)
|
||||
* @param string|null $order_by An optional ORDER clause as a string
|
||||
* @param string|null $limit An optional LIMIT clause as a string
|
||||
* @param string $table The table name
|
||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
||||
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||
* array (optional, default: all table fields will be returned)
|
||||
* @param string|null $order_by An optional ORDER clause as a string
|
||||
* @param string|null $limit An optional LIMIT clause as a string
|
||||
* @param array<array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string}>|array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string} $joins Join specification as array (see apply_joins())
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_many(
|
||||
$table, $where=null, $fields=null, $order_by=null, $limit=null
|
||||
$table, $where=null, $fields=null, $order_by=null, $limit=null, $joins=null
|
||||
) {
|
||||
try {
|
||||
$query = $this -> fpdo -> from($table);
|
||||
if ($joins)
|
||||
self :: apply_joins($query, $joins);
|
||||
if ($fields)
|
||||
$query -> select(null) -> select($fields);
|
||||
if ($where)
|
||||
$query -> where($where);
|
||||
if ($order_by)
|
||||
$query -> orderBy($order_by);
|
||||
if ($query->execute() === false) // @phpstan-ignore-line
|
||||
if ($query->execute() === false)
|
||||
return false;
|
||||
$return = $query->fetchAll();
|
||||
if (is_array($return))
|
||||
return $return;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
Log :: error(
|
||||
"Error occured getting rows of the table %s in database (where %s): %s",
|
||||
$table,
|
||||
is_array($where)?
|
||||
preg_replace("/\n */", " ", print_r($where, true)):
|
||||
vardump($where),
|
||||
$e->getMessage()
|
||||
self :: _log_simple_select_query_error(
|
||||
false, $table, $e, $where, $fields, $order_by, $limit, $joins
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of JOIN type with corresponding query object method
|
||||
* @var array<string,string>
|
||||
*/
|
||||
private static $join_type_to_query_method = array(
|
||||
'LEFT' => 'leftJoin',
|
||||
'RIGHT' => 'rightJoin',
|
||||
'INNER' => 'innerJoin',
|
||||
'OUTER' => 'outerJoin',
|
||||
'FULL' => 'fullJoin',
|
||||
);
|
||||
|
||||
/**
|
||||
* Apply JOIN clauses on a query object
|
||||
* @param \Envms\FluentPDO\Query $query The reference of the query object
|
||||
* @param array<array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string}>|array{0: 'LEFT'|'RIGHT'|'INNER'|'OUTER'|'FULL', 1: string, 2: string} $joins Join specification as array: ['type', 'table', 'ON clause']
|
||||
* - type: LEFT, RIGHT, INNER, OUTER or FULL
|
||||
* - table: the joined table name
|
||||
* - ON clause: the ON clause (ex: "user.id = article.user_id")
|
||||
* @return void
|
||||
*/
|
||||
public static function apply_joins(&$query, &$joins) {
|
||||
if (!$joins) return;
|
||||
if (isset($joins[0]) && !is_array($joins[0]))
|
||||
$joins = [$joins];
|
||||
foreach ($joins as $join) {
|
||||
if (!is_array($join) || count($join) != 3) {
|
||||
throw new Exception(sprintf("Invalid JOIN clause provided: %s", vardump($join)));
|
||||
}
|
||||
if (!array_key_exists(strtoupper($join[0]), self :: $join_type_to_query_method)) {
|
||||
throw new Exception(sprintf("Invalid JOIN type '%s'", $join[0]));
|
||||
}
|
||||
$method = self :: $join_type_to_query_method[strtoupper($join[0])];
|
||||
call_user_func([$query, $method], sprintf("%s ON %s", $join[1], $join[2]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to log error during simple select query
|
||||
* @param bool $multiple True if expected multiple rows, False instead
|
||||
* @param string $table The table name
|
||||
* @param Exception $e The exception
|
||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
||||
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||
* array (optional, default: all table fields will be returned)
|
||||
* @param string|null $order_by An optional ORDER clause as a string
|
||||
* @param string|null $limit An optional LIMIT clause as a string
|
||||
* @param array<array<string>>|null $joins Join specification as array (see apply_joins())
|
||||
* @return void
|
||||
*/
|
||||
private function _log_simple_select_query_error(
|
||||
$multiple, $table, $e, $where=null, $fields=null, $order_by=null, $limit=null, $joins=null
|
||||
) {
|
||||
$msg = "Error occured getting %s of the table %s";
|
||||
$params = [
|
||||
$multiple?"rows":"one row",
|
||||
$table,
|
||||
];
|
||||
if (is_array($joins)) {
|
||||
foreach($joins as $join) {
|
||||
$msg .= ", %s join with table %s on '%s'";
|
||||
$params = array_merge($params, $join);
|
||||
}
|
||||
}
|
||||
$extra_clauses = [];
|
||||
if ($where)
|
||||
$extra_clauses['where'] = (
|
||||
is_array($where)?
|
||||
preg_replace("/\n */", " ", print_r($where, true)):
|
||||
vardump($where)
|
||||
);
|
||||
if ($fields)
|
||||
$extra_clauses['selected fields'] = is_array($fields)?implode(',', $fields):$fields;
|
||||
if ($order_by)
|
||||
$extra_clauses['order by'] = $order_by;
|
||||
if ($limit)
|
||||
$extra_clauses['limit'] = $limit;
|
||||
$msg .= "in database (%s): %s";
|
||||
$params[] = implode_with_keys($extra_clauses);
|
||||
$params[] = $e->getMessage();
|
||||
Log :: error($msg, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to insert a row in a table
|
||||
* @param string $table The table name
|
||||
|
|
Loading…
Reference in a new issue