pak_db/query/
mod.rs

1#![doc = include_str!("../../docs/queries.md")]
2
3pub mod pql;
4
5use std::{marker::PhantomData, ops::{BitAnd, BitOr}, rc::Rc, sync::Arc};
6use ordermap::OrderSet;
7
8use crate::{error::PakResult, group::DeserializeGroup, pointer::PakPointer};
9use super::{value::PakValue, Pak};
10
11//==============================================================================================
12//        Pak Query
13//==============================================================================================
14
15pub trait PakQueryExpression<T> where T : DeserializeGroup {
16    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>>;
17}
18
19impl <T> PakQueryExpression<T> for Box<dyn PakQueryExpression<T>> where T : DeserializeGroup {
20    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
21        self.as_ref().execute(pak)
22    }
23}
24
25impl <T> PakQueryExpression<T> for Rc<dyn PakQueryExpression<T>> where T : DeserializeGroup {
26    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
27        Rc::as_ref(&self).execute(pak)
28    }
29}
30
31impl <T> PakQueryExpression<T> for Arc<dyn PakQueryExpression<T>> where T : DeserializeGroup {
32    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
33        Arc::as_ref(&self).execute(pak)
34    }
35}
36
37impl <T, Q> PakQueryExpression<T> for Box<Q> where T : DeserializeGroup, Q : PakQueryExpression<T> {
38    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
39        self.as_ref().execute(pak)
40    }
41}
42
43impl <T, Q> PakQueryExpression<T> for Rc<Q> where T : DeserializeGroup, Q : PakQueryExpression<T>  {
44    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
45        Rc::as_ref(&self).execute(pak)
46    }
47}
48
49impl <T, Q> PakQueryExpression<T> for Arc<Q> where T : DeserializeGroup, Q : PakQueryExpression<T> {
50    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
51        Arc::as_ref(&self).execute(pak)
52    }
53}
54
55//==============================================================================================
56//        PakQueryUnion
57//==============================================================================================
58
59pub struct PakQueryUnion<T>(Box<dyn PakQueryExpression<T>>, Box<dyn PakQueryExpression<T>>) where T : DeserializeGroup;
60
61impl <T> PakQueryExpression<T> for PakQueryUnion<T> where T : DeserializeGroup {
62    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
63        let results_a = self.0.execute(pak)?;
64        let results_b = self.1.execute(pak)?;
65        let results = results_a.into_iter().chain(results_b.into_iter()).collect::<OrderSet<_>>();
66        Ok(results)
67    }
68}
69
70impl <T> PakQueryUnion<T> where T : DeserializeGroup {
71    pub fn new(first : impl PakQueryExpression<T> + 'static, second : impl PakQueryExpression<T> + 'static) -> Self {
72        PakQueryUnion(Box::new(first), Box::new(second))
73    } 
74}
75
76impl <T, B> BitOr<B> for PakQueryUnion<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
77    type Output = Self;
78
79    fn bitor(self, other: B) -> Self::Output {
80        PakQueryUnion(Box::new(self), Box::new(other))
81    }
82}
83
84impl <T, B> BitOr<B> for PakQueryIntersection<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
85    type Output = PakQueryUnion<T>;
86
87    fn bitor(self, other: B) -> Self::Output {
88        PakQueryUnion(Box::new(self), Box::new(other))
89    }
90}
91
92impl <T, B> BitOr<B> for PakQuery<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
93    type Output = PakQueryUnion<T>;
94
95    fn bitor(self, other: B) -> Self::Output {
96        PakQueryUnion(Box::new(self), Box::new(other))
97    }
98}
99
100//==============================================================================================
101//        Pak Query Intersection
102//==============================================================================================
103
104pub struct PakQueryIntersection<T>(Box::<dyn PakQueryExpression<T>>, Box::<dyn PakQueryExpression<T>>) where T : DeserializeGroup;
105
106impl <T> PakQueryIntersection<T> where T : DeserializeGroup {
107    pub fn new(first : impl PakQueryExpression<T> + 'static, second : impl PakQueryExpression<T> + 'static) -> Self {
108        PakQueryIntersection(Box::new(first), Box::new(second))
109    } 
110}
111
112impl <T> PakQueryExpression<T> for PakQueryIntersection<T> where T : DeserializeGroup {
113    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
114        let results_a = self.0.execute(pak)?;
115        let results_b = self.1.execute(pak)?;
116        Ok(results_a.into_iter().filter(|e| results_b.contains(e)).collect())
117    }
118}
119
120impl <T, B> BitAnd<B> for PakQuery<T> where  T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
121    type Output = PakQueryIntersection<T>;
122
123    fn bitand(self, rhs: B) -> Self::Output {
124        PakQueryIntersection(Box::new(self), Box::new(rhs))
125    }
126}
127
128impl <T, B> BitAnd<B> for PakQueryUnion<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
129    type Output = PakQueryIntersection<T>;
130
131    fn bitand(self, rhs: B) -> Self::Output {
132        PakQueryIntersection(Box::new(self), Box::new(rhs))
133    }
134}
135
136impl <T, B> BitAnd<B> for PakQueryIntersection<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
137    type Output = PakQueryIntersection<T>;
138
139    fn bitand(self, rhs: B) -> Self::Output {
140        PakQueryIntersection(Box::new(self), Box::new(rhs))
141    }
142}
143
144
145//==============================================================================================
146//        Pak Query Expression
147//==============================================================================================
148
149#[derive(Default)]
150pub enum PakQuery<T : DeserializeGroup> {
151    Equal(String, PakValue, PhantomData<T>),
152    GreaterThan(String, PakValue),
153    LessThan(String, PakValue),
154    GreaterThanEqual(String, PakValue),
155    LessThanEqual(String, PakValue),
156    Contains(String, PakValue),
157    #[default]
158    All
159}
160
161impl <T> PakQuery<T> where T : DeserializeGroup {
162    pub fn equals(key : &str, value : impl Into<PakValue>) -> Self {
163        PakQuery::Equal(key.to_string(), value.into(), PhantomData)
164    }
165
166    pub fn greater_than(key : &str, value : impl Into<PakValue>) -> Self {
167        PakQuery::GreaterThan(key.to_string(), value.into())
168    }
169
170    pub fn less_than(key : &str, value : impl Into<PakValue>) -> Self {
171        PakQuery::LessThan(key.to_string(), value.into())
172    }
173    
174    pub fn greater_than_or_equal(key : &str, value : impl Into<PakValue>) -> Self {
175        PakQuery::GreaterThanEqual(key.to_string(), value.into())
176    }
177    
178    pub fn less_than_or_equal(key : &str, value : impl Into<PakValue>) -> Self {
179        PakQuery::LessThanEqual(key.to_string(), value.into())
180    }
181    
182    pub fn contains(key : &str, value : impl Into<PakValue>) -> Self {
183        PakQuery::Contains(key.to_string(), value.into())
184    }
185}
186
187pub fn equals<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
188    PakQuery::Equal(key.to_string(), value.into(), PhantomData)
189}
190
191pub fn greater_than<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
192    PakQuery::GreaterThan(key.to_string(), value.into())
193}
194
195pub fn less_than<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
196    PakQuery::LessThan(key.to_string(), value.into())
197}
198
199pub fn greater_than_equal<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
200    PakQuery::GreaterThanEqual(key.to_string(), value.into())
201}
202
203pub fn less_than_equal<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
204    PakQuery::LessThanEqual(key.to_string(), value.into())
205}
206
207impl <T> PakQueryExpression<T> for PakQuery<T> where T : DeserializeGroup {
208    fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
209        match self {
210            PakQuery::Equal(key, pak_value, _) => {
211                let tree = pak.get_tree(key)?;
212                tree.get(pak_value)
213            },
214            PakQuery::GreaterThan(key, pak_value) => {
215                let tree = pak.get_tree(key)?;
216                tree.get_greater(pak_value)
217            },
218            PakQuery::LessThan(key, pak_value) => {
219                let tree = pak.get_tree(key)?;
220                tree.get_less(pak_value)
221            },
222            PakQuery::GreaterThanEqual(key, pak_value) => {
223                let tree = pak.get_tree(key)?;
224                tree.get_greater_eq(pak_value)
225            },
226            PakQuery::LessThanEqual(key, pak_value) => {
227                let tree = pak.get_tree(key)?;
228                tree.get_less_eq(pak_value)
229            },
230            PakQuery::Contains(key, pak_value) => {
231                let tree = pak.get_tree(key)?;
232                tree.get_contains(pak_value)
233            },
234            PakQuery::All => {
235                let list = pak.fetch_all_pointers_of::<T>()?;
236                Ok(list.into_iter().collect::<OrderSet<_>>())
237            }
238        }
239    }
240}