How to build queries from a set of "optional parameters" like chained filters, ordering, limits etc? #185
Replies: 1 comment 2 replies
-
Hi @SwiftedMind, for the most part you are on the right track. Here are a few comments on your explorations so far:
One small improvement you can make to this is the following: Self
.where { memory in
if let query = filter.query {
memory.name.like(query) || memory.content.like(query)
}
if let tagIds = filter.tagIds {
memory.tagId.in(tagIds)
}
if let memoryIds = filter.memoryIds {
memory.id.in(memoryIds)
}
if let isRead = filter.isRead {
memory.isRead.eq(isRead)
}
if let isFlagged = filter.isFlagged {
memory.isFlagged.eq(isFlagged)
}
if let createdAfter = filter.createdAfter {
memory.createdAt.gt(createdAfter)
}
if let createdBefore = filter.createdBefore {
memory.createdAt.lt(createdBefore)
}
}
Yeah overall this is correct, though of course it isn't the nicest thing. It is a bummer we don't have a conditional way of applying The only small change I would make is to use static func `where`(filter: MemoryFilter) -> SelectOf<Memory> {
let baseQuery = Self
+ .all
.where { /* ... */ }
.where { /* ... */ }
/* ... */
if let limit = filter.limit {
return baseQuery.limit(limit, offset: filter.offset)
}
- return baseQuery.asSelect()
+ return baseQuery
}
In this code snippet you erased the return type to try Memory.where(filter: .init()).ordered …because we leverage static dynamic member lookup so that However, this: try Memory.ordered.where(filter: .init()) …won't work until Swift gets dynamic member look up methods, which hopefully is coming soon. There is another way to get reusable queries by defining helpers directly on the table columns themselves. We have docs for that here. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey, I'm currently in the process of migrating my
GRDB
setup tosqlite-data
, which is looking amazing! It's been going super smoothly so far (though the compiler is really struggling; I barely get any autocompletion) and I'm looking forward to replacing my own iCloud sync code with the one in sqlite-data, which is likely much more robust than what I have built 😅.One thing I'm having trouble with, though, is finding a proper way to build queries from "optional parameters" like chained filters, ordering, limits, etc.
In my old setup with
GRDB
, I’ve been building a versatile filter request that I can configure with a niceMemoryFilter
structure. A simplified version looks like this:Using this filter object, I can create a database request with GRDB:
I'm unsure how to build a query like this with
StructuredQueries
. Most of the filters can be composed like this:But this is where it's getting tricky. I want to conditionally add a
limit
to the query, but thelimit()
function does not accept an optional value. So I've tried the following, returning aSelectOf<Memory>
:Is this the right way to do it?
Additionally, I am trying to figure out how you would "chain" this
where(filter:)
with other query "options". For example:With the extension on
Memory
itself, I can only ever use one of the properties/functions when building the query. What do I need to extend to make this work generally on a memory query? I've played around with some things and the following does compile:Is this the right way to do it?
Thanks! 😃
Beta Was this translation helpful? Give feedback.
All reactions