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
70// Keep libsqlite3-sys linked so its bundled SQLite build script owns the native
71// library search path for the manual FFI declarations in ffi.rs.
72extern crate libsqlite3_sys as _;
73
74pub mod connection;
75pub mod ffi;
76pub mod types;
77
78pub use connection::{OpenFlags, SqliteConfig, SqliteConnection, SqliteTransaction};
79
80// Console integration (feature-gated)
81#[cfg(feature = "console")]
82pub use sqlmodel_console::ConsoleAware;
83
84/// Re-export the SQLite library version.
85pub fn sqlite_version() -> &'static str {
86 ffi::version()
87}
88
89/// Re-export the SQLite library version number.
90pub fn sqlite_version_number() -> i32 {
91 ffi::version_number()
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_sqlite_version() {
100 let version = sqlite_version();
101 assert!(
102 version.starts_with('3'),
103 "Expected SQLite 3.x, got {}",
104 version
105 );
106 }
107
108 #[test]
109 fn test_sqlite_version_number() {
110 let num = sqlite_version_number();
111 assert!(
112 num >= 3_000_000,
113 "Expected SQLite 3.x.x (>= 3000000), got {}",
114 num
115 );
116 }
117}