diff --git a/geekorm-core/src/backends/libsql.rs b/geekorm-core/src/backends/libsql.rs index bda249f..28e0324 100644 --- a/geekorm-core/src/backends/libsql.rs +++ b/geekorm-core/src/backends/libsql.rs @@ -8,7 +8,7 @@ //! //! ```no_run //! # #[cfg(feature = "libsql")] { -//! use std::sync::{Arc, RwLock}; +//! use std::sync::Arc; //! use geekorm::prelude::*; //! //! #[derive(Table, Clone, Default, serde::Serialize, serde::Deserialize)] @@ -22,7 +22,7 @@ //! #[tokio::main] //! async fn main() -> anyhow::Result<()> { //! let database = libsql::Builder::new_local(":memory:").build().await?; -//! let connection = Arc::new(RwLock::new(database.connect().unwrap())); +//! let connection = Arc::new(tokio::sync::Mutex::new(database.connect().unwrap())); //! //! Users::create_table(&connection).await?; //! @@ -40,16 +40,15 @@ use libsql::{de, params::IntoValue}; #[cfg(feature = "log")] use log::{debug, error}; use serde::{de::DeserializeOwned, Serialize}; -#[cfg(not(feature = "backends-tokio"))] -use std::sync::Mutex; -use std::{collections::HashMap, sync::Arc}; -#[cfg(feature = "backends-tokio")] -use tokio::sync::Mutex; +use std::collections::HashMap; use crate::{ builder::models::QueryType, GeekConnection, QueryBuilderTrait, TableBuilder, Value, Values, }; +#[cfg(feature = "backends-tokio")] +mod mutex; + impl GeekConnection for libsql::Connection { type Connection = libsql::Connection; @@ -382,116 +381,6 @@ impl GeekConnection for libsql::Connection { } } -const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); - -impl GeekConnection for Arc> -where - Self: Sync + Send + 'static, - C: GeekConnection, -{ - type Connection = Arc>; - - async fn create_table(connection: &Self::Connection) -> Result<(), crate::Error> - where - T: TableBuilder + QueryBuilderTrait + Sized + Serialize + DeserializeOwned, - { - let start = std::time::Instant::now(); - while start.elapsed() < TIMEOUT { - match connection.try_lock() { - Ok(conn) => return C::create_table::(&conn).await, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - Err(crate::Error::LibSQLError( - "Error getting write lock on connection".to_string(), - )) - } - - async fn row_count( - connection: &Self::Connection, - query: crate::Query, - ) -> Result { - let start = std::time::Instant::now(); - while start.elapsed() < TIMEOUT { - match connection.try_lock() { - Ok(conn) => return C::row_count(&conn, query).await, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - Err(crate::Error::LibSQLError( - "Error getting write lock on connection in row_count".to_string(), - )) - } - - async fn query( - connection: &Self::Connection, - query: crate::Query, - ) -> Result, crate::Error> - where - T: serde::de::DeserializeOwned, - { - let start = std::time::Instant::now(); - while start.elapsed() < TIMEOUT { - match connection.try_lock() { - Ok(conn) => return C::query::(&conn, query).await, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - - Err(crate::Error::LibSQLError( - "Error getting write lock on connection".to_string(), - )) - } - - async fn query_first( - connection: &Self::Connection, - query: crate::Query, - ) -> Result - where - T: serde::de::DeserializeOwned, - { - let start = std::time::Instant::now(); - while start.elapsed() < TIMEOUT { - match connection.try_lock() { - Ok(conn) => return C::query_first::(&conn, query).await, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - Err(crate::Error::LibSQLError( - "Error getting write lock on connection".to_string(), - )) - } - - async fn execute( - connection: &Self::Connection, - query: crate::Query, - ) -> Result<(), crate::Error> - where - T: serde::de::DeserializeOwned, - { - let start = std::time::Instant::now(); - while start.elapsed() < TIMEOUT { - match connection.try_lock() { - Ok(conn) => return C::execute::(&conn, query).await, - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - Err(crate::Error::LibSQLError( - "Error getting write lock on connection in execute".to_string(), - )) - } -} - fn convert_values(query: &crate::Query) -> Result, crate::Error> { let mut parameters: Vec = Vec::new(); diff --git a/geekorm-core/src/backends/libsql/mutex.rs b/geekorm-core/src/backends/libsql/mutex.rs new file mode 100644 index 0000000..6270be4 --- /dev/null +++ b/geekorm-core/src/backends/libsql/mutex.rs @@ -0,0 +1,119 @@ +use serde::{de::DeserializeOwned, Serialize}; +use std::sync::Arc; + +#[cfg(not(feature = "backends-tokio"))] +use std::sync::Mutex; +#[cfg(feature = "backends-tokio")] +use tokio::sync::Mutex; + +use crate::{GeekConnection, QueryBuilderTrait, TableBuilder}; + +const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); + +impl GeekConnection for Arc> +where + Self: Sync + Send + 'static, + C: GeekConnection, +{ + type Connection = Arc>; + + async fn create_table(connection: &Self::Connection) -> Result<(), crate::Error> + where + T: TableBuilder + QueryBuilderTrait + Sized + Serialize + DeserializeOwned, + { + let start = std::time::Instant::now(); + while start.elapsed() < TIMEOUT { + match connection.try_lock() { + Ok(conn) => return C::create_table::(&conn).await, + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + } + Err(crate::Error::LibSQLError( + "Error getting write lock on connection".to_string(), + )) + } + + async fn row_count( + connection: &Self::Connection, + query: crate::Query, + ) -> Result { + let start = std::time::Instant::now(); + while start.elapsed() < TIMEOUT { + match connection.try_lock() { + Ok(conn) => return C::row_count(&conn, query).await, + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + } + Err(crate::Error::LibSQLError( + "Error getting write lock on connection in row_count".to_string(), + )) + } + + async fn query( + connection: &Self::Connection, + query: crate::Query, + ) -> Result, crate::Error> + where + T: serde::de::DeserializeOwned, + { + let start = std::time::Instant::now(); + while start.elapsed() < TIMEOUT { + match connection.try_lock() { + Ok(conn) => return C::query::(&conn, query).await, + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + } + + Err(crate::Error::LibSQLError( + "Error getting write lock on connection".to_string(), + )) + } + + async fn query_first( + connection: &Self::Connection, + query: crate::Query, + ) -> Result + where + T: serde::de::DeserializeOwned, + { + let start = std::time::Instant::now(); + while start.elapsed() < TIMEOUT { + match connection.try_lock() { + Ok(conn) => return C::query_first::(&conn, query).await, + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + } + Err(crate::Error::LibSQLError( + "Error getting write lock on connection".to_string(), + )) + } + + async fn execute( + connection: &Self::Connection, + query: crate::Query, + ) -> Result<(), crate::Error> + where + T: serde::de::DeserializeOwned, + { + let start = std::time::Instant::now(); + while start.elapsed() < TIMEOUT { + match connection.try_lock() { + Ok(conn) => return C::execute::(&conn, query).await, + Err(_) => { + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } + } + Err(crate::Error::LibSQLError( + "Error getting write lock on connection in execute".to_string(), + )) + } +}