Test sub-type

This commit is contained in:
gwenn 2024-01-20 19:16:48 +01:00
parent 13399c5808
commit 83d67d5a29
2 changed files with 49 additions and 2 deletions

View File

@ -263,11 +263,18 @@ pub trait SqlFnOutput {
} }
impl<T: ToSql> SqlFnOutput for T { impl<T: ToSql> SqlFnOutput for T {
#[inline]
fn to_sql(&self) -> Result<(ToSqlOutput<'_>, SubType)> { fn to_sql(&self) -> Result<(ToSqlOutput<'_>, SubType)> {
ToSql::to_sql(self).map(|o| (o, None)) ToSql::to_sql(self).map(|o| (o, None))
} }
} }
impl<T: ToSql> SqlFnOutput for (T, SubType) {
fn to_sql(&self) -> Result<(ToSqlOutput<'_>, SubType)> {
ToSql::to_sql(&self.0).map(|o| (o, self.1))
}
}
unsafe fn sql_result<T: SqlFnOutput>(ctx: *mut sqlite3_context, r: Result<T>) { unsafe fn sql_result<T: SqlFnOutput>(ctx: *mut sqlite3_context, r: Result<T>) {
let t = r.as_ref().map(SqlFnOutput::to_sql); let t = r.as_ref().map(SqlFnOutput::to_sql);
@ -802,8 +809,8 @@ mod test {
#[cfg(feature = "window")] #[cfg(feature = "window")]
use crate::functions::WindowAggregate; use crate::functions::WindowAggregate;
use crate::functions::{Aggregate, Context, FunctionFlags}; use crate::functions::{Aggregate, Context, FunctionFlags, SubType};
use crate::{Connection, Error, Result}; use crate::{Connection, Error, Result, ValueRef};
fn half(ctx: &Context<'_>) -> Result<c_double> { fn half(ctx: &Context<'_>) -> Result<c_double> {
assert_eq!(ctx.len(), 1, "called with unexpected number of arguments"); assert_eq!(ctx.len(), 1, "called with unexpected number of arguments");
@ -1080,4 +1087,37 @@ mod test {
assert_eq!(expected, results); assert_eq!(expected, results);
Ok(()) Ok(())
} }
#[test]
fn test_sub_type() -> Result<()> {
fn test_getsubtype(ctx: &Context<'_>) -> Result<i32> {
Ok(ctx.get_subtype(0) as i32)
}
fn test_setsubtype<'a>(ctx: &'a Context<'_>) -> Result<(ValueRef<'a>, SubType)> {
use std::os::raw::c_uint;
let value = ctx.get_raw(0);
let sub_type = ctx.get::<c_uint>(1)?;
Ok((value, Some(sub_type)))
}
let db = Connection::open_in_memory()?;
db.create_scalar_function(
"test_getsubtype",
1,
FunctionFlags::SQLITE_UTF8,
test_getsubtype,
)?;
db.create_scalar_function(
"test_setsubtype",
2,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_RESULT_SUBTYPE,
test_setsubtype,
)?;
let result: i32 = db.one_column("SELECT test_getsubtype('hello');")?;
assert_eq!(0, result);
let result: i32 = db.one_column("SELECT test_getsubtype(test_setsubtype('hello',123));")?;
assert_eq!(123, result);
Ok(())
}
} }

View File

@ -292,6 +292,13 @@ impl ToSql for Value {
} }
} }
impl<'a> ToSql for ValueRef<'a> {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::Borrowed(*self))
}
}
impl<T: ToSql> ToSql for Option<T> { impl<T: ToSql> ToSql for Option<T> {
#[inline] #[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {