libsql_orm/
database.rs

1//! Database connection and query execution
2//!
3//! This module handles the connection to Turso databases and provides
4//! query execution capabilities for Cloudflare Workers.
5
6#[cfg(all(not(target_arch = "wasm32"), feature = "libsql"))]
7use libsql::Connection;
8#[cfg(all(target_arch = "wasm32", feature = "libsql"))]
9use libsql::wasm::{CloudflareSender, Connection};
10
11/// Database connection wrapper for Turso in Cloudflare Workers
12///
13/// Provides a high-level interface for connecting to and interacting with
14/// Turso databases in WebAssembly environments, specifically optimized
15/// for Cloudflare Workers.
16///
17/// # Examples
18///
19/// ```no_run
20/// use libsql_orm::Database;
21///
22/// async fn connect_example() -> Result<(), Box<dyn std::error::Error>> {
23///     let db = Database::new_connect(
24///         "libsql://your-db.turso.io",
25///         "your-auth-token"
26///     ).await?;
27///     Ok(())
28/// }
29/// ```
30#[cfg(any(feature = "libsql", not(target_arch = "wasm32")))]
31pub struct Database {
32    #[cfg(all(target_arch = "wasm32", feature = "libsql"))]
33    pub inner: Connection<CloudflareSender>,
34    #[cfg(all(not(target_arch = "wasm32"), feature = "libsql"))]
35    pub inner: Connection,
36}
37
38#[cfg(all(target_arch = "wasm32", not(feature = "libsql")))]
39pub struct Database {
40    // Placeholder for WASM-only builds without libsql
41    _phantom: std::marker::PhantomData<()>,
42}
43
44#[cfg(all(target_arch = "wasm32", feature = "libsql"))]
45impl From<Connection<CloudflareSender>> for Database {
46    fn from(inner: Connection<CloudflareSender>) -> Self {
47        Self { inner }
48    }
49}
50
51#[cfg(all(not(target_arch = "wasm32"), feature = "libsql"))]
52impl From<Connection> for Database {
53    fn from(inner: Connection) -> Self {
54        Self { inner }
55    }
56}
57
58#[cfg(feature = "libsql")]
59impl Database {
60    /// Creates a new database connection to a Turso database
61    ///
62    /// # Arguments
63    ///
64    /// * `url` - The database URL (e.g., "turso://your-db.turso.io")
65    /// * `token` - The authentication token for the database
66    ///
67    /// # Returns
68    ///
69    /// Returns a `Result` containing the `Database` instance or a `libsql::Error`
70    ///
71    /// # Examples
72    ///
73    /// ```no_run
74    /// use libsql_orm::Database;
75    ///
76    /// async fn example() -> Result<(), Box<dyn std::error::Error>> {
77    ///     let db = Database::new_connect(
78    ///         "turso://your-db.turso.io",
79    ///         "your-auth-token"
80    ///     ).await?;
81    ///     println!("Connected to database successfully!");
82    ///     Ok(())
83    /// }
84    /// ```
85    #[cfg(target_arch = "wasm32")]
86    pub async fn new_connect(url: &str, token: &str) -> std::result::Result<Self, crate::compat::LibsqlError> {
87        let conn = Connection::open_cloudflare_worker(url.to_string(), token.to_string());
88        conn.execute("SELECT 1", ()).await.map(|_| Self::from(conn))
89    }
90
91    #[cfg(not(target_arch = "wasm32"))]
92    pub async fn new_connect(_url: &str, _token: &str) -> std::result::Result<Self, crate::compat::LibsqlError> {
93        // For native builds, return an error directing users to use the full libsql crate
94        panic!("Native database connections not supported in this build configuration. Use the 'libsql_default' feature for native support.")
95    }
96
97    /// Executes a SQL query with parameters
98    ///
99    /// # Arguments
100    ///
101    /// * `sql` - The SQL query string
102    /// * `params` - Vector of parameters to bind to the query
103    ///
104    /// # Returns
105    ///
106    /// Returns a `Result` containing `Rows` iterator or a `libsql::Error`
107    ///
108    /// # Examples
109    ///
110    /// ```no_run
111    /// use libsql_orm::Database;
112    ///
113    /// async fn query_example(db: &Database) -> Result<(), Box<dyn std::error::Error>> {
114    ///     let rows = db.query(
115    ///         "SELECT * FROM users WHERE age > ?",
116    ///         vec![libsql::Value::Integer(18)]
117    ///     ).await?;
118    ///     Ok(())
119    /// }
120    /// ```
121    pub async fn query(
122        &self,
123        sql: &str,
124        params: Vec<crate::compat::LibsqlValue>,
125    ) -> Result<crate::compat::LibsqlRows, crate::compat::LibsqlError> {
126        self.inner.query(sql, params).await
127    }
128
129    /// Execute a SQL statement with parameters
130    pub async fn execute(
131        &self,
132        sql: &str,
133        params: Vec<crate::compat::LibsqlValue>,
134    ) -> Result<u64, crate::compat::LibsqlError> {
135        self.inner.execute(sql, params).await
136    }
137}
138
139#[cfg(all(target_arch = "wasm32", not(feature = "libsql")))]
140impl Database {
141    /// Creates a new database connection for WASM without libsql
142    pub async fn new_connect(_url: &str, _token: &str) -> Result<Self, crate::error::Error> {
143        Ok(Database {
144            _phantom: std::marker::PhantomData,
145        })
146    }
147
148    /// Query method stub for WASM-only builds
149    pub async fn query(&self, _sql: &str, _params: Vec<crate::compat::LibsqlValue>) -> Result<crate::compat::LibsqlRows, crate::compat::LibsqlError> {
150        // Return empty results for WASM-only builds
151        Ok(crate::compat::LibsqlRows::new(vec![]))
152    }
153
154    /// Execute method stub for WASM-only builds
155    pub async fn execute(&self, _sql: &str, _params: Vec<crate::compat::LibsqlValue>) -> Result<u64, crate::compat::LibsqlError> {
156        // Return success for WASM-only builds (stub implementation)
157        Ok(0)
158    }
159}