1#[allow(deprecated)]
2use crate::{
3 filter::Filter,
4 filter_builder::Reader,
5 internal::{EmbeddedDescription, Projection},
6 Fetch, FilterBuilder, IntoResult, OwnedSytx, Persistent, PersistentEmbedded, Ref, Snapshot, Structsy,
7};
8pub struct StructsyIter<'a, T> {
10 iterator: Box<dyn Iterator<Item = T> + 'a>,
11}
12
13impl<'a, T> StructsyIter<'a, T> {
14 pub fn new<I>(iterator: I) -> StructsyIter<'a, T>
15 where
16 I: Iterator<Item = T>,
17 I: 'a,
18 {
19 StructsyIter {
20 iterator: Box::new(iterator),
21 }
22 }
23}
24
25impl<'a, T> Iterator for StructsyIter<'a, T> {
26 type Item = T;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 self.iterator.next()
30 }
31}
32
33pub trait Operators<F> {
77 fn or<FN: Fn(F) -> F>(self, builder: FN) -> Self;
78 fn and<FN: Fn(F) -> F>(self, builder: FN) -> Self;
79 fn not<FN: Fn(F) -> F>(self, builder: FN) -> Self;
80}
81
82pub trait EmbeddedQuery<T: PersistentEmbedded + 'static>: Sized {
83 fn filter_builder(&mut self) -> &mut FilterBuilder<T>;
84 fn add_group(&mut self, filter: Filter<T>);
85}
86
87impl<T: EmbeddedDescription + 'static, Q: EmbeddedQuery<T>> Operators<Filter<T>> for Q {
88 fn or<FN: Fn(Filter<T>) -> Filter<T>>(mut self, builder: FN) -> Self {
89 self.filter_builder().or(builder(Filter::<T>::new()).extract_filter());
90 self
91 }
92 fn and<FN: Fn(Filter<T>) -> Filter<T>>(mut self, builder: FN) -> Self {
93 self.filter_builder().and(builder(Filter::<T>::new()).extract_filter());
94 self
95 }
96 fn not<FN: Fn(Filter<T>) -> Filter<T>>(mut self, builder: FN) -> Self {
97 self.filter_builder().not(builder(Filter::<T>::new()).extract_filter());
98 self
99 }
100}
101
102pub struct ProjectionResult<P, T> {
103 filter: FilterBuilder<T>,
104 phantom: std::marker::PhantomData<P>,
105}
106impl<P, T> ProjectionResult<P, T> {
107 pub(crate) fn new(filter: FilterBuilder<T>) -> Self {
108 Self {
109 filter,
110 phantom: std::marker::PhantomData,
111 }
112 }
113}
114
115impl<P: Projection<T>, T: Persistent + 'static> Fetch<P> for ProjectionResult<P, T> {
116 fn into(self, structsy: &Structsy) -> StructsyIter<P> {
117 self.fetch(structsy)
118 }
119
120 fn into_tx(self, tx: &mut OwnedSytx) -> StructsyIter<P> {
121 self.fetch_tx(tx)
122 }
123
124 fn fetch(self, structsy: &Structsy) -> StructsyIter<P> {
125 let data = self.filter.finish(Reader::Structsy(structsy.clone()));
126 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
127 }
128
129 fn fetch_tx(self, tx: &mut OwnedSytx) -> StructsyIter<P> {
130 let data = self.filter.finish(Reader::Tx(tx.reference()));
131 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
132 }
133
134 fn fetch_snapshot(self, snapshot: &Snapshot) -> StructsyIter<P> {
135 let data = self.filter.finish(Reader::Snapshot(snapshot.clone()));
136 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
137 }
138}
139
140#[allow(deprecated)]
141impl<P: Projection<T>, T: Persistent + 'static> IntoResult<P> for ProjectionResult<P, T> {}
142
143#[allow(deprecated)]
144impl<T: Persistent + 'static> IntoResult<(Ref<T>, T)> for Filter<T> {}
145
146pub trait Query<T: Persistent + 'static>: Sized {
148 fn filter_builder(&mut self) -> &mut FilterBuilder<T>;
149 fn add_group(&mut self, filter: Filter<T>);
150}
151
152pub struct SnapshotQuery<T> {
154 pub(crate) snapshot: Snapshot,
155 pub(crate) builder: FilterBuilder<T>,
156}
157
158impl<T: Persistent + 'static> IntoIterator for SnapshotQuery<T> {
159 type Item = (Ref<T>, T);
160 type IntoIter = StructsyIter<'static, (Ref<T>, T)>;
161 fn into_iter(self) -> Self::IntoIter {
162 StructsyIter::new(self.builder.finish(Reader::Snapshot(self.snapshot)))
163 }
164}
165
166impl<T: Persistent + 'static> Query<T> for SnapshotQuery<T> {
167 fn filter_builder(&mut self) -> &mut FilterBuilder<T> {
168 &mut self.builder
169 }
170 fn add_group(&mut self, filter: Filter<T>) {
171 let base = self.filter_builder();
172 base.and_filter(filter.extract_filter());
173 }
174}
175impl<T: Persistent + 'static> SnapshotQuery<T> {
176 pub(crate) fn builder(self) -> FilterBuilder<T> {
177 self.builder
178 }
179 pub fn projection<P: Projection<T>>(self) -> ProjectionSnapshotQuery<P, T> {
180 ProjectionSnapshotQuery {
181 builder: self.builder,
182 snapshot: self.snapshot,
183 phantom: std::marker::PhantomData,
184 }
185 }
186
187 pub fn fetch(self) -> StructsyIter<'static, (Ref<T>, T)> {
188 StructsyIter::new(self.builder.finish(Reader::Snapshot(self.snapshot)))
189 }
190}
191
192pub struct ProjectionSnapshotQuery<P, T> {
193 builder: FilterBuilder<T>,
194 snapshot: Snapshot,
195 phantom: std::marker::PhantomData<P>,
196}
197
198impl<P: Projection<T>, T: Persistent + 'static> ProjectionSnapshotQuery<P, T> {
199 pub fn fetch(self) -> StructsyIter<'static, P> {
200 let data = self.builder.finish(Reader::Snapshot(self.snapshot));
201 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
202 }
203}
204
205impl<P: Projection<T>, T: Persistent + 'static> IntoIterator for ProjectionSnapshotQuery<P, T> {
206 type Item = P;
207 type IntoIter = StructsyIter<'static, P>;
208 fn into_iter(self) -> Self::IntoIter {
209 let data = self.builder.finish(Reader::Snapshot(self.snapshot));
210 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
211 }
212}
213
214pub struct StructsyQuery<T: Persistent + 'static> {
248 pub(crate) structsy: Structsy,
249 pub(crate) builder: FilterBuilder<T>,
250}
251
252impl<T: Persistent + 'static> Query<T> for StructsyQuery<T> {
253 fn filter_builder(&mut self) -> &mut FilterBuilder<T> {
254 &mut self.builder
255 }
256 fn add_group(&mut self, filter: Filter<T>) {
257 let base = self.filter_builder();
258 base.and_filter(filter.extract_filter());
259 }
260}
261impl<T: Persistent + 'static> StructsyQuery<T> {
262 pub(crate) fn builder(self) -> FilterBuilder<T> {
263 self.builder
264 }
265 pub fn projection<P: Projection<T>>(self) -> ProjectionQuery<P, T> {
266 ProjectionQuery {
267 builder: self.builder,
268 structsy: self.structsy,
269 phantom: std::marker::PhantomData,
270 }
271 }
272
273 pub fn fetch(self) -> StructsyIter<'static, (Ref<T>, T)> {
274 StructsyIter::new(self.builder.finish(Reader::Structsy(self.structsy.clone())))
275 }
276}
277
278impl<T: Persistent> IntoIterator for StructsyQuery<T> {
279 type Item = (Ref<T>, T);
280 type IntoIter = StructsyIter<'static, (Ref<T>, T)>;
281 fn into_iter(self) -> Self::IntoIter {
282 StructsyIter::new(self.builder.finish(Reader::Structsy(self.structsy.clone())))
283 }
284}
285
286pub struct ProjectionQuery<P: Projection<T>, T> {
287 builder: FilterBuilder<T>,
288 structsy: Structsy,
289 phantom: std::marker::PhantomData<P>,
290}
291
292impl<P: Projection<T>, T: Persistent + 'static> ProjectionQuery<P, T> {
293 pub fn fetch(self) -> StructsyIter<'static, P> {
294 let data = self.builder.finish(Reader::Structsy(self.structsy.clone()));
295 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
296 }
297}
298
299impl<P: Projection<T>, T: Persistent + 'static> IntoIterator for ProjectionQuery<P, T> {
300 type Item = P;
301 type IntoIter = StructsyIter<'static, P>;
302 fn into_iter(self) -> Self::IntoIter {
303 let data = self.builder.finish(Reader::Structsy(self.structsy.clone()));
304 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
305 }
306}
307
308pub struct StructsyQueryTx<'a, T: Persistent + 'static> {
343 pub(crate) tx: &'a mut OwnedSytx,
344 pub(crate) builder: FilterBuilder<T>,
345}
346
347impl<'a, T: Persistent + 'static> Query<T> for StructsyQueryTx<'a, T> {
348 fn filter_builder(&mut self) -> &mut FilterBuilder<T> {
349 &mut self.builder
350 }
351 fn add_group(&mut self, filter: Filter<T>) {
352 let base = self.filter_builder();
353 base.and_filter(filter.extract_filter());
354 }
355}
356impl<'a, T: Persistent> StructsyQueryTx<'a, T> {
357 pub fn projection<P: Projection<T>>(self) -> ProjectionQueryTx<'a, P, T> {
404 ProjectionQueryTx {
405 tx: self.tx,
406 builder: self.builder,
407 phantom: std::marker::PhantomData,
408 }
409 }
410
411 pub fn fetch(self) -> StructsyIter<'a, (Ref<T>, T)> {
412 StructsyIter::new(self.builder.finish(Reader::Tx(self.tx.reference())))
413 }
414}
415pub struct ProjectionQueryTx<'a, P, T> {
416 tx: &'a mut OwnedSytx,
417 builder: FilterBuilder<T>,
418 phantom: std::marker::PhantomData<P>,
419}
420
421impl<'a, P: Projection<T>, T: Persistent + 'static> ProjectionQueryTx<'a, P, T> {
422 pub fn fetch(self) -> StructsyIter<'a, P> {
423 let data = self.builder.finish(Reader::Tx(self.tx.reference()));
424 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
425 }
426}
427
428impl<'a, P: Projection<T>, T: Persistent + 'static> IntoIterator for ProjectionQueryTx<'a, P, T> {
429 type Item = P;
430 type IntoIter = StructsyIter<'a, P>;
431 fn into_iter(self) -> Self::IntoIter {
432 let data = self.builder.finish(Reader::Tx(self.tx.reference()));
433 StructsyIter::new(Box::new(data.map(|(_, r)| Projection::projection(&r))))
434 }
435}
436
437impl<'a, T: Persistent> IntoIterator for StructsyQueryTx<'a, T> {
438 type Item = (Ref<T>, T);
439 type IntoIter = StructsyIter<'a, (Ref<T>, T)>;
440 fn into_iter(self) -> Self::IntoIter {
441 StructsyIter::new(self.builder.finish(Reader::Tx(self.tx.reference())))
442 }
443}
444
445pub struct StructsyFilter<T: Persistent> {
446 filter: Filter<T>,
447}
448
449impl<T: Persistent + 'static> StructsyFilter<T> {
450 pub fn new() -> StructsyFilter<T> {
451 StructsyFilter {
452 filter: Filter::<T>::new(),
453 }
454 }
455}
456impl<T: Persistent + 'static> Query<T> for StructsyFilter<T> {
457 fn filter_builder(&mut self) -> &mut FilterBuilder<T> {
458 self.filter.filter_builder()
459 }
460 fn add_group(&mut self, filter: Filter<T>) {
461 self.filter.add_group(filter)
462 }
463}
464
465impl<T: Persistent + 'static, Q: Query<T>> Operators<StructsyFilter<T>> for Q {
466 fn or<FN: Fn(StructsyFilter<T>) -> StructsyFilter<T>>(mut self, builder: FN) -> Self {
467 self.filter_builder()
468 .or(builder(StructsyFilter::<T>::new()).filter.extract_filter());
469 self
470 }
471 fn and<FN: Fn(StructsyFilter<T>) -> StructsyFilter<T>>(mut self, builder: FN) -> Self {
472 self.filter_builder()
473 .and(builder(StructsyFilter::<T>::new()).filter.extract_filter());
474 self
475 }
476 fn not<FN: Fn(StructsyFilter<T>) -> StructsyFilter<T>>(mut self, builder: FN) -> Self {
477 self.filter_builder()
478 .not(builder(StructsyFilter::<T>::new()).filter.extract_filter());
479 self
480 }
481}
482
483#[cfg(test)]
484mod tests {
485 use super::Query;
486 use crate::{
487 actions::EqualAction,
488 internal::{Description, Field},
489 Filter, Persistent, Ref, SRes, Sytx,
490 };
491
492 use std::io::{Read, Write};
493 struct ToQuery {
494 first: String,
495 second: Vec<String>,
496 }
497 impl Persistent for ToQuery {
498 fn get_name() -> &'static str {
499 "ToQuery"
500 }
501 fn get_description() -> Description {
502 let fields = [
503 crate::internal::FieldDescription::new::<String>(0u32, "first", None),
504 crate::internal::FieldDescription::new::<Vec<String>>(2u32, "second", None),
505 ];
506 Description::Struct(crate::internal::StructDescription::new("ToQuery", &fields))
507 }
508 fn read(_read: &mut dyn Read) -> SRes<Self>
509 where
510 Self: std::marker::Sized,
511 {
512 unimplemented!()
513 }
514 fn remove_indexes(&self, _tx: &mut dyn Sytx, _id: &Ref<Self>) -> SRes<()>
515 where
516 Self: std::marker::Sized,
517 {
518 unimplemented!()
519 }
520 fn write(&self, _write: &mut dyn Write) -> SRes<()> {
521 unimplemented!()
522 }
523 fn put_indexes(&self, _tx: &mut dyn Sytx, _id: &Ref<Self>) -> SRes<()>
524 where
525 Self: std::marker::Sized,
526 {
527 unimplemented!()
528 }
529 fn declare(_db: &mut dyn Sytx) -> SRes<()> {
530 unimplemented!()
531 }
532 }
533 impl ToQuery {
534 pub fn field_first() -> Field<Self, String> {
535 Field::<ToQuery, String>::new("first", |x| &x.first)
536 }
537 pub fn field_second() -> Field<Self, Vec<String>> {
538 Field::<ToQuery, Vec<String>>::new("second", |x| &x.second)
539 }
540 }
541
542 trait MyQuery {
543 fn by_name(self, first: String) -> Self;
544 fn by_second(self, second: String) -> Self;
545 fn by_first_and_second(self, first: String, second: String) -> Self;
546 }
547
548 impl MyQuery for Filter<ToQuery> {
549 fn by_name(mut self, first: String) -> Self {
550 let builder = self.filter_builder();
551 EqualAction::equal((ToQuery::field_first(), builder), first);
552 self
553 }
554 fn by_second(mut self, second: String) -> Self {
555 let builder = self.filter_builder();
556 EqualAction::equal((ToQuery::field_second(), builder), second);
557 self
558 }
559 fn by_first_and_second(mut self, first: String, second: String) -> Self {
560 EqualAction::equal((ToQuery::field_first(), self.filter_builder()), first);
561 EqualAction::equal((ToQuery::field_second(), self.filter_builder()), second);
562 self
563 }
564 }
565 #[test]
566 fn test_query_build() {
567 let filter = Filter::<ToQuery>::new();
568 filter.by_name("one".to_string()).by_second("second".to_string());
569 }
570}