1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
extern crate libsqlite3_sys as ffi; use super::raw::RawConnection; use super::serialized_value::SerializedValue; use super::{Sqlite, SqliteValue}; use deserialize::{FromSqlRow, Queryable}; use result::{DatabaseErrorKind, Error, QueryResult}; use row::Row; use serialize::{IsNull, Output, ToSql}; use sql_types::HasSqlType; pub fn register<ArgsSqlType, RetSqlType, Args, Ret, F>( conn: &RawConnection, fn_name: &str, deterministic: bool, mut f: F, ) -> QueryResult<()> where F: FnMut(&RawConnection, Args) -> Ret + Send + 'static, Args: Queryable<ArgsSqlType, Sqlite>, Ret: ToSql<RetSqlType, Sqlite>, Sqlite: HasSqlType<RetSqlType>, { let fields_needed = Args::Row::FIELDS_NEEDED; if fields_needed > 127 { return Err(Error::DatabaseError( DatabaseErrorKind::UnableToSendCommand, Box::new("SQLite functions cannot take more than 127 parameters".to_string()), )); } conn.register_sql_function(fn_name, fields_needed, deterministic, move |conn, args| { let mut row = FunctionRow { args }; let args_row = Args::Row::build_from_row(&mut row).map_err(Error::DeserializationError)?; let args = Args::build(args_row); let result = f(conn, args); let mut buf = Output::new(Vec::new(), &()); let is_null = result.to_sql(&mut buf).map_err(Error::SerializationError)?; let bytes = if let IsNull::Yes = is_null { None } else { Some(buf.into_inner()) }; Ok(SerializedValue { ty: Sqlite::metadata(&()), data: bytes, }) })?; Ok(()) } struct FunctionRow<'a> { args: &'a [*mut ffi::sqlite3_value], } impl<'a> Row<Sqlite> for FunctionRow<'a> { fn take(&mut self) -> Option<&SqliteValue> { self.args.split_first().and_then(|(&first, rest)| { self.args = rest; unsafe { SqliteValue::new(first) } }) } fn next_is_null(&self, count: usize) -> bool { self.args[..count] .iter() .all(|&p| unsafe { SqliteValue::new(p) }.is_none()) } }