From 8c5396898a715ce22dce1d69b4b3dc7bd3def204 Mon Sep 17 00:00:00 2001 From: Rob Amos Date: Sun, 6 Oct 2024 23:18:13 +1100 Subject: [PATCH 1/2] Add `DatabaseValueConvertible` tip --- GRDB/Documentation.docc/JSON.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/GRDB/Documentation.docc/JSON.md b/GRDB/Documentation.docc/JSON.md index ad4acad302..d0e02abec7 100644 --- a/GRDB/Documentation.docc/JSON.md +++ b/GRDB/Documentation.docc/JSON.md @@ -98,6 +98,18 @@ extension Team: FetchableRecord, PersistableRecord { } ``` +> Tip: Conform your `Codable` property to `DatabaseValueConvertible` if you want to be able to filter on specific values of it: +> +> ```swift +> extension Address: DatabaseValueConvertible {} +> +> // SELECT * FROM player +> // WHERE "address" = '{"street": "...", "city": "...", "country": "..."}' +> let players = try Player +> .filter(JSONColumn("address") == Address(...)) +> .fetchAll(db) +> ``` + ## Manipulate JSON values at the database level [SQLite JSON functions and operators](https://www.sqlite.org/json1.html) are available starting iOS 16+, macOS 10.15+, tvOS 17+, and watchOS 9+. From a9fa2871aaf45b5aa5aa3df4427d883c37aa138f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sun, 6 Oct 2024 18:19:11 +0200 Subject: [PATCH 2/2] Document the requirements --- GRDB/Documentation.docc/JSON.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/GRDB/Documentation.docc/JSON.md b/GRDB/Documentation.docc/JSON.md index d0e02abec7..5e3dcd6b89 100644 --- a/GRDB/Documentation.docc/JSON.md +++ b/GRDB/Documentation.docc/JSON.md @@ -101,14 +101,17 @@ extension Team: FetchableRecord, PersistableRecord { > Tip: Conform your `Codable` property to `DatabaseValueConvertible` if you want to be able to filter on specific values of it: > > ```swift +> struct Address: Codable { ... } > extension Address: DatabaseValueConvertible {} > > // SELECT * FROM player -> // WHERE "address" = '{"street": "...", "city": "...", "country": "..."}' +> // WHERE address = '{"street": "...", "city": "...", "country": "..."}' > let players = try Player > .filter(JSONColumn("address") == Address(...)) > .fetchAll(db) > ``` +> +> Take care that SQLite will compare strings, not JSON objects: white-space and key ordering matter. For this comparison to succeed, make sure that the database contains values that are formatted exactly like a serialized `Address`. ## Manipulate JSON values at the database level