Skip to main content

sqlmodel_sqlite/
lib.rs

1//! SQLite driver for SQLModel Rust.
2//!
3//! `sqlmodel-sqlite` is the **SQLite driver** for the SQLModel ecosystem. It implements
4//! the `Connection` trait from `sqlmodel-core`, providing a lightweight backend that is
5//! ideal for local development, embedded use, and testing.
6//!
7//! # Role In The Architecture
8//!
9//! - Implements `sqlmodel-core::Connection` for SQLite
10//! - Supplies FFI-backed execution and type conversion
11//! - Enables `sqlmodel-query` and `sqlmodel-session` to run against SQLite
12//!
13// FFI bindings require unsafe code - this is expected for database drivers
14#![allow(unsafe_code)]
15//!
16//! This crate provides a SQLite database driver using FFI bindings to libsqlite3.
17//! It implements the `Connection` trait from sqlmodel-core for seamless integration
18//! with the rest of the SQLModel ecosystem.
19//!
20//! # Features
21//!
22//! - Full Connection trait implementation
23//! - Transaction support with savepoints
24//! - Type-safe parameter binding
25//! - In-memory and file-based databases
26//! - Configurable open flags and busy timeout
27//!
28//! # Example
29//!
30//! ```rust,ignore
31//! use sqlmodel_sqlite::{SqliteConnection, SqliteConfig};
32//! use sqlmodel_core::{Connection, Value, Cx, Outcome};
33//!
34//! // Open an in-memory database
35//! let conn = SqliteConnection::open_memory().unwrap();
36//!
37//! // Create a table
38//! conn.execute_raw("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)").unwrap();
39//!
40//! // Insert data using the Connection trait
41//! let cx = Cx::for_testing();
42//! match conn.insert(&cx, "INSERT INTO users (name) VALUES (?)", &[Value::Text("Alice".into())]).await {
43//!     Outcome::Ok(id) => println!("Inserted user with id: {}", id),
44//!     Outcome::Err(e) => eprintln!("Error: {}", e),
45//!     _ => {}
46//! }
47//! ```
48//!
49//! # Type Mapping
50//!
51//! | Rust Type | SQLite Type |
52//! |-----------|-------------|
53//! | `bool` | INTEGER (0/1) |
54//! | `i8`, `i16`, `i32` | INTEGER |
55//! | `i64` | INTEGER |
56//! | `f32`, `f64` | REAL |
57//! | `String` | TEXT |
58//! | `Vec<u8>` | BLOB |
59//! | `Option<T>` | NULL or T |
60//! | `Date`, `Time`, `Timestamp` | TEXT (ISO-8601) |
61//! | `Uuid` | BLOB (16 bytes) |
62//! | `Json` | TEXT |
63//!
64//! # Thread Safety
65//!
66//! `SqliteConnection` is both `Send` and `Sync`, using internal mutex
67//! synchronization to protect the underlying SQLite handle. This allows
68//! connections to be shared across async tasks safely.
69
70pub mod connection;
71pub mod ffi;
72pub mod types;
73
74pub use connection::{OpenFlags, SqliteConfig, SqliteConnection, SqliteTransaction};
75
76// Console integration (feature-gated)
77#[cfg(feature = "console")]
78pub use sqlmodel_console::ConsoleAware;
79
80/// Re-export the SQLite library version.
81pub fn sqlite_version() -> &'static str {
82    ffi::version()
83}
84
85/// Re-export the SQLite library version number.
86pub fn sqlite_version_number() -> i32 {
87    ffi::version_number()
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn test_sqlite_version() {
96        let version = sqlite_version();
97        assert!(
98            version.starts_with('3'),
99            "Expected SQLite 3.x, got {}",
100            version
101        );
102    }
103
104    #[test]
105    fn test_sqlite_version_number() {
106        let num = sqlite_version_number();
107        assert!(
108            num >= 3_000_000,
109            "Expected SQLite 3.x.x (>= 3000000), got {}",
110            num
111        );
112    }
113}