* @license MIT */ declare(strict_types=1); namespace BitBadger\PDODocument\Query; use BitBadger\PDODocument\{Configuration, DocumentException, Field, FieldMatch, Mode, Query}; use Exception; /** * Queries to perform partial updates on documents */ class Patch { /** * Create an UPDATE statement to patch documents * * @param string $tableName The name of the table in which documents should be patched * @param string $whereClause The body of the WHERE clause to use in the UPDATE statement * @return string The UPDATE statement to perform the patch * @throws Exception If the database mode has not been set */ public static function update(string $tableName, string $whereClause): string { $setValue = match (Configuration::mode('make patch statement')) { Mode::PgSQL => 'data || :data', Mode::SQLite => 'json_patch(data, json(:data))', }; return "UPDATE $tableName SET data = $setValue WHERE $whereClause"; } /** * Query to patch (partially update) a document by its ID * * @param string $tableName The name of the table in which a document should be patched * @param mixed $docId The ID of the document to be patched (optional; string ID assumed) * @return string The query to patch a document by its ID * @throws DocumentException If the database mode has not been set */ public static function byId(string $tableName, mixed $docId = null): string { return self::update($tableName, Query::whereById(docId: $docId)); } /** * Query to patch (partially update) a document via a comparison on a JSON field * * @param string $tableName The name of the table in which documents should be patched * @param array|Field[] $field The field comparison to match * @param FieldMatch|null $match How to handle multiple conditions (optional; defaults to All) * @return string The query to patch documents via field comparison * @throws DocumentException If the database mode has not been set */ public static function byFields(string $tableName, array $field, ?FieldMatch $match = null): string { return self::update($tableName, Query::whereByFields($field, $match)); } /** * Query to patch (partially update) a document via a JSON containment query (PostgreSQL only) * * @param string $tableName The name of the table in which documents should be patched * @return string The query to patch documents via a JSON containment query * @throws DocumentException If the database mode is not PostgreSQL */ public static function byContains(string $tableName): string { return self::update($tableName, Query::whereDataContains()); } /** * Query to patch (partially update) a document via a JSON Path match query (PostgreSQL only) * * @param string $tableName The name of the table in which documents should be patched * @return string The query to patch documents via a JSON Path match * @throws DocumentException If the database mode is not PostgreSQL */ public static function byJsonPath(string $tableName): string { return self::update($tableName, Query::whereJsonPathMatches()); } }