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
115
src/Db.php
115
src/Db.php
|
@ -133,27 +133,25 @@ class Db {
|
||||||
* @param array|string $where WHERE clause(s) as expected by Envms\FluentPDO\Query
|
* @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
|
* @param array|string|null $fields The expected fields as string (separeted by comma) or an
|
||||||
* array (optional, default: all table fields will be returned)
|
* 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
|
* @return array|false
|
||||||
*/
|
*/
|
||||||
public function get_one($table, $where, $fields=null) {
|
public function get_one($table, $where, $fields=null, $joins=null) {
|
||||||
try {
|
try {
|
||||||
$query = $this -> fpdo -> from($table) -> where($where);
|
$query = $this -> fpdo -> from($table) -> where($where);
|
||||||
|
if ($joins)
|
||||||
|
self :: apply_joins($query, $joins);
|
||||||
if ($fields)
|
if ($fields)
|
||||||
$query -> select(null) -> select($fields);
|
$query -> select(null) -> select($fields);
|
||||||
if ($query->execute() === false) // @phpstan-ignore-line
|
if ($query->execute() === false)
|
||||||
return false;
|
return false;
|
||||||
$return = $query->fetchAll();
|
$return = $query->fetchAll();
|
||||||
if (is_array($return) && count($return) == 1)
|
if (is_array($return) && count($return) == 1)
|
||||||
return $return[0];
|
return $return[0];
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
Log :: error(
|
self :: _log_simple_select_query_error(
|
||||||
"Error occured getting one row of the table %s in database (where %s): %s",
|
false, $table, $e, $where, $fields, null, null, $joins
|
||||||
$table,
|
|
||||||
is_array($where)?
|
|
||||||
preg_replace("/\n */", " ", print_r($where, true)):
|
|
||||||
vardump($where),
|
|
||||||
$e->getMessage()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -168,38 +166,119 @@ class Db {
|
||||||
* array (optional, default: all table fields will be returned)
|
* array (optional, default: all table fields will be returned)
|
||||||
* @param string|null $order_by An optional ORDER clause as a string
|
* @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|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
|
* @return array|false
|
||||||
*/
|
*/
|
||||||
public function get_many(
|
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 {
|
try {
|
||||||
$query = $this -> fpdo -> from($table);
|
$query = $this -> fpdo -> from($table);
|
||||||
|
if ($joins)
|
||||||
|
self :: apply_joins($query, $joins);
|
||||||
if ($fields)
|
if ($fields)
|
||||||
$query -> select(null) -> select($fields);
|
$query -> select(null) -> select($fields);
|
||||||
if ($where)
|
if ($where)
|
||||||
$query -> where($where);
|
$query -> where($where);
|
||||||
if ($order_by)
|
if ($order_by)
|
||||||
$query -> orderBy($order_by);
|
$query -> orderBy($order_by);
|
||||||
if ($query->execute() === false) // @phpstan-ignore-line
|
if ($query->execute() === false)
|
||||||
return false;
|
return false;
|
||||||
$return = $query->fetchAll();
|
$return = $query->fetchAll();
|
||||||
if (is_array($return))
|
if (is_array($return))
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
Log :: error(
|
self :: _log_simple_select_query_error(
|
||||||
"Error occured getting rows of the table %s in database (where %s): %s",
|
false, $table, $e, $where, $fields, $order_by, $limit, $joins
|
||||||
$table,
|
|
||||||
is_array($where)?
|
|
||||||
preg_replace("/\n */", " ", print_r($where, true)):
|
|
||||||
vardump($where),
|
|
||||||
$e->getMessage()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return false;
|
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
|
* Helper to insert a row in a table
|
||||||
* @param string $table The table name
|
* @param string $table The table name
|
||||||
|
|
Loading…
Reference in a new issue