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
use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::ops::Deref; use rusqlite::*; use thread_local::ThreadLocal; static COUNTER: AtomicU64 = AtomicU64::new(0u64); pub fn open_shared(name: &str) -> Result<Connection> { let uri = format!("file:{}?mode=memory&cache=shared", name); Connection::open(uri) } pub fn new_shared() -> Result<Connection> { open_shared(&format!( "shared_{}", COUNTER.fetch_add(1u64, Ordering::AcqRel) )) } pub struct SyncSqliteConnection { connection: ThreadLocal<Connection>, name: String, } impl SyncSqliteConnection { pub fn new() -> Self { let name = format!("shared_{}", COUNTER.fetch_add(1u64, Ordering::AcqRel)); SyncSqliteConnection { connection: ThreadLocal::new(), name: name, } } pub fn open(name: String) -> Self { SyncSqliteConnection { connection: ThreadLocal::new(), name: name, } } pub fn name(&self) -> &String { &self.name } pub fn force(&self) -> &Connection { self.connection.get_or(|| { open_shared(&self.name()).expect( "ERROR: Creating the connection to the sqlite in memory database has failed!", ) }) } } impl Deref for SyncSqliteConnection { type Target = Connection; fn deref(&self) -> &Self::Target { self.force() } } impl Clone for SyncSqliteConnection { fn clone(&self) -> Self { SyncSqliteConnection::open(self.name().clone()) } fn clone_from(&mut self, source: &Self) { self.name = source.name().clone(); self.connection.clear(); } } mod test { #[test] fn testnew() { crate::SyncSqliteConnection::new(); } #[test] fn testnewrealconnection() { let c = crate::SyncSqliteConnection::new(); c.force(); } #[test] fn test_open() { let dummy = crate::SyncSqliteConnection::new(); dummy.force(); let c1 = crate::SyncSqliteConnection::new(); c1.force(); let c2 = crate::SyncSqliteConnection::open(c1.name().clone()); c2.force(); assert_eq!(c1.name(), c2.name()); assert_ne!(dummy.name(), c1.name()); } #[test] fn test_clone() { let c1 = crate::SyncSqliteConnection::new(); c1.force(); let c2 = c1.clone(); assert_eq!(c1.name(), c2.name()); } }