use crate::core::{Error, Result};
use super::database::{Database, FromValue};
use super::params::Params;
use super::rows::Rows;
#[derive(Clone)]
pub struct Statement {
db: Database,
sql: String,
}
impl Statement {
pub(crate) fn new(db: Database, sql: String) -> Result<Self> {
{
let executor = db
.executor()
.lock()
.map_err(|_| Error::LockAcquisitionFailed("executor".to_string()))?;
let _ = executor.query_cache().get(&sql);
}
Ok(Self { db, sql })
}
pub fn execute<P: Params>(&self, params: P) -> Result<i64> {
self.db.execute(&self.sql, params)
}
pub fn query<P: Params>(&self, params: P) -> Result<Rows> {
self.db.query(&self.sql, params)
}
pub fn query_one<T: FromValue, P: Params>(&self, params: P) -> Result<T> {
self.db.query_one(&self.sql, params)
}
pub fn query_opt<T: FromValue, P: Params>(&self, params: P) -> Result<Option<T>> {
self.db.query_opt(&self.sql, params)
}
pub fn sql(&self) -> &str {
&self.sql
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_prepared_statement_execute() {
let db = Database::open_in_memory().unwrap();
db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)", ())
.unwrap();
let stmt = db.prepare("INSERT INTO users VALUES ($1, $2)").unwrap();
stmt.execute((1, "Alice")).unwrap();
stmt.execute((2, "Bob")).unwrap();
stmt.execute((3, "Charlie")).unwrap();
let count: i64 = db.query_one("SELECT COUNT(*) FROM users", ()).unwrap();
assert_eq!(count, 3);
}
#[test]
fn test_prepared_statement_query() {
let db = Database::open_in_memory().unwrap();
db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)", ())
.unwrap();
db.execute(
"INSERT INTO users VALUES ($1, $2), ($3, $4), ($5, $6)",
(1, "Alice", 2, "Bob", 3, "Charlie"),
)
.unwrap();
let stmt = db.prepare("SELECT name FROM users WHERE id = $1").unwrap();
let name: String = stmt.query_one((1,)).unwrap();
assert_eq!(name, "Alice");
let name: String = stmt.query_one((2,)).unwrap();
assert_eq!(name, "Bob");
let name: String = stmt.query_one((3,)).unwrap();
assert_eq!(name, "Charlie");
}
#[test]
fn test_prepared_statement_query_opt() {
let db = Database::open_in_memory().unwrap();
db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)", ())
.unwrap();
db.execute("INSERT INTO users VALUES ($1, $2)", (1, "Alice"))
.unwrap();
let stmt = db.prepare("SELECT name FROM users WHERE id = $1").unwrap();
let name: Option<String> = stmt.query_opt((1,)).unwrap();
assert_eq!(name, Some("Alice".to_string()));
let name: Option<String> = stmt.query_opt((999,)).unwrap();
assert_eq!(name, None);
}
#[test]
fn test_prepared_statement_sql() {
let db = Database::open_in_memory().unwrap();
let stmt = db.prepare("SELECT 1").unwrap();
assert_eq!(stmt.sql(), "SELECT 1");
}
}