I am new to Vapor/Fluent. I have a model with two timestamp fields like this:
import Fluent
import Vapor
final class User: Model, Content {
@Timestamp(key: "updated_at", on: .update, format: .unix)
var modificationDate: Date?
@Timestamp(key: "deleted_at", on: .delete, format: .unix)
var deletionDate: Date?
}
I want to write a Fluent query for users based on these dates, i.e. get all users with modificationDate or deletionDate not nil and within a given time interval. Something like this:
func getUpdatedOrDeletedUsers(startDate: Date, endDate: Date) async throws -> [User] {
let interval: Range<Date> = startDate..<endDate
return try await User.query(on: request.db)
.withDeleted()
.filter((\.$modificationDate != nil && interval.contains(\.$modificationDate!)) || (\.$deletionDate != nil && interval.contains(\.$deletionDate!)))
.all()
}
Unfortunately, this kind of syntax does not seem to be allowed. After reading the documentation I came up with this solution:
func getUpdatedOrDeletedUsers(startDate: Date, endDate: Date) async throws -> [User] {
return try await User.query(on: request.db)
.withDeleted()
.group(.or) { group in
group.group(.and) { group in
group.filter(\.$modificationDate != nil)
.filter(\.$modificationDate >= startDate)
.filter(\.$modificationDate < endDate)
}
.group(.and) { group in
group.filter(\.$deletionDate != nil)
.filter(\.$deletionDate >= startDate)
.filter(\.$deletionDate < endDate)
}
}
.all()
}
But this does not seem very readable. I thought about making two separate queries, but I think that might have a negative impact on performance. Is this the right way to do it with Fluent? Is there a better way?