Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions Sources/StructuredQueriesCore/SQLite/JSONFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ extension PrimaryKeyedTableDefinition where QueryValue: Codable & Sendable {
/// ```swift
/// @Selection struct Row {
/// let remindersList: RemindersList
/// @Column(as: JSONRepresentation<[Reminder]>.self)
/// @Column(as: [Reminder].JSONRepresentation.self)
/// let reminders: [Reminder]
/// }
/// RemindersList
Expand All @@ -87,15 +87,15 @@ extension PrimaryKeyedTableDefinition where QueryValue: Codable & Sendable {
/// ```sql
/// SELECT
/// "remindersLists".…,
/// iif(
/// "reminders"."id" IS NULL,
/// NULL,
/// CASE WHEN
/// ("reminders"."id" IS NOT NULL)
/// THEN
/// json_object(
/// 'id', json_quote("id"),
/// 'title', json_quote("title"),
/// 'priority', json_quote("priority")
/// )
/// )
/// END AS "reminders"
/// FROM "remindersLists"
/// JOIN "reminders"
/// ON ("remindersLists"."id" = "reminders"."remindersListID")
Expand Down Expand Up @@ -123,7 +123,7 @@ extension PrimaryKeyedTableDefinition where QueryValue: Codable & Sendable {
}
}

extension PrimaryKeyedTableDefinition {
extension PrimaryKeyedTableDefinition where QueryValue: _OptionalProtocol & Codable & Sendable, QueryValue.Wrapped: Codable & Sendable {
/// A JSON array representation of the aggregation of a table's columns.
///
/// Constructs a JSON array of JSON objects with a field for each column of the table. This can be
Expand All @@ -136,7 +136,7 @@ extension PrimaryKeyedTableDefinition {
/// ```swift
/// @Selection struct Row {
/// let remindersList: RemindersList
/// @Column(as: JSONRepresentation<[Reminder]>.self)
/// @Column(as: [Reminder].JSONRepresentation.self)
/// let reminders: [Reminder]
/// }
/// RemindersList
Expand All @@ -153,15 +153,15 @@ extension PrimaryKeyedTableDefinition {
/// ```sql
/// SELECT
/// "remindersLists".…,
/// iif(
/// "reminders"."id" IS NULL,
/// NULL,
/// CASE WHEN
/// ("reminders"."id" IS NOT NULL)
/// THEN
/// json_object(
/// 'id', json_quote("id"),
/// 'title', json_quote("title"),
/// 'priority', json_quote("priority")
/// )
/// )
/// END AS "reminders"
/// FROM "remindersLists"
/// JOIN "reminders"
/// ON ("remindersLists"."id" = "reminders"."remindersListID")
Expand All @@ -174,12 +174,11 @@ extension PrimaryKeyedTableDefinition {
/// - order: An `ORDER BY` clause to apply to the aggregation.
/// - filter: A `FILTER` clause to apply to the aggregation.
/// - Returns: A JSON array aggregate of this table.
public func jsonGroupArray<Wrapped: Codable & Sendable>(
public func jsonGroupArray(
isDistinct: Bool = false,
order: (some QueryExpression)? = Bool?.none,
filter: (some QueryExpression<Bool>)? = Bool?.none
) -> some QueryExpression<[Wrapped].JSONRepresentation>
where QueryValue == Wrapped? {
) -> some QueryExpression<[QueryValue.Wrapped].JSONRepresentation> {
let filterQueryFragment =
if let filter {
self.primaryKey.isNot(nil).and(filter).queryFragment
Expand All @@ -194,6 +193,9 @@ extension PrimaryKeyedTableDefinition {
filter: filterQueryFragment
)
}
}

extension PrimaryKeyedTableDefinition {

fileprivate var jsonObject: some QueryExpression<QueryValue> {
func open<TableColumn: TableColumnExpression>(_ column: TableColumn) -> QueryFragment {
Expand Down
2 changes: 1 addition & 1 deletion Tests/StructuredQueriesTests/KitchenSinkTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ extension SnapshotTests {
.select { ($0, $1.jsonGroupArray()) }
) {
"""
SELECT "kitchens"."id", json_group_array(CASE WHEN ("kitchenSinks"."id" IS NOT NULL) THEN json_object('id', json_quote("kitchenSinks"."id"), 'kitchenID', json_quote("kitchenSinks"."kitchenID"), 'bool', json(CASE "kitchenSinks"."bool" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'optionalBool', json(CASE "kitchenSinks"."optionalBool" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'string', json_quote("kitchenSinks"."string"), 'optionalString', json_quote("kitchenSinks"."optionalString"), 'int', json_quote("kitchenSinks"."int"), 'optionalInt', json_quote("kitchenSinks"."optionalInt"), 'double', json_quote("kitchenSinks"."double"), 'optionalDouble', json_quote("kitchenSinks"."optionalDouble"), 'rawRepresentable', json_quote("kitchenSinks"."rawRepresentable"), 'optionalRawRepresentable', json_quote("kitchenSinks"."optionalRawRepresentable"), 'iso8601Date', json_quote("kitchenSinks"."iso8601Date"), 'optionalISO8601Date', json_quote("kitchenSinks"."optionalISO8601Date"), 'unixTimeDate', datetime("kitchenSinks"."unixTimeDate", 'unixepoch'), 'optionalUnixTimeDate', datetime("kitchenSinks"."optionalUnixTimeDate", 'unixepoch'), 'julianDayDate', datetime("kitchenSinks"."julianDayDate", 'julianday'), 'optionalJulianDayDate', datetime("kitchenSinks"."optionalJulianDayDate", 'julianday'), 'jsonArray', json("kitchenSinks"."jsonArray"), 'optionalJSONArray', json("kitchenSinks"."optionalJSONArray"), 'jsonArrayOfDates', json("kitchenSinks"."jsonArrayOfDates")) END)
SELECT "kitchens"."id", json_group_array(CASE WHEN ("kitchenSinks"."id" IS NOT NULL) THEN json_object('id', json_quote("kitchenSinks"."id"), 'kitchenID', json_quote("kitchenSinks"."kitchenID"), 'bool', json(CASE "kitchenSinks"."bool" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'optionalBool', json(CASE "kitchenSinks"."optionalBool" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'string', json_quote("kitchenSinks"."string"), 'optionalString', json_quote("kitchenSinks"."optionalString"), 'int', json_quote("kitchenSinks"."int"), 'optionalInt', json_quote("kitchenSinks"."optionalInt"), 'double', json_quote("kitchenSinks"."double"), 'optionalDouble', json_quote("kitchenSinks"."optionalDouble"), 'rawRepresentable', json_quote("kitchenSinks"."rawRepresentable"), 'optionalRawRepresentable', json_quote("kitchenSinks"."optionalRawRepresentable"), 'iso8601Date', json_quote("kitchenSinks"."iso8601Date"), 'optionalISO8601Date', json_quote("kitchenSinks"."optionalISO8601Date"), 'unixTimeDate', datetime("kitchenSinks"."unixTimeDate", 'unixepoch'), 'optionalUnixTimeDate', datetime("kitchenSinks"."optionalUnixTimeDate", 'unixepoch'), 'julianDayDate', datetime("kitchenSinks"."julianDayDate", 'julianday'), 'optionalJulianDayDate', datetime("kitchenSinks"."optionalJulianDayDate", 'julianday'), 'jsonArray', json("kitchenSinks"."jsonArray"), 'optionalJSONArray', json("kitchenSinks"."optionalJSONArray"), 'jsonArrayOfDates', json("kitchenSinks"."jsonArrayOfDates")) END) FILTER (WHERE ("kitchenSinks"."id" IS NOT NULL))
FROM "kitchens"
FULL JOIN "kitchenSinks" ON ("kitchens"."id" IS "kitchenSinks"."kitchenID")
"""
Expand Down
2 changes: 1 addition & 1 deletion Tests/StructuredQueriesTests/SelectTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ extension SnapshotTests {
.select { ($0, $1.jsonGroupArray()) }
) {
"""
SELECT "r1s"."id", "r1s"."assignedUserID", "r1s"."dueDate", "r1s"."isCompleted", "r1s"."isFlagged", "r1s"."notes", "r1s"."priority", "r1s"."remindersListID", "r1s"."title", "r1s"."updatedAt", json_group_array(CASE WHEN ("r2s"."id" IS NOT NULL) THEN json_object('id', json_quote("r2s"."id"), 'assignedUserID', json_quote("r2s"."assignedUserID"), 'dueDate', json_quote("r2s"."dueDate"), 'isCompleted', json(CASE "r2s"."isCompleted" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'isFlagged', json(CASE "r2s"."isFlagged" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'notes', json_quote("r2s"."notes"), 'priority', json_quote("r2s"."priority"), 'remindersListID', json_quote("r2s"."remindersListID"), 'title', json_quote("r2s"."title"), 'updatedAt', json_quote("r2s"."updatedAt")) END)
SELECT "r1s"."id", "r1s"."assignedUserID", "r1s"."dueDate", "r1s"."isCompleted", "r1s"."isFlagged", "r1s"."notes", "r1s"."priority", "r1s"."remindersListID", "r1s"."title", "r1s"."updatedAt", json_group_array(CASE WHEN ("r2s"."id" IS NOT NULL) THEN json_object('id', json_quote("r2s"."id"), 'assignedUserID', json_quote("r2s"."assignedUserID"), 'dueDate', json_quote("r2s"."dueDate"), 'isCompleted', json(CASE "r2s"."isCompleted" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'isFlagged', json(CASE "r2s"."isFlagged" WHEN 0 THEN 'false' WHEN 1 THEN 'true' END), 'notes', json_quote("r2s"."notes"), 'priority', json_quote("r2s"."priority"), 'remindersListID', json_quote("r2s"."remindersListID"), 'title', json_quote("r2s"."title"), 'updatedAt', json_quote("r2s"."updatedAt")) END) FILTER (WHERE ("r2s"."id" IS NOT NULL))
FROM "reminders" AS "r1s"
LEFT JOIN "reminders" AS "r2s" ON ("r1s"."id" = "r2s"."id")
GROUP BY "r1s"."id"
Expand Down