Skip to main content

sqll/
connection.rs

1use core::ffi::CStr;
2#[cfg(feature = "alloc")]
3use core::ffi::c_void;
4use core::ffi::{c_int, c_uint};
5use core::fmt;
6use core::mem::{ManuallyDrop, MaybeUninit};
7use core::ops::{BitOr, Deref, DerefMut};
8use core::ptr::{NonNull, null_mut};
9use core::slice;
10
11#[cfg(feature = "std")]
12use std::path::Path;
13
14use crate::ffi;
15#[cfg(feature = "alloc")]
16use crate::owned::Owned;
17use crate::utils::{c_to_error_text, sqlite3_try};
18use crate::{
19    Code, DatabaseNotFound, Error, NotThreadSafe, OpenOptions, OwnedBytes, Result, Statement, Text,
20};
21
22/// A collection of flags use to prepare a statement.
23pub struct Prepare(c_uint);
24
25impl Prepare {
26    /// No flags.
27    ///
28    /// This provides the default behavior when preparing a statement.
29    pub const EMPTY: Self = Self(0);
30
31    /// The PERSISTENT flag is a hint to the query planner that the prepared
32    /// statement will be retained for a long time and probably reused many
33    /// times. Without this flag, [`Connection::prepare`] assume that the
34    /// prepared statement will be used just once or at most a few times and
35    /// then destroyed relatively soon.
36    ///
37    /// The current implementation acts on this hint by avoiding the use of
38    /// lookaside memory so as not to deplete the limited store of lookaside
39    /// memory. Future versions of SQLite may act on this hint differently.
40    pub const PERSISTENT: Self = Self(ffi::SQLITE_PREPARE_PERSISTENT as c_uint);
41
42    /// The NORMALIZE flag is a no-op. This flag used to be required for any
43    /// prepared statement that wanted to use the normalized sql interface.
44    /// However, the normalized sql interface is now available to all prepared
45    /// statements, regardless of whether or not they use this flag.
46    pub const NORMALIZE: Self = Self(ffi::SQLITE_PREPARE_NORMALIZE as c_uint);
47
48    /// The NO_VTAB flag causes the SQL compiler to return an error if the
49    /// statement uses any virtual tables.
50    pub const NO_VTAB: Self = Self(ffi::SQLITE_PREPARE_NO_VTAB as c_uint);
51}
52
53impl BitOr for Prepare {
54    type Output = Self;
55
56    fn bitor(self, rhs: Self) -> Self::Output {
57        Self(self.0 | rhs.0)
58    }
59}
60
61/// A SQLite database connection.
62///
63/// For detailed information on how to safetly use a connection, including
64/// complex topics such as *Thread Safety* and asynchronous use, see
65/// [`OpenOptions`].
66///
67/// # Examples
68///
69/// Opening a connection to a filesystem path:
70///
71/// ```no_run
72/// use sqll::Connection;
73///
74/// let c = Connection::open("database.db")?;
75///
76/// c.execute(r#"
77///     CREATE TABLE test (id INTEGER);
78/// "#)?;
79/// # Ok::<_, sqll::Error>(())
80/// ```
81///
82/// Opening an in-memory database:
83///
84/// ```
85/// use sqll::Connection;
86///
87/// let c = Connection::open_in_memory()?;
88///
89/// c.execute(r#"
90///     CREATE TABLE test (id INTEGER);
91/// "#)?;
92/// # Ok::<_, sqll::Error>(())
93/// ```
94pub struct Connection {
95    raw: NonNull<ffi::sqlite3>,
96    #[cfg(feature = "alloc")]
97    busy_callback: Option<Owned>,
98    is_thread_safe: bool,
99}
100
101/// Connection is `Send`.
102#[cfg(feature = "threadsafe")]
103unsafe impl Send for Connection {}
104
105impl Connection {
106    /// Construct a connection from a raw pointer.
107    #[inline]
108    pub(crate) fn from_raw(raw: NonNull<ffi::sqlite3>, is_thread_safe: bool) -> Self {
109        Self {
110            raw,
111            #[cfg(feature = "alloc")]
112            busy_callback: None,
113            is_thread_safe,
114        }
115    }
116
117    /// Coerce this statement into a [`SendConnection`] which can be sent across
118    /// threads.
119    ///
120    /// # Errors
121    ///
122    /// This return an error if neither [`full_mutex`] or [`no_mutex`] are set,
123    /// or if the sqlite library is not configured to be thread safe.
124    ///
125    /// ```
126    /// use sqll::OpenOptions;
127    ///
128    /// let mut c = OpenOptions::new()
129    ///     .create()
130    ///     .read_write()
131    ///     .open_in_memory()?;
132    ///
133    /// let e = unsafe { c.into_send().unwrap_err() };
134    /// assert!(matches!(e, sqll::NotThreadSafe { .. }));
135    /// # Ok::<_, sqll::Error>(())
136    /// ```
137    ///
138    /// [`full_mutex`]: crate::OpenOptions::full_mutex
139    /// [`no_mutex`]: crate::OpenOptions::no_mutex
140    ///
141    /// # Safety
142    ///
143    /// This is unsafe because it required that the caller ensures that any
144    /// database objects are synchronized. The exact level of synchronization
145    /// depends on how the connection was opened:
146    /// * If [`full_mutex`] was set and [`no_mutex`] was not set, no external
147    ///   synchronization is necessary, but calls to the statement might block
148    ///   if it's busy.
149    /// * If [`no_mutex`] was set, the caller must ensure that the [`Statement`]
150    ///   is fully synchronized with respect to the connection that constructed
151    ///   it. One way to achieve this is to wrap all the statements behind a
152    ///   single mutex.
153    ///
154    /// [`full_mutex`]: crate::OpenOptions::full_mutex
155    /// [`no_mutex`]: crate::OpenOptions::no_mutex
156    ///
157    /// # Examples
158    ///
159    /// The following example showcases how you can share a single connection in
160    /// a multi-threaded asynchronous application.
161    ///
162    /// > In this example, statements are compiled and executed on-the-fly. See
163    /// > [`Statement::into_send`] for an example which is more idiomatic and
164    /// > uses prepared statement.
165    ///
166    /// ```
167    /// use std::sync::Arc;
168    /// use sqll::{OpenOptions, SendConnection};
169    /// use anyhow::Result;
170    /// use tokio::task;
171    /// use tokio::sync::Mutex;
172    ///
173    /// #[derive(Clone)]
174    /// struct Database {
175    ///     c: Arc<Mutex<SendConnection>>,
176    /// }
177    ///
178    /// fn setup_database() -> Result<Database> {
179    ///     let c = OpenOptions::new()
180    ///         .create()
181    ///         .read_write()
182    ///         .no_mutex()
183    ///         .open_in_memory()?;
184    ///
185    ///     c.execute(
186    ///         r#"
187    ///         CREATE TABLE users (name TEXT PRIMARY KEY NOT NULL, age INTEGER);
188    ///
189    ///         INSERT INTO users VALUES ('Alice', 60), ('Bob', 70), ('Charlie', 20);
190    ///         "#,
191    ///     )?;
192    ///
193    ///     // SAFETY: We serialize all accesses to the connection behind a mutex.
194    ///     let c = unsafe {
195    ///         c.into_send()?
196    ///     };
197    ///
198    ///     Ok(Database {
199    ///         c: Arc::new(Mutex::new(c)),
200    ///     })
201    /// }
202    ///
203    /// #[tokio::main]
204    /// async fn main() -> Result<()> {
205    ///     let db = setup_database()?;
206    ///
207    ///     let mut tasks = Vec::new();
208    ///
209    ///     for _ in 0..10 {
210    ///         _ = task::spawn({
211    ///             let db = db.clone();
212    ///
213    ///             async move {
214    ///                 let mut c = db.c.lock_owned().await;
215    ///
216    ///                 let task = task::spawn_blocking(move || {
217    ///                     let mut update = c.prepare("UPDATE users SET age = age + ?")?;
218    ///                     update.execute(2)
219    ///                 });
220    ///
221    ///                 Ok::<_, anyhow::Error>(task.await??)
222    ///             }
223    ///         });
224    ///
225    ///         let t = task::spawn({
226    ///             let db = db.clone();
227    ///
228    ///             async move {
229    ///                 let mut c = db.c.lock_owned().await;
230    ///
231    ///                 let task = task::spawn_blocking(move || -> Result<Option<i64>> {
232    ///                     let mut select = c.prepare("SELECT age FROM users ORDER BY age")?;
233    ///                     Ok(select.next::<i64>()?)
234    ///                 });
235    ///
236    ///                 task.await?
237    ///             }
238    ///         });
239    ///
240    ///         tasks.push(t);
241    ///     }
242    ///
243    ///     for t in tasks {
244    ///         let first = t.await??;
245    ///         assert!(matches!(first, Some(20..=40)));
246    ///     }
247    ///
248    ///     Ok(())
249    /// }
250    /// ```
251    pub unsafe fn into_send(self) -> Result<SendConnection, NotThreadSafe> {
252        if !self.is_thread_safe {
253            return Err(NotThreadSafe::connection());
254        }
255
256        Ok(SendConnection { inner: self })
257    }
258
259    /// Open a database to the given path.
260    ///
261    /// Note that it is possible to open an in-memory database by passing
262    /// `":memory:"` here, this call might require allocating depending on the
263    /// platform, so it should be avoided in favor of using [`open_in_memory`]. To avoid
264    /// allocating for regular paths, you can use [`open_c_str`], however you
265    /// are responsible for ensuring the c-string is a valid path.
266    ///
267    /// This is the same as calling:
268    ///
269    /// ```
270    /// use sqll::OpenOptions;
271    /// # let path = ":memory:";
272    ///
273    /// let c = OpenOptions::new()
274    ///     .extended_result_codes()
275    ///     .read_write()
276    ///     .create()
277    ///     .open(path)?;
278    ///
279    /// # Ok::<_, sqll::Error>(())
280    /// ```
281    ///
282    /// [`open_in_memory`]: Self::open_in_memory
283    /// [`open_c_str`]: Self::open_c_str
284    #[cfg(feature = "std")]
285    #[cfg_attr(docsrs, cfg(feature = "std"))]
286    #[inline]
287    pub fn open(path: impl AsRef<Path>) -> Result<Connection> {
288        OpenOptions::new()
289            .extended_result_codes()
290            .read_write()
291            .create()
292            .open(path)
293    }
294
295    /// Open a database connection with a raw c-string.
296    ///
297    /// This can be used to open in-memory databases by passing `c":memory:"` or
298    /// a regular open call with a filesystem path like
299    /// `c"/path/to/database.sql"`.
300    ///
301    /// This is the same as calling:
302    ///
303    /// ```
304    /// use sqll::OpenOptions;
305    /// # let name = c":memory:";
306    ///
307    /// let c = OpenOptions::new()
308    ///     .extended_result_codes()
309    ///     .read_write()
310    ///     .create()
311    ///     .open_c_str(name)?;
312    ///
313    /// # Ok::<_, sqll::Error>(())
314    /// ```
315    #[inline]
316    pub fn open_c_str(name: &CStr) -> Result<Connection> {
317        OpenOptions::new()
318            .extended_result_codes()
319            .read_write()
320            .create()
321            .open_c_str(name)
322    }
323
324    /// Open an in-memory database.
325    ///
326    /// This is the same as calling
327    ///
328    /// This is the same as calling:
329    ///
330    /// ```
331    /// use sqll::OpenOptions;
332    ///
333    /// let c = OpenOptions::new()
334    ///     .extended_result_codes()
335    ///     .read_write()
336    ///     .create()
337    ///     .open_in_memory()?;
338    ///
339    /// # Ok::<_, sqll::Error>(())
340    /// ```
341    #[inline]
342    pub fn open_in_memory() -> Result<Connection> {
343        OpenOptions::new()
344            .extended_result_codes()
345            .read_write()
346            .create()
347            .open_in_memory()
348    }
349
350    /// Check if the database connection is read-only.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use sqll::{Connection, Code, OpenOptions, DatabaseNotFound};
356    ///
357    /// let c = OpenOptions::new().read_write().open_in_memory()?;
358    ///
359    /// assert!(!c.database_read_only(c"main")?);
360    /// let e = c.database_read_only(c"not a db").unwrap_err();
361    /// assert!(matches!(e, DatabaseNotFound { .. }));
362    ///
363    /// let c = OpenOptions::new().read_only().open_in_memory()?;
364    ///
365    /// assert!(c.database_read_only(c"main")?);
366    /// let e = c.database_read_only(c"not a db").unwrap_err();
367    /// assert!(matches!(e, DatabaseNotFound { .. }));
368    /// # Ok::<_, Box<dyn std::error::Error>>(())
369    /// ```
370    pub fn database_read_only(&self, name: &CStr) -> Result<bool, DatabaseNotFound> {
371        unsafe {
372            match ffi::sqlite3_db_readonly(self.raw.as_ptr(), name.as_ptr()) {
373                1 => Ok(true),
374                0 => Ok(false),
375                _ => Err(DatabaseNotFound),
376            }
377        }
378    }
379
380    /// Execute a batch of statements.
381    ///
382    /// Unlike [`prepare`], this can be used to execute multiple statements
383    /// separated by a semi-colon `;` and is internally optimized for one-off
384    /// queries.
385    ///
386    /// [`prepare`]: Self::prepare
387    ///
388    /// # Errors
389    ///
390    /// If any of the statements fail, an error is returned.
391    ///
392    /// ```
393    /// use sqll::{Code, Connection};
394    ///
395    /// let c = Connection::open_in_memory()?;
396    ///
397    /// let e = c.execute(":)").unwrap_err();
398    /// assert_eq!(e.code(), Code::ERROR);
399    /// # Ok::<_, sqll::Error>(())
400    /// ```
401    ///
402    /// # Examples
403    ///
404    /// ```
405    /// use sqll::{Connection, Result};
406    ///
407    /// let c = Connection::open_in_memory()?;
408    ///
409    /// c.execute(r#"
410    ///     CREATE TABLE users (name TEXT, age INTEGER);
411    ///
412    ///     INSERT INTO users VALUES ('Alice', 42);
413    ///     INSERT INTO users VALUES ('Bob', 72);
414    /// "#)?;
415    ///
416    /// let results = c.prepare("SELECT name, age FROM users")?
417    ///     .iter::<(String, u32)>()
418    ///     .collect::<Result<Vec<_>>>()?;
419    ///
420    /// assert_eq!(results, [("Alice".to_string(), 42), ("Bob".to_string(), 72)]);
421    /// # Ok::<_, sqll::Error>(())
422    /// ```
423    #[inline]
424    pub fn execute(&self, stmt: impl AsRef<[u8]>) -> Result<()> {
425        self.execute_raw(stmt.as_ref())
426    }
427
428    fn execute_raw(&self, stmt: &[u8]) -> Result<()> {
429        unsafe {
430            let mut ptr = stmt.as_ptr().cast();
431            let mut len = stmt.len();
432
433            while len > 0 {
434                let mut raw = MaybeUninit::uninit();
435                let mut rest = MaybeUninit::uninit();
436
437                let l = i32::try_from(len).unwrap_or(i32::MAX);
438
439                sqlite3_try!(
440                    self,
441                    ffi::sqlite3_prepare_v3(
442                        self.raw.as_ptr(),
443                        ptr,
444                        l,
445                        0,
446                        raw.as_mut_ptr(),
447                        rest.as_mut_ptr(),
448                    )
449                );
450
451                let rest = rest.assume_init();
452
453                // If statement is null then it's simply empty, so we can safely
454                // skip it, otherwise iterate over all rows.
455                if let Some(raw) = NonNull::new(raw.assume_init()) {
456                    let mut statement = Statement::from_raw(raw, self.is_thread_safe);
457                    while statement.step()?.is_row() {}
458                }
459
460                // Skip over empty statements.
461                let o = rest.offset_from_unsigned(ptr);
462                len -= o;
463                ptr = rest;
464            }
465
466            Ok(())
467        }
468    }
469
470    /// Enable or disable extended result codes.
471    ///
472    /// This can also be set during construction with
473    /// [`OpenOptions::extended_result_codes`].
474    ///
475    /// # Examples
476    ///
477    /// ```
478    /// use sqll::{OpenOptions, Code};
479    ///
480    /// let mut c = OpenOptions::new().create().read_write().open_in_memory()?;
481    ///
482    /// let e = c.execute("
483    ///     CREATE TABLE users (name TEXT);
484    ///     CREATE UNIQUE INDEX idx_users_name ON users (name);
485    ///
486    ///     INSERT INTO users VALUES ('Bob');
487    /// ");
488    ///
489    /// let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
490    /// assert_eq!(e.code(), Code::CONSTRAINT_UNIQUE);
491    /// assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");
492    ///
493    /// c.extended_result_codes(false)?;
494    /// let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
495    /// assert_eq!(e.code(), Code::CONSTRAINT);
496    /// assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");
497    /// # Ok::<_, sqll::Error>(())
498    /// ```
499    pub fn extended_result_codes(&mut self, enabled: bool) -> Result<()> {
500        unsafe {
501            let onoff = i32::from(enabled);
502            sqlite3_try!(
503                self,
504                ffi::sqlite3_extended_result_codes(self.raw.as_ptr(), onoff)
505            );
506        }
507
508        Ok(())
509    }
510
511    /// Get the last error message for this connection.
512    ///
513    /// When operating in multi-threaded environment, the error message seen
514    /// here might not correspond to the query that failed unless some kind of
515    /// external synchronization is in use which is the recommended way to use
516    /// sqlite.
517    ///
518    /// This is only meaningful if an error has occured. If no errors have
519    /// occured, this returns a non-erronous message like `"not an error"`
520    /// (default for sqlite3).
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// use sqll::{Connection, Code};
526    ///
527    /// let c = Connection::open_in_memory()?;
528    ///
529    /// let e = c.execute("
530    ///     CREATE TABLE users (name TEXT);
531    ///     CREATE UNIQUE INDEX idx_users_name ON users (name);
532    ///
533    ///     INSERT INTO users VALUES ('Bob');
534    /// ");
535    ///
536    /// let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
537    /// assert_eq!(e.code(), Code::CONSTRAINT_UNIQUE);
538    /// assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");
539    /// # Ok::<_, sqll::Error>(())
540    /// ```
541    pub fn error_message(&self) -> &Text {
542        unsafe { c_to_error_text(ffi::sqlite3_errmsg(self.raw.as_ptr())) }
543    }
544
545    /// Build a prepared statement with default options.
546    ///
547    /// This is the same as calling `prepare_with` with without setting any
548    /// options.
549    ///
550    /// The database connection will be kept open for the lifetime of this
551    /// statement.
552    ///
553    /// # Errors
554    ///
555    /// If the prepare call contains multiple statements, it will error. To
556    /// execute multiple statements, use [`execute`] instead.
557    ///
558    /// ```
559    /// use sqll::{Connection, Code};
560    ///
561    /// let c = Connection::open_in_memory()?;
562    ///
563    /// let e = c.prepare("CREATE TABLE test (id INTEGER) /* test */; INSERT INTO test (id) VALUES (1);").unwrap_err();
564    ///
565    /// assert_eq!(e.code(), Code::MISUSE);
566    /// # Ok::<_, sqll::Error>(())
567    /// ```
568    ///
569    /// [`execute`]: Self::execute
570    ///
571    /// # Examples
572    ///
573    /// ```
574    /// use sqll::Connection;
575    ///
576    /// let c = Connection::open_in_memory()?;
577    ///
578    /// c.execute(r#"
579    ///     CREATE TABLE test (id INTEGER);
580    /// "#)?;
581    ///
582    /// let mut insert_stmt = c.prepare("INSERT INTO test (id) VALUES (?);")?;
583    /// let mut query_stmt = c.prepare("SELECT id FROM test;")?;
584    ///
585    /// drop(c);
586    ///
587    /// insert_stmt.execute(42)?;
588    ///
589    /// query_stmt.bind(())?;
590    /// assert_eq!(query_stmt.iter::<i64>().collect::<Vec<_>>(), [Ok(42)]);
591    /// # Ok::<_, sqll::Error>(())
592    /// ```
593    #[inline]
594    pub fn prepare(&self, stmt: impl AsRef<[u8]>) -> Result<Statement> {
595        self.prepare_raw(stmt.as_ref(), Prepare::EMPTY)
596    }
597
598    /// Build a prepared statement with custom flags.
599    ///
600    /// For long-running statements it is recommended that they have the
601    /// [`Prepare::PERSISTENT`] flag set.
602    ///
603    /// The database connection will be kept open for the lifetime of this
604    /// statement.
605    ///
606    /// # Errors
607    ///
608    /// If the prepare call contains multiple statements, it will error. To
609    /// execute multiple statements, use [`execute`] instead.
610    ///
611    /// ```
612    /// use sqll::{Connection, Code};
613    ///
614    /// let c = Connection::open_in_memory()?;
615    ///
616    /// let e = c.prepare_with("CREATE TABLE test (id INTEGER); INSERT INTO test (id) VALUES (1);")
617    ///     .persistent()
618    ///     .build()
619    ///     .unwrap_err();
620    ///
621    /// assert_eq!(e.code(), Code::MISUSE);
622    /// # Ok::<_, sqll::Error>(())
623    /// ```
624    ///
625    /// [`execute`]: Self::execute
626    ///
627    /// # Examples
628    ///
629    /// ```
630    /// use sqll::Connection;
631    ///
632    /// let c = Connection::open_in_memory()?;
633    ///
634    /// c.execute(r#"
635    ///     CREATE TABLE test (id INTEGER);
636    /// "#)?;
637    ///
638    /// let mut insert_stmt = c.prepare_with("INSERT INTO test (id) VALUES (?)")
639    ///     .persistent()
640    ///     .build()?;
641    ///
642    /// let mut query_stmt = c.prepare_with("SELECT id FROM test")
643    ///     .persistent()
644    ///     .build()?;
645    ///
646    /// drop(c);
647    ///
648    /// /* .. */
649    ///
650    /// insert_stmt.bind(42)?;
651    /// assert!(insert_stmt.step()?.is_done());
652    ///
653    /// query_stmt.bind(())?;
654    /// assert_eq!(query_stmt.iter::<i64>().collect::<Vec<_>>(), [Ok(42)]);
655    /// # Ok::<_, sqll::Error>(())
656    /// ```
657    pub fn prepare_with<S>(&self, stmt: S) -> PrepareWith<'_, S>
658    where
659        S: AsRef<[u8]>,
660    {
661        PrepareWith {
662            conn: self,
663            stmt,
664            flags: Prepare::EMPTY,
665        }
666    }
667
668    fn prepare_raw(&self, stmt: &[u8], flags: Prepare) -> Result<Statement> {
669        unsafe {
670            let mut raw = MaybeUninit::uninit();
671            let mut rest = MaybeUninit::uninit();
672
673            let ptr = stmt.as_ptr().cast();
674            let len = i32::try_from(stmt.len()).unwrap_or(i32::MAX);
675
676            sqlite3_try! {
677                self,
678                ffi::sqlite3_prepare_v3(
679                    self.raw.as_ptr(),
680                    ptr,
681                    len,
682                    flags.0,
683                    raw.as_mut_ptr(),
684                    rest.as_mut_ptr(),
685                )
686            };
687
688            let rest = rest.assume_init();
689
690            let o = rest.offset_from_unsigned(ptr);
691
692            if o != stmt.len() {
693                return Err(Error::new(
694                    Code::MISUSE,
695                    "multiple statements in a single prepare are not allowed",
696                ));
697            }
698
699            let raw = NonNull::new_unchecked(raw.assume_init());
700            Ok(Statement::from_raw(raw, self.is_thread_safe))
701        }
702    }
703
704    /// Return the number of rows inserted, updated, or deleted by the most
705    /// recent INSERT, UPDATE, or DELETE statement.
706    ///
707    /// # Examples
708    ///
709    /// ```
710    /// use sqll::Connection;
711    ///
712    /// let c = Connection::open_in_memory()?;
713    ///
714    /// c.execute(r#"
715    ///     CREATE TABLE users (name TEXT, age INTEGER);
716    ///
717    ///     INSERT INTO users VALUES ('Alice', 42);
718    ///     INSERT INTO users VALUES ('Bob', 72);
719    /// "#)?;
720    ///
721    /// assert_eq!(c.changes(), 1);
722    /// # Ok::<_, sqll::Error>(())
723    /// ```
724    #[inline]
725    pub fn changes(&self) -> usize {
726        unsafe { ffi::sqlite3_changes(self.raw.as_ptr()) as usize }
727    }
728
729    /// Return the total number of rows inserted, updated, and deleted by all
730    /// INSERT, UPDATE, and DELETE statements since the connection was opened.
731    ///
732    /// # Examples
733    ///
734    /// ```
735    /// use sqll::Connection;
736    ///
737    /// let c = Connection::open_in_memory()?;
738    ///
739    /// c.execute(r#"
740    ///     CREATE TABLE users (name TEXT, age INTEGER);
741    ///
742    ///     INSERT INTO users VALUES ('Alice', 42);
743    ///     INSERT INTO users VALUES ('Bob', 72);
744    /// "#)?;
745    ///
746    /// assert_eq!(c.total_changes(), 2);
747    /// # Ok::<_, sqll::Error>(())
748    /// ```
749    #[inline]
750    pub fn total_changes(&self) -> usize {
751        unsafe { ffi::sqlite3_total_changes(self.raw.as_ptr()) as usize }
752    }
753
754    /// Return the rowid of the most recent successful INSERT into a rowid table
755    /// or virtual table.
756    ///
757    /// # Examples
758    ///
759    /// If there is no primary key, the last inserted row id is an internal
760    /// identifier for the row:
761    ///
762    /// ```
763    /// use sqll::Connection;
764    ///
765    /// let c = Connection::open_in_memory()?;
766    ///
767    /// c.execute(r#"
768    ///     CREATE TABLE users (name TEXT);
769    ///
770    ///     INSERT INTO users VALUES ('Alice');
771    ///     INSERT INTO users VALUES ('Bob');
772    /// "#)?;
773    /// assert_eq!(c.last_insert_rowid(), 2);
774    ///
775    /// c.execute(r#"
776    ///     INSERT INTO users VALUES ('Charlie');
777    /// "#)?;
778    /// assert_eq!(c.last_insert_rowid(), 3);
779    ///
780    /// let mut stmt = c.prepare("INSERT INTO users VALUES (?)")?;
781    /// stmt.execute("Dave")?;
782    ///
783    /// assert_eq!(c.last_insert_rowid(), 4);
784    /// # Ok::<_, sqll::Error>(())
785    /// ```
786    ///
787    /// If there is a primary key, the last inserted row id corresponds to it:
788    ///
789    /// ```
790    /// use sqll::Connection;
791    ///
792    /// let c = Connection::open_in_memory()?;
793    ///
794    /// c.execute(r#"
795    ///     CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
796    ///
797    ///     INSERT INTO users (name) VALUES ('Alice');
798    ///     INSERT INTO users (name) VALUES ('Bob');
799    /// "#)?;
800    /// assert_eq!(c.last_insert_rowid(), 2);
801    ///
802    /// c.execute("INSERT INTO users (name) VALUES ('Charlie')")?;
803    /// assert_eq!(c.last_insert_rowid(), 3);
804    ///
805    /// c.execute("INSERT INTO users (name) VALUES ('Dave')")?;
806    /// assert_eq!(c.last_insert_rowid(), 4);
807    ///
808    /// let mut select = c.prepare("SELECT id FROM users WHERE name = ?")?;
809    /// select.bind("Dave")?;
810    ///
811    /// for id in select.iter::<i64>() {
812    ///     assert_eq!(id?, 4);
813    /// }
814    ///
815    /// c.execute("DELETE FROM users WHERE id = 3")?;
816    /// assert_eq!(c.last_insert_rowid(), 4);
817    ///
818    /// c.execute("INSERT INTO users (name) VALUES ('Charlie')")?;
819    /// assert_eq!(c.last_insert_rowid(), 5);
820    ///
821    /// select.bind("Charlie")?;
822    ///
823    /// while let Some(id) = select.next::<i64>()? {
824    ///     assert_eq!(id, 5);
825    /// }
826    /// # Ok::<_, sqll::Error>(())
827    /// ```
828    #[inline]
829    pub fn last_insert_rowid(&self) -> i64 {
830        unsafe { ffi::sqlite3_last_insert_rowid(self.raw.as_ptr()) }
831    }
832
833    /// Set a callback for handling busy events.
834    ///
835    /// The callback is triggered when the database cannot perform an operation
836    /// due to processing of some other request. If the callback returns `true`,
837    /// the operation will be repeated.
838    ///
839    /// The busy callback should not take any actions which modify the database
840    /// connection that invoked the busy handler. In other words, the busy
841    /// handler is not reentrant. Any such actions result in undefined behavior.
842    ///
843    /// Since this needs to allocate space to store the closure the `alloc`
844    /// feature has to be enabled.
845    ///
846    /// # Examples
847    ///
848    /// ```
849    /// use sqll::Connection;
850    ///
851    /// let mut c = Connection::open_in_memory()?;
852    ///
853    /// c.busy_handler(|attempts| {
854    ///     println!("busy attempt: {attempts}");
855    ///     attempts < 5
856    /// })?;
857    /// # Ok::<_, sqll::Error>(())
858    /// ```
859    #[cfg(feature = "alloc")]
860    #[cfg_attr(docsrs, cfg(feature = "alloc"))]
861    pub fn busy_handler<F>(&mut self, callback: F) -> Result<()>
862    where
863        F: FnMut(usize) -> bool + Send + 'static,
864    {
865        extern "C" fn glue<F>(callback: *mut c_void, attempts: c_int) -> c_int
866        where
867            F: FnMut(usize) -> bool,
868        {
869            unsafe {
870                if (*(callback as *mut F))(attempts as usize) {
871                    1
872                } else {
873                    0
874                }
875            }
876        }
877
878        unsafe {
879            let callback = Owned::new(callback)?;
880
881            let result = ffi::sqlite3_busy_handler(
882                self.raw.as_ptr(),
883                Some(glue::<F>),
884                callback.as_ptr().cast(),
885            );
886
887            // NB: Old callback will be dropped and freed when we set the new
888            // one here.
889            self.busy_callback = Some(callback);
890            sqlite3_try!(self, result);
891        }
892
893        Ok(())
894    }
895
896    /// Clear any previously registered busy handler.
897    ///
898    /// # Examples
899    ///
900    /// ```
901    /// use sqll::Connection;
902    ///
903    /// let mut c = Connection::open_in_memory()?;
904    ///
905    /// c.busy_handler(|attempts| {
906    ///     println!("busy attempt: {attempts}");
907    ///     attempts < 5
908    /// })?;
909    ///
910    /// c.clear_busy_handler()?;
911    /// # Ok::<_, sqll::Error>(())
912    /// ```
913    #[inline]
914    pub fn clear_busy_handler(&mut self) -> Result<()> {
915        unsafe {
916            sqlite3_try! {
917                self,
918                ffi::sqlite3_busy_handler(
919                    self.raw.as_ptr(),
920                    None,
921                    null_mut()
922                )
923            };
924        }
925
926        #[cfg(feature = "alloc")]
927        {
928            self.busy_callback = None;
929        }
930
931        Ok(())
932    }
933
934    /// Set an implicit callback for handling busy events that tries to repeat
935    /// rejected operations until a timeout expires.
936    ///
937    /// # Examples
938    ///
939    /// ```
940    /// use sqll::Connection;
941    ///
942    /// let mut c = Connection::open_in_memory()?;
943    ///
944    /// c.busy_timeout(5000)?;
945    /// # Ok::<_, sqll::Error>(())
946    /// ```
947    #[inline]
948    pub fn busy_timeout(&mut self, ms: c_int) -> Result<()> {
949        unsafe {
950            sqlite3_try! {
951                self,
952                ffi::sqlite3_busy_timeout(
953                    self.raw.as_ptr(),
954                    ms
955                )
956            };
957        }
958
959        Ok(())
960    }
961
962    /// Serialize the database to a byte buffer.
963    ///
964    /// The returned buffer is allocated by sqlite and will be freed when
965    /// dropped.
966    ///
967    /// The `name` parameter specifies the name of the database to serialize,
968    /// which is typically `c"main"` for the main database.
969    ///
970    /// # Examples
971    ///
972    /// ```
973    /// use sqll::{Connection, Result};
974    ///
975    /// let c = Connection::open_in_memory()?;
976    ///
977    /// c.execute(r#"
978    ///     CREATE TABLE users (name TEXT, age INTEGER);
979    ///     INSERT INTO users VALUES ('Alice', 42);
980    ///     INSERT INTO users VALUES ('Bob', 72);
981    /// "#)?;
982    ///
983    /// let data = c.serialize(c"main")?;
984    /// assert!(!data.is_empty());
985    ///
986    /// let c2 = Connection::open_in_memory()?;
987    /// c2.deserialize(c"main", data)?;
988    ///
989    /// let results = c2.prepare("SELECT name, age FROM users")?
990    ///     .iter::<(String, u32)>()
991    ///     .collect::<Result<Vec<_>>>()?;
992    ///
993    /// assert_eq!(results, [("Alice".to_string(), 42), ("Bob".to_string(), 72)]);
994    /// # Ok::<_, sqll::Error>(())
995    /// ```
996    pub fn serialize(&self, name: &CStr) -> Result<OwnedBytes, Error> {
997        unsafe {
998            let mut len = MaybeUninit::uninit();
999
1000            match ffi::sqlite3_serialize(self.raw.as_ptr(), name.as_ptr(), len.as_mut_ptr(), 0) {
1001                ptr if ptr.is_null() => {
1002                    Err(Error::new(Code::NOMEM, "failed to serialize database"))
1003                }
1004                ptr => {
1005                    let ptr = NonNull::new_unchecked(ptr);
1006                    let len = len.assume_init();
1007
1008                    let Ok(len) = usize::try_from(len) else {
1009                        ffi::sqlite3_free(ptr.as_ptr().cast());
1010
1011                        return Err(Error::new(
1012                            Code::ERROR,
1013                            format_args!(
1014                                "failed to serialize database, returned size {len} is non-sensical"
1015                            ),
1016                        ));
1017                    };
1018
1019                    Ok(OwnedBytes::from_raw(ptr, len))
1020                }
1021            }
1022        }
1023    }
1024
1025    /// Serialize the database to a byte buffer without copying.
1026    ///
1027    /// This requires that database storage is contiguous in memory which might
1028    /// be difficult to satisfy. One way to do so is if the current database is
1029    /// [`deserialize`] from a previously serialized database (without having
1030    /// been modified).
1031    ///
1032    /// The `name` parameter specifies the name of the database to serialize,
1033    /// which is typically `c"main"` for the main database.
1034    ///
1035    /// [`deserialize`]: Self::deserialize
1036    ///
1037    /// # Safety
1038    ///
1039    /// The returned buffer is valid until the next call to `serialize` or
1040    /// `deserialize`, or until the connection is dropped. Modifying the
1041    /// database in any way might invalidate the returned buffer, so it should
1042    /// be used with care.
1043    ///
1044    /// For a safe variant of this method, see [`serialize`].
1045    ///
1046    /// [`serialize`]: Self::serialize
1047    ///
1048    /// # Examples
1049    ///
1050    /// ```
1051    /// use sqll::{Connection, Result};
1052    ///
1053    /// let c = Connection::open_in_memory()?;
1054    ///
1055    /// c.execute(r#"
1056    ///     CREATE TABLE users (name TEXT, age INTEGER);
1057    ///     INSERT INTO users VALUES ('Alice', 42);
1058    ///     INSERT INTO users VALUES ('Bob', 72);
1059    /// "#)?;
1060    ///
1061    /// let data = c.serialize(c"main")?;
1062    /// assert!(!data.is_empty());
1063    ///
1064    /// let c2 = Connection::open_in_memory()?;
1065    /// c2.deserialize(c"main", data.clone())?;
1066    ///
1067    /// let results = c2.prepare("SELECT name, age FROM users")?
1068    ///     .iter::<(String, u32)>()
1069    ///     .collect::<Result<Vec<_>>>()?;
1070    ///
1071    /// assert_eq!(results, [("Alice".to_string(), 42), ("Bob".to_string(), 72)]);
1072    ///
1073    /// let data2 = unsafe { c2.serialize_no_copy(c"main")? };
1074    /// assert_eq!(data, *data2);
1075    /// # Ok::<_, sqll::Error>(())
1076    /// ```
1077    pub unsafe fn serialize_no_copy(&self, name: &CStr) -> Result<&[u8], Error> {
1078        unsafe {
1079            let mut len = MaybeUninit::uninit();
1080
1081            match ffi::sqlite3_serialize(
1082                self.raw.as_ptr(),
1083                name.as_ptr(),
1084                len.as_mut_ptr(),
1085                ffi::SQLITE_SERIALIZE_NOCOPY as u32,
1086            ) {
1087                ptr if ptr.is_null() => Err(Error::new(
1088                    Code::MISUSE,
1089                    "database is not contiguous and cannot be serialized without copying",
1090                )),
1091                ptr => {
1092                    let len = len.assume_init();
1093
1094                    let Ok(len) = usize::try_from(len) else {
1095                        return Err(Error::new(
1096                            Code::ERROR,
1097                            format_args!(
1098                                "failed to serialize database, returned size {len} is non-sensical"
1099                            ),
1100                        ));
1101                    };
1102
1103                    Ok(slice::from_raw_parts(ptr.cast(), len))
1104                }
1105            }
1106        }
1107    }
1108
1109    /// Deserialize and take ownership of the specified byte buffer into the
1110    /// database.
1111    ///
1112    /// The `name` parameter specifies the name of the database to deserialize
1113    /// into, which is typically `c"main"` for the main database.
1114    ///
1115    /// The `data` parameter is the byte buffer containing the serialized
1116    /// database, which should be obtained from a previous call to `serialize`
1117    /// or read from a file.
1118    ///
1119    /// # Examples
1120    ///
1121    /// ```
1122    /// use sqll::{Connection, Result};
1123    ///
1124    /// let c = Connection::open_in_memory()?;
1125    ///
1126    /// c.execute(r#"
1127    ///     CREATE TABLE users (name TEXT, age INTEGER);
1128    ///     INSERT INTO users VALUES ('Alice', 42);
1129    ///     INSERT INTO users VALUES ('Bob', 72);
1130    /// "#)?;
1131    ///
1132    /// let data = c.serialize(c"main")?;
1133    /// assert!(!data.is_empty());
1134    ///
1135    /// let c2 = Connection::open_in_memory()?;
1136    /// c2.deserialize(c"main", data)?;
1137    ///
1138    /// let results = c2.prepare("SELECT name, age FROM users")?
1139    ///     .iter::<(String, u32)>()
1140    ///     .collect::<Result<Vec<_>>>()?;
1141    ///
1142    /// assert_eq!(results, [("Alice".to_string(), 42), ("Bob".to_string(), 72)]);
1143    /// # Ok::<_, sqll::Error>(())
1144    /// ```
1145    pub fn deserialize(&self, name: &CStr, data: OwnedBytes) -> Result<()> {
1146        let data = ManuallyDrop::new(data);
1147
1148        let Ok(len) = i64::try_from(data.len()) else {
1149            return Err(Error::new(
1150                Code::MISUSE,
1151                "length of owned buffer is too large",
1152            ));
1153        };
1154
1155        let Ok(capacity) = i64::try_from(data.capacity()) else {
1156            return Err(Error::new(
1157                Code::MISUSE,
1158                "capacity of owned buffer is too large",
1159            ));
1160        };
1161
1162        unsafe {
1163            sqlite3_try! {
1164                self,
1165                ffi::sqlite3_deserialize(
1166                    self.raw.as_ptr(),
1167                    name.as_ptr(),
1168                    data.as_ptr().cast_mut(),
1169                    len,
1170                    capacity,
1171                    (ffi::SQLITE_DESERIALIZE_FREEONCLOSE | ffi::SQLITE_DESERIALIZE_RESIZEABLE) as u32,
1172                )
1173            };
1174        }
1175
1176        Ok(())
1177    }
1178}
1179
1180impl fmt::Debug for Connection {
1181    #[inline]
1182    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1183        f.debug_struct("Connection")
1184            .field("is_thread_safe", &self.is_thread_safe)
1185            .finish_non_exhaustive()
1186    }
1187}
1188
1189impl Drop for Connection {
1190    #[inline]
1191    #[allow(unused_must_use)]
1192    fn drop(&mut self) {
1193        self.clear_busy_handler();
1194
1195        // Will close the connection unconditionally. The database will stay
1196        // alive until all associated prepared statements have been closed since
1197        // we're using v2.
1198        let code = unsafe { ffi::sqlite3_close_v2(self.raw.as_ptr()) };
1199        debug_assert_eq!(code, ffi::SQLITE_OK);
1200    }
1201}
1202
1203/// A [`Connection`] that can be sent between threads.
1204///
1205/// Constructed using [`Connection::into_send`].
1206pub struct SendConnection {
1207    inner: Connection,
1208}
1209
1210unsafe impl Send for SendConnection {}
1211
1212impl Deref for SendConnection {
1213    type Target = Connection;
1214
1215    #[inline]
1216    fn deref(&self) -> &Self::Target {
1217        &self.inner
1218    }
1219}
1220
1221impl DerefMut for SendConnection {
1222    #[inline]
1223    fn deref_mut(&mut self) -> &mut Self::Target {
1224        &mut self.inner
1225    }
1226}
1227
1228impl fmt::Debug for SendConnection {
1229    #[inline]
1230    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1231        self.inner.fmt(f)
1232    }
1233}
1234
1235/// A builder for customizing a prepared [`Statement`].
1236///
1237/// See [`Connection::prepare_with`] for more details.
1238pub struct PrepareWith<'a, S>
1239where
1240    S: AsRef<[u8]>,
1241{
1242    conn: &'a Connection,
1243    stmt: S,
1244    flags: Prepare,
1245}
1246
1247impl<S> PrepareWith<'_, S>
1248where
1249    S: AsRef<[u8]>,
1250{
1251    /// Set custom flags for the prepared statement.
1252    ///
1253    /// When setting [`Prepare::PERSISTENT`] it is recommended to use
1254    /// [`PrepareWith::persistent`] instead for improved readability.
1255    ///
1256    /// # Examples
1257    ///
1258    /// ```
1259    /// use sqll::{Connection, Prepare};
1260    ///
1261    /// let c = Connection::open_in_memory()?;
1262    ///
1263    /// c.execute(r#"
1264    ///     CREATE TABLE test (id INTEGER);
1265    /// "#)?;
1266    ///
1267    /// let mut stmt = c.prepare_with("SELECT id FROM test")
1268    ///     .with_flags(Prepare::PERSISTENT | Prepare::NO_VTAB)
1269    ///     .build()?;
1270    ///
1271    /// stmt.bind(())?;
1272    /// assert_eq!(stmt.iter::<i64>().collect::<Vec<_>>(), []);
1273    /// # Ok::<_, sqll::Error>(())
1274    /// ```
1275    #[inline]
1276    pub fn with_flags(mut self, flags: Prepare) -> Self {
1277        self.flags = flags;
1278        self
1279    }
1280
1281    /// Set the [`Prepare::PERSISTENT`] flag for the built prepared
1282    /// [`Statement`].
1283    ///
1284    /// # Examples
1285    ///
1286    /// ```
1287    /// use sqll::Connection;
1288    ///
1289    /// let c = Connection::open_in_memory()?;
1290    ///
1291    /// c.execute(r#"
1292    ///     CREATE TABLE test (id INTEGER);
1293    /// "#)?;
1294    ///
1295    /// let mut insert_stmt = c.prepare_with("INSERT INTO test (id) VALUES (?)")
1296    ///     .persistent()
1297    ///     .build()?;
1298    ///
1299    /// let mut query_stmt = c.prepare_with("SELECT id FROM test")
1300    ///     .persistent()
1301    ///     .build()?;
1302    ///
1303    /// drop(c);
1304    ///
1305    /// /* .. */
1306    ///
1307    /// insert_stmt.bind(42)?;
1308    /// assert!(insert_stmt.step()?.is_done());
1309    ///
1310    /// query_stmt.bind(())?;
1311    /// assert_eq!(query_stmt.iter::<i64>().collect::<Vec<_>>(), [Ok(42)]);
1312    /// # Ok::<_, sqll::Error>(())
1313    /// ```
1314    #[inline]
1315    pub fn persistent(self) -> Self {
1316        self.with_flags(Prepare::PERSISTENT)
1317    }
1318
1319    /// Build the prepared statement.
1320    #[inline]
1321    pub fn build(self) -> Result<Statement> {
1322        self.conn.prepare_raw(self.stmt.as_ref(), self.flags)
1323    }
1324}