cfx_storage/impls/storage_db/
kvdb_sqlite.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5pub struct KvdbSqlite<ValueType> {
6    // The main table is the number_key_table_name, if with_number_key_table
7    // was true when statements are created.
8    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    /// When numbered key is turned off, the bytes_key_table is the same as the
37    /// main table.
38    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    // TODO(yz): check if WITHOUT ROWID is faster: see https://www.sqlite.org/withoutrowid.html.
58    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    // INTEGER PRIMARY KEY is special, see https://www.sqlite.org/lang_createtable.html#rowid.
61    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, /* readonly = */ false, statements)?))
243        } else {
244            Ok((
245                false,
246                Self::create_and_open(
247                    path,
248                    statements,
249                    /* create_table = */ 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        // Create the extra table for bytes key when the main table has
297        // number key.
298        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        // Main table. When with_number_key_table is true it's the
310        // number key table. Otherwise it's the bytes
311        // key table.
312        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        // Maybe extra bytes table.
324        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        // Main table.
341        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        // Maybe extra bytes table.
360        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        // Main table.
372        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        // Maybe extra bytes table.
381        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        // Main table.
393        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
451// 'static because Any is static.
452impl<
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                // TODO try pooled connections
678                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
967// Section for marking automatic implementation of KeyValueDbTraitOwnedRead,
968// etc.
969impl<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;