1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
mod alter_table;
mod index;
mod metadata;
mod transaction;

use {
    async_trait::async_trait,
    gluesql_core::{
        data::{Row, Schema},
        result::{MutResult, Result},
        store::{GStore, GStoreMut, RowIter, Store, StoreMut},
    },
    serde::{Deserialize, Serialize},
    std::{
        collections::{BTreeMap, HashMap},
        iter::empty,
    },
};

#[derive(Debug, Clone)]
pub struct Key {
    pub table_name: String,
    pub id: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Item {
    pub schema: Schema,
    pub rows: BTreeMap<u64, Row>,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct MemoryStorage {
    pub id_counter: u64,
    pub items: HashMap<String, Item>,
}

#[async_trait(?Send)]
impl Store<Key> for MemoryStorage {
    async fn fetch_schema(&self, table_name: &str) -> Result<Option<Schema>> {
        self.items
            .get(table_name)
            .map(|item| Ok(item.schema.clone()))
            .transpose()
    }

    async fn scan_data(&self, table_name: &str) -> Result<RowIter<Key>> {
        let rows = match self.items.get(table_name) {
            Some(item) => &item.rows,
            None => {
                return Ok(Box::new(empty()));
            }
        };

        let rows = rows
            .iter()
            .map(|(id, row)| {
                let key = Key {
                    table_name: table_name.to_owned(),
                    id: *id,
                };

                Ok((key, row.clone()))
            })
            .collect::<Vec<_>>()
            .into_iter();

        Ok(Box::new(rows))
    }
}

#[async_trait(?Send)]
impl StoreMut<Key> for MemoryStorage {
    async fn insert_schema(self, schema: &Schema) -> MutResult<Self, ()> {
        let mut storage = self;

        let table_name = schema.table_name.clone();
        let item = Item {
            schema: schema.clone(),
            rows: BTreeMap::new(),
        };

        storage.items.insert(table_name, item);
        Ok((storage, ()))
    }

    async fn delete_schema(self, table_name: &str) -> MutResult<Self, ()> {
        let mut storage = self;

        storage.items.remove(table_name);
        Ok((storage, ()))
    }

    async fn insert_data(self, table_name: &str, rows: Vec<Row>) -> MutResult<Self, ()> {
        let mut storage = self;
        let mut id = storage.id_counter;

        if let Some(item) = storage.items.get_mut(table_name) {
            for row in rows {
                id += 1;

                item.rows.insert(id, row);
            }
        }

        storage.id_counter = id;
        Ok((storage, ()))
    }

    async fn update_data(self, table_name: &str, rows: Vec<(Key, Row)>) -> MutResult<Self, ()> {
        let mut storage = self;

        if let Some(item) = storage.items.get_mut(table_name) {
            for (key, row) in rows {
                let id = key.id;

                item.rows.insert(id, row);
            }
        }

        Ok((storage, ()))
    }

    async fn delete_data(self, table_name: &str, keys: Vec<Key>) -> MutResult<Self, ()> {
        let mut storage = self;

        if let Some(item) = storage.items.get_mut(table_name) {
            for key in keys {
                item.rows.remove(&key.id);
            }
        }

        Ok((storage, ()))
    }
}

impl GStore<Key> for MemoryStorage {}
impl GStoreMut<Key> for MemoryStorage {}