Merge pull request #7 from pleshevskiy/sqlite
feat: add support of sqlite database
This commit is contained in:
commit
26bb849ede
7 changed files with 213 additions and 11 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"rust.unstable_features": true
|
||||
"rust.unstable_features": true,
|
||||
"rust.all_features": true,
|
||||
}
|
83
Cargo.lock
generated
83
Cargo.lock
generated
|
@ -2,6 +2,17 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -156,6 +167,12 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -277,6 +294,24 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -409,6 +444,16 @@ version = "0.2.103"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abd5850c449b40bacb498b2bbdfaff648b1b055630073ba8db499caf2d0ea9f2"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
|
@ -500,6 +545,7 @@ dependencies = [
|
|||
"bb8-postgres",
|
||||
"r2d2",
|
||||
"r2d2_postgres",
|
||||
"r2d2_sqlite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -569,6 +615,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
||||
|
||||
[[package]]
|
||||
name = "postgres"
|
||||
version = "0.19.2"
|
||||
|
@ -687,6 +739,16 @@ dependencies = [
|
|||
"r2d2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2_sqlite"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54ca3c9468a76fc2ad724c486a59682fc362efeac7b18d1c012958bc19f34800"
|
||||
dependencies = [
|
||||
"r2d2",
|
||||
"rusqlite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
|
@ -753,6 +815,21 @@ version = "0.6.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a82b0b91fad72160c56bf8da7a549b25d7c31109f52cc1437eac4c0ad2550a7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"memchr",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
@ -1033,6 +1110,12 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
|
|
|
@ -18,6 +18,7 @@ sync = []
|
|||
|
||||
bb8_postgres = ["async", "bb8", "bb8-postgres"]
|
||||
r2d2_postgres = ["sync", "r2d2", "r2d2-postgres"]
|
||||
r2d2_sqlite = ["sync", "r2d2", "r2d2-sqlite"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = { version = "0.1", optional = true }
|
||||
|
@ -27,6 +28,7 @@ bb8-postgres = { version = "0.7", optional = true }
|
|||
|
||||
r2d2 = { version = "0.8", optional = true }
|
||||
r2d2-postgres = { package = "r2d2_postgres", version = "0.18", optional = true }
|
||||
r2d2-sqlite = { package = "r2d2_sqlite", version = "0.19", optional = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
20
src/error.rs
20
src/error.rs
|
@ -1,6 +1,14 @@
|
|||
use std::error;
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "bb8_postgres")]
|
||||
use bb8_postgres::tokio_postgres::Error as PostgresError;
|
||||
#[cfg(all(feature = "r2d2_postgres", not(feature = "bb8_postgres")))]
|
||||
use r2d2_postgres::postgres::Error as PostgresError;
|
||||
|
||||
#[cfg(feature = "r2d2_sqlite")]
|
||||
use r2d2_sqlite::rusqlite::Error as RusqliteError;
|
||||
|
||||
/// A helper type for any result with persistence error.
|
||||
///
|
||||
/// Use this type in your repository or in something else that implements methods for your persistence.
|
||||
|
@ -45,16 +53,16 @@ impl fmt::Display for PersistenceError {
|
|||
|
||||
impl error::Error for PersistenceError {}
|
||||
|
||||
#[cfg(feature = "bb8_postgres")]
|
||||
impl From<bb8_postgres::tokio_postgres::Error> for PersistenceError {
|
||||
fn from(err: bb8_postgres::tokio_postgres::Error) -> Self {
|
||||
#[cfg(any(feature = "r2d2_postgres", feature = "bb8_postgres"))]
|
||||
impl From<PostgresError> for PersistenceError {
|
||||
fn from(err: PostgresError) -> Self {
|
||||
Self::DbError(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "r2d2_postgres", not(feature = "bb8_postgres")))]
|
||||
impl From<r2d2_postgres::postgres::Error> for PersistenceError {
|
||||
fn from(err: r2d2_postgres::postgres::Error) -> Self {
|
||||
#[cfg(feature = "r2d2_sqlite")]
|
||||
impl From<RusqliteError> for PersistenceError {
|
||||
fn from(err: RusqliteError) -> Self {
|
||||
Self::DbError(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -57,7 +57,7 @@ pub use bb8;
|
|||
|
||||
/// This module contains implementation for async interface of postgres database.
|
||||
///
|
||||
/// The implementation uses bb8 as the pool and tokio_postgres as the client.
|
||||
/// The implementation uses `bb8` as the pool and `tokio_postgres` as the client.
|
||||
///
|
||||
/// **Note:** This mod requires enabling the `bb8_postgres` feature
|
||||
#[cfg(feature = "bb8_postgres")]
|
||||
|
@ -70,12 +70,20 @@ pub use r2d2;
|
|||
|
||||
/// This module contains implementation for sync interface of postgres database.
|
||||
///
|
||||
/// The implementation uses r2d2 as the pool and postgres as the client.
|
||||
/// The implementation uses `r2d2` as the pool and `postgres` as the client.
|
||||
///
|
||||
/// **Note:** This mod requires enabling the `r2d2_postgres` feature.
|
||||
#[cfg(feature = "r2d2_postgres")]
|
||||
pub mod r2d2_postgres;
|
||||
|
||||
/// This module contains implementation for sync interface of sqlite database.
|
||||
///
|
||||
/// The implementation uses `r2d2` as the pool and `rusqlite` as the client.
|
||||
///
|
||||
/// **Note:** This mod requires enabling the `r2d2_sqlite` feature.
|
||||
#[cfg(feature = "r2d2_sqlite")]
|
||||
pub mod r2d2_sqlite;
|
||||
|
||||
/// This module contains implementations for errors and result, that this
|
||||
/// crate uses
|
||||
pub mod error;
|
||||
|
|
|
@ -9,7 +9,7 @@ pub use r2d2_postgres::PostgresConnectionManager as Manager;
|
|||
|
||||
/// Inner connection of r2d2 implementation.
|
||||
pub type InnerConn<M> = PooledConnection<M>;
|
||||
/// Inner connection of postgres connection.
|
||||
/// Inner transaction of postgres.
|
||||
pub type InnerTrx<'t> = postgres::Transaction<'t>;
|
||||
|
||||
/// Alias for r2d2 postgres no tls manager.
|
||||
|
@ -37,7 +37,7 @@ pub struct Persistence<'p, M>(&'p Pool<M>)
|
|||
where
|
||||
M: r2d2::ManageConnection;
|
||||
|
||||
impl<'p> PersistencePool for NoTlsPersistence<'p> {
|
||||
impl PersistencePool for NoTlsPersistence<'_> {
|
||||
type Conn = NoTlsConnection;
|
||||
|
||||
fn get_connection(&self) -> error::Result<Self::Conn> {
|
||||
|
|
100
src/r2d2_sqlite.rs
Normal file
100
src/r2d2_sqlite.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use crate::error;
|
||||
#[cfg(feature = "nightly")]
|
||||
use crate::syn::TransactionClient;
|
||||
use crate::syn::{ConnectionClient, PersistencePool};
|
||||
pub use r2d2::{Pool, PooledConnection};
|
||||
pub use r2d2_sqlite::rusqlite;
|
||||
pub use r2d2_sqlite::SqliteConnectionManager as Manager;
|
||||
|
||||
/// Inner connection of r2d2 implementation.
|
||||
pub type InnerConn = PooledConnection<Manager>;
|
||||
/// Inner transaction of rusqlite.
|
||||
pub type InnerTrx<'t> = rusqlite::Transaction<'t>;
|
||||
|
||||
/// It creates new persistence of r2d2 sqlite implementation.
|
||||
pub fn new(pool: &Pool<Manager>) -> Persistence {
|
||||
Persistence(pool)
|
||||
}
|
||||
|
||||
/// Persistence wrap over r2d2 pool.
|
||||
#[derive(Clone)]
|
||||
pub struct Persistence<'p>(&'p Pool<Manager>);
|
||||
|
||||
impl PersistencePool for Persistence<'_> {
|
||||
type Conn = Connection;
|
||||
|
||||
fn get_connection(&self) -> error::Result<Self::Conn> {
|
||||
self.0
|
||||
.get()
|
||||
.map_err(|_| error::PersistenceError::GetConnection)
|
||||
.map(Connection)
|
||||
}
|
||||
}
|
||||
|
||||
/// Connection wrap over r2d2 sqlite inner connection.
|
||||
pub struct Connection(InnerConn);
|
||||
|
||||
impl ConnectionClient for Connection {
|
||||
type InnerConn = InnerConn;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
type Trx<'t> = Transaction<'t>;
|
||||
|
||||
fn inner(&mut self) -> &mut Self::InnerConn {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn start_transaction(&mut self) -> error::Result<Self::Trx<'_>> {
|
||||
self.0
|
||||
.transaction()
|
||||
.map_err(|_| error::PersistenceError::UpgradeToTransaction)
|
||||
.map(Transaction)
|
||||
}
|
||||
}
|
||||
|
||||
/// Transaction wrap over rusqlite transaction.
|
||||
///
|
||||
/// **Note:** requires nightly rust channel and enabling the `nightly` feature.
|
||||
///
|
||||
/// # Limits
|
||||
///
|
||||
/// It doesn't support nested transaction, because the transaction in `rusqlite`
|
||||
/// requires DerefMut, which cannot be implemented at the moment. 😣
|
||||
pub struct Transaction<'me>(InnerTrx<'me>);
|
||||
|
||||
impl<'me> ConnectionClient for Transaction<'me> {
|
||||
type InnerConn = InnerTrx<'me>;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
type Trx<'t> = Transaction<'t>;
|
||||
|
||||
fn inner(&mut self) -> &mut Self::InnerConn {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn start_transaction(&mut self) -> error::Result<Self::Trx<'_>> {
|
||||
// At the moment we cannot implement nested transaction because
|
||||
// the transaction in `rusqlite` requires DerefMut, which cannot be
|
||||
// implemented yet 😣
|
||||
unimplemented!()
|
||||
// self.0
|
||||
// .transaction()
|
||||
// .map_err(|_| error::PersistenceError::UpgradeToTransaction)
|
||||
// .map(Transaction)
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionClient for Transaction<'_> {
|
||||
fn commit(self) -> error::Result<()> {
|
||||
self.0
|
||||
.commit()
|
||||
.map_err(|_| error::PersistenceError::CommitTransaction)
|
||||
}
|
||||
fn rollback(self) -> error::Result<()> {
|
||||
self.0
|
||||
.rollback()
|
||||
.map_err(|_| error::PersistenceError::RollbackTransaction)
|
||||
}
|
||||
}
|
Reference in a new issue