* @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 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 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 $parameters An associative array of parameters to which the fields should be added * @return array 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 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)) }; } }