product_os_store/
lib.rs

1#![no_std]
2extern crate no_std_compat as std;
3extern crate alloc;
4
5use core::fmt::Formatter;
6use std::prelude::v1::*;
7use std::fmt::Display;
8
9// #![feature(box_patterns)]
10
11cfg_if::cfg_if! {
12    if #[cfg(feature = "key_value_store")] {
13        mod key_value_store;
14        #[cfg(feature = "redis_key_value_store")]
15        mod redis_key_value_store;
16        #[cfg(feature = "memory_key_value_store")]
17        mod memory_key_value_store;
18        #[cfg(feature = "file_key_value_store")]
19        mod file_key_value_store;
20        mod sink_key_value_store;
21
22        use product_os_configuration::KeyValueKind;
23        use std::collections::BTreeMap;
24
25        use crate::key_value_store::ProductOSKeyValueStoreEngine;
26        use crate::sink_key_value_store::ProductOSSinkKeyValueStore;
27        #[cfg(feature = "redis_key_value_store")]
28        use crate::redis_key_value_store::ProductOSRedisKeyValueStore;
29        #[cfg(feature = "memory_key_value_store")]
30        use crate::memory_key_value_store::ProductOSMemoryKeyValueStore;
31        #[cfg(feature = "file_key_value_store")]
32        use crate::file_key_value_store::ProductOSFileKeyValueStore;
33    }
34}
35
36
37cfg_if::cfg_if! {
38    if #[cfg(feature = "queue_store")] {
39        mod queue_store;
40        #[cfg(feature = "redis_queue_store")]
41        mod redis_queue_store;
42        #[cfg(feature = "memory_queue_store")]
43        mod memory_queue_store;
44        #[cfg(feature = "file_queue_store")]
45        mod file_queue_store;
46
47        mod sink_queue_store;
48
49        use product_os_configuration::QueueKind;
50
51        use crate::queue_store::ProductOSQueueStoreEngine;
52        use crate::sink_queue_store::ProductOSSinkQueueStore;
53        #[cfg(feature = "redis_queue_store")]
54        use crate::redis_queue_store::ProductOSRedisQueueStore;
55        #[cfg(feature = "memory_queue_store")]
56        use crate::memory_queue_store::ProductOSMemoryQueueStore;
57        #[cfg(feature = "file_queue_store")]
58        use crate::file_queue_store::ProductOSFileQueueStore;
59    }
60}
61
62
63cfg_if::cfg_if! {
64    if #[cfg(feature = "relational_store")] {
65        mod relational_store;
66        #[cfg(feature = "postgres_relational_store")]
67        mod postgres_relational_store;
68        #[cfg(feature = "sqlite_relational_store")]
69        mod sqlite_relational_store;
70        mod memory_relational_store;
71        mod sink_relational_store;
72        mod sql_query_processing;
73
74        pub use relational_store::{
75            ProductOSRelationalObject, ProductOSRelationalStoreEngine,Query, Fields, Field, Operation, Table,
76            SortOrder, DistinctType, Expression, Join, Fetch, InstructionType, Value, Target, Action, Instruction,
77            Constraint, ConstraintFunction, ConstraintAction, DataType, Sharding,
78            RelationalRow, RelationalColumn, RelationalError, RelationalResult, RelationalTransaction
79        };
80
81        use product_os_configuration::RelationalKind;
82
83        use crate::sql_query_processing::{query_to_string, instruction_to_string, process_instruction_to_string, process_query_to_string};
84
85        #[cfg(feature = "postgres_relational_store")]
86        use postgres_relational_store::ProductOSPostgresRelationalStore;
87        #[cfg(feature = "sqlite_relational_store")]
88        use sqlite_relational_store::ProductOSSqliteRelationalStore;
89        // use memory_relational_store::ProductOSMemoryRelationalStore;
90        use sink_relational_store::ProductOSSinkRelationalStore;
91
92        #[cfg(feature = "sql_relational_store")]
93        pub use sqlx::{
94            Row as ProductOSRow, FromRow, types,
95            Column as ProductOSColumn,
96            Error as SqlError,
97            error::UnexpectedNullError as SqlNullError
98        };
99
100        #[cfg(feature = "postgres_relational_store")]
101        pub use sqlx::{
102            Postgres, postgres::{ PgQueryResult, PgRow },
103        };
104
105        #[cfg(feature = "sqlite_relational_store")]
106        pub use sqlx::{
107            Sqlite, sqlite::{ SqliteQueryResult, SqliteRow },
108        };
109    }
110}
111
112
113#[cfg(feature = "document_store")]
114mod document_store;
115// https://github.com/robconery/dox
116
117
118#[cfg(feature = "event_store")]
119mod event_store;
120// https://medium.com/@tobyhede/event-sourcing-with-postgresql-28c5e8f211a2
121
122
123
124#[derive(Debug)]
125pub enum ProductOSStoreError {
126    ConnectionError(String),
127    QueryError(String),
128    WriteError(String),
129    ReadError(String),
130    DeleteError(String)
131}
132
133impl Display for ProductOSStoreError {
134    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
135        let value = format!("{:?}", self);
136        write!(f, "{:?}", value)
137    }
138}
139
140
141#[cfg(feature = "relational_store")]
142pub enum ProductOSKeyValueStorageType {
143    Redis,
144    Memory,
145    File,
146    Sink
147}
148
149
150
151#[cfg(feature = "key_value_store")]
152pub enum ProductOSKeyValueStorage {
153    #[cfg(feature = "redis_key_value_store")]
154    Redis(ProductOSRedisKeyValueStore),
155    #[cfg(feature = "memory_key_value_store")]
156    Memory(ProductOSMemoryKeyValueStore),
157    #[cfg(feature = "file_key_value_store")]
158    File(ProductOSFileKeyValueStore),
159    Sink(ProductOSSinkKeyValueStore)
160}
161
162
163#[cfg(feature = "key_value_store")]
164pub struct ProductOSKeyValueStore {
165    store: ProductOSKeyValueStorage
166}
167
168#[cfg(feature = "key_value_store")]
169impl ProductOSKeyValueStore {
170    pub fn new(config: &product_os_configuration::KeyValueStore) -> Self {
171        match config.kind {
172            #[cfg(feature = "redis_key_value_store")]
173            KeyValueKind::Redis => Self {
174                store: ProductOSKeyValueStorage::Redis(ProductOSRedisKeyValueStore::new(config))
175            },
176            KeyValueKind::Sink => Self {
177                store: ProductOSKeyValueStorage::Sink(ProductOSSinkKeyValueStore::new(config))
178            },
179            #[cfg(feature = "memory_key_value_store")]
180            KeyValueKind::Memory => Self {
181                store: ProductOSKeyValueStorage::Memory(ProductOSMemoryKeyValueStore::new(config))
182            },
183            #[cfg(feature = "file_key_value_store")]
184            KeyValueKind::File => Self {
185                store: ProductOSKeyValueStorage::File(ProductOSFileKeyValueStore::new(config))
186            },
187            _ => panic!("Key value store kind not currently supported")
188        }
189    }
190
191    pub fn connect(&mut self) -> Result<(), ProductOSStoreError> {
192        match &mut self.store {
193            #[cfg(feature = "redis_key_value_store")]
194            ProductOSKeyValueStorage::Redis(store) => store.connect(),
195            ProductOSKeyValueStorage::Sink(store) => store.connect(),
196            #[cfg(feature = "memory_key_value_store")]
197            ProductOSKeyValueStorage::Memory(store) => store.connect(),
198            #[cfg(feature = "file_key_value_store")]
199            ProductOSKeyValueStorage::File(store) => store.connect(),
200            _ => panic!("Key value store kind not currently supported")
201        }
202    }
203
204    pub fn disconnect(&mut self) -> Result<(), ProductOSStoreError> {
205        match &mut self.store {
206            #[cfg(feature = "redis_key_value_store")]
207            ProductOSKeyValueStorage::Redis(store) => store.disconnect(),
208            ProductOSKeyValueStorage::Sink(store) => store.disconnect(),
209            #[cfg(feature = "memory_key_value_store")]
210            ProductOSKeyValueStorage::Memory(store) => store.disconnect(),
211            #[cfg(feature = "file_key_value_store")]
212            ProductOSKeyValueStorage::File(store) => store.disconnect(),
213            _ => panic!("Key value store kind not currently supported")
214        }
215    }
216
217    pub fn set_group(&mut self, group: &str) {
218        match &mut self.store {
219            #[cfg(feature = "redis_key_value_store")]
220            ProductOSKeyValueStorage::Redis(store) => store.set_group(group),
221            ProductOSKeyValueStorage::Sink(store) => store.set_group(group),
222            #[cfg(feature = "memory_key_value_store")]
223            ProductOSKeyValueStorage::Memory(store) => store.set_group(group),
224            #[cfg(feature = "file_key_value_store")]
225            ProductOSKeyValueStorage::File(store) => store.set_group(group),
226            _ => panic!("Key value store kind not currently supported")
227        }
228    }
229
230    pub fn set_group_type(&mut self, group_type: &str) {
231        match &mut self.store {
232            #[cfg(feature = "redis_key_value_store")]
233            ProductOSKeyValueStorage::Redis(store) => store.set_group_type(group_type),
234            ProductOSKeyValueStorage::Sink(store) => store.set_group_type(group_type),
235            #[cfg(feature = "memory_key_value_store")]
236            ProductOSKeyValueStorage::Memory(store) => store.set_group_type(group_type),
237            #[cfg(feature = "file_key_value_store")]
238            ProductOSKeyValueStorage::File(store) => store.set_group_type(group_type),
239            _ => panic!("Key value store kind not currently supported")
240        }
241    }
242
243    pub fn group_get(&self, key: &str) -> Result<String, ProductOSStoreError> {
244        match &self.store {
245            #[cfg(feature = "redis_key_value_store")]
246            ProductOSKeyValueStorage::Redis(store) => store.group_get(key),
247            ProductOSKeyValueStorage::Sink(store) => store.group_get(key),
248            #[cfg(feature = "memory_key_value_store")]
249            ProductOSKeyValueStorage::Memory(store) => store.group_get(key),
250            #[cfg(feature = "file_key_value_store")]
251            ProductOSKeyValueStorage::File(store) => store.group_get(key),
252            _ => panic!("Key value store kind not currently supported")
253        }
254    }
255
256    pub fn group_set(&self, key: &str, value: &str) -> Result<(), ProductOSStoreError> {
257        match &self.store {
258            #[cfg(feature = "redis_key_value_store")]
259            ProductOSKeyValueStorage::Redis(store) => store.group_set(key, value),
260            ProductOSKeyValueStorage::Sink(store) => store.group_set(key, value),
261            #[cfg(feature = "memory_key_value_store")]
262            ProductOSKeyValueStorage::Memory(store) => store.group_set(key, value),
263            #[cfg(feature = "file_key_value_store")]
264            ProductOSKeyValueStorage::File(store) => store.group_set(key, value),
265            _ => panic!("Key value store kind not currently supported")
266        }
267    }
268
269    pub fn group_remove(&self, key: &str) -> Result<(), ProductOSStoreError> {
270        match &self.store {
271            #[cfg(feature = "redis_key_value_store")]
272            ProductOSKeyValueStorage::Redis(store) => store.group_remove(key),
273            ProductOSKeyValueStorage::Sink(store) => store.group_remove(key),
274            #[cfg(feature = "memory_key_value_store")]
275            ProductOSKeyValueStorage::Memory(store) => store.group_remove(key),
276            #[cfg(feature = "file_key_value_store")]
277            ProductOSKeyValueStorage::File(store) => store.group_remove(key),
278            _ => panic!("Key value store kind not currently supported")
279        }
280    }
281
282    pub fn group_find(&self, query: Option<&str>) -> Result<BTreeMap<String, String>, ProductOSStoreError> {
283        match &self.store {
284            #[cfg(feature = "redis_key_value_store")]
285            ProductOSKeyValueStorage::Redis(store) => store.group_find(query),
286            ProductOSKeyValueStorage::Sink(store) => store.group_find(query),
287            #[cfg(feature = "memory_key_value_store")]
288            ProductOSKeyValueStorage::Memory(store) => store.group_find(query),
289            #[cfg(feature = "file_key_value_store")]
290            ProductOSKeyValueStorage::File(store) => store.group_find(query),
291            _ => panic!("Key value store kind not currently supported")
292        }
293    }
294
295    pub fn group_specific_get(&self, key: &str, group: &str) -> Result<String, ProductOSStoreError> {
296        match &self.store {
297            #[cfg(feature = "redis_key_value_store")]
298            ProductOSKeyValueStorage::Redis(store) => store.group_specific_get(key, group),
299            ProductOSKeyValueStorage::Sink(store) => store.group_specific_get(key, group),
300            #[cfg(feature = "memory_key_value_store")]
301            ProductOSKeyValueStorage::Memory(store) => store.group_specific_get(key, group),
302            #[cfg(feature = "file_key_value_store")]
303            ProductOSKeyValueStorage::File(store) => store.group_specific_get(key, group),
304            _ => panic!("Key value store kind not currently supported")
305        }
306    }
307
308    pub fn group_specific_set(&self, key: &str, value: &str, group: &str) -> Result<(), ProductOSStoreError> {
309        match &self.store {
310            #[cfg(feature = "redis_key_value_store")]
311            ProductOSKeyValueStorage::Redis(store) => store.group_specific_set(key, value, group),
312            ProductOSKeyValueStorage::Sink(store) => store.group_specific_set(key, value, group),
313            #[cfg(feature = "memory_key_value_store")]
314            ProductOSKeyValueStorage::Memory(store) => store.group_specific_set(key, value, group),
315            #[cfg(feature = "file_key_value_store")]
316            ProductOSKeyValueStorage::File(store) => store.group_specific_set(key, value, group),
317            _ => panic!("Key value store kind not currently supported")
318        }
319    }
320
321    pub fn group_specific_remove(&self, key: &str, group: &str) -> Result<(), ProductOSStoreError> {
322        match &self.store {
323            #[cfg(feature = "redis_key_value_store")]
324            ProductOSKeyValueStorage::Redis(store) => store.group_specific_remove(key, group),
325            ProductOSKeyValueStorage::Sink(store) => store.group_specific_remove(key, group),
326            #[cfg(feature = "memory_key_value_store")]
327            ProductOSKeyValueStorage::Memory(store) => store.group_specific_remove(key, group),
328            #[cfg(feature = "file_key_value_store")]
329            ProductOSKeyValueStorage::File(store) => store.group_specific_remove(key, group),
330            _ => panic!("Key value store kind not currently supported")
331        }
332    }
333
334    pub fn group_specific_find(&self, query: Option<&str>, group: &str) -> Result<BTreeMap<String, String>, ProductOSStoreError> {
335        match &self.store {
336            #[cfg(feature = "redis_key_value_store")]
337            ProductOSKeyValueStorage::Redis(store) => store.group_specific_find(query, group),
338            ProductOSKeyValueStorage::Sink(store) => store.group_specific_find(query, group),
339            #[cfg(feature = "memory_key_value_store")]
340            ProductOSKeyValueStorage::Memory(store) => store.group_specific_find(query, group),
341            #[cfg(feature = "file_key_value_store")]
342            ProductOSKeyValueStorage::File(store) => store.group_specific_find(query, group),
343            _ => panic!("Key value store kind not currently supported")
344        }
345    }
346}
347
348
349#[cfg(feature = "queue_store")]
350pub enum ProductOSQueueStorageType {
351    Redis,
352    Memory,
353    File,
354    Sink
355}
356
357#[cfg(feature = "queue_store")]
358pub enum ProductOSQueueStorage {
359    #[cfg(feature = "redis_queue_store")]
360    Redis(ProductOSRedisQueueStore),
361    Sink(ProductOSSinkQueueStore),
362    #[cfg(feature = "memory_queue_store")]
363    Memory(ProductOSMemoryQueueStore),
364    #[cfg(feature = "file_queue_store")]
365    File(ProductOSFileQueueStore)
366}
367
368#[cfg(feature = "queue_store")]
369pub struct ProductOSQueueStore {
370    store: ProductOSQueueStorage
371}
372
373#[cfg(feature = "queue_store")]
374impl ProductOSQueueStore {
375    // TODO: Handle as a queue store values (okay for now)
376    pub fn new(config: &product_os_configuration::QueueStore) -> Self {
377        match config.kind {
378            #[cfg(feature = "redis_queue_store")]
379            QueueKind::Redis => Self {
380                store: ProductOSQueueStorage::Redis(ProductOSRedisQueueStore::new(config))
381            },
382            QueueKind::Sink => Self {
383                store: ProductOSQueueStorage::Sink(ProductOSSinkQueueStore::new(config))
384            },
385            #[cfg(feature = "memory_queue_store")]
386            QueueKind::Memory => Self {
387                store: ProductOSQueueStorage::Memory(ProductOSMemoryQueueStore::new(config))
388            },
389            #[cfg(feature = "file_queue_store")]
390            QueueKind::File => Self {
391                store: ProductOSQueueStorage::File(ProductOSFileQueueStore::new(config))
392            },
393            _ => panic!("Queue kind module not loaded: {:?}", config.kind)
394        }
395    }
396
397    pub fn connect(&mut self) -> Result<(), ProductOSStoreError> {
398        match &mut self.store {
399            #[cfg(feature = "redis_queue_store")]
400            ProductOSQueueStorage::Redis(store) => store.connect(),
401            ProductOSQueueStorage::Sink(store) => store.connect(),
402            #[cfg(feature = "memory_queue_store")]
403            ProductOSQueueStorage::Memory(store) => store.connect(),
404            #[cfg(feature = "file_queue_store")]
405            ProductOSQueueStorage::File(store) => store.connect()
406        }
407    }
408
409    pub fn disconnect(&mut self) -> Result<(), ProductOSStoreError> {
410        match &mut self.store {
411            #[cfg(feature = "redis_queue_store")]
412            ProductOSQueueStorage::Redis(store) => store.disconnect(),
413            ProductOSQueueStorage::Sink(store) => store.disconnect(),
414            #[cfg(feature = "memory_queue_store")]
415            ProductOSQueueStorage::Memory(store) => store.disconnect(),
416            #[cfg(feature = "file_queue_store")]
417            ProductOSQueueStorage::File(store) => store.disconnect()
418        }
419    }
420
421    pub fn set_queue(&mut self, queue: &str) {
422        match &mut self.store {
423            #[cfg(feature = "redis_queue_store")]
424            ProductOSQueueStorage::Redis(store) => store.set_queue(queue),
425            ProductOSQueueStorage::Sink(store) => store.set_queue(queue),
426            #[cfg(feature = "memory_queue_store")]
427            ProductOSQueueStorage::Memory(store) => store.set_queue(queue),
428            #[cfg(feature = "file_queue_store")]
429            ProductOSQueueStorage::File(store) => store.set_queue(queue)
430        }
431    }
432
433    pub fn set_queue_type(&mut self, queue_type: &str) {
434        match &mut self.store {
435            #[cfg(feature = "redis_queue_store")]
436            ProductOSQueueStorage::Redis(store) => store.set_queue_type(queue_type),
437            ProductOSQueueStorage::Sink(store) => store.set_queue_type(queue_type),
438            #[cfg(feature = "memory_queue_store")]
439            ProductOSQueueStorage::Memory(store) => store.set_queue_type(queue_type),
440            #[cfg(feature = "file_queue_store")]
441            ProductOSQueueStorage::File(store) => store.set_queue_type(queue_type)
442        }
443    }
444
445    pub fn queue_push(&self, value: &str) -> Result<(), ProductOSStoreError> {
446        match &self.store {
447            #[cfg(feature = "redis_queue_store")]
448            ProductOSQueueStorage::Redis(store) => store.queue_push(value),
449            ProductOSQueueStorage::Sink(store) => store.queue_push(value),
450            #[cfg(feature = "memory_queue_store")]
451            ProductOSQueueStorage::Memory(store) => store.queue_push(value),
452            #[cfg(feature = "file_queue_store")]
453            ProductOSQueueStorage::File(store) => store.queue_push(value)
454        }
455    }
456
457    pub fn queue_insert(&self, position: u64, value: &str) -> Result<(), ProductOSStoreError> {
458        match &self.store {
459            #[cfg(feature = "redis_queue_store")]
460            ProductOSQueueStorage::Redis(store) => store.queue_insert(position, value),
461            ProductOSQueueStorage::Sink(store) => store.queue_insert(position, value),
462            #[cfg(feature = "memory_queue_store")]
463            ProductOSQueueStorage::Memory(store) => store.queue_insert(position, value),
464            #[cfg(feature = "file_queue_store")]
465            ProductOSQueueStorage::File(store) => store.queue_insert(position, value)
466        }
467    }
468
469    pub fn queue_remove(&self) -> Result<String, ProductOSStoreError> {
470        match &self.store {
471            #[cfg(feature = "redis_queue_store")]
472            ProductOSQueueStorage::Redis(store) => store.queue_remove(),
473            ProductOSQueueStorage::Sink(store) => store.queue_remove(),
474            #[cfg(feature = "memory_queue_store")]
475            ProductOSQueueStorage::Memory(store) => store.queue_remove(),
476            #[cfg(feature = "file_queue_store")]
477            ProductOSQueueStorage::File(store) => store.queue_remove()
478        }
479    }
480
481    pub fn queue_pop(&self) -> Result<String, ProductOSStoreError> {
482        match &self.store {
483            #[cfg(feature = "redis_queue_store")]
484            ProductOSQueueStorage::Redis(store) => store.queue_pop(),
485            ProductOSQueueStorage::Sink(store) => store.queue_pop(),
486            #[cfg(feature = "memory_queue_store")]
487            ProductOSQueueStorage::Memory(store) => store.queue_pop(),
488            #[cfg(feature = "file_queue_store")]
489            ProductOSQueueStorage::File(store) => store.queue_pop()
490        }
491    }
492
493    pub fn queue_specific_push(&self, value: &str, queue: &str) -> Result<(), ProductOSStoreError> {
494        match &self.store {
495            #[cfg(feature = "redis_queue_store")]
496            ProductOSQueueStorage::Redis(store) => store.queue_specific_push(value, queue),
497            ProductOSQueueStorage::Sink(store) => store.queue_specific_push(value, queue),
498            #[cfg(feature = "memory_queue_store")]
499            ProductOSQueueStorage::Memory(store) => store.queue_specific_push(value, queue),
500            #[cfg(feature = "file_queue_store")]
501            ProductOSQueueStorage::File(store) => store.queue_specific_push(value, queue)
502        }
503    }
504
505    pub fn queue_specific_insert(&self, position: u64, value: &str, queue: &str) -> Result<(), ProductOSStoreError> {
506        match &self.store {
507            #[cfg(feature = "redis_queue_store")]
508            ProductOSQueueStorage::Redis(store) => store.queue_specific_insert(position, value, queue),
509            ProductOSQueueStorage::Sink(store) => store.queue_specific_insert(position, value, queue),
510            #[cfg(feature = "memory_queue_store")]
511            ProductOSQueueStorage::Memory(store) => store.queue_specific_insert(position, value, queue),
512            #[cfg(feature = "file_queue_store")]
513            ProductOSQueueStorage::File(store) => store.queue_specific_insert(position, value, queue)
514        }
515    }
516
517    pub fn queue_specific_remove(&self, queue: &str) -> Result<String, ProductOSStoreError> {
518        match &self.store {
519            #[cfg(feature = "redis_queue_store")]
520            ProductOSQueueStorage::Redis(store) => store.queue_specific_remove(queue),
521            ProductOSQueueStorage::Sink(store) => store.queue_specific_remove(queue),
522            #[cfg(feature = "memory_queue_store")]
523            ProductOSQueueStorage::Memory(store) => store.queue_specific_remove(queue),
524            #[cfg(feature = "file_queue_store")]
525            ProductOSQueueStorage::File(store) => store.queue_specific_remove(queue)
526        }
527    }
528
529    pub fn queue_specific_pop(&self, queue: &str) -> Result<String, ProductOSStoreError> {
530        match &self.store {
531            #[cfg(feature = "redis_queue_store")]
532            ProductOSQueueStorage::Redis(store) => store.queue_specific_pop(queue),
533            ProductOSQueueStorage::Sink(store) => store.queue_specific_pop(queue),
534            #[cfg(feature = "memory_queue_store")]
535            ProductOSQueueStorage::Memory(store) => store.queue_specific_pop(queue),
536            #[cfg(feature = "file_queue_store")]
537            ProductOSQueueStorage::File(store) => store.queue_specific_pop(queue)
538        }
539    }
540}
541
542
543#[cfg(feature = "relational_store")]
544pub enum ProductOSRelationalStorageType {
545    Postgres,
546    Sqlite,
547    Sink
548}
549
550
551#[cfg(feature = "relational_store")]
552pub enum ProductOSRelationalStorage {
553    #[cfg(feature = "postgres_relational_store")]
554    Postgres(ProductOSPostgresRelationalStore<Postgres>),
555    #[cfg(feature = "sqlite_relational_store")]
556    Sqlite(ProductOSSqliteRelationalStore<Sqlite>),
557    Sink(ProductOSSinkRelationalStore)
558    // Memory(ProductOSMemoryRelationalStore)
559}
560
561
562#[cfg(feature = "relational_store")]
563pub struct ProductOSRelationalStore {
564    store: ProductOSRelationalStorage
565}
566
567#[cfg(feature = "relational_store")]
568impl ProductOSRelationalStore {
569    pub fn new(config: &product_os_configuration::RelationalStore) -> Self {
570        match config.kind {
571            #[cfg(feature = "postgres_relational_store")]
572            RelationalKind::Postgres => Self {
573                store: ProductOSRelationalStorage::Postgres(ProductOSPostgresRelationalStore::new(config))
574            },
575            #[cfg(feature = "sqlite_relational_store")]
576            RelationalKind::Sqlite => Self {
577                store: ProductOSRelationalStorage::Sqlite(ProductOSSqliteRelationalStore::new(config))
578            },
579            RelationalKind::Sink => Self {
580                store: ProductOSRelationalStorage::Sink(ProductOSSinkRelationalStore::new(config))
581            },
582            _ => panic!("Relational store kind not currently supported")
583        }
584    }
585
586    pub async fn connect(&mut self) -> Result<(), ProductOSStoreError> {
587        match &mut self.store {
588            #[cfg(feature = "postgres_relational_store")]
589            ProductOSRelationalStorage::Postgres(store) => store.connect().await,
590            #[cfg(feature = "sqlite_relational_store")]
591            ProductOSRelationalStorage::Sqlite(store) => store.connect().await,
592            ProductOSRelationalStorage::Sink(store) => store.connect().await,
593            _ => panic!("Relational store kind not currently supported")
594        }
595    }
596
597    pub fn connect_sync(&mut self) -> Result<(), ProductOSStoreError> {
598        match &mut self.store {
599            #[cfg(feature = "postgres_relational_store")]
600            ProductOSRelationalStorage::Postgres(store) => store.connect_sync(),
601            #[cfg(feature = "sqlite_relational_store")]
602            ProductOSRelationalStorage::Sqlite(store) => store.connect_sync(),
603            ProductOSRelationalStorage::Sink(store) => store.connect_sync(),
604            _ => panic!("Relational store kind not currently supported")
605        }
606    }
607
608    pub async fn disconnect(&mut self) -> Result<(), ProductOSStoreError> {
609        match &mut self.store {
610            #[cfg(feature = "postgres_relational_store")]
611            ProductOSRelationalStorage::Postgres(store) => store.disconnect().await,
612            #[cfg(feature = "sqlite_relational_store")]
613            ProductOSRelationalStorage::Sqlite(store) => store.disconnect().await,
614            ProductOSRelationalStorage::Sink(store) => store.disconnect().await,
615            _ => panic!("Relational store kind not currently supported")
616        }
617    }
618
619    pub async fn get_one_raw(&self, query: &str) -> Result<Option<RelationalRow>, ProductOSStoreError> {
620        match &self.store {
621            #[cfg(feature = "postgres_relational_store")]
622            ProductOSRelationalStorage::Postgres(store) => store.get_one_raw(query).await,
623            #[cfg(feature = "sqlite_relational_store")]
624            ProductOSRelationalStorage::Sqlite(store) => store.get_one_raw(query).await,
625            ProductOSRelationalStorage::Sink(store) => store.get_one_raw(query).await,
626            _ => panic!("Relational store kind not currently supported")
627        }
628    }
629
630    pub async fn get_all_raw(&self, query: &str) -> Result<Vec<RelationalRow>, ProductOSStoreError> {
631        match &self.store {
632            #[cfg(feature = "postgres_relational_store")]
633            ProductOSRelationalStorage::Postgres(store) => store.get_all_raw(query).await,
634            #[cfg(feature = "sqlite_relational_store")]
635            ProductOSRelationalStorage::Sqlite(store) => store.get_all_raw(query).await,
636            ProductOSRelationalStorage::Sink(store) => store.get_all_raw(query).await,
637            _ => panic!("Relational store kind not currently supported")
638        }
639    }
640
641    pub async fn get_raw(&self, query: &str) -> Result<Vec<RelationalRow>, ProductOSStoreError> {
642        match &self.store {
643            #[cfg(feature = "postgres_relational_store")]
644            ProductOSRelationalStorage::Postgres(store) => store.get_raw(query).await,
645            #[cfg(feature = "sqlite_relational_store")]
646            ProductOSRelationalStorage::Sqlite(store) => store.get_raw(query).await,
647            ProductOSRelationalStorage::Sink(store) => store.get_raw(query).await,
648            _ => panic!("Relational store kind not currently supported")
649        }
650    }
651
652    pub async fn execute_raw(&self, instruction: &str) -> Result<RelationalResult, ProductOSStoreError> {
653        match &self.store {
654            #[cfg(feature = "postgres_relational_store")]
655            ProductOSRelationalStorage::Postgres(store) => store.execute_raw(instruction).await,
656            #[cfg(feature = "sqlite_relational_store")]
657            ProductOSRelationalStorage::Sqlite(store) => store.execute_raw(instruction).await,
658            ProductOSRelationalStorage::Sink(store) => store.execute_raw(instruction).await,
659            _ => panic!("Relational store kind not currently supported")
660        }
661    }
662
663    pub async fn transaction_raw(&self, instructions: &[String]) -> Result<Vec<RelationalResult>, ProductOSStoreError> {
664        match &self.store {
665            #[cfg(feature = "postgres_relational_store")]
666            ProductOSRelationalStorage::Postgres(store) => store.transaction_raw(instructions).await,
667            #[cfg(feature = "sqlite_relational_store")]
668            ProductOSRelationalStorage::Sqlite(store) => store.transaction_raw(instructions).await,
669            ProductOSRelationalStorage::Sink(store) => store.transaction_raw(instructions).await,
670            _ => panic!("Relational store kind not currently supported")
671        }
672    }
673
674    pub async fn transaction(&self, instructions: &[Instruction]) -> Result<Vec<RelationalResult>, ProductOSStoreError> {
675        match &self.store {
676            #[cfg(feature = "postgres_relational_store")]
677            ProductOSRelationalStorage::Postgres(store) => store.transaction(instructions).await,
678            #[cfg(feature = "sqlite_relational_store")]
679            ProductOSRelationalStorage::Sqlite(store) => store.transaction(instructions).await,
680            ProductOSRelationalStorage::Sink(store) => store.transaction(instructions).await,
681            _ => panic!("Relational store kind not currently supported")
682        }
683    }
684
685    pub async fn get_one<IRO>(&self, query: &Query) -> Result<Option<IRO>, ProductOSStoreError>
686    where
687        IRO: ProductOSRelationalObject + Default
688    {
689        match &self.store {
690            #[cfg(feature = "postgres_relational_store")]
691            ProductOSRelationalStorage::Postgres(store) => store.get_one(query).await,
692            #[cfg(feature = "sqlite_relational_store")]
693            ProductOSRelationalStorage::Sqlite(store) => store.get_one(query).await,
694            ProductOSRelationalStorage::Sink(store) => store.get_one(query).await,
695            _ => panic!("Relational store kind not currently supported")
696        }
697    }
698
699    pub async fn get_one_specific(&self, query: &Query) -> Result<Option<RelationalRow>, ProductOSStoreError> {
700        match &self.store {
701            #[cfg(feature = "postgres_relational_store")]
702            ProductOSRelationalStorage::Postgres(store) => store.get_one_specific(query).await,
703            #[cfg(feature = "sqlite_relational_store")]
704            ProductOSRelationalStorage::Sqlite(store) => store.get_one_specific(query).await,
705            ProductOSRelationalStorage::Sink(store) => store.get_one_specific(query).await,
706            _ => panic!("Relational store kind not currently supported")
707        }
708    }
709
710    pub async fn get_all<IRO>(&self, query: &Query) -> Result<Vec<IRO>, ProductOSStoreError>
711    where
712        IRO: ProductOSRelationalObject + Default
713    {
714        match &self.store {
715            #[cfg(feature = "postgres_relational_store")]
716            ProductOSRelationalStorage::Postgres(store) => store.get_all(query).await,
717            #[cfg(feature = "sqlite_relational_store")]
718            ProductOSRelationalStorage::Sqlite(store) => store.get_all(query).await,
719            ProductOSRelationalStorage::Sink(store) => store.get_all(query).await,
720            _ => panic!("Relational store kind not currently supported")
721        }
722    }
723
724    pub async fn get_all_specific(&self, query: &Query) -> Result<Vec<RelationalRow>, ProductOSStoreError> {
725        match &self.store {
726            #[cfg(feature = "postgres_relational_store")]
727            ProductOSRelationalStorage::Postgres(store) => store.get_all_specific(query).await,
728            #[cfg(feature = "sqlite_relational_store")]
729            ProductOSRelationalStorage::Sqlite(store) => store.get_all_specific(query).await,
730            ProductOSRelationalStorage::Sink(store) => store.get_all_specific(query).await,
731            _ => panic!("Relational store kind not currently supported")
732        }
733    }
734
735    pub async fn count(&self, query: &Query, identifier_name: &str) -> Result<i64, ProductOSStoreError> {
736        match &self.store {
737            #[cfg(feature = "postgres_relational_store")]
738            ProductOSRelationalStorage::Postgres(store) => store.count(query, identifier_name).await,
739            #[cfg(feature = "sqlite_relational_store")]
740            ProductOSRelationalStorage::Sqlite(store) => store.count(query, identifier_name).await,
741            ProductOSRelationalStorage::Sink(store) => store.count(query, identifier_name).await,
742            _ => panic!("Relational store kind not currently supported")
743        }
744    }
745
746    pub async fn execute(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
747        match &self.store {
748            #[cfg(feature = "postgres_relational_store")]
749            ProductOSRelationalStorage::Postgres(store) => store.execute(instruction).await,
750            #[cfg(feature = "sqlite_relational_store")]
751            ProductOSRelationalStorage::Sqlite(store) => store.execute(instruction).await,
752            ProductOSRelationalStorage::Sink(store) => store.execute(instruction).await,
753            _ => panic!("Relational store kind not currently supported")
754        }
755    }
756
757    pub async fn create(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
758        match &self.store {
759            #[cfg(feature = "postgres_relational_store")]
760            ProductOSRelationalStorage::Postgres(store) => store.create(instruction).await,
761            #[cfg(feature = "sqlite_relational_store")]
762            ProductOSRelationalStorage::Sqlite(store) => store.create(instruction).await,
763            ProductOSRelationalStorage::Sink(store) => store.create(instruction).await,
764            _ => panic!("Relational store kind not currently supported")
765        }
766    }
767
768    pub async fn alter(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
769        match &self.store {
770            #[cfg(feature = "postgres_relational_store")]
771            ProductOSRelationalStorage::Postgres(store) => store.alter(instruction).await,
772            #[cfg(feature = "sqlite_relational_store")]
773            ProductOSRelationalStorage::Sqlite(store) => store.alter(instruction).await,
774            ProductOSRelationalStorage::Sink(store) => store.alter(instruction).await,
775            _ => panic!("Relational store kind not currently supported")
776        }
777    }
778
779    pub async fn drop(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
780        match &self.store {
781            #[cfg(feature = "postgres_relational_store")]
782            ProductOSRelationalStorage::Postgres(store) => store.drop(instruction).await,
783            #[cfg(feature = "sqlite_relational_store")]
784            ProductOSRelationalStorage::Sqlite(store) => store.drop(instruction).await,
785            ProductOSRelationalStorage::Sink(store) => store.drop(instruction).await,
786            _ => panic!("Relational store kind not currently supported")
787        }
788    }
789
790    pub async fn insert(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
791        match &self.store {
792            #[cfg(feature = "postgres_relational_store")]
793            ProductOSRelationalStorage::Postgres(store) => store.insert(instruction).await,
794            #[cfg(feature = "sqlite_relational_store")]
795            ProductOSRelationalStorage::Sqlite(store) => store.insert(instruction).await,
796            ProductOSRelationalStorage::Sink(store) => store.insert(instruction).await,
797            _ => panic!("Relational store kind not currently supported")
798        }
799    }
800
801    pub async fn update(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
802        match &self.store {
803            #[cfg(feature = "postgres_relational_store")]
804            ProductOSRelationalStorage::Postgres(store) => store.update(instruction).await,
805            #[cfg(feature = "sqlite_relational_store")]
806            ProductOSRelationalStorage::Sqlite(store) => store.update(instruction).await,
807            ProductOSRelationalStorage::Sink(store) => store.update(instruction).await,
808            _ => panic!("Relational store kind not currently supported")
809        }
810    }
811
812    pub async fn upsert(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
813        match &self.store {
814            #[cfg(feature = "postgres_relational_store")]
815            ProductOSRelationalStorage::Postgres(store) => store.upsert(instruction).await,
816            #[cfg(feature = "sqlite_relational_store")]
817            ProductOSRelationalStorage::Sqlite(store) => store.upsert(instruction).await,
818            ProductOSRelationalStorage::Sink(store) => store.upsert(instruction).await,
819            _ => panic!("Relational store kind not currently supported")
820        }
821    }
822
823    pub async fn delete(&self, instruction: &Instruction) -> Result<RelationalResult, ProductOSStoreError> {
824        match &self.store {
825            #[cfg(feature = "postgres_relational_store")]
826            ProductOSRelationalStorage::Postgres(store) => store.delete(instruction).await,
827            #[cfg(feature = "sqlite_relational_store")]
828            ProductOSRelationalStorage::Sqlite(store) => store.delete(instruction).await,
829            ProductOSRelationalStorage::Sink(store) => store.delete(instruction).await,
830            _ => panic!("Relational store kind not currently supported")
831        }
832    }
833
834    pub async fn index(&self, table: Option<&str>) -> Result<RelationalResult, ProductOSStoreError> {
835        match &self.store {
836            #[cfg(feature = "postgres_relational_store")]
837            ProductOSRelationalStorage::Postgres(store) => store.index(table).await,
838            #[cfg(feature = "sqlite_relational_store")]
839            ProductOSRelationalStorage::Sqlite(store) => store.index(table).await,
840            ProductOSRelationalStorage::Sink(store) => store.index(table).await,
841            _ => panic!("Relational store kind not currently supported")
842        }
843    }
844
845    pub async fn total(&self, table: &str) -> Result<i64, ProductOSStoreError> {
846        match &self.store {
847            #[cfg(feature = "postgres_relational_store")]
848            ProductOSRelationalStorage::Postgres(store) => store.total(table).await,
849            #[cfg(feature = "sqlite_relational_store")]
850            ProductOSRelationalStorage::Sqlite(store) => store.total(table).await,
851            ProductOSRelationalStorage::Sink(store) => store.total(table).await,
852            _ => panic!("Relational store kind not currently supported")
853        }
854    }
855
856    pub fn get_query(query: &Query, relational_type: ProductOSRelationalStorageType) -> Result<String, ProductOSStoreError> {
857        process_query_to_string(query, &relational_type)
858    }
859
860    pub fn get_instruction(instruction: &Instruction, relational_type: ProductOSRelationalStorageType) -> Result<String, ProductOSStoreError> {
861        process_instruction_to_string(instruction, &relational_type)
862    }
863}