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(target_arch = "wasm32", feature = "libsql"))]
7use libsql::wasm::{CloudflareSender, Connection};
8#[cfg(all(not(target_arch = "wasm32"), feature = "libsql"))]
9use libsql::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(
87        url: &str,
88        token: &str,
89    ) -> std::result::Result<Self, crate::compat::LibsqlError> {
90        let conn = Connection::open_cloudflare_worker(url.to_string(), token.to_string());
91        conn.execute("SELECT 1", ()).await.map(|_| Self::from(conn))
92    }
93
94    #[cfg(not(target_arch = "wasm32"))]
95    pub async fn new_connect(
96        _url: &str,
97        _token: &str,
98    ) -> std::result::Result<Self, crate::compat::LibsqlError> {
99        // For native builds, return an error directing users to use the full libsql crate
100        panic!("Native database connections not supported in this build configuration. Use the 'libsql_default' feature for native support.")
101    }
102
103    /// Executes a SQL query with parameters
104    ///
105    /// # Arguments
106    ///
107    /// * `sql` - The SQL query string
108    /// * `params` - Vector of parameters to bind to the query
109    ///
110    /// # Returns
111    ///
112    /// Returns a `Result` containing `Rows` iterator or a `libsql::Error`
113    ///
114    /// # Examples
115    ///
116    /// ```no_run
117    /// use libsql_orm::Database;
118    ///
119    /// async fn query_example(db: &Database) -> Result<(), Box<dyn std::error::Error>> {
120    ///     let rows = db.query(
121    ///         "SELECT * FROM users WHERE age > ?",
122    ///         vec![libsql::Value::Integer(18)]
123    ///     ).await?;
124    ///     Ok(())
125    /// }
126    /// ```
127    pub async fn query(
128        &self,
129        sql: &str,
130        params: Vec<crate::compat::LibsqlValue>,
131    ) -> Result<crate::compat::LibsqlRows, crate::compat::LibsqlError> {
132        self.inner.query(sql, params).await
133    }
134
135    /// Execute a SQL statement with parameters
136    pub async fn execute(
137        &self,
138        sql: &str,
139        params: Vec<crate::compat::LibsqlValue>,
140    ) -> Result<u64, crate::compat::LibsqlError> {
141        self.inner.execute(sql, params).await
142    }
143}
144
145#[cfg(all(target_arch = "wasm32", not(feature = "libsql")))]
146impl Database {
147    /// Creates a new database connection for WASM without libsql
148    pub async fn new_connect(_url: &str, _token: &str) -> Result<Self, crate::error::Error> {
149        Ok(Database {
150            _phantom: std::marker::PhantomData,
151        })
152    }
153
154    /// Query method stub for WASM-only builds
155    pub async fn query(
156        &self,
157        _sql: &str,
158        _params: Vec<crate::compat::LibsqlValue>,
159    ) -> Result<crate::compat::LibsqlRows, crate::compat::LibsqlError> {
160        // Return empty results for WASM-only builds
161        Ok(crate::compat::LibsqlRows::new(vec![]))
162    }
163
164    /// Execute method stub for WASM-only builds
165    pub async fn execute(
166        &self,
167        _sql: &str,
168        _params: Vec<crate::compat::LibsqlValue>,
169    ) -> Result<u64, crate::compat::LibsqlError> {
170        // Return success for WASM-only builds (stub implementation)
171        Ok(0)
172    }
173}