1pub struct KvdbSqlite<ValueType> {
6 connection: Option<SqliteConnection>,
9 statements: Arc<KvdbSqliteStatements>,
10 __marker_value: PhantomData<ValueType>,
11}
12
13impl<ValueType> MallocSizeOf for KvdbSqlite<ValueType> {
14 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
15 self.connection.size_of(ops)
16 }
17}
18
19pub struct KvdbSqliteBorrowShared<'db, ValueType> {
20 connection: Option<*const SqliteConnection>,
21 statements: *const KvdbSqliteStatements,
22 __marker_lifetime: PhantomData<&'db SqliteConnection>,
23 __marker_value: PhantomData<ValueType>,
24}
25
26pub struct KvdbSqliteBorrowMut<'db, ValueType> {
27 connection: Option<*mut SqliteConnection>,
28 statements: *const KvdbSqliteStatements,
29 __marker_lifetime: PhantomData<&'db mut SqliteConnection>,
30 __marker_value: PhantomData<ValueType>,
31}
32
33#[derive(Clone)]
34pub struct KvdbSqliteStatements {
35 pub stmts_main_table: KvdbSqliteStatementsPerTable,
36 pub stmts_bytes_key_table: KvdbSqliteStatementsPerTable,
39}
40
41#[derive(Clone)]
42pub struct KvdbSqliteStatementsPerTable {
43 pub create_table: String,
44 pub drop_table: String,
45 pub get: String,
46 pub put: String,
47 pub delete: String,
48 pub range_select_statement: String,
49 pub range_select_till_end_statement: String,
50 pub range_excl_select_statement: String,
51 pub select_tbl_name: String,
52 pub vacuum: String,
53}
54
55impl KvdbSqliteStatements {
56 pub const BYTES_KEY_TABLE_SUFFIX: &'static str = "_bytes_key";
57 pub const CREATE_TABLE_BLOB_KV_STATEMENT_TMPL: &'static str =
59 "CREATE TABLE IF NOT EXISTS {table_name} ( key BLOB PRIMARY KEY {comma_value_columns_def} ) WITHOUT ROWID";
60 pub const CREATE_TABLE_NUMBER_KV_STATEMENT_TMPL: &'static str =
62 "CREATE TABLE IF NOT EXISTS {table_name} ( key INTEGER PRIMARY KEY {comma_value_columns_def} )";
63 pub const DELETE_STATEMENT: &'static str =
64 "DELETE FROM {table_name} where key = :key";
65 pub const DROP_TABLE_STATEMENT: &'static str =
66 "DROP TABLE IF EXISTS {table_name}";
67 pub const GET_STATEMENT_TMPL: &'static str =
68 "SELECT {value_columns} FROM {table_name} WHERE key = :key";
69 pub const PUT_STATEMENT_TMPL: &'static str =
70 "INSERT OR REPLACE INTO {table_name} VALUES (:key {comma_value_columns_to_bind})";
71 pub const RANGE_EXCL_SELECT_STATEMENT: &'static str =
72 "SELECT key {comma_value_columns} FROM {table_name} \
73 WHERE key > :lower_bound_excl AND key < :upper_bound_excl ORDER BY key ASC";
74 pub const RANGE_SELECT_STATEMENT: &'static str =
75 "SELECT key {comma_value_columns} FROM {table_name} \
76 WHERE key >= :lower_bound_incl AND key < :upper_bound_excl ORDER BY key ASC";
77 pub const RANGE_SELECT_STATEMENT_TILL_END: &'static str =
78 "SELECT key {comma_value_columns} FROM {table_name} \
79 WHERE key >= :lower_bound_incl ORDER BY key ASC";
80 pub const SELECT_TBL_NAME: &'static str =
81 "SELECT tbl_name FROM sqlite_master WHERE tbl_name = \"{table_name}\" AND type = \"table\"";
82 pub const VACUUM: &'static str = "vacuum";
83
84 pub fn make_statements(
85 value_column_names: &[&str], value_column_types: &[&str],
86 main_table_name: &str, with_number_key_table: bool,
87 ) -> Result<Self> {
88 let bytes_key_table_name;
89 let bytes_key_table;
90 if with_number_key_table {
91 bytes_key_table = main_table_name.to_string()
92 + KvdbSqliteStatements::BYTES_KEY_TABLE_SUFFIX;
93 bytes_key_table_name = bytes_key_table.as_str();
94 } else {
95 bytes_key_table_name = main_table_name;
96 }
97 Ok(Self {
98 stmts_main_table:
99 KvdbSqliteStatementsPerTable::make_table_statements(
100 value_column_names,
101 value_column_types,
102 main_table_name,
103 if with_number_key_table {
104 Self::CREATE_TABLE_NUMBER_KV_STATEMENT_TMPL
105 } else {
106 Self::CREATE_TABLE_BLOB_KV_STATEMENT_TMPL
107 },
108 )?,
109 stmts_bytes_key_table: {
110 KvdbSqliteStatementsPerTable::make_table_statements(
111 value_column_names,
112 value_column_types,
113 bytes_key_table_name,
114 Self::CREATE_TABLE_BLOB_KV_STATEMENT_TMPL,
115 )?
116 },
117 })
118 }
119}
120
121impl KvdbSqliteStatementsPerTable {
122 pub fn make_table_statements(
123 value_column_names: &[&str], value_column_types: &[&str],
124 table_name: &str, create_table_sql: &str,
125 ) -> Result<Self> {
126 let comma_value_columns_def = value_column_names
127 .iter()
128 .zip(value_column_types.iter())
129 .map(|(n, t)| format!(", {} {}", n, t))
130 .collect::<Vec<String>>()
131 .concat();
132 let value_columns = value_column_names.join(", ");
133 let comma_value_columns = if value_columns.len() == 0 {
134 value_columns.clone()
135 } else {
136 ", ".to_string() + &value_columns
137 };
138 let comma_value_columns_to_bind = value_column_names
139 .iter()
140 .map(|n| ", :".to_string() + n)
141 .collect::<Vec<String>>()
142 .concat();
143
144 let mut strfmt_vars = HashMap::new();
145 strfmt_vars.insert(
146 "comma_value_columns_def".to_string(),
147 comma_value_columns_def,
148 );
149 strfmt_vars.insert("value_columns".to_string(), value_columns);
150 strfmt_vars
151 .insert("comma_value_columns".to_string(), comma_value_columns);
152 strfmt_vars.insert(
153 "comma_value_columns_to_bind".to_string(),
154 comma_value_columns_to_bind,
155 );
156 strfmt_vars.insert("table_name".to_string(), table_name.to_string());
157
158 Ok(Self {
159 create_table: strfmt(create_table_sql, &strfmt_vars)?,
160 drop_table: strfmt(
161 KvdbSqliteStatements::DROP_TABLE_STATEMENT,
162 &strfmt_vars,
163 )?,
164 get: strfmt(
165 KvdbSqliteStatements::GET_STATEMENT_TMPL,
166 &strfmt_vars,
167 )?,
168 put: strfmt(
169 KvdbSqliteStatements::PUT_STATEMENT_TMPL,
170 &strfmt_vars,
171 )?,
172 delete: strfmt(
173 KvdbSqliteStatements::DELETE_STATEMENT,
174 &strfmt_vars,
175 )?,
176 range_select_statement: strfmt(
177 KvdbSqliteStatements::RANGE_SELECT_STATEMENT,
178 &strfmt_vars,
179 )?,
180 range_select_till_end_statement: strfmt(
181 KvdbSqliteStatements::RANGE_SELECT_STATEMENT_TILL_END,
182 &strfmt_vars,
183 )?,
184 range_excl_select_statement: strfmt(
185 KvdbSqliteStatements::RANGE_EXCL_SELECT_STATEMENT,
186 &strfmt_vars,
187 )?,
188 select_tbl_name: strfmt(
189 KvdbSqliteStatements::SELECT_TBL_NAME,
190 &strfmt_vars,
191 )?,
192 vacuum: strfmt(KvdbSqliteStatements::VACUUM, &strfmt_vars)?,
193 })
194 }
195}
196
197impl<ValueType> KvdbSqlite<ValueType> {
198 pub fn new(
199 connection: Option<SqliteConnection>,
200 statements: Arc<KvdbSqliteStatements>,
201 ) -> Result<Self> {
202 Ok(Self {
203 connection,
204 statements,
205 __marker_value: Default::default(),
206 })
207 }
208
209 pub fn into_connection(self) -> Option<SqliteConnection> { self.connection }
210}
211
212impl<ValueType> KvdbSqlite<ValueType> {
213 pub fn try_clone(&self) -> Result<Self> {
214 Ok(Self {
215 connection: match &self.connection {
216 None => None,
217 Some(conn) => Some(conn.try_clone()?),
218 },
219 statements: self.statements.clone(),
220 __marker_value: Default::default(),
221 })
222 }
223
224 pub fn open<P: AsRef<Path>>(
225 path: P, readonly: bool, statements: Arc<KvdbSqliteStatements>,
226 ) -> Result<Self> {
227 Ok(Self {
228 connection: Some(SqliteConnection::open(
229 path,
230 readonly,
231 SqliteConnection::default_open_flags(),
232 )?),
233 statements,
234 __marker_value: Default::default(),
235 })
236 }
237
238 pub fn open_or_create<P: AsRef<Path>>(
239 path: P, statements: Arc<KvdbSqliteStatements>, unsafe_mode: bool,
240 ) -> Result<(bool, Self)> {
241 if path.as_ref().exists() {
242 Ok((true, Self::open(path, false, statements)?))
243 } else {
244 Ok((
245 false,
246 Self::create_and_open(
247 path,
248 statements,
249 true,
250 unsafe_mode,
251 )?,
252 ))
253 }
254 }
255
256 pub fn create_and_open<P: AsRef<Path>>(
257 path: P, statements: Arc<KvdbSqliteStatements>, create_table: bool,
258 unsafe_mode: bool,
259 ) -> Result<Self> {
260 let create_result = (|statements, path| -> Result<SqliteConnection> {
261 let mut connection = SqliteConnection::create_and_open(
262 path,
263 SqliteConnection::default_open_flags(),
264 unsafe_mode,
265 )?;
266 if create_table {
267 Self::create_table(&mut connection, statements)?
268 }
269 Ok(connection)
270 })(&*statements, path.as_ref());
271
272 match create_result {
273 Ok(connection) => Ok(Self {
274 connection: Some(connection),
275 statements,
276 __marker_value: Default::default(),
277 }),
278 Err(e) => {
279 let files_to_remove =
280 SqliteConnection::possible_temporary_files(
281 &*path.as_ref().to_string_lossy(),
282 );
283 warn!("Failed to create sqlite db for {}, remove all temporary files {:?}", path.as_ref().display(), files_to_remove);
284 for file in files_to_remove {
285 fs::remove_file(file)?;
286 }
287
288 Err(e)
289 }
290 }
291 }
292
293 pub fn create_table(
294 connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
295 ) -> Result<()> {
296 if statements.stmts_main_table.create_table
299 != statements.stmts_bytes_key_table.create_table
300 {
301 connection
302 .execute(
303 &statements.stmts_bytes_key_table.create_table,
304 SQLITE_NO_PARAM,
305 )?
306 .finish_ignore_rows()?;
307 }
308
309 connection
313 .execute(
314 &statements.stmts_main_table.create_table,
315 SQLITE_NO_PARAM,
316 )?
317 .finish_ignore_rows()
318 }
319
320 pub fn check_if_table_exist(
321 connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
322 ) -> Result<bool> {
323 if statements.stmts_main_table.create_table
325 != statements.stmts_bytes_key_table.create_table
326 {
327 if connection
328 .execute(
329 &statements.stmts_bytes_key_table.select_tbl_name,
330 SQLITE_NO_PARAM,
331 )?
332 .map(|_| true)
333 .expect_one_row()?
334 .is_none()
335 {
336 return Ok(false);
337 }
338 }
339
340 if connection
342 .execute(
343 &statements.stmts_main_table.select_tbl_name,
344 SQLITE_NO_PARAM,
345 )?
346 .map(|_| true)
347 .expect_one_row()?
348 .is_some()
349 {
350 Ok(true)
351 } else {
352 Ok(false)
353 }
354 }
355
356 pub fn drop_table(
357 connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
358 ) -> Result<()> {
359 if statements.stmts_main_table.create_table
361 != statements.stmts_bytes_key_table.create_table
362 {
363 connection
364 .execute(
365 &statements.stmts_bytes_key_table.drop_table,
366 SQLITE_NO_PARAM,
367 )?
368 .finish_ignore_rows()?;
369 }
370
371 connection
373 .execute(&statements.stmts_main_table.drop_table, SQLITE_NO_PARAM)?
374 .finish_ignore_rows()
375 }
376
377 pub fn vacuum_db(
378 connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
379 ) -> Result<()> {
380 if statements.stmts_main_table.create_table
382 != statements.stmts_bytes_key_table.create_table
383 {
384 connection
385 .execute(
386 &statements.stmts_bytes_key_table.vacuum,
387 SQLITE_NO_PARAM,
388 )?
389 .finish_ignore_rows()?;
390 }
391
392 connection
394 .execute(&statements.stmts_main_table.vacuum, SQLITE_NO_PARAM)?
395 .finish_ignore_rows()
396 }
397}
398
399impl ElementConstrainMark for dyn SqlReadableIntoSelf {}
400impl<Element: 'static + SqlReadableIntoSelf>
401 ElementSatisfy<dyn SqlReadableIntoSelf> for Element
402{
403 fn to_constrain_object(&self) -> &(dyn 'static + SqlReadableIntoSelf) {
404 self
405 }
406
407 fn to_constrain_object_mut(
408 &mut self,
409 ) -> &mut (dyn 'static + SqlReadableIntoSelf) {
410 self
411 }
412}
413
414impl ElementConstrainMark for dyn BindValueAppendImpl<dyn SqlBindable> {}
415impl<Element: 'static + BindValueAppendImpl<dyn SqlBindable>>
416 ElementSatisfy<dyn BindValueAppendImpl<dyn SqlBindable>> for Element
417{
418 fn to_constrain_object(
419 &self,
420 ) -> &(dyn 'static + BindValueAppendImpl<dyn SqlBindable>) {
421 self
422 }
423
424 fn to_constrain_object_mut(
425 &mut self,
426 ) -> &mut (dyn 'static + BindValueAppendImpl<dyn SqlBindable>) {
427 self
428 }
429}
430
431impl<ValueType: ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>>
432 KvdbSqlite<ValueType>
433{
434 pub fn from_row(row: &Statement<'_>) -> Result<ValueType> {
435 ValueType::from_row_impl(row, 0)
436 }
437
438 pub fn kv_from_iter_row<Key: Default + SqlReadableIntoSelf>(
439 row: &Statement<'_>,
440 ) -> Result<(Key, ValueType)> {
441 let mut key = Key::default();
442 let value = ValueType::from_kv_row_impl(row, &mut key)?;
443 Ok((key, value))
444 }
445}
446
447impl<ValueType: DbValueType> KeyValueDbTypes for KvdbSqlite<ValueType> {
448 type ValueType = ValueType;
449}
450
451impl<
453 ValueType: 'static
454 + DbValueType
455 + ValueRead
456 + ValueReadImpl<<ValueType as ValueRead>::Kind>,
457 > KeyValueDbTraitTransactional for KvdbSqlite<ValueType>
458where ValueType::Type: SqlBindableValue
459 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
460{
461 type TransactionType = KvdbSqliteTransaction<ValueType>;
462
463 fn start_transaction(
464 &self, immediate_write: bool,
465 ) -> Result<KvdbSqliteTransaction<ValueType>> {
466 if self.connection.is_none() {
467 bail!(Error::DbNotExist);
468 }
469
470 KvdbSqliteTransaction::new(self.try_clone()?, immediate_write)
471 }
472}
473
474pub struct KvdbSqliteTransaction<
475 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
476> where ValueType::Type: SqlBindableValue
477 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
478{
479 db: KvdbSqlite<ValueType>,
480 committed: bool,
481}
482
483impl<
484 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
485 > KvdbSqliteTransaction<ValueType>
486where ValueType::Type: SqlBindableValue
487 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
488{
489 fn new(
490 mut db: KvdbSqlite<ValueType>, immediate_write: bool,
491 ) -> Result<Self> {
492 match &mut db.connection {
493 None => {}
494 Some(conn) => {
495 Self::start_transaction(conn.get_db_mut(), immediate_write)?;
496 }
497 }
498 Ok(Self {
499 db,
500 committed: false,
501 })
502 }
503
504 pub fn start_transaction(
505 db: &mut Connection, immediate_write: bool,
506 ) -> Result<()> {
507 if immediate_write {
508 db.execute("BEGIN IMMEDIATE")?;
509 } else {
510 db.execute("BEGIN DEFERRED")?;
511 }
512 Ok(())
513 }
514}
515
516impl<
517 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
518 > Drop for KvdbSqliteTransaction<ValueType>
519where ValueType::Type: SqlBindableValue
520 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
521{
522 fn drop(&mut self) {
523 if !self.committed {
524 self.revert().ok();
525 }
526 }
527}
528
529impl<
530 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
531 > KeyValueDbTypes for KvdbSqliteTransaction<ValueType>
532where ValueType::Type: SqlBindableValue
533 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
534{
535 type ValueType = ValueType;
536}
537
538impl<
539 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
540 > KeyValueDbTransactionTrait for KvdbSqliteTransaction<ValueType>
541where ValueType::Type: SqlBindableValue
542 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
543{
544 fn commit(&mut self, _db: &dyn Any) -> Result<()> {
545 self.committed = true;
546 Ok(self
547 .connection
548 .as_mut()
549 .unwrap()
550 .get_db_mut()
551 .execute("COMMIT")?)
552 }
553
554 fn revert(&mut self) -> Result<()> {
555 self.committed = true;
556 self.connection
557 .as_mut()
558 .unwrap()
559 .get_db_mut()
560 .execute("ROLLBACK")?;
561 Ok(())
562 }
563
564 fn restart(
565 &mut self, immediate_write: bool, no_revert: bool,
566 ) -> Result<()> {
567 if !no_revert {
568 self.revert()?;
569 }
570 Self::start_transaction(
571 self.connection.as_mut().unwrap().get_db_mut(),
572 immediate_write,
573 )
574 }
575}
576
577impl<
578 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
579 > Deref for KvdbSqliteTransaction<ValueType>
580where ValueType::Type: SqlBindableValue
581 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
582{
583 type Target = KvdbSqlite<ValueType>;
584
585 fn deref(&self) -> &Self::Target { &self.db }
586}
587
588impl<
589 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
590 > DerefMut for KvdbSqliteTransaction<ValueType>
591where ValueType::Type: SqlBindableValue
592 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
593{
594 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.db }
595}
596
597impl<ValueType: DbValueType> KeyValueDbTypes
598 for KvdbSqliteBorrowShared<'_, ValueType>
599{
600 type ValueType = ValueType;
601}
602
603impl<ValueType: DbValueType> KeyValueDbTypes
604 for KvdbSqliteBorrowMut<'_, ValueType>
605{
606 type ValueType = ValueType;
607}
608
609pub fn kvdb_sqlite_iter_range_impl<
610 'db,
611 Item: 'db,
612 F: FnMut(&Statement<'db>) -> Result<Item>,
613>(
614 maybe_connection: Option<&'db mut SqliteConnection>,
615 statements: &KvdbSqliteStatements, lower_bound_incl: &[u8],
616 upper_bound_excl: Option<&[u8]>, f: F,
617) -> Result<MappedRows<'db, F>> {
618 match maybe_connection {
619 None => Ok(MaybeRows::default().map(f)),
620 Some(conn) => match upper_bound_excl {
621 Some(upper_bound_excl) => Ok(conn
622 .execute(
623 &statements.stmts_bytes_key_table.range_select_statement,
624 &[&&lower_bound_incl as SqlBindableRef, &&upper_bound_excl],
625 )?
626 .map(f)),
627 None => Ok(conn
628 .execute(
629 &statements
630 .stmts_bytes_key_table
631 .range_select_till_end_statement,
632 &[&&lower_bound_incl as SqlBindableRef],
633 )?
634 .map(f)),
635 },
636 }
637}
638
639pub fn kvdb_sqlite_iter_range_excl_impl<
640 'db,
641 Item: 'db,
642 F: FnMut(&Statement<'db>) -> Result<Item>,
643>(
644 maybe_connection: Option<&'db mut SqliteConnection>,
645 statements: &KvdbSqliteStatements, lower_bound_excl: &[u8],
646 upper_bound_excl: &[u8], f: F,
647) -> Result<MappedRows<'db, F>> {
648 match maybe_connection {
649 None => Ok(MaybeRows::default().map(f)),
650 Some(conn) => Ok(conn
651 .execute(
652 &statements.stmts_bytes_key_table.range_excl_select_statement,
653 &[&&lower_bound_excl as SqlBindableRef, &&upper_bound_excl],
654 )?
655 .map(f)),
656 }
657}
658
659impl<
660 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
661 > KeyValueDbTraitMultiReader for KvdbSqlite<ValueType>
662{
663}
664
665impl<
666 T: ReadImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
667 + KvdbSqliteRefDestructureTrait
668 + KeyValueDbTypes<ValueType = ValueType>,
669 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
670 > ReadImplByFamily<KvdbSqlite<ValueType>> for T
671{
672 fn get_impl(&self, key: &[u8]) -> Result<Option<Self::ValueType>> {
673 let (connection, statements) = self.destructure();
674 match connection {
675 None => Ok(None),
676 Some(conn) => {
677 let mut db = conn.lock_db();
679 let mut statement_cache = conn.lock_statement_cache();
680
681 let statement = SqliteConnection::prepare(
682 &mut db,
683 &mut statement_cache,
684 &statements.stmts_bytes_key_table.get,
685 )?;
686 let mut maybe_rows = SqliteConnection::execute_locked(
687 statement,
688 &[&&key as SqlBindableRef],
689 )?
690 .map(KvdbSqlite::<ValueType>::from_row);
691 Ok(maybe_rows.expect_one_row()?.transpose()?)
692 }
693 }
694 }
695
696 fn get_with_number_key_impl(
697 &self, key: i64,
698 ) -> Result<Option<Self::ValueType>> {
699 let (connection, statements) = self.destructure();
700 match connection {
701 None => Ok(None),
702 Some(conn) => {
703 let mut db = conn.lock_db();
704 let mut statement_cache = conn.lock_statement_cache();
705
706 let statement = SqliteConnection::prepare(
707 &mut db,
708 &mut statement_cache,
709 &statements.stmts_main_table.get,
710 )?;
711 let mut maybe_rows = SqliteConnection::execute_locked(
712 statement,
713 &[&key as SqlBindableRef],
714 )?
715 .map(KvdbSqlite::<ValueType>::from_row);
716 Ok(maybe_rows.expect_one_row()?.transpose()?)
717 }
718 }
719 }
720}
721
722impl<
723 T: OwnedReadImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
724 + KvdbSqliteDestructureTrait
725 + KeyValueDbTypes<ValueType = ValueType>,
726 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
727 > OwnedReadImplByFamily<KvdbSqlite<ValueType>> for T
728{
729 fn get_mut_impl(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>> {
730 let (connection, statements) = self.destructure_mut();
731 match connection {
732 None => Ok(None),
733 Some(conn) => Ok(conn
734 .execute(
735 &statements.stmts_bytes_key_table.get,
736 &[&&key as SqlBindableRef],
737 )?
738 .map(|row| KvdbSqlite::<ValueType>::from_row(row))
739 .expect_one_row()?
740 .transpose()?),
741 }
742 }
743
744 fn get_mut_with_number_key_impl(
745 &mut self, key: i64,
746 ) -> Result<Option<Self::ValueType>> {
747 let (connection, statements) = self.destructure_mut();
748 match connection {
749 None => Ok(None),
750 Some(conn) => Ok(conn
751 .execute(
752 &statements.stmts_main_table.get,
753 &[&key as SqlBindableRef],
754 )?
755 .map(|row| KvdbSqlite::<ValueType>::from_row(row))
756 .expect_one_row()?
757 .transpose()?),
758 }
759 }
760}
761
762impl<
763 T: SingleWriterImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
764 + KvdbSqliteDestructureTrait
765 + KeyValueDbTypes<ValueType = ValueType>,
766 ValueType: DbValueType,
767 > SingleWriterImplByFamily<KvdbSqlite<ValueType>> for T
768where ValueType::Type: SqlBindableValue
769 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
770{
771 fn delete_impl(
772 &mut self, key: &[u8],
773 ) -> Result<Option<Option<Self::ValueType>>> {
774 let (connection, statements) = self.destructure_mut();
775 match connection {
776 None => Err(Error::from(Error::DbNotExist)),
777 Some(conn) => {
778 conn.execute(
779 &statements.stmts_bytes_key_table.delete,
780 &[&&key as SqlBindableRef],
781 )?
782 .finish_ignore_rows()?;
783 Ok(None)
784 }
785 }
786 }
787
788 fn delete_with_number_key_impl(
789 &mut self, key: i64,
790 ) -> Result<Option<Option<<Self as KeyValueDbTypes>::ValueType>>> {
791 let (connection, statements) = self.destructure_mut();
792 match connection {
793 None => Err(Error::from(Error::DbNotExist)),
794 Some(conn) => {
795 conn.execute(
796 &statements.stmts_main_table.delete,
797 &[&key as SqlBindableRef],
798 )?
799 .finish_ignore_rows()?;
800 Ok(None)
801 }
802 }
803 }
804
805 fn put_impl(
806 &mut self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
807 ) -> Result<Option<Option<Self::ValueType>>> {
808 random_crash_if_enabled("sqlite put");
809 let (connection, statements) = self.destructure_mut();
810 match connection {
811 None => Err(Error::from(Error::DbNotExist)),
812 Some(conn) => {
813 let mut bind_list = Vec::<SqlBindableBox>::new();
814 bind_list.push(Box::new(&key));
815 let mut value_bind_list = value.make_bind_list();
816 bind_list.append(&mut value_bind_list);
817
818 conn.execute(
819 &statements.stmts_bytes_key_table.put,
820 &bind_list,
821 )?
822 .finish_ignore_rows()?;
823 Ok(None)
824 }
825 }
826 }
827
828 fn put_with_number_key_impl(
829 &mut self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
830 ) -> Result<Option<Option<Self::ValueType>>> {
831 random_crash_if_enabled("sqlite put_with_number_key");
832 let (connection, statements) = self.destructure_mut();
833 match connection {
834 None => Err(Error::from(Error::DbNotExist)),
835 Some(conn) => {
836 let mut bind_list = Vec::<SqlBindableBox>::new();
837 bind_list.push(Box::new(key));
838 let mut value_bind_list = value.make_bind_list();
839 bind_list.append(&mut value_bind_list);
840
841 conn.execute(&statements.stmts_main_table.put, &bind_list)?
842 .finish_ignore_rows()?;
843 Ok(None)
844 }
845 }
846 }
847}
848
849impl<
850 T: DbImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
851 + KvdbSqliteRefDestructureTrait
852 + KeyValueDbTypes<ValueType = ValueType>,
853 ValueType: DbValueType,
854 > DbImplByFamily<KvdbSqlite<ValueType>> for T
855where ValueType::Type: SqlBindableValue
856 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
857{
858 fn delete_impl(
859 &self, key: &[u8],
860 ) -> Result<Option<Option<Self::ValueType>>> {
861 random_crash_if_enabled("sqlite delete");
862 let (connection, statements) = self.destructure();
863 match connection {
864 None => Err(Error::from(Error::DbNotExist)),
865 Some(conn) => {
866 let mut db = conn.lock_db();
867 let mut statement_cache = conn.lock_statement_cache();
868
869 let statement = SqliteConnection::prepare(
870 &mut db,
871 &mut statement_cache,
872 &statements.stmts_bytes_key_table.delete,
873 )?;
874 SqliteConnection::execute_locked(
875 statement,
876 &[&&key as SqlBindableRef],
877 )?
878 .finish_ignore_rows()?;
879 Ok(None)
880 }
881 }
882 }
883
884 fn delete_with_number_key_impl(
885 &self, key: i64,
886 ) -> Result<Option<Option<Self::ValueType>>> {
887 random_crash_if_enabled("sqlite delete_with_number_key");
888 let (connection, statements) = self.destructure();
889 match connection {
890 None => Err(Error::from(Error::DbNotExist)),
891 Some(conn) => {
892 let mut db = conn.lock_db();
893 let mut statement_cache = conn.lock_statement_cache();
894
895 let statement = SqliteConnection::prepare(
896 &mut db,
897 &mut statement_cache,
898 &statements.stmts_main_table.delete,
899 )?;
900 SqliteConnection::execute_locked(
901 statement,
902 &[&key as SqlBindableRef],
903 )?
904 .finish_ignore_rows()?;
905 Ok(None)
906 }
907 }
908 }
909
910 fn put_impl(
911 &self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
912 ) -> Result<Option<Option<Self::ValueType>>> {
913 let (connection, statements) = self.destructure();
914 match connection {
915 None => Err(Error::from(Error::DbNotExist)),
916 Some(conn) => {
917 let mut bind_list = Vec::<SqlBindableBox>::new();
918 bind_list.push(Box::new(&key));
919 let mut value_bind_list = value.make_bind_list();
920 bind_list.append(&mut value_bind_list);
921
922 let mut db = conn.lock_db();
923 let mut statement_cache = conn.lock_statement_cache();
924
925 let statement = SqliteConnection::prepare(
926 &mut db,
927 &mut statement_cache,
928 &statements.stmts_bytes_key_table.put,
929 )?;
930
931 SqliteConnection::execute_locked(statement, &bind_list)?
932 .finish_ignore_rows()?;
933 Ok(None)
934 }
935 }
936 }
937
938 fn put_with_number_key_impl(
939 &self, key: i64,
940 value: &<<Self as KeyValueDbTypes>::ValueType as DbValueType>::Type,
941 ) -> Result<Option<Option<Self::ValueType>>> {
942 let (connection, statements) = self.destructure();
943 match connection {
944 None => Err(Error::from(Error::DbNotExist)),
945 Some(conn) => {
946 let mut bind_list = Vec::<SqlBindableBox>::new();
947 bind_list.push(Box::new(key));
948 let mut value_bind_list = value.make_bind_list();
949 bind_list.append(&mut value_bind_list);
950
951 let mut db = conn.lock_db();
952 let mut statement_cache = conn.lock_statement_cache();
953
954 let statement = SqliteConnection::prepare(
955 &mut db,
956 &mut statement_cache,
957 &statements.stmts_main_table.put,
958 )?;
959 SqliteConnection::execute_locked(statement, &bind_list)?
960 .finish_ignore_rows()?;
961 Ok(None)
962 }
963 }
964 }
965}
966
967impl<ValueType> OwnedReadImplFamily for KvdbSqlite<ValueType> {
970 type FamilyRepresentative = KvdbSqlite<ValueType>;
971}
972
973impl<
974 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
975 > OwnedReadImplFamily for KvdbSqliteTransaction<ValueType>
976where ValueType::Type: SqlBindableValue
977 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
978{
979 type FamilyRepresentative = KvdbSqlite<ValueType>;
980}
981
982impl<ValueType> OwnedReadImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
983 type FamilyRepresentative = KvdbSqlite<ValueType>;
984}
985
986impl<
987 'any,
988 ValueType: DbValueType,
989 T: KeyValueDbTypes<ValueType = ValueType>
990 + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
991 F,
992 > KeyValueDbTypes for ConnectionWithRowParser<T, F>
993{
994 type ValueType = ValueType;
995}
996
997impl<
998 'any,
999 ValueType: DbValueType,
1000 T: KeyValueDbTypes<ValueType = ValueType>
1001 + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
1002 F,
1003 > OwnedReadImplFamily for ConnectionWithRowParser<T, F>
1004{
1005 type FamilyRepresentative = KvdbSqlite<ValueType>;
1006}
1007
1008impl<ValueType> SingleWriterImplFamily for KvdbSqlite<ValueType> {
1009 type FamilyRepresentative = KvdbSqlite<ValueType>;
1010}
1011
1012impl<
1013 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
1014 > SingleWriterImplFamily for KvdbSqliteTransaction<ValueType>
1015where ValueType::Type: SqlBindableValue
1016 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
1017{
1018 type FamilyRepresentative = KvdbSqlite<ValueType>;
1019}
1020
1021impl<ValueType> SingleWriterImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
1022 type FamilyRepresentative = KvdbSqlite<ValueType>;
1023}
1024
1025impl<
1026 'any,
1027 ValueType: DbValueType,
1028 T: KeyValueDbTypes<ValueType = ValueType>
1029 + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
1030 F,
1031 > SingleWriterImplFamily for ConnectionWithRowParser<T, F>
1032{
1033 type FamilyRepresentative = KvdbSqlite<ValueType>;
1034}
1035
1036impl<ValueType> ReadImplFamily for KvdbSqlite<ValueType> {
1037 type FamilyRepresentative = KvdbSqlite<ValueType>;
1038}
1039
1040impl<
1041 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
1042 > ReadImplFamily for KvdbSqliteTransaction<ValueType>
1043where ValueType::Type: SqlBindableValue
1044 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
1045{
1046 type FamilyRepresentative = KvdbSqlite<ValueType>;
1047}
1048
1049impl<ValueType> ReadImplFamily for KvdbSqliteBorrowShared<'_, ValueType> {
1050 type FamilyRepresentative = KvdbSqlite<ValueType>;
1051}
1052
1053impl<ValueType> ReadImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
1054 type FamilyRepresentative = KvdbSqlite<ValueType>;
1055}
1056
1057impl<
1058 'any,
1059 ValueType: DbValueType,
1060 T: KeyValueDbTypes<ValueType = ValueType>
1061 + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteRefDestructureTrait>,
1062 F,
1063 > ReadImplFamily for ConnectionWithRowParser<T, F>
1064{
1065 type FamilyRepresentative = KvdbSqlite<ValueType>;
1066}
1067
1068impl<ValueType> DbImplFamily for KvdbSqlite<ValueType> {
1069 type FamilyRepresentative = KvdbSqlite<ValueType>;
1070}
1071
1072impl<
1073 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
1074 > DbImplFamily for KvdbSqliteTransaction<ValueType>
1075where ValueType::Type: SqlBindableValue
1076 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
1077{
1078 type FamilyRepresentative = KvdbSqlite<ValueType>;
1079}
1080
1081impl<ValueType> DbImplFamily for KvdbSqliteBorrowShared<'_, ValueType> {
1082 type FamilyRepresentative = KvdbSqlite<ValueType>;
1083}
1084
1085impl<ValueType> DbImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
1086 type FamilyRepresentative = KvdbSqlite<ValueType>;
1087}
1088
1089pub trait KvdbSqliteRefDestructureTrait {
1090 fn destructure(&self)
1091 -> (Option<&SqliteConnection>, &KvdbSqliteStatements);
1092}
1093
1094pub trait KvdbSqliteDestructureTrait {
1095 fn destructure_mut(
1096 &mut self,
1097 ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements);
1098}
1099
1100impl<ValueType> KvdbSqliteRefDestructureTrait for KvdbSqlite<ValueType> {
1101 fn destructure(
1102 &self,
1103 ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
1104 (self.connection.as_ref(), &self.statements)
1105 }
1106}
1107
1108impl<ValueType> KvdbSqliteDestructureTrait for KvdbSqlite<ValueType> {
1109 fn destructure_mut(
1110 &mut self,
1111 ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
1112 (self.connection.as_mut(), &self.statements)
1113 }
1114}
1115
1116impl<
1117 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
1118 > KvdbSqliteRefDestructureTrait for KvdbSqliteTransaction<ValueType>
1119where ValueType::Type: SqlBindableValue
1120 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
1121{
1122 fn destructure(
1123 &self,
1124 ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
1125 (self.db.connection.as_ref(), &self.db.statements)
1126 }
1127}
1128
1129impl<
1130 ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
1131 > KvdbSqliteDestructureTrait for KvdbSqliteTransaction<ValueType>
1132where ValueType::Type: SqlBindableValue
1133 + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
1134{
1135 fn destructure_mut(
1136 &mut self,
1137 ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
1138 (self.db.connection.as_mut(), &self.db.statements)
1139 }
1140}
1141
1142impl<ValueType> KvdbSqliteRefDestructureTrait
1143 for KvdbSqliteBorrowShared<'_, ValueType>
1144{
1145 fn destructure(
1146 &self,
1147 ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
1148 unsafe { ((self.connection.map(|conn| &*conn)), &*self.statements) }
1149 }
1150}
1151
1152impl<ValueType> KvdbSqliteRefDestructureTrait
1153 for KvdbSqliteBorrowMut<'_, ValueType>
1154{
1155 fn destructure(
1156 &self,
1157 ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
1158 unsafe { ((self.connection.map(|conn| &*conn)), &*self.statements) }
1159 }
1160}
1161
1162impl<ValueType> KvdbSqliteDestructureTrait
1163 for KvdbSqliteBorrowMut<'_, ValueType>
1164{
1165 fn destructure_mut(
1166 &mut self,
1167 ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
1168 unsafe { ((self.connection.map(|conn| &mut *conn)), &*self.statements) }
1169 }
1170}
1171
1172impl<T: DerefPlusImplOrBorrowSelf<dyn KvdbSqliteRefDestructureTrait>, F>
1173 KvdbSqliteRefDestructureTrait for ConnectionWithRowParser<T, F>
1174{
1175 fn destructure(
1176 &self,
1177 ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
1178 self.0.borrow().destructure()
1179 }
1180}
1181
1182impl<
1183 T: DerefPlusImplOrBorrowSelf<dyn KvdbSqliteRefDestructureTrait>
1184 + DerefMutPlusImplOrBorrowMutSelf<dyn KvdbSqliteDestructureTrait>,
1185 F,
1186 > KvdbSqliteDestructureTrait for ConnectionWithRowParser<T, F>
1187{
1188 fn destructure_mut(
1189 &mut self,
1190 ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
1191 self.0.borrow_mut().destructure_mut()
1192 }
1193}
1194
1195impl<ValueType> KvdbSqliteBorrowShared<'_, ValueType> {
1196 pub fn new(
1197 destructure: (Option<&'_ SqliteConnection>, &'_ KvdbSqliteStatements),
1198 ) -> Self {
1199 Self {
1200 connection: destructure.0.map(|x| x as *const SqliteConnection),
1201 statements: destructure.1,
1202 __marker_lifetime: Default::default(),
1203 __marker_value: Default::default(),
1204 }
1205 }
1206}
1207
1208impl<ValueType> KvdbSqliteBorrowMut<'_, ValueType> {
1209 pub fn new(
1210 destructure: (
1211 Option<&'_ mut SqliteConnection>,
1212 &'_ KvdbSqliteStatements,
1213 ),
1214 ) -> Self {
1215 Self {
1216 connection: destructure.0.map(|x| x as *mut SqliteConnection),
1217 statements: destructure.1,
1218 __marker_lifetime: Default::default(),
1219 __marker_value: Default::default(),
1220 }
1221 }
1222}
1223
1224enable_deref_for_self! {KvdbSqlite<Box<[u8]>>}
1225enable_deref_plus_impl_or_borrow_self!(KvdbSqliteRefDestructureTrait);
1226enable_deref_mut_plus_impl_or_borrow_mut_self!(KvdbSqliteRefDestructureTrait);
1227enable_deref_plus_impl_or_borrow_self!(KvdbSqliteDestructureTrait);
1228enable_deref_mut_plus_impl_or_borrow_mut_self!(KvdbSqliteDestructureTrait);
1229
1230use super::{
1231 super::{
1232 super::{
1233 storage_db::key_value_db::*,
1234 utils::{deref_plus_impl_or_borrow_self::*, tuple::*},
1235 },
1236 errors::*,
1237 },
1238 sqlite::*,
1239};
1240use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
1241use random_crash::random_crash_if_enabled;
1242use sqlite::{Connection, Statement};
1243use std::{
1244 any::Any,
1245 collections::HashMap,
1246 fs,
1247 marker::PhantomData,
1248 ops::{Deref, DerefMut},
1249 path::Path,
1250 sync::Arc,
1251};
1252use strfmt::strfmt;