mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-22 16:29:20 +08:00
Remove int_array module
Replaced by array module.
This commit is contained in:
parent
1a1d41b4e4
commit
e040dc9e1f
@ -1,214 +0,0 @@
|
||||
//! Int array virtual table.
|
||||
//! Port of C ["intarray"](http://www.sqlite.org/cgi/src/finfo?name=src/test_intarray.h).
|
||||
use std::cell::RefCell;
|
||||
use std::default::Default;
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::rc::Rc;
|
||||
|
||||
use ffi;
|
||||
use vtab::{declare_vtab, escape_double_quote, Context, IndexInfo, VTab, VTabCursor, Values};
|
||||
use {Connection, Error, Result};
|
||||
|
||||
/// Create a specific instance of an intarray object.
|
||||
/// The new intarray object is returned.
|
||||
///
|
||||
/// Each intarray object corresponds to a virtual table in the TEMP table
|
||||
/// with the specified `name`.
|
||||
pub fn create_int_array(conn: &Connection, name: &str) -> Result<Rc<RefCell<Vec<i64>>>> {
|
||||
let array = Rc::new(RefCell::new(Vec::new()));
|
||||
try!(conn.create_module(name, &INT_ARRAY_MODULE, Some(array.clone())));
|
||||
try!(conn.execute_batch(&format!(
|
||||
"CREATE VIRTUAL TABLE temp.\"{0}\" USING \"{0}\"",
|
||||
escape_double_quote(name)
|
||||
)));
|
||||
Ok(array)
|
||||
}
|
||||
|
||||
/// Destroy the intarray object by dropping the virtual table.
|
||||
/// If not done explicitly by the application, the virtual table will be dropped implicitly
|
||||
/// by the system when the database connection is closed.
|
||||
/// In fact, the intarray is not destroy until the connection is closed
|
||||
/// because there is no other way to destroy the associated module.
|
||||
pub fn drop_int_array(conn: &Connection, name: &str) -> Result<()> {
|
||||
conn.execute_batch(&format!(
|
||||
"DROP TABLE temp.\"{0}\"",
|
||||
escape_double_quote(name)
|
||||
))
|
||||
// http://www.mail-archive.com/sqlite-users%40mailinglists.sqlite.org/msg08423.html
|
||||
// "Once a virtual table module has been created, it cannot be modified or destroyed, except by closing the database connection."
|
||||
// let aux: Option<()> = None;
|
||||
// conn.create_module(name, ptr::null() as *const ffi::sqlite3_module, aux)
|
||||
}
|
||||
|
||||
eponymous_module!(
|
||||
INT_ARRAY_MODULE,
|
||||
IntArrayVTab,
|
||||
Rc<RefCell<Vec<i64>>>,
|
||||
IntArrayVTabCursor,
|
||||
Some(int_array_connect),
|
||||
int_array_connect,
|
||||
int_array_best_index,
|
||||
int_array_disconnect,
|
||||
Some(int_array_disconnect),
|
||||
int_array_open,
|
||||
int_array_close,
|
||||
int_array_filter,
|
||||
int_array_next,
|
||||
int_array_eof,
|
||||
int_array_column,
|
||||
int_array_rowid
|
||||
);
|
||||
|
||||
#[repr(C)]
|
||||
struct IntArrayVTab {
|
||||
/// Base class
|
||||
base: ffi::sqlite3_vtab,
|
||||
array: *const Rc<RefCell<Vec<i64>>>,
|
||||
}
|
||||
|
||||
impl VTab for IntArrayVTab {
|
||||
type Aux = Rc<RefCell<Vec<i64>>>;
|
||||
type Cursor = IntArrayVTabCursor;
|
||||
|
||||
unsafe fn connect(
|
||||
db: *mut ffi::sqlite3,
|
||||
aux: *mut Rc<RefCell<Vec<i64>>>,
|
||||
_args: &[&[u8]],
|
||||
) -> Result<IntArrayVTab> {
|
||||
let array = aux as *const Rc<RefCell<Vec<i64>>>;
|
||||
let vtab = IntArrayVTab {
|
||||
base: Default::default(),
|
||||
array,
|
||||
};
|
||||
try!(declare_vtab(
|
||||
db,
|
||||
"CREATE TABLE x(value INTEGER PRIMARY KEY)"
|
||||
));
|
||||
Ok(vtab)
|
||||
}
|
||||
|
||||
fn best_index(&self, _info: &mut IndexInfo) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn open(&self) -> Result<IntArrayVTabCursor> {
|
||||
Ok(IntArrayVTabCursor::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[repr(C)]
|
||||
struct IntArrayVTabCursor {
|
||||
/// Base class
|
||||
base: ffi::sqlite3_vtab_cursor,
|
||||
/// Current cursor position
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl IntArrayVTabCursor {
|
||||
fn new() -> IntArrayVTabCursor {
|
||||
IntArrayVTabCursor {
|
||||
base: Default::default(),
|
||||
i: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VTabCursor for IntArrayVTabCursor {
|
||||
type Table = IntArrayVTab;
|
||||
|
||||
fn vtab(&self) -> &IntArrayVTab {
|
||||
unsafe { &*(self.base.pVtab as *const IntArrayVTab) }
|
||||
}
|
||||
fn filter(&mut self, _idx_num: c_int, _idx_str: Option<&str>, _args: &Values) -> Result<()> {
|
||||
self.i = 0;
|
||||
Ok(())
|
||||
}
|
||||
fn next(&mut self) -> Result<()> {
|
||||
self.i += 1;
|
||||
Ok(())
|
||||
}
|
||||
fn eof(&self) -> bool {
|
||||
let vtab = self.vtab();
|
||||
unsafe {
|
||||
let array = (*vtab.array).borrow();
|
||||
self.i >= array.len()
|
||||
}
|
||||
}
|
||||
fn column(&self, ctx: &mut Context, _i: c_int) -> Result<()> {
|
||||
let vtab = self.vtab();
|
||||
unsafe {
|
||||
let array = (*vtab.array).borrow();
|
||||
ctx.set_result(&array[self.i])
|
||||
}
|
||||
}
|
||||
fn rowid(&self) -> Result<i64> {
|
||||
Ok(self.i as i64)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use vtab::int_array;
|
||||
use Connection;
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn test_int_array_module() {
|
||||
let db = Connection::open_in_memory().unwrap();
|
||||
db.execute_batch("CREATE TABLE t1 (x INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO t1 VALUES (3);
|
||||
CREATE TABLE t2 (y INT);
|
||||
INSERT INTO t2 VALUES (11);
|
||||
CREATE TABLE t3 (z INT);
|
||||
INSERT INTO t3 VALUES (-5);").unwrap();
|
||||
let p1 = int_array::create_int_array(&db, "ex1").unwrap();
|
||||
let p2 = int_array::create_int_array(&db, "ex2").unwrap();
|
||||
let p3 = int_array::create_int_array(&db, "ex3").unwrap();
|
||||
|
||||
let mut s = db.prepare("SELECT * FROM t1, t2, t3
|
||||
WHERE t1.x IN ex1
|
||||
AND t2.y IN ex2
|
||||
AND t3.z IN ex3").unwrap();
|
||||
|
||||
p1.borrow_mut().append(&mut vec![1, 2, 3, 4]);
|
||||
p2.borrow_mut().append(&mut vec![5, 6, 7, 8, 9, 10, 11]);
|
||||
p3.borrow_mut().append(&mut vec![-1, -5, -10]);
|
||||
|
||||
{
|
||||
s.query_map(&[], |row| {
|
||||
let i1: i64 = row.get(0);
|
||||
assert!(i1 == 1 || i1 == 3);
|
||||
assert_eq!(11, row.get::<_, i32>(1));
|
||||
assert_eq!(-5, row.get::<_, i32>(2));
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
p1.borrow_mut().clear();
|
||||
p2.borrow_mut().clear();
|
||||
p3.borrow_mut().clear();
|
||||
p1.borrow_mut().append(&mut vec![1]);
|
||||
p2.borrow_mut().append(&mut vec![7, 11]);
|
||||
p3.borrow_mut().append(&mut vec![-5, -10]);
|
||||
|
||||
{
|
||||
let mut rows = s.query(&[]).unwrap();
|
||||
let row = rows.next().unwrap().unwrap();
|
||||
assert_eq!(1, row.get::<_, i32>(0));
|
||||
assert_eq!(11, row.get::<_, i32>(1));
|
||||
assert_eq!(-5, row.get::<_, i32>(2));
|
||||
}
|
||||
|
||||
p2.borrow_mut().clear();
|
||||
p3.borrow_mut().clear();
|
||||
p2.borrow_mut().append(&mut vec![3, 4, 5]);
|
||||
p3.borrow_mut().append(&mut vec![0, -5]);
|
||||
let mut rows = s.query(&[]).unwrap();
|
||||
assert!(rows.next().is_none());
|
||||
|
||||
int_array::drop_int_array(&db, "ex1").unwrap();
|
||||
int_array::drop_int_array(&db, "ex2").unwrap();
|
||||
int_array::drop_int_array(&db, "ex3").unwrap();
|
||||
}
|
||||
}
|
@ -779,7 +779,6 @@ pub fn mprintf(err_msg: &str) -> *mut c_char {
|
||||
pub mod array;
|
||||
#[cfg(feature = "csvtab")]
|
||||
pub mod csvtab;
|
||||
pub mod int_array;
|
||||
#[cfg(feature = "bundled")]
|
||||
pub mod series; // SQLite >= 3.9.0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user