Skip to content

Commit 4eddc50

Browse files
committed
wip
1 parent 8056cf4 commit 4eddc50

File tree

3 files changed

+364
-49
lines changed

3 files changed

+364
-49
lines changed

Sources/StructuredQueriesCore/SQLite/JSONFunctions.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,34 @@ extension PrimaryKeyedTableDefinition where QueryValue: Codable & Sendable {
9797

9898
private var jsonObject: some QueryExpression<QueryValue> {
9999
func open<TableColumn: TableColumnExpression>(_ column: TableColumn) -> QueryFragment {
100-
func isJSONRepresentation<T: Codable & Sendable>(_: T.Type) -> Bool {
101-
TableColumn.QueryValue.self == JSONRepresentation<T>.self
100+
typealias Value = TableColumn.QueryValue._Optionalized.Wrapped
101+
102+
func isJSONRepresentation<T: Codable & Sendable>(_: T.Type, isOptional: Bool = false) -> Bool
103+
{
104+
func isOptionalJSONRepresentation<U: _OptionalProtocol>(_: U.Type) -> Bool {
105+
if let codableType = U.Wrapped.self as? any (Codable & Sendable).Type {
106+
return isJSONRepresentation(codableType, isOptional: true)
107+
} else {
108+
return false
109+
}
110+
}
111+
if let optionalType = T.self as? any _OptionalProtocol.Type {
112+
return isOptionalJSONRepresentation(optionalType)
113+
} else if isOptional {
114+
return TableColumn.QueryValue.self == JSONRepresentation<T>?.self
115+
} else {
116+
return Value.self == JSONRepresentation<T>.self
117+
}
102118
}
103119

104-
if TableColumn.QueryValue.self == Bool.self {
120+
if Value.self == Bool.self {
105121
return """
106122
\(quote: column.name, delimiter: .text), \
107123
json(CASE \(column) WHEN 0 THEN 'false' WHEN 1 THEN 'true' END)
108124
"""
109-
} else if TableColumn.QueryValue.self == Date.UnixTimeRepresentation.self {
125+
} else if Value.self == Date.UnixTimeRepresentation.self {
110126
return "\(quote: column.name, delimiter: .text), datetime(\(column), 'unixepoch')"
111-
} else if TableColumn.QueryValue.self == Date.JulianDayRepresentation.self {
127+
} else if Value.self == Date.JulianDayRepresentation.self {
112128
return "\(quote: column.name, delimiter: .text), datetime(\(column), 'julianday')"
113129
} else if let codableType = TableColumn.QueryValue.QueryOutput.self
114130
as? any (Codable & Sendable).Type,

Tests/StructuredQueriesTests/JSONFunctionsTests.swift

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -267,36 +267,8 @@ extension SnapshotTests {
267267
"""
268268
}
269269
}
270-
271-
@Test func associationWithJSONField() {
272-
assertQuery(
273-
TaskList
274-
.join(Task.all) { $0.id.eq($1.taskListID) }
275-
.select {
276-
TaskListRow.Columns(taskList: $0, tasks: $1.jsonGroupArray())
277-
}
278-
) {
279-
"""
280-
SELECT "taskLists"."id" AS "taskList", json_group_array(CASE WHEN ("tasks"."id" IS NOT NULL) THEN json_object('id', json_quote("tasks"."id"), 'notes', json("tasks"."notes"), 'taskListID', json_quote("tasks"."taskListID")) END) AS "tasks"
281-
FROM "taskLists"
282-
JOIN "tasks" ON ("taskLists"."id" = "tasks"."taskListID")
283-
"""
284-
} results: {
285-
"""
286-
no such table: taskLists
287-
"""
288-
}
289-
}
290270
}
291271
}
292-
/*
293-
TODO: split json association tests into own suite with custom schema
294-
* exercise Bool? path
295-
* exercise Data/UUID path with JSON
296-
* exercise dates
297-
* exercise JSONRepresentation field (such as [String] notes)
298-
* exercise path that removes the NULL filter to see how that can come up
299-
*/
300272

301273
@Selection
302274
private struct ReminderRow {
@@ -312,19 +284,3 @@ private struct RemindersListRow {
312284
@Column(as: JSONRepresentation<[Reminder]>.self)
313285
let reminders: [Reminder]
314286
}
315-
316-
@Table struct TaskList {
317-
let id: Int
318-
}
319-
@Table
320-
struct Task: Codable {
321-
let id: Int
322-
@Column(as: JSONRepresentation<[String]>.self)
323-
var notes: [String]
324-
var taskListID: Int
325-
}
326-
@Selection struct TaskListRow {
327-
let taskList: TaskList
328-
@Column(as: JSONRepresentation<[Task]>.self)
329-
let tasks: [Task]
330-
}

0 commit comments

Comments
 (0)