How to model a query that uses a Date Range? #62
-
Hi there, I'm trying to retrieve a series of func getWeightsForDateRange(startDate: Date, endDate: Date) -> [Weight] {
do
{
return try database.read { db in
return try Weight
.order(by: \.timestamp)
.where {
$0.timestamp.between(startDate, and: endDate)
}
.fetchAll(db)
}
}
catch {
Logger.data.error("Error fetching weights: \(error)")
}
return []
} This does not compile without any changes. The error I'm getting indicates that to make this compile I should conform extension Date : @retroactive QueryExpression
{
public typealias QueryValue = Date.ISO8601Representation
public var queryFragment: StructuredQueriesCore.QueryFragment {
return StructuredQueriesCore.QueryFragment(stringLiteral: "'" + self.ISO8601Format() + "'")
}
} This makes the code compile, but the resulting sql is not valid :(. It results in the following error: Error fetching weights: SQLite error 1: near ")": syntax error - while executing `SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights" WHERE ("weights"."timestamp" BETWEEN ('2025-04-27T22:00:00Z' AND '2025-06-01T22:00:00Z')) ORDER BY "weights"."timestamp"` Is the above extension the way to go or am I missing something? Shouldn't kind regards, Tim |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 4 replies
-
Tried the above query in SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights"
WHERE ("weights"."timestamp" BETWEEN '2025-04-27T22:00:00Z' AND '2025-06-01T22:00:00Z')
ORDER BY "weights"."timestamp" and SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights"
WHERE "weights"."timestamp" BETWEEN '2025-04-27T22:00:00Z' AND '2025-06-01T22:00:00Z'
ORDER BY "weights"."timestamp" it looks like SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights"
WHERE "weights"."timestamp" BETWEEN ('2025-04-27T22:00:00Z' AND '2025-06-01T22:00:00Z')
ORDER BY "weights"."timestamp"; Is there something I'm doing wrong here or is this some possible issue in kind regards, Tim |
Beta Was this translation helpful? Give feedback.
-
Hi @mbrandonw, Thanks! I've tried #bind (also before) but somehow it doesn't work either, here's my code: func getWeightsForDateRange(startDate: Date, endDate: Date) -> [Weight] {
do
{
return try database.read { db in
return try Weight
.order(by: \.timestamp)
.where {
$0.timestamp.between(#bind(startDate), and: #bind(endDate))
}
.fetchAll(db)
}
}
catch {
Logger.data.error("Error fetching weights: \(error)")
}
return []
} Also here I'm getting an error concerning the brackets: Error fetching weights: SQLite error 1: near ")": syntax error - while executing
`SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights"
WHERE ("weights"."timestamp" BETWEEN (? AND ?))
ORDER BY "weights"."timestamp"` I guess the positional placeholders are correct? See that again there are nested brackets in the |
Beta Was this translation helpful? Give feedback.
-
@mbrandonw that would be great! Thanks! Should I file an issue? Or is this discussion enough? |
Beta Was this translation helpful? Give feedback.
-
Thanks :) Will keep an eye out for when it arrives. |
Beta Was this translation helpful? Give feedback.
-
@mbrandonw I've fixed my code to use the func getWeightsForDateRange(startDate: Date, endDate: Date) -> [Weight] {
do
{
return try database.read { db in
let weights = try Weight
.order(by: \.timestamp)
.where {
$0.timestamp.between(#bind(startDate), and: #bind(endDate))
}
.fetchAll(db)
return weights
}
}
catch {
Logger.data.error("Error fetching weights: \(error)")
}
return []
} I'm using this query to return the weighs for a month. This works correctly in the unit tests. The query generated by the UI for June is: SELECT "weights"."id", "weights"."timestamp", "weights"."weightInKilograms" FROM "weights"
WHERE ("weights"."timestamp" BETWEEN '2025-04-27 22:00:00.000' AND '2025-06-01 22:00:00.000')
ORDER BY "weights"."timestamp" When I try this in EDIT: If I add another record today, it also shows up correctly. However, when I change the date of a previous record to today (using Also I'm displaying all weights in a chart using: @FetchAll(Weight.order(by: \.timestamp)) private var weights: [Weight] and this does return all the weights in the database. |
Beta Was this translation helpful? Give feedback.
Ah, that just seems like a bug in our generated SQL! We should not be parenthesizing the
? AND ?
when usingBETWEEN
. We will fix that soon.