Initial commit

This commit is contained in:
2026-05-06 23:05:46 +09:00
commit 2bb2a395f7
7 changed files with 676 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
use sqlite3_ext::{
function::{Context, FunctionOptions},
*,
};
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn add_sqlite(ctx: &mut Context, args: &mut [&mut ValueRef]) -> Result<()> {
if args.len() != 2 {
return Err(sqlite3_ext::Error::Module(
"myadd requires exactly 2 arguments".to_string(),
));
}
if args[0].value_type() != ValueType::Integer || args[1].value_type() != ValueType::Integer {
return Err(sqlite3_ext::Error::Module(
"myadd requires both arguments to be an integer".to_string(),
));
}
let a = args[0].get_i32();
let b = args[1].get_i32();
let result = add(a, b);
ctx.set_result(result)?;
Ok(())
}
#[sqlite3_ext_main(persistent)]
fn init(db: &Connection) -> Result<()> {
db.create_scalar_function(
"myadd",
&FunctionOptions::default()
.set_n_args(2)
.set_deterministic(true),
add_sqlite,
)?;
Ok(())
}
#[cfg(all(test, feature = "static"))]
mod test {
use super::*;
use sqlite3_ext::Error;
fn setup() -> Result<Database> {
let conn = Database::open(":memory:")?;
init(&conn)?;
Ok(conn)
}
#[test]
fn test_working() -> Result<()> {
let conn = setup()?;
let results: Vec<i64> = conn
.prepare("SELECT myadd(10, 20)")?
.query(())?
.map(|row| Ok(row[0].get_i64()))
.collect()?;
assert_eq!(results, vec![30]);
Ok(())
}
#[test]
fn test_wrong_arg_number() -> Result<()> {
let conn = setup()?;
let result = conn.prepare("SELECT myadd(10)");
assert_eq!(
result.unwrap_err(),
Error::Sqlite(
1,
Some("wrong number of arguments to function myadd()".to_string()),
)
);
Ok(())
}
#[test]
fn test_wrong_arg_type() -> Result<()> {
let conn = setup()?;
let mut statement = conn.prepare("SELECT myadd(10, 'hello!')")?;
let result = statement.query(())?.next();
assert_eq!(
result.unwrap_err(),
Error::Sqlite(
1,
Some("myadd requires both arguments to be an integer".to_string()),
)
);
Ok(())
}
}