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}