Skip to main content

premix_core/
sql_cache.rs

1use std::sync::OnceLock;
2use std::{any::TypeId, collections::HashMap, sync::Mutex};
3
4use crate::dialect::SqlDialect;
5
6type PlaceholderKey = (TypeId, usize);
7type PlaceholderFromKey = (TypeId, usize, usize);
8type PlaceholderCache = Mutex<HashMap<PlaceholderKey, &'static str>>;
9type PlaceholderFromCache = Mutex<HashMap<PlaceholderFromKey, &'static str>>;
10
11static PLACEHOLDER_CACHE: OnceLock<PlaceholderCache> = OnceLock::new();
12static PLACEHOLDER_FROM_CACHE: OnceLock<PlaceholderFromCache> = OnceLock::new();
13
14/// Returns a cached placeholder list for `(DB, count)` combinations.
15pub fn cached_placeholders<DB>(count: usize) -> &'static str
16where
17    DB: SqlDialect + 'static,
18{
19    let key = (TypeId::of::<DB>(), count);
20    let cache = PLACEHOLDER_CACHE.get_or_init(|| Mutex::new(HashMap::new()));
21    let mut guard = cache.lock().expect("placeholder cache poisoned");
22    if let Some(value) = guard.get(&key) {
23        value
24    } else {
25        let placeholders = crate::build_placeholders::<DB>(1, count);
26        let leaked: &'static str = Box::leak(placeholders.into_boxed_str());
27        guard.insert(key, leaked);
28        leaked
29    }
30}
31
32/// Returns a cached placeholder list for `(DB, start, count)` combinations.
33pub fn cached_placeholders_from<DB>(start: usize, count: usize) -> &'static str
34where
35    DB: SqlDialect + 'static,
36{
37    let key = (TypeId::of::<DB>(), start, count);
38    let cache = PLACEHOLDER_FROM_CACHE.get_or_init(|| Mutex::new(HashMap::new()));
39    let mut guard = cache.lock().expect("placeholder cache poisoned");
40    if let Some(value) = guard.get(&key) {
41        value
42    } else {
43        let placeholders = crate::build_placeholders::<DB>(start, count);
44        let leaked: &'static str = Box::leak(placeholders.into_boxed_str());
45        guard.insert(key, leaked);
46        leaked
47    }
48}