shoal_core/shared/
queries.rs

1//! The types needed for querying the database
2
3use rkyv::{Archive, Deserialize, Serialize};
4use uuid::Uuid;
5
6use super::traits::ShoalDatabase;
7
8use super::traits::ShoalTable;
9use crate::server::ring::Ring;
10use crate::server::shard::ShardInfo;
11
12/// A bundle of different query kinds
13#[derive(Debug, Archive, Serialize, Deserialize)]
14pub struct Queries<S: ShoalDatabase> {
15    /// The id for this query
16    pub id: Uuid,
17    /// The individual queries to execute
18    pub queries: Vec<S::QueryKinds>,
19}
20
21impl<S: ShoalDatabase> Queries<S> {
22    /// Add a new query onto this queries bundle
23    ///
24    /// # Arguments
25    ///
26    /// * `query` - The query to add
27    #[must_use]
28    pub fn add<Q: Into<S::QueryKinds>>(mut self, query: Q) -> Self {
29        // add our query
30        self.queries.push(query.into());
31        self
32    }
33}
34
35impl<S: ShoalDatabase> Default for Queries<S> {
36    fn default() -> Self {
37        Queries {
38            id: Uuid::new_v4(),
39            queries: Vec::default(),
40        }
41    }
42}
43
44/// The different types of queries for a single datatype
45#[derive(Debug, Archive, Serialize, Deserialize, Clone)]
46pub enum Query<T: ShoalTable + std::fmt::Debug> {
47    /// Insert a row into shoal
48    Insert { key: u64, row: T },
49    /// Get some data from shoal
50    Get(Get<T>),
51    /// Delete a row from shoal
52    Delete { key: u64, sort_key: T::Sort },
53    /// Update a row in a shoal
54    Update(Update<T>),
55}
56
57impl<T: ShoalTable + std::fmt::Debug> Query<T> {
58    // sort our queries by shard
59    pub fn find_shard<'a>(&self, ring: &'a Ring, tmp: &mut Vec<&'a ShardInfo>) {
60        // get the correct shard for this query
61        match self {
62            Query::Insert { key, .. } | Query::Delete { key, .. } => {
63                tmp.push(ring.find_shard(*key))
64            }
65            Query::Get(get) => {
66                for key in &get.partition_keys {
67                    tmp.push(ring.find_shard(*key))
68                }
69            }
70            Query::Update(update) => tmp.push(ring.find_shard(update.partition_key)),
71        }
72    }
73}
74
75/// A single query tagged with client info
76pub struct TaggedQuery<R: ShoalTable> {
77    /// The id for this query
78    pub id: Uuid,
79    /// This queries index in the queries vec
80    pub index: usize,
81    /// The query to execute
82    pub query: Query<R>,
83}
84
85impl<R: ShoalTable> TaggedQuery<R> {
86    /// Create a new tagged query
87    ///
88    /// # Arguments
89    ///
90    /// * `id` - The id for this query's bundle
91    /// * `index` - The index for this query in its parent bundle
92    /// * `query` - The query to execute
93    pub fn new(id: Uuid, index: usize, query: Query<R>) -> Self {
94        Self { id, index, query }
95    }
96}
97
98/// A get query
99#[derive(Debug, Archive, Serialize, Deserialize, Clone)]
100//#[archive_attr(derive(Debug))]
101pub struct Get<R: ShoalTable> {
102    /// The partition keys to get data from
103    pub partition_keys: Vec<u64>,
104    /// The sort keys to get data from
105    pub sort_keys: Vec<R::Sort>,
106    /// Any filters to apply to rows
107    pub filters: Option<R::Filters>,
108    /// The number of rows to get at most
109    pub limit: Option<usize>,
110}
111
112/// An update query for a single row in Shoal
113#[derive(Debug, Archive, Serialize, Deserialize, Clone)]
114pub struct Update<T: ShoalTable> {
115    /// The key to the partition to update data in
116    pub partition_key: u64,
117    /// The sort key to apply updates too
118    pub sort_key: T::Sort,
119    /// The updates to apply
120    pub update: T::Update,
121}
122
123//impl<T: ShoalTable> Update<T> {
124//    /// Get this updates sort key
125//    pub fn get_sort_key(&self) -> T::Sort {
126//        self.sort_key
127//    }
128//}