pub struct KvdbSqlite<ValueType> {
    connection: Option<SqliteConnection>,
    statements: Arc<KvdbSqliteStatements>,
    __marker_value: PhantomData<ValueType>,
}
impl<ValueType> MallocSizeOf for KvdbSqlite<ValueType> {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        self.connection.size_of(ops)
    }
}
pub struct KvdbSqliteBorrowShared<'db, ValueType> {
    connection: Option<*const SqliteConnection>,
    statements: *const KvdbSqliteStatements,
    __marker_lifetime: PhantomData<&'db SqliteConnection>,
    __marker_value: PhantomData<ValueType>,
}
pub struct KvdbSqliteBorrowMut<'db, ValueType> {
    connection: Option<*mut SqliteConnection>,
    statements: *const KvdbSqliteStatements,
    __marker_lifetime: PhantomData<&'db mut SqliteConnection>,
    __marker_value: PhantomData<ValueType>,
}
#[derive(Clone)]
pub struct KvdbSqliteStatements {
    pub stmts_main_table: KvdbSqliteStatementsPerTable,
    pub stmts_bytes_key_table: KvdbSqliteStatementsPerTable,
}
#[derive(Clone)]
pub struct KvdbSqliteStatementsPerTable {
    pub create_table: String,
    pub drop_table: String,
    pub get: String,
    pub put: String,
    pub delete: String,
    pub range_select_statement: String,
    pub range_select_till_end_statement: String,
    pub range_excl_select_statement: String,
    pub select_tbl_name: String,
    pub vacuum: String,
}
impl KvdbSqliteStatements {
    pub const BYTES_KEY_TABLE_SUFFIX: &'static str = "_bytes_key";
    pub const CREATE_TABLE_BLOB_KV_STATEMENT_TMPL: &'static str =
        "CREATE TABLE IF NOT EXISTS {table_name} ( key BLOB PRIMARY KEY {comma_value_columns_def} ) WITHOUT ROWID";
    pub const CREATE_TABLE_NUMBER_KV_STATEMENT_TMPL: &'static str =
        "CREATE TABLE IF NOT EXISTS {table_name} ( key INTEGER PRIMARY KEY {comma_value_columns_def} )";
    pub const DELETE_STATEMENT: &'static str =
        "DELETE FROM {table_name} where key = :key";
    pub const DROP_TABLE_STATEMENT: &'static str =
        "DROP TABLE IF EXISTS {table_name}";
    pub const GET_STATEMENT_TMPL: &'static str =
        "SELECT {value_columns} FROM {table_name} WHERE key = :key";
    pub const PUT_STATEMENT_TMPL: &'static str =
        "INSERT OR REPLACE INTO {table_name} VALUES (:key {comma_value_columns_to_bind})";
    pub const RANGE_EXCL_SELECT_STATEMENT: &'static str =
        "SELECT key {comma_value_columns} FROM {table_name} \
        WHERE key > :lower_bound_excl AND key < :upper_bound_excl ORDER BY key ASC";
    pub const RANGE_SELECT_STATEMENT: &'static str =
        "SELECT key {comma_value_columns} FROM {table_name} \
        WHERE key >= :lower_bound_incl AND key < :upper_bound_excl ORDER BY key ASC";
    pub const RANGE_SELECT_STATEMENT_TILL_END: &'static str =
        "SELECT key {comma_value_columns} FROM {table_name} \
         WHERE key >= :lower_bound_incl ORDER BY key ASC";
    pub const SELECT_TBL_NAME: &'static str =
        "SELECT tbl_name FROM sqlite_master WHERE tbl_name = \"{table_name}\" AND type = \"table\"";
    pub const VACUUM: &'static str = "vacuum";
    pub fn make_statements(
        value_column_names: &[&str], value_column_types: &[&str],
        main_table_name: &str, with_number_key_table: bool,
    ) -> Result<Self> {
        let bytes_key_table_name;
        let bytes_key_table;
        if with_number_key_table {
            bytes_key_table = main_table_name.to_string()
                + KvdbSqliteStatements::BYTES_KEY_TABLE_SUFFIX;
            bytes_key_table_name = bytes_key_table.as_str();
        } else {
            bytes_key_table_name = main_table_name;
        }
        Ok(Self {
            stmts_main_table:
                KvdbSqliteStatementsPerTable::make_table_statements(
                    value_column_names,
                    value_column_types,
                    main_table_name,
                    if with_number_key_table {
                        Self::CREATE_TABLE_NUMBER_KV_STATEMENT_TMPL
                    } else {
                        Self::CREATE_TABLE_BLOB_KV_STATEMENT_TMPL
                    },
                )?,
            stmts_bytes_key_table: {
                KvdbSqliteStatementsPerTable::make_table_statements(
                    value_column_names,
                    value_column_types,
                    bytes_key_table_name,
                    Self::CREATE_TABLE_BLOB_KV_STATEMENT_TMPL,
                )?
            },
        })
    }
}
impl KvdbSqliteStatementsPerTable {
    pub fn make_table_statements(
        value_column_names: &[&str], value_column_types: &[&str],
        table_name: &str, create_table_sql: &str,
    ) -> Result<Self> {
        let comma_value_columns_def = value_column_names
            .iter()
            .zip(value_column_types.iter())
            .map(|(n, t)| format!(", {} {}", n, t))
            .collect::<Vec<String>>()
            .concat();
        let value_columns = value_column_names.join(", ");
        let comma_value_columns = if value_columns.len() == 0 {
            value_columns.clone()
        } else {
            ", ".to_string() + &value_columns
        };
        let comma_value_columns_to_bind = value_column_names
            .iter()
            .map(|n| ", :".to_string() + n)
            .collect::<Vec<String>>()
            .concat();
        let mut strfmt_vars = HashMap::new();
        strfmt_vars.insert(
            "comma_value_columns_def".to_string(),
            comma_value_columns_def,
        );
        strfmt_vars.insert("value_columns".to_string(), value_columns);
        strfmt_vars
            .insert("comma_value_columns".to_string(), comma_value_columns);
        strfmt_vars.insert(
            "comma_value_columns_to_bind".to_string(),
            comma_value_columns_to_bind,
        );
        strfmt_vars.insert("table_name".to_string(), table_name.to_string());
        Ok(Self {
            create_table: strfmt(create_table_sql, &strfmt_vars)?,
            drop_table: strfmt(
                KvdbSqliteStatements::DROP_TABLE_STATEMENT,
                &strfmt_vars,
            )?,
            get: strfmt(
                KvdbSqliteStatements::GET_STATEMENT_TMPL,
                &strfmt_vars,
            )?,
            put: strfmt(
                KvdbSqliteStatements::PUT_STATEMENT_TMPL,
                &strfmt_vars,
            )?,
            delete: strfmt(
                KvdbSqliteStatements::DELETE_STATEMENT,
                &strfmt_vars,
            )?,
            range_select_statement: strfmt(
                KvdbSqliteStatements::RANGE_SELECT_STATEMENT,
                &strfmt_vars,
            )?,
            range_select_till_end_statement: strfmt(
                KvdbSqliteStatements::RANGE_SELECT_STATEMENT_TILL_END,
                &strfmt_vars,
            )?,
            range_excl_select_statement: strfmt(
                KvdbSqliteStatements::RANGE_EXCL_SELECT_STATEMENT,
                &strfmt_vars,
            )?,
            select_tbl_name: strfmt(
                KvdbSqliteStatements::SELECT_TBL_NAME,
                &strfmt_vars,
            )?,
            vacuum: strfmt(KvdbSqliteStatements::VACUUM, &strfmt_vars)?,
        })
    }
}
impl<ValueType> KvdbSqlite<ValueType> {
    pub fn new(
        connection: Option<SqliteConnection>,
        statements: Arc<KvdbSqliteStatements>,
    ) -> Result<Self> {
        Ok(Self {
            connection,
            statements,
            __marker_value: Default::default(),
        })
    }
    pub fn into_connection(self) -> Option<SqliteConnection> { self.connection }
}
impl<ValueType> KvdbSqlite<ValueType> {
    pub fn try_clone(&self) -> Result<Self> {
        Ok(Self {
            connection: match &self.connection {
                None => None,
                Some(conn) => Some(conn.try_clone()?),
            },
            statements: self.statements.clone(),
            __marker_value: Default::default(),
        })
    }
    pub fn open<P: AsRef<Path>>(
        path: P, readonly: bool, statements: Arc<KvdbSqliteStatements>,
    ) -> Result<Self> {
        Ok(Self {
            connection: Some(SqliteConnection::open(
                path,
                readonly,
                SqliteConnection::default_open_flags(),
            )?),
            statements,
            __marker_value: Default::default(),
        })
    }
    pub fn open_or_create<P: AsRef<Path>>(
        path: P, statements: Arc<KvdbSqliteStatements>, unsafe_mode: bool,
    ) -> Result<(bool, Self)> {
        if path.as_ref().exists() {
            Ok((true, Self::open(path, false, statements)?))
        } else {
            Ok((
                false,
                Self::create_and_open(
                    path,
                    statements,
                    true,
                    unsafe_mode,
                )?,
            ))
        }
    }
    pub fn create_and_open<P: AsRef<Path>>(
        path: P, statements: Arc<KvdbSqliteStatements>, create_table: bool,
        unsafe_mode: bool,
    ) -> Result<Self> {
        let create_result = (|statements, path| -> Result<SqliteConnection> {
            let mut connection = SqliteConnection::create_and_open(
                path,
                SqliteConnection::default_open_flags(),
                unsafe_mode,
            )?;
            if create_table {
                Self::create_table(&mut connection, statements)?
            }
            Ok(connection)
        })(&*statements, path.as_ref());
        match create_result {
            Ok(connection) => Ok(Self {
                connection: Some(connection),
                statements,
                __marker_value: Default::default(),
            }),
            Err(e) => {
                let files_to_remove =
                    SqliteConnection::possible_temporary_files(
                        &*path.as_ref().to_string_lossy(),
                    );
                warn!("Failed to create sqlite db for {}, remove all temporary files {:?}", path.as_ref().display(), files_to_remove);
                for file in files_to_remove {
                    fs::remove_file(file)?;
                }
                Err(e)
            }
        }
    }
    pub fn create_table(
        connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
    ) -> Result<()> {
        if statements.stmts_main_table.create_table
            != statements.stmts_bytes_key_table.create_table
        {
            connection
                .execute(
                    &statements.stmts_bytes_key_table.create_table,
                    SQLITE_NO_PARAM,
                )?
                .finish_ignore_rows()?;
        }
        connection
            .execute(
                &statements.stmts_main_table.create_table,
                SQLITE_NO_PARAM,
            )?
            .finish_ignore_rows()
    }
    pub fn check_if_table_exist(
        connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
    ) -> Result<bool> {
        if statements.stmts_main_table.create_table
            != statements.stmts_bytes_key_table.create_table
        {
            if connection
                .execute(
                    &statements.stmts_bytes_key_table.select_tbl_name,
                    SQLITE_NO_PARAM,
                )?
                .map(|_| true)
                .expect_one_row()?
                .is_none()
            {
                return Ok(false);
            }
        }
        if connection
            .execute(
                &statements.stmts_main_table.select_tbl_name,
                SQLITE_NO_PARAM,
            )?
            .map(|_| true)
            .expect_one_row()?
            .is_some()
        {
            Ok(true)
        } else {
            Ok(false)
        }
    }
    pub fn drop_table(
        connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
    ) -> Result<()> {
        if statements.stmts_main_table.create_table
            != statements.stmts_bytes_key_table.create_table
        {
            connection
                .execute(
                    &statements.stmts_bytes_key_table.drop_table,
                    SQLITE_NO_PARAM,
                )?
                .finish_ignore_rows()?;
        }
        connection
            .execute(&statements.stmts_main_table.drop_table, SQLITE_NO_PARAM)?
            .finish_ignore_rows()
    }
    pub fn vacuum_db(
        connection: &mut SqliteConnection, statements: &KvdbSqliteStatements,
    ) -> Result<()> {
        if statements.stmts_main_table.create_table
            != statements.stmts_bytes_key_table.create_table
        {
            connection
                .execute(
                    &statements.stmts_bytes_key_table.vacuum,
                    SQLITE_NO_PARAM,
                )?
                .finish_ignore_rows()?;
        }
        connection
            .execute(&statements.stmts_main_table.vacuum, SQLITE_NO_PARAM)?
            .finish_ignore_rows()
    }
}
impl ElementConstrainMark for dyn SqlReadableIntoSelf {}
impl<Element: 'static + SqlReadableIntoSelf>
    ElementSatisfy<dyn SqlReadableIntoSelf> for Element
{
    fn to_constrain_object(&self) -> &(dyn 'static + SqlReadableIntoSelf) {
        self
    }
    fn to_constrain_object_mut(
        &mut self,
    ) -> &mut (dyn 'static + SqlReadableIntoSelf) {
        self
    }
}
impl ElementConstrainMark for dyn BindValueAppendImpl<dyn SqlBindable> {}
impl<Element: 'static + BindValueAppendImpl<dyn SqlBindable>>
    ElementSatisfy<dyn BindValueAppendImpl<dyn SqlBindable>> for Element
{
    fn to_constrain_object(
        &self,
    ) -> &(dyn 'static + BindValueAppendImpl<dyn SqlBindable>) {
        self
    }
    fn to_constrain_object_mut(
        &mut self,
    ) -> &mut (dyn 'static + BindValueAppendImpl<dyn SqlBindable>) {
        self
    }
}
impl<ValueType: ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>>
    KvdbSqlite<ValueType>
{
    pub fn from_row(row: &Statement<'_>) -> Result<ValueType> {
        ValueType::from_row_impl(row, 0)
    }
    pub fn kv_from_iter_row<Key: Default + SqlReadableIntoSelf>(
        row: &Statement<'_>,
    ) -> Result<(Key, ValueType)> {
        let mut key = Key::default();
        let value = ValueType::from_kv_row_impl(row, &mut key)?;
        Ok((key, value))
    }
}
impl<ValueType: DbValueType> KeyValueDbTypes for KvdbSqlite<ValueType> {
    type ValueType = ValueType;
}
impl<
        ValueType: 'static
            + DbValueType
            + ValueRead
            + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KeyValueDbTraitTransactional for KvdbSqlite<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type TransactionType = KvdbSqliteTransaction<ValueType>;
    fn start_transaction(
        &self, immediate_write: bool,
    ) -> Result<KvdbSqliteTransaction<ValueType>> {
        if self.connection.is_none() {
            bail!(Error::DbNotExist);
        }
        KvdbSqliteTransaction::new(self.try_clone()?, immediate_write)
    }
}
pub struct KvdbSqliteTransaction<
    ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
> where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    db: KvdbSqlite<ValueType>,
    committed: bool,
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn new(
        mut db: KvdbSqlite<ValueType>, immediate_write: bool,
    ) -> Result<Self> {
        match &mut db.connection {
            None => {}
            Some(conn) => {
                Self::start_transaction(conn.get_db_mut(), immediate_write)?;
            }
        }
        Ok(Self {
            db,
            committed: false,
        })
    }
    pub fn start_transaction(
        db: &mut Connection, immediate_write: bool,
    ) -> Result<()> {
        if immediate_write {
            db.execute("BEGIN IMMEDIATE")?;
        } else {
            db.execute("BEGIN DEFERRED")?;
        }
        Ok(())
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > Drop for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn drop(&mut self) {
        if !self.committed {
            self.revert().ok();
        }
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KeyValueDbTypes for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type ValueType = ValueType;
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KeyValueDbTransactionTrait for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn commit(&mut self, _db: &dyn Any) -> Result<()> {
        self.committed = true;
        Ok(self
            .connection
            .as_mut()
            .unwrap()
            .get_db_mut()
            .execute("COMMIT")?)
    }
    fn revert(&mut self) -> Result<()> {
        self.committed = true;
        self.connection
            .as_mut()
            .unwrap()
            .get_db_mut()
            .execute("ROLLBACK")?;
        Ok(())
    }
    fn restart(
        &mut self, immediate_write: bool, no_revert: bool,
    ) -> Result<()> {
        if !no_revert {
            self.revert()?;
        }
        Self::start_transaction(
            self.connection.as_mut().unwrap().get_db_mut(),
            immediate_write,
        )
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > Deref for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type Target = KvdbSqlite<ValueType>;
    fn deref(&self) -> &Self::Target { &self.db }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > DerefMut for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.db }
}
impl<ValueType: DbValueType> KeyValueDbTypes
    for KvdbSqliteBorrowShared<'_, ValueType>
{
    type ValueType = ValueType;
}
impl<ValueType: DbValueType> KeyValueDbTypes
    for KvdbSqliteBorrowMut<'_, ValueType>
{
    type ValueType = ValueType;
}
pub fn kvdb_sqlite_iter_range_impl<
    'db,
    Item: 'db,
    F: FnMut(&Statement<'db>) -> Result<Item>,
>(
    maybe_connection: Option<&'db mut SqliteConnection>,
    statements: &KvdbSqliteStatements, lower_bound_incl: &[u8],
    upper_bound_excl: Option<&[u8]>, f: F,
) -> Result<MappedRows<'db, F>> {
    match maybe_connection {
        None => Ok(MaybeRows::default().map(f)),
        Some(conn) => match upper_bound_excl {
            Some(upper_bound_excl) => Ok(conn
                .execute(
                    &statements.stmts_bytes_key_table.range_select_statement,
                    &[&&lower_bound_incl as SqlBindableRef, &&upper_bound_excl],
                )?
                .map(f)),
            None => Ok(conn
                .execute(
                    &statements
                        .stmts_bytes_key_table
                        .range_select_till_end_statement,
                    &[&&lower_bound_incl as SqlBindableRef],
                )?
                .map(f)),
        },
    }
}
pub fn kvdb_sqlite_iter_range_excl_impl<
    'db,
    Item: 'db,
    F: FnMut(&Statement<'db>) -> Result<Item>,
>(
    maybe_connection: Option<&'db mut SqliteConnection>,
    statements: &KvdbSqliteStatements, lower_bound_excl: &[u8],
    upper_bound_excl: &[u8], f: F,
) -> Result<MappedRows<'db, F>> {
    match maybe_connection {
        None => Ok(MaybeRows::default().map(f)),
        Some(conn) => Ok(conn
            .execute(
                &statements.stmts_bytes_key_table.range_excl_select_statement,
                &[&&lower_bound_excl as SqlBindableRef, &&upper_bound_excl],
            )?
            .map(f)),
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KeyValueDbTraitMultiReader for KvdbSqlite<ValueType>
{
}
impl<
        T: ReadImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
            + KvdbSqliteRefDestructureTrait
            + KeyValueDbTypes<ValueType = ValueType>,
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > ReadImplByFamily<KvdbSqlite<ValueType>> for T
{
    fn get_impl(&self, key: &[u8]) -> Result<Option<Self::ValueType>> {
        let (connection, statements) = self.destructure();
        match connection {
            None => Ok(None),
            Some(conn) => {
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_bytes_key_table.get,
                )?;
                let mut maybe_rows = SqliteConnection::execute_locked(
                    statement,
                    &[&&key as SqlBindableRef],
                )?
                .map(KvdbSqlite::<ValueType>::from_row);
                Ok(maybe_rows.expect_one_row()?.transpose()?)
            }
        }
    }
    fn get_with_number_key_impl(
        &self, key: i64,
    ) -> Result<Option<Self::ValueType>> {
        let (connection, statements) = self.destructure();
        match connection {
            None => Ok(None),
            Some(conn) => {
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_main_table.get,
                )?;
                let mut maybe_rows = SqliteConnection::execute_locked(
                    statement,
                    &[&key as SqlBindableRef],
                )?
                .map(KvdbSqlite::<ValueType>::from_row);
                Ok(maybe_rows.expect_one_row()?.transpose()?)
            }
        }
    }
}
impl<
        T: OwnedReadImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
            + KvdbSqliteDestructureTrait
            + KeyValueDbTypes<ValueType = ValueType>,
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > OwnedReadImplByFamily<KvdbSqlite<ValueType>> for T
{
    fn get_mut_impl(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>> {
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Ok(None),
            Some(conn) => Ok(conn
                .execute(
                    &statements.stmts_bytes_key_table.get,
                    &[&&key as SqlBindableRef],
                )?
                .map(|row| KvdbSqlite::<ValueType>::from_row(row))
                .expect_one_row()?
                .transpose()?),
        }
    }
    fn get_mut_with_number_key_impl(
        &mut self, key: i64,
    ) -> Result<Option<Self::ValueType>> {
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Ok(None),
            Some(conn) => Ok(conn
                .execute(
                    &statements.stmts_main_table.get,
                    &[&key as SqlBindableRef],
                )?
                .map(|row| KvdbSqlite::<ValueType>::from_row(row))
                .expect_one_row()?
                .transpose()?),
        }
    }
}
impl<
        T: SingleWriterImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
            + KvdbSqliteDestructureTrait
            + KeyValueDbTypes<ValueType = ValueType>,
        ValueType: DbValueType,
    > SingleWriterImplByFamily<KvdbSqlite<ValueType>> for T
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn delete_impl(
        &mut self, key: &[u8],
    ) -> Result<Option<Option<Self::ValueType>>> {
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                conn.execute(
                    &statements.stmts_bytes_key_table.delete,
                    &[&&key as SqlBindableRef],
                )?
                .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn delete_with_number_key_impl(
        &mut self, key: i64,
    ) -> Result<Option<Option<<Self as KeyValueDbTypes>::ValueType>>> {
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                conn.execute(
                    &statements.stmts_main_table.delete,
                    &[&key as SqlBindableRef],
                )?
                .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn put_impl(
        &mut self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
    ) -> Result<Option<Option<Self::ValueType>>> {
        random_crash_if_enabled("sqlite put");
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut bind_list = Vec::<SqlBindableBox>::new();
                bind_list.push(Box::new(&key));
                let mut value_bind_list = value.make_bind_list();
                bind_list.append(&mut value_bind_list);
                conn.execute(
                    &statements.stmts_bytes_key_table.put,
                    &bind_list,
                )?
                .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn put_with_number_key_impl(
        &mut self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
    ) -> Result<Option<Option<Self::ValueType>>> {
        random_crash_if_enabled("sqlite put_with_number_key");
        let (connection, statements) = self.destructure_mut();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut bind_list = Vec::<SqlBindableBox>::new();
                bind_list.push(Box::new(key));
                let mut value_bind_list = value.make_bind_list();
                bind_list.append(&mut value_bind_list);
                conn.execute(&statements.stmts_main_table.put, &bind_list)?
                    .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
}
impl<
        T: DbImplFamily<FamilyRepresentative = KvdbSqlite<ValueType>>
            + KvdbSqliteRefDestructureTrait
            + KeyValueDbTypes<ValueType = ValueType>,
        ValueType: DbValueType,
    > DbImplByFamily<KvdbSqlite<ValueType>> for T
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn delete_impl(
        &self, key: &[u8],
    ) -> Result<Option<Option<Self::ValueType>>> {
        random_crash_if_enabled("sqlite delete");
        let (connection, statements) = self.destructure();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_bytes_key_table.delete,
                )?;
                SqliteConnection::execute_locked(
                    statement,
                    &[&&key as SqlBindableRef],
                )?
                .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn delete_with_number_key_impl(
        &self, key: i64,
    ) -> Result<Option<Option<Self::ValueType>>> {
        random_crash_if_enabled("sqlite delete_with_number_key");
        let (connection, statements) = self.destructure();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_main_table.delete,
                )?;
                SqliteConnection::execute_locked(
                    statement,
                    &[&key as SqlBindableRef],
                )?
                .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn put_impl(
        &self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
    ) -> Result<Option<Option<Self::ValueType>>> {
        let (connection, statements) = self.destructure();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut bind_list = Vec::<SqlBindableBox>::new();
                bind_list.push(Box::new(&key));
                let mut value_bind_list = value.make_bind_list();
                bind_list.append(&mut value_bind_list);
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_bytes_key_table.put,
                )?;
                SqliteConnection::execute_locked(statement, &bind_list)?
                    .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
    fn put_with_number_key_impl(
        &self, key: i64,
        value: &<<Self as KeyValueDbTypes>::ValueType as DbValueType>::Type,
    ) -> Result<Option<Option<Self::ValueType>>> {
        let (connection, statements) = self.destructure();
        match connection {
            None => Err(Error::from(Error::DbNotExist)),
            Some(conn) => {
                let mut bind_list = Vec::<SqlBindableBox>::new();
                bind_list.push(Box::new(key));
                let mut value_bind_list = value.make_bind_list();
                bind_list.append(&mut value_bind_list);
                let mut db = conn.lock_db();
                let mut statement_cache = conn.lock_statement_cache();
                let statement = SqliteConnection::prepare(
                    &mut db,
                    &mut statement_cache,
                    &statements.stmts_main_table.put,
                )?;
                SqliteConnection::execute_locked(statement, &bind_list)?
                    .finish_ignore_rows()?;
                Ok(None)
            }
        }
    }
}
impl<ValueType> OwnedReadImplFamily for KvdbSqlite<ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > OwnedReadImplFamily for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> OwnedReadImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        'any,
        ValueType: DbValueType,
        T: KeyValueDbTypes<ValueType = ValueType>
            + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
        F,
    > KeyValueDbTypes for ConnectionWithRowParser<T, F>
{
    type ValueType = ValueType;
}
impl<
        'any,
        ValueType: DbValueType,
        T: KeyValueDbTypes<ValueType = ValueType>
            + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
        F,
    > OwnedReadImplFamily for ConnectionWithRowParser<T, F>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> SingleWriterImplFamily for KvdbSqlite<ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > SingleWriterImplFamily for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> SingleWriterImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        'any,
        ValueType: DbValueType,
        T: KeyValueDbTypes<ValueType = ValueType>
            + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteDestructureTrait>,
        F,
    > SingleWriterImplFamily for ConnectionWithRowParser<T, F>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> ReadImplFamily for KvdbSqlite<ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > ReadImplFamily for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> ReadImplFamily for KvdbSqliteBorrowShared<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> ReadImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        'any,
        ValueType: DbValueType,
        T: KeyValueDbTypes<ValueType = ValueType>
            + ImplOrBorrowMutSelf<dyn 'any + KvdbSqliteRefDestructureTrait>,
        F,
    > ReadImplFamily for ConnectionWithRowParser<T, F>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> DbImplFamily for KvdbSqlite<ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > DbImplFamily for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> DbImplFamily for KvdbSqliteBorrowShared<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
impl<ValueType> DbImplFamily for KvdbSqliteBorrowMut<'_, ValueType> {
    type FamilyRepresentative = KvdbSqlite<ValueType>;
}
pub trait KvdbSqliteRefDestructureTrait {
    fn destructure(&self)
        -> (Option<&SqliteConnection>, &KvdbSqliteStatements);
}
pub trait KvdbSqliteDestructureTrait {
    fn destructure_mut(
        &mut self,
    ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements);
}
impl<ValueType> KvdbSqliteRefDestructureTrait for KvdbSqlite<ValueType> {
    fn destructure(
        &self,
    ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
        (self.connection.as_ref(), &self.statements)
    }
}
impl<ValueType> KvdbSqliteDestructureTrait for KvdbSqlite<ValueType> {
    fn destructure_mut(
        &mut self,
    ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
        (self.connection.as_mut(), &self.statements)
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KvdbSqliteRefDestructureTrait for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn destructure(
        &self,
    ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
        (self.db.connection.as_ref(), &self.db.statements)
    }
}
impl<
        ValueType: DbValueType + ValueRead + ValueReadImpl<<ValueType as ValueRead>::Kind>,
    > KvdbSqliteDestructureTrait for KvdbSqliteTransaction<ValueType>
where ValueType::Type: SqlBindableValue
        + BindValueAppendImpl<<ValueType::Type as SqlBindableValue>::Kind>
{
    fn destructure_mut(
        &mut self,
    ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
        (self.db.connection.as_mut(), &self.db.statements)
    }
}
impl<ValueType> KvdbSqliteRefDestructureTrait
    for KvdbSqliteBorrowShared<'_, ValueType>
{
    fn destructure(
        &self,
    ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
        unsafe { ((self.connection.map(|conn| &*conn)), &*self.statements) }
    }
}
impl<ValueType> KvdbSqliteRefDestructureTrait
    for KvdbSqliteBorrowMut<'_, ValueType>
{
    fn destructure(
        &self,
    ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
        unsafe { ((self.connection.map(|conn| &*conn)), &*self.statements) }
    }
}
impl<ValueType> KvdbSqliteDestructureTrait
    for KvdbSqliteBorrowMut<'_, ValueType>
{
    fn destructure_mut(
        &mut self,
    ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
        unsafe { ((self.connection.map(|conn| &mut *conn)), &*self.statements) }
    }
}
impl<T: DerefPlusImplOrBorrowSelf<dyn KvdbSqliteRefDestructureTrait>, F>
    KvdbSqliteRefDestructureTrait for ConnectionWithRowParser<T, F>
{
    fn destructure(
        &self,
    ) -> (Option<&SqliteConnection>, &KvdbSqliteStatements) {
        self.0.borrow().destructure()
    }
}
impl<
        T: DerefPlusImplOrBorrowSelf<dyn KvdbSqliteRefDestructureTrait>
            + DerefMutPlusImplOrBorrowMutSelf<dyn KvdbSqliteDestructureTrait>,
        F,
    > KvdbSqliteDestructureTrait for ConnectionWithRowParser<T, F>
{
    fn destructure_mut(
        &mut self,
    ) -> (Option<&mut SqliteConnection>, &KvdbSqliteStatements) {
        self.0.borrow_mut().destructure_mut()
    }
}
impl<ValueType> KvdbSqliteBorrowShared<'_, ValueType> {
    pub fn new(
        destructure: (Option<&'_ SqliteConnection>, &'_ KvdbSqliteStatements),
    ) -> Self {
        Self {
            connection: destructure.0.map(|x| x as *const SqliteConnection),
            statements: destructure.1,
            __marker_lifetime: Default::default(),
            __marker_value: Default::default(),
        }
    }
}
impl<ValueType> KvdbSqliteBorrowMut<'_, ValueType> {
    pub fn new(
        destructure: (
            Option<&'_ mut SqliteConnection>,
            &'_ KvdbSqliteStatements,
        ),
    ) -> Self {
        Self {
            connection: destructure.0.map(|x| x as *mut SqliteConnection),
            statements: destructure.1,
            __marker_lifetime: Default::default(),
            __marker_value: Default::default(),
        }
    }
}
enable_deref_for_self! {KvdbSqlite<Box<[u8]>>}
enable_deref_plus_impl_or_borrow_self!(KvdbSqliteRefDestructureTrait);
enable_deref_mut_plus_impl_or_borrow_mut_self!(KvdbSqliteRefDestructureTrait);
enable_deref_plus_impl_or_borrow_self!(KvdbSqliteDestructureTrait);
enable_deref_mut_plus_impl_or_borrow_mut_self!(KvdbSqliteDestructureTrait);
use super::{
    super::{
        super::{
            storage_db::key_value_db::*,
            utils::{deref_plus_impl_or_borrow_self::*, tuple::*},
        },
        errors::*,
    },
    sqlite::*,
};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use random_crash::random_crash_if_enabled;
use sqlite::{Connection, Statement};
use std::{
    any::Any,
    collections::HashMap,
    fs,
    marker::PhantomData,
    ops::{Deref, DerefMut},
    path::Path,
    sync::Arc,
};
use strfmt::strfmt;