This commit is contained in:
Emily Toop 2018-05-23 17:27:18 +01:00
parent 9d8c666052
commit baa7cb4f8f

View file

@ -65,12 +65,16 @@ use query::{
/// A process is only permitted to have one open handle to each database. This manager /// A process is only permitted to have one open handle to each database. This manager
/// exists to enforce that constraint: don't open databases directly. /// exists to enforce that constraint: don't open databases directly.
lazy_static! { thread_local! {
static ref STORES: Arc<RwLock<Stores>> = { static STORES: RwLock<Stores> = {
Arc::new(RwLock::new(Stores::new())) RwLock::new(Stores::new())
}; };
} }
lazy_static! {
static ref CONNECTIONS: BTreeMap<String, Arc<Conn>> = BTreeMap::default();
}
pub struct Stores { pub struct Stores {
stores: BTreeMap<String, Store>, stores: BTreeMap<String, Store>,
} }
@ -81,10 +85,6 @@ impl Stores {
stores: Default::default(), stores: Default::default(),
} }
} }
pub fn singleton() -> &'static RwLock<Stores> {
&*STORES
}
} }
impl Stores { impl Stores {
@ -92,9 +92,32 @@ impl Stores {
Stores::singleton().read().unwrap().stores.contains_key(path) Stores::singleton().read().unwrap().stores.contains_key(path)
} }
pub fn open(path: &str) -> Result<&mut Store> { pub fn open(path: &str) -> Result<Store> {
let p = path.to_string(); let p = path.to_string();
Ok(Stores::singleton().write().unwrap().stores.entry(p).or_insert(Store::open(path)?)) let stores = Stores::singleton().read().unwrap().stores;
let store = match stores.get(path) {
Some(conn) => {
let connection = CONNECTIONS.with(|s| s.entry(path.to_string()).or_insert_with(|| {
::new_connection(path).unwrap()
}));
Store {
conn: conn.clone(),
sqlite: *connection,
}
},
None => {
let mut connection = ::new_connection(path)?;
CONNECTIONS.with(|s| s.insert(path.to_string(), connection));
let conn = Arc::new(Conn::connect(&mut connection)?);
stores.insert(path.to_string(), conn);
let store = Store {
conn: conn,
sqlite: connection,
};
store
}
};
Ok(store)
} }
pub fn get(path: &str) -> Result<Option<&Store>> { pub fn get(path: &str) -> Result<Option<&Store>> {