drizzle_sqlite/builder/
prepared.rs

1use std::borrow::Cow;
2
3use drizzle_core::{
4    OwnedParam, Param,
5    prepared::{
6        PreparedStatement as CorePreparedStatement,
7        owned::OwnedPreparedStatement as CoreOwnedPreparedStatement,
8    },
9};
10
11use crate::{SQLiteValue, values::OwnedSQLiteValue};
12
13/// SQLite-specific prepared statement wrapper.
14///
15/// A prepared statement represents a compiled SQL query with placeholder parameters
16/// that can be executed multiple times with different parameter values. This wrapper
17/// provides SQLite-specific functionality while maintaining compatibility with the
18/// core Drizzle prepared statement infrastructure.
19///
20/// ## Features
21///
22/// - **Parameter Binding**: Safely bind values to SQL placeholders
23/// - **Reusable Execution**: Execute the same query multiple times efficiently  
24/// - **Memory Management**: Automatic handling of borrowed/owned lifetimes
25/// - **Type Safety**: Compile-time verification of parameter types
26///
27/// ## Basic Usage
28///
29/// ```rust,ignore
30/// use drizzle_sqlite::builder::QueryBuilder;
31/// use drizzle_macros::{SQLiteTable, SQLiteSchema};
32/// use drizzle_core::{ToSQL, expressions::conditions::eq};
33///
34/// #[SQLiteTable(name = "users")]
35/// struct User {
36///     #[integer(primary)]
37///     id: i32,
38///     #[text]
39///     name: String,
40/// }
41///
42/// #[derive(SQLiteSchema)]
43/// struct Schema {
44///     user: User,
45/// }
46///
47/// let builder = QueryBuilder::new::<Schema>();
48/// let Schema { user } = Schema::new();
49///
50/// // Build query that will become a prepared statement
51/// let query = builder
52///     .select(user.name)
53///     .from(user)
54///     .r#where(eq(user.id, drizzle_core::Placeholder::question()));
55///
56/// // Convert to prepared statement (this would typically be done by the driver)
57/// let sql = query.to_sql();
58/// println!("SQL: {}", sql.sql());  // "SELECT "users"."name" FROM "users" WHERE "users"."id" = ?"
59/// ```
60///
61/// ## Lifetime Management
62///
63/// The prepared statement can be converted between borrowed and owned forms:
64///
65/// - `PreparedStatement<'a>` - Borrows data with lifetime 'a
66/// - `OwnedPreparedStatement` - Owns all data, no lifetime constraints
67///
68/// This allows for flexible usage patterns depending on whether you need to
69/// store the prepared statement long-term or use it immediately.
70#[derive(Debug, Clone)]
71pub struct PreparedStatement<'a> {
72    pub inner: CorePreparedStatement<'a, crate::SQLiteValue<'a>>,
73}
74
75impl<'a> PreparedStatement<'a> {
76    /// Converts this borrowed prepared statement into an owned one.
77    ///
78    /// This method clones all the internal data to create an `OwnedPreparedStatement`
79    /// that doesn't have any lifetime constraints. This is useful when you need to
80    /// store the prepared statement beyond the lifetime of the original query builder.
81    ///
82    /// # Examples
83    ///
84    /// ```rust,ignore
85    /// # use drizzle_sqlite::builder::PreparedStatement;
86    /// # let prepared_statement: PreparedStatement = todo!(); // Would come from driver
87    /// // Convert borrowed to owned for long-term storage
88    /// let owned = prepared_statement.into_owned();
89    ///
90    /// // Now `owned` can be stored without lifetime constraints
91    /// ```
92    pub fn into_owned(&self) -> OwnedPreparedStatement {
93        let owned_params = self.inner.params.iter().map(|p| OwnedParam {
94            placeholder: p.placeholder,
95            value: p
96                .value
97                .clone()
98                .map(|v| OwnedSQLiteValue::from(v.into_owned())),
99        });
100
101        let inner = CoreOwnedPreparedStatement {
102            text_segments: self.inner.text_segments.clone(),
103            params: owned_params.collect::<Box<[_]>>(),
104        };
105
106        OwnedPreparedStatement { inner }
107    }
108}
109
110/// Owned SQLite prepared statement wrapper.
111///
112/// This is the owned counterpart to [`PreparedStatement`] that doesn't have any lifetime
113/// constraints. All data is owned by this struct, making it suitable for long-term storage,
114/// caching, or passing across thread boundaries.
115///
116/// ## Use Cases
117///
118/// - **Caching**: Store prepared statements in a cache for reuse
119/// - **Multi-threading**: Pass prepared statements between threads
120/// - **Long-term storage**: Keep prepared statements in application state
121/// - **Serialization**: Convert to/from persistent storage (when serialization is implemented)
122///
123/// ## Examples
124///
125/// ```rust,ignore
126/// use drizzle_sqlite::builder::{QueryBuilder, PreparedStatement, OwnedPreparedStatement};
127/// use drizzle_macros::{SQLiteTable, SQLiteSchema};
128/// use drizzle_core::ToSQL;
129///
130/// #[SQLiteTable(name = "users")]
131/// struct User {
132///     #[integer(primary)]
133///     id: i32,
134///     #[text]
135///     name: String,
136/// }
137///
138/// #[derive(SQLiteSchema)]
139/// struct Schema {
140///     user: User,
141/// }
142///
143/// let builder = QueryBuilder::new::<Schema>();
144/// let Schema { user } = Schema::new();
145///
146/// // Create a prepared statement and convert to owned
147/// let query = builder.select(user.name).from(user);
148/// let sql = query.to_sql();
149///
150/// // In practice, this conversion would be handled by the database driver
151/// // let prepared: PreparedStatement = driver.prepare(sql)?;
152/// // let owned: OwnedPreparedStatement = prepared.into_owned();
153/// ```
154///
155/// ## Conversion
156///
157/// You can convert between borrowed and owned forms:
158/// - `PreparedStatement::into_owned()` → `OwnedPreparedStatement`
159/// - `OwnedPreparedStatement` → `PreparedStatement` (via `From` trait)
160#[derive(Debug, Clone)]
161pub struct OwnedPreparedStatement {
162    pub inner: CoreOwnedPreparedStatement<crate::values::OwnedSQLiteValue>,
163}
164impl<'a> From<PreparedStatement<'a>> for OwnedPreparedStatement {
165    fn from(value: PreparedStatement<'a>) -> Self {
166        let owned_params = value.inner.params.iter().map(|p| OwnedParam {
167            placeholder: p.placeholder,
168            value: p
169                .value
170                .clone()
171                .map(|v| OwnedSQLiteValue::from(v.into_owned())),
172        });
173        let inner = CoreOwnedPreparedStatement {
174            text_segments: value.inner.text_segments,
175            params: owned_params.collect::<Box<[_]>>(),
176        };
177        Self { inner }
178    }
179}
180
181impl From<OwnedPreparedStatement> for PreparedStatement<'_> {
182    fn from(value: OwnedPreparedStatement) -> Self {
183        let sqlitevalue = value.inner.params.iter().map(|v| {
184            Param::new(
185                v.placeholder,
186                v.value.clone().map(|v| Cow::Owned(SQLiteValue::from(v))),
187            )
188        });
189        let inner = CorePreparedStatement {
190            text_segments: value.inner.text_segments,
191            params: sqlitevalue.collect::<Box<[_]>>(),
192        };
193        PreparedStatement { inner }
194    }
195}
196
197impl OwnedPreparedStatement {}
198
199impl<'a> std::fmt::Display for PreparedStatement<'a> {
200    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201        write!(f, "{}", self.inner)
202    }
203}
204
205impl std::fmt::Display for OwnedPreparedStatement {
206    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207        write!(f, "{}", self.inner)
208    }
209}