radish_database/
lib.rs

1/* Copyright (c) 2020 Dmitry Shatilov <shatilov dot diman at gmail dot com>
2 * 
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU Affero General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU Affero General Public License for more details.
12
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 */
16
17mod container;
18mod strings;
19mod expire;
20mod list;
21mod keys;
22mod hash;
23mod set;
24
25use std::sync::Arc;
26use std::time::SystemTime;
27
28use tokio::sync::Mutex;
29use indexmap::IndexMap;
30
31use container::ContainersPtr;
32
33pub type Key = radish_types::Key;
34pub type Value = radish_types::Value;
35pub type Arguments = radish_types::Arguments;
36pub type ExecResult = radish_types::ExecResult;
37pub type Command = radish_types::Command;
38
39#[derive(Clone)]
40pub struct Storage {
41	containers: ContainersPtr,
42	expire_controller: Arc<Mutex<expire::ExpireController>>,
43	expire_awaker: Arc<Mutex<Option<Box<dyn FnMut(SystemTime) + Send + 'static>>>>,
44}
45
46impl Storage {
47	pub fn new() -> Self {
48		Self {
49			containers: Arc::new(Mutex::new(IndexMap::new())),
50			expire_controller: Arc::new(Mutex::new(expire::ExpireController::new())),
51			expire_awaker: Arc::new(Mutex::new(None)),
52		}
53	}
54
55	pub fn set_expire_awaker<A>(&mut self, a: A)
56	where A: FnMut(SystemTime) + Send + 'static {
57		self.expire_awaker = Arc::new(Mutex::new(Some(Box::new(a))));
58	}
59
60	pub async fn unimplemented(&self) -> ExecResult {
61		Err("Unimplemented".to_owned())
62	}
63
64	pub async fn execute(&mut self, command: Command) -> Value {
65		let result = match &command.command.to_uppercase()[..] {
66			"NOW" => self.keys_now(command.arguments).await,
67			"PNOW" => self.keys_pnow(command.arguments).await,
68			"DEL" => self.keys_del(command.arguments).await,
69			"KEYS" => self.keys_keys(command.arguments).await,
70			"EXISTS" => self.keys_exists(command.arguments).await,
71			"RENAME" => self.keys_rename(command.arguments).await,
72			"DUMP" => self.unimplemented().await,
73			"EXPIRE" => self.keys_expire(command.arguments).await,
74			"EXPIREAT" => self.keys_expire_at(command.arguments).await,
75			"MIGRATE" => self.unimplemented().await,
76			"MOVE" => self.unimplemented().await,
77			"OBJECT" => self.unimplemented().await,
78			"PERSIST" => self.unimplemented().await,
79			"PEXPIRE" => self.keys_pexpire(command.arguments).await,
80			"PEXPIREAT" => self.keys_pexpire_at(command.arguments).await,
81			"PTTL" => self.keys_pttl(command.arguments).await,
82			"RANDOMKEY" => self.unimplemented().await,
83			"RENAMENX" => self.unimplemented().await,
84			"RESTORE" => self.unimplemented().await,
85			"SORT" => self.unimplemented().await,
86			"TOUCH" => self.unimplemented().await,
87			"TTL" => self.keys_ttl(command.arguments).await,
88			"TYPE" => self.keys_type(command.arguments).await,
89			"UNLINK" => self.unimplemented().await,
90			"WAIT" => self.unimplemented().await,
91			"SCAN" => self.keys_scan(command.arguments).await,
92
93			"APPEND" => self.strings_append(command.arguments).await,
94			"GET" => self.strings_get(command.arguments).await,
95			"GETSET" => self.strings_getset(command.arguments).await,
96			"STRLEN" => self.strings_len(command.arguments).await,
97			"BITCOUNT" => self.strings_bitcount(command.arguments).await,
98			"BITFIELD" => self.unimplemented().await,
99			"BITOP" => self.strings_bitop(command.arguments).await,
100			"BITPOS" => self.unimplemented().await,
101			"DECR" => self.strings_decrby(command.arguments).await,
102			"DECRBY" => self.strings_decrby(command.arguments).await,
103			"GETBIT" => self.strings_getbit(command.arguments).await,
104			"GETRANGE" => self.strings_get_range(command.arguments).await,
105			"INCR" => self.strings_incrby(command.arguments).await,
106			"INCRBY" => self.strings_incrby(command.arguments).await,
107			"INCRBYFLOAT" => self.strings_incrby_float(command.arguments).await,
108			"MGET" => self.strings_mget(command.arguments).await,
109			"MSET" => self.strings_mset(command.arguments).await,
110			"MSETNX" => self.unimplemented().await,
111			"PSETEX" => self.strings_psetex(command.arguments).await,
112			"SET" => self.strings_set(command.arguments).await,
113			"SETBIT" => self.strings_setbit(command.arguments).await,
114			"SETEX" => self.strings_setex(command.arguments).await,
115			"SETNX" => self.strings_setnx(command.arguments).await,
116			"SETRANGE" => self.strings_set_range(command.arguments).await,
117
118			"LLEN" => self.list_len(command.arguments).await,
119			"LPOP" => self.list_lpop(command.arguments).await,
120			"RPOP" => self.list_rpop(command.arguments).await,
121			"LREM" => self.list_rem(command.arguments).await,
122			"LSET" => self.list_set(command.arguments).await,
123			"LPUSH" => self.list_lpush(command.arguments).await,
124			"RPUSH" => self.list_rpush(command.arguments).await,
125			"LPUSHX" => self.list_lpushx(command.arguments).await,
126			"RPUSHX" => self.list_rpushx(command.arguments).await,
127			"LINDEX" => self.list_index(command.arguments).await,
128			"LRANGE" => self.list_range(command.arguments).await,
129			"LINSERT" => self.list_insert(command.arguments).await,
130			"LTRIM" => self.list_trim(command.arguments).await,
131			"RPOPLPUSH" => self.unimplemented().await,
132			"BRPOP" => self.unimplemented().await,
133			"BLPOP" => self.unimplemented().await,
134			"BRPOPLPUSH" => self.unimplemented().await,
135
136			"SADD" => self.set_add(command.arguments).await,
137			"SREM" => self.set_rem(command.arguments).await,
138			"SPOP" => self.set_pop(command.arguments).await,
139			"SSCAN" => self.set_scan(command.arguments).await,
140			"SCARD" => self.set_card(command.arguments).await,
141			"SMOVE" => self.set_move(command.arguments).await,
142			"SMEMBERS" => self.set_members(command.arguments).await,
143			"SISMEMBER" => self.set_is_member(command.arguments).await,
144			"SDIFF" => self.set_diff(command.arguments).await,
145			"SINTER" => self.set_inter(command.arguments).await,
146			"SUNION" => self.set_union(command.arguments).await,
147			"SDIFFSTORE" => self.set_diff_store(command.arguments).await,
148			"SINTERSTORE" => self.set_inter_store(command.arguments).await,
149			"SUNIONSTORE" => self.set_union_store(command.arguments).await,
150			"SRANDMEMBER" => self.unimplemented().await,
151
152			"HSET" => self.hash_set(command.arguments).await,
153			"HSETNX" => self.hash_set_nx(command.arguments).await,
154			"HDEL" => self.hash_del(command.arguments).await,
155			"HGET" => self.hash_get(command.arguments).await,
156			"HGETALL" => self.hash_get_all(command.arguments).await,
157			"HEXISTS" => self.hash_exists(command.arguments).await,
158			"HKEYS" => self.hash_keys(command.arguments).await,
159			"HVALUES" => self.hash_values(command.arguments).await,
160			"HLEN" => self.hash_len(command.arguments).await,
161			"HSTRLEN" => self.hash_strlen(command.arguments).await,
162			"HINCRBY" => self.hash_incrby(command.arguments).await,
163			"HINCRBYFLOAT" => self.hash_incrbyfloat(command.arguments).await,
164			"HMGET" => self.hash_mget(command.arguments).await,
165			"HMSET" => self.hash_set(command.arguments).await,
166			"HSCAN" => self.hash_scan(command.arguments).await,
167
168			"" => Err(format!("HELP docs.....")),
169			_ => Err(format!("Unsupported command")),
170		};
171		match result {
172			Ok(r) => r,
173			Err(err) => Value::Error(err),
174		}
175	}
176}
177