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}