Make connect/create return a tuple

This commit is contained in:
gwenn 2018-06-22 17:20:47 +02:00
parent 861e8edb96
commit 6463db906d
4 changed files with 45 additions and 33 deletions

View File

@ -4,6 +4,7 @@ use std::default::Default;
use std::os::raw::{c_char, c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};
use std::rc::Rc; use std::rc::Rc;
use error::error_from_sqlite_code;
use ffi; use ffi;
use types::{ToSql, ToSqlOutput, Value}; use types::{ToSql, ToSqlOutput, Value};
use vtab::{self, Context, IndexInfo, Module, VTab, VTabCursor, Values}; use vtab::{self, Context, IndexInfo, Module, VTab, VTabCursor, Values};
@ -62,15 +63,15 @@ impl Module for ArrayModule {
self.0 self.0
} }
fn connect(db: &mut ffi::sqlite3, _aux: Option<&()>, _args: &[&[u8]]) -> Result<ArrayTab> { fn connect(
_: &mut ffi::sqlite3,
_aux: Option<&()>,
_args: &[&[u8]],
) -> Result<(String, ArrayTab)> {
let vtab = ArrayTab { let vtab = ArrayTab {
base: Default::default(), base: Default::default(),
}; };
try!(ArrayModule::declare_vtab( Ok(("CREATE TABLE x(value,pointer hidden)".to_owned(), vtab))
db,
"CREATE TABLE x(value,pointer hidden)"
));
Ok(vtab)
} }
} }

View File

@ -7,6 +7,7 @@ use std::path::Path;
use std::result; use std::result;
use std::str; use std::str;
use error::error_from_sqlite_code;
use ffi; use ffi;
use types::Null; use types::Null;
use vtab::{ use vtab::{
@ -84,7 +85,11 @@ impl Module for CSVModule {
self.0 self.0
} }
fn connect(db: &mut ffi::sqlite3, _aux: Option<&()>, args: &[&[u8]]) -> Result<CSVTab> { fn connect(
_: &mut ffi::sqlite3,
_aux: Option<&()>,
args: &[&[u8]],
) -> Result<(String, CSVTab)> {
if args.len() < 4 { if args.len() < 4 {
return Err(Error::ModuleError("no CSV file specified".to_owned())); return Err(Error::ModuleError("no CSV file specified".to_owned()));
} }
@ -230,8 +235,7 @@ impl Module for CSVModule {
schema = Some(sql); schema = Some(sql);
} }
try!(CSVModule::declare_vtab(db, &schema.unwrap())); Ok((schema.unwrap().to_owned(), vtab))
Ok(vtab)
} }
} }

View File

@ -7,7 +7,6 @@ use std::ptr;
use std::slice; use std::slice;
use context::set_result; use context::set_result;
use error::error_from_sqlite_code;
use ffi; use ffi;
use types::{FromSql, FromSqlError, ToSql, ValueRef}; use types::{FromSql, FromSqlError, ToSql, ValueRef};
use {str_to_cstring, Connection, Error, InnerConnection, Result}; use {str_to_cstring, Connection, Error, InnerConnection, Result};
@ -54,7 +53,7 @@ pub trait Module {
db: &mut ffi::sqlite3, db: &mut ffi::sqlite3,
aux: Option<&Self::Aux>, aux: Option<&Self::Aux>,
args: &[&[u8]], args: &[&[u8]],
) -> Result<Self::Table> { ) -> Result<(String, Self::Table)> {
Self::connect(db, aux, args) Self::connect(db, aux, args)
} }
/// Similar to `create`. The difference is that `connect` is called to establish a new connection /// Similar to `create`. The difference is that `connect` is called to establish a new connection
@ -63,18 +62,7 @@ pub trait Module {
db: &mut ffi::sqlite3, db: &mut ffi::sqlite3,
aux: Option<&Self::Aux>, aux: Option<&Self::Aux>,
args: &[&[u8]], args: &[&[u8]],
) -> Result<Self::Table>; ) -> Result<(String, Self::Table)>;
/// Declare the schema of a virtual table.
fn declare_vtab(db: &mut ffi::sqlite3, sql: &str) -> Result<()> {
let c_sql = try!(CString::new(sql));
let rc = unsafe { ffi::sqlite3_declare_vtab(db, c_sql.as_ptr()) };
if rc == ffi::SQLITE_OK {
Ok(())
} else {
Err(error_from_sqlite_code(rc, None))
}
}
} }
/// Virtual table instance trait. /// Virtual table instance trait.
@ -573,10 +561,25 @@ macro_rules! create_or_connect {
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error> .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
.collect::<Vec<_>>(); .collect::<Vec<_>>();
match $module::$module_func(db.as_mut().expect("non null db pointer"), aux.as_ref(), &vec[..]) { match $module::$module_func(db.as_mut().expect("non null db pointer"), aux.as_ref(), &vec[..]) {
Ok(vtab) => { Ok((sql, vtab)) => {
let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab)); match ::std::ffi::CString::new(sql) {
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab; Ok(c_sql) => {
ffi::SQLITE_OK let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
if rc == ffi::SQLITE_OK {
let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
ffi::SQLITE_OK
} else {
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
rc
}
}
Err(err) => {
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
}
}
} }
Err(Error::SqliteFailure(err, s)) => { Err(Error::SqliteFailure(err, s)) => {
if let Some(s) = s { if let Some(s) = s {

View File

@ -3,6 +3,7 @@
use std::default::Default; use std::default::Default;
use std::os::raw::{c_char, c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};
use error::error_from_sqlite_code;
use ffi; use ffi;
use types::Type; use types::Type;
use vtab::{self, Context, IndexInfo, Module, VTab, VTabCursor, Values}; use vtab::{self, Context, IndexInfo, Module, VTab, VTabCursor, Values};
@ -45,15 +46,18 @@ impl Module for Series {
self.0 self.0
} }
fn connect(db: &mut ffi::sqlite3, _aux: Option<&()>, _args: &[&[u8]]) -> Result<SeriesTab> { fn connect(
_: &mut ffi::sqlite3,
_aux: Option<&()>,
_args: &[&[u8]],
) -> Result<(String, SeriesTab)> {
let vtab = SeriesTab { let vtab = SeriesTab {
base: Default::default(), base: Default::default(),
}; };
try!(Series::declare_vtab( Ok((
db, "CREATE TABLE x(value,start hidden,stop hidden,step hidden)".to_owned(),
"CREATE TABLE x(value,start hidden,stop hidden,step hidden)" vtab,
)); ))
Ok(vtab)
} }
} }