- Add In/InArray support - Add ORDER BY support for `Find` functions - Update dependencies - Implement fixes identified via static analysis Reviewed-on: #5
102 lines
3.8 KiB
PHP
102 lines
3.8 KiB
PHP
<?php
|
|
/**
|
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
* @license MIT
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace BitBadger\PDODocument;
|
|
|
|
use Exception;
|
|
|
|
/**
|
|
* Functions to create parameters for queries
|
|
*/
|
|
class Parameters
|
|
{
|
|
/**
|
|
* Create an ID parameter (name ":id", key will be treated as a string)
|
|
*
|
|
* @param mixed $key The key representing the ID of the document
|
|
* @return array<string, mixed> An associative array with an "@id" parameter/value pair
|
|
*/
|
|
public static function id(mixed $key): array
|
|
{
|
|
return [':id' => ((is_int($key) || is_string($key)) ? $key : "$key")];
|
|
}
|
|
|
|
/**
|
|
* Create a parameter with a JSON value
|
|
*
|
|
* @param string $name The name of the JSON parameter
|
|
* @param mixed[]|object $document The value that should be passed as a JSON string
|
|
* @return array<string, string> An associative array with the named parameter/value pair
|
|
*/
|
|
public static function json(string $name, object|array $document): array
|
|
{
|
|
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
|
|
|
|
if (is_object($document)) {
|
|
return [
|
|
$name => method_exists($document, 'toJson') ? $document->toJson($flags) : json_encode($document, $flags)
|
|
];
|
|
}
|
|
|
|
$key = array_key_first($document);
|
|
if (is_array($document[$key])) {
|
|
if (empty($document[$key])) return [$name => json_encode($document, $flags)];
|
|
if (method_exists($document[$key][array_key_first($document[$key])], 'toJson')) {
|
|
return [
|
|
$name => sprintf('{%s:[%s]}', json_encode($key, $flags),
|
|
implode(',', array_map(fn($it) => $it->toJson($flags), $document[$key])))
|
|
];
|
|
}
|
|
}
|
|
return [$name => json_encode($document, $flags)];
|
|
}
|
|
|
|
/**
|
|
* Fill in parameter names for any fields missing one
|
|
*
|
|
* @param Field[] $fields The fields for the query (entries with no names will be modified)
|
|
*/
|
|
public static function nameFields(array &$fields): void
|
|
{
|
|
array_walk($fields, function (Field $field, int $idx) {
|
|
if (empty($field->paramName)) $field->paramName =":field$idx";
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add field parameters to the given set of parameters
|
|
*
|
|
* @param Field[] $fields The fields being compared in the query
|
|
* @param array<string, mixed> $parameters An associative array of parameters to which the fields should be added
|
|
* @return array<string, mixed> An associative array of parameter names and values with the fields added
|
|
*/
|
|
public static function addFields(array $fields, array $parameters): array
|
|
{
|
|
return array_reduce($fields, fn($carry, $item) => $item->appendParameter($carry), $parameters);
|
|
}
|
|
|
|
/**
|
|
* Create JSON field name parameters for the given field names to the given parameter
|
|
*
|
|
* @param string $paramName The name of the parameter for the field names
|
|
* @param string[] $fieldNames The names of the fields for the parameter
|
|
* @return array<string, string> An associative array of parameter/value pairs for the field names
|
|
* @throws Exception If the database mode has not been set
|
|
*/
|
|
public static function fieldNames(string $paramName, array $fieldNames): array
|
|
{
|
|
$mode = Configuration::mode('generate field name parameters');
|
|
return match ($mode) {
|
|
Mode::PgSQL => [$paramName => "{" . implode(",", $fieldNames) . "}"],
|
|
Mode::SQLite => array_combine(array_map(fn($idx) => $paramName . $idx,
|
|
empty($fieldNames) ? [] : range(0, sizeof($fieldNames) - 1)),
|
|
array_map(fn($field) => "$.$field", $fieldNames))
|
|
};
|
|
}
|
|
}
|