Skip to content

Commit 2f8a01f

Browse files
committed
Refactor document retrieval and enhance query specifications
- Updated the document retrieval method to use a generic type for fetching `Customer` instances, improving type safety. - Introduced an `include_deleted` flag in the `QuerySpec` struct to allow querying of soft-deleted documents. - Added methods to `DocumentQueryContext` and `DocumentQuery` for including or filtering only deleted documents, enhancing query flexibility. - Updated integration tests to reflect changes in document retrieval logic, ensuring consistency and correctness.
1 parent 483c95a commit 2f8a01f

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

examples/quickstart.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async fn main() -> rillflow::Result<()> {
2020
};
2121

2222
store.docs().upsert(&customer.id, &customer).await?;
23-
let fetched: Option<Customer> = store.docs().get(&customer.id).await?;
23+
let fetched = store.docs().get::<Customer>(&customer.id).await?;
2424
println!("Fetched: {fetched:?}");
2525

2626
store

src/query/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub(crate) struct QuerySpec {
6262
sort: Vec<SortSpec>,
6363
limit: Option<i64>,
6464
offset: Option<i64>,
65+
include_deleted: bool,
6566
}
6667

6768
impl Default for QuerySpec {
@@ -72,6 +73,7 @@ impl Default for QuerySpec {
7273
sort: Vec::new(),
7374
limit: None,
7475
offset: None,
76+
include_deleted: false,
7577
}
7678
}
7779
}
@@ -128,6 +130,7 @@ impl QuerySpec {
128130
sort,
129131
limit,
130132
offset,
133+
include_deleted,
131134
} = self;
132135

133136
let mut builder = QueryBuilder::new("select ");
@@ -158,8 +161,10 @@ impl QuerySpec {
158161

159162
builder.push(" from docs");
160163

164+
let mut has_where = false;
161165
if !filters.is_empty() {
162166
builder.push(" where ");
167+
has_where = true;
163168
let mut iter = filters.into_iter();
164169
if let Some(first) = iter.next() {
165170
first.push_sql(&mut builder);
@@ -169,6 +174,11 @@ impl QuerySpec {
169174
predicate.push_sql(&mut builder);
170175
}
171176
}
177+
if !include_deleted {
178+
builder.push(if has_where { " and " } else { " where " });
179+
builder.push("deleted_at is null");
180+
has_where = true;
181+
}
172182

173183
if !sort.is_empty() {
174184
builder.push(" order by ");
@@ -273,6 +283,17 @@ impl DocumentQueryContext {
273283
self
274284
}
275285

286+
pub fn include_deleted(&mut self) -> &mut Self {
287+
self.spec.include_deleted = true;
288+
self
289+
}
290+
291+
pub fn only_deleted(&mut self) -> &mut Self {
292+
self.spec.include_deleted = true;
293+
self.spec.push_filter(Predicate::exists("deleted_at"));
294+
self
295+
}
296+
276297
pub fn select_fields(&mut self, fields: &[(&str, &str)]) -> &mut Self {
277298
let projections = fields
278299
.iter()
@@ -671,6 +692,17 @@ impl<T> DocumentQuery<T> {
671692
self
672693
}
673694

695+
pub fn include_deleted(mut self) -> Self {
696+
self.spec.include_deleted = true;
697+
self
698+
}
699+
700+
pub fn only_deleted(mut self) -> Self {
701+
self.spec.include_deleted = true;
702+
self.spec.push_filter(Predicate::exists("deleted_at"));
703+
self
704+
}
705+
674706
pub fn select_fields(mut self, fields: &[(&str, &str)]) -> Self {
675707
let projections = fields
676708
.iter()

tests/integration_postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async fn roundtrip() -> Result<()> {
7070
};
7171

7272
store.docs().upsert(&id, &customer).await?;
73-
let fetched: Option<Customer> = store.docs().get(&id).await?;
73+
let fetched = store.docs().get::<Customer>(&id).await?;
7474
assert!(fetched.is_some());
7575

7676
store

0 commit comments

Comments
 (0)