Change VTab::create signature

This commit is contained in:
gwenn 2016-08-13 11:54:19 +02:00
parent 3f55a4583c
commit 59ad638875
3 changed files with 19 additions and 14 deletions

View File

@ -1,6 +1,5 @@
//! CSV Virtual Table //! CSV Virtual Table
extern crate csv; extern crate csv;
use std::ffi::CStr;
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use std::result; use std::result;
@ -32,14 +31,17 @@ init_module!(CSV_MODULE,
csv_column, csv_column,
csv_rowid); csv_rowid);
/// An instance of the CSV virtual table
#[repr(C)] #[repr(C)]
struct CSVTab { struct CSVTab {
/// Base class /// Base class. Must be first
base: ffi::sqlite3_vtab, base: ffi::sqlite3_vtab,
/// Name of the CSV file
filename: String, filename: String,
has_headers: bool, has_headers: bool,
delimiter: u8, delimiter: u8,
quote: u8, quote: u8,
/// Offset to start of data
offset_first_row: u64, offset_first_row: u64,
} }
@ -56,13 +58,13 @@ impl CSVTab {
impl VTab<CSVTabCursor> for CSVTab { impl VTab<CSVTabCursor> for CSVTab {
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3,
_aux: *mut libc::c_void, _aux: *mut libc::c_void,
args: &[*const libc::c_char]) args: &[&[u8]])
-> Result<CSVTab> { -> Result<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()));
} }
// pull out name of csv file (remove quotes) // pull out name of csv file (remove quotes)
let mut c_filename = unsafe { CStr::from_ptr(args[3]).to_bytes() }; let mut c_filename = args[3];
if c_filename[0] == b'\'' { if c_filename[0] == b'\'' {
c_filename = &c_filename[1..c_filename.len() - 1]; c_filename = &c_filename[1..c_filename.len() - 1];
} }
@ -81,8 +83,7 @@ impl VTab<CSVTabCursor> for CSVTab {
let mut cols: Vec<String> = Vec::new(); let mut cols: Vec<String> = Vec::new();
let args = &args[4..]; let args = &args[4..];
for c_arg in args { for c_slice in args {
let c_slice = unsafe { CStr::from_ptr(*c_arg).to_bytes() };
if c_slice.len() == 1 { if c_slice.len() == 1 {
vtab.delimiter = c_slice[0]; vtab.delimiter = c_slice[0];
} else if c_slice.len() == 3 && c_slice[0] == b'\'' { } else if c_slice.len() == 3 && c_slice[0] == b'\'' {
@ -121,7 +122,7 @@ impl VTab<CSVTabCursor> for CSVTab {
} }
sql.push('"'); sql.push('"');
sql.push_str(col); sql.push_str(col);
sql.push('"'); sql.push_str("\" TEXT");
if i == cols.len() - 1 { if i == cols.len() - 1 {
sql.push_str(");"); sql.push_str(");");
} else { } else {
@ -140,11 +141,12 @@ impl VTab<CSVTabCursor> for CSVTab {
} }
} }
/// A cursor for the CSV virtual table
#[repr(C)] #[repr(C)]
struct CSVTabCursor { struct CSVTabCursor {
/// Base class /// Base class. Must be first
base: ffi::sqlite3_vtab_cursor, base: ffi::sqlite3_vtab_cursor,
/// The CSV reader object
reader: csv::Reader<File>, reader: csv::Reader<File>,
/// Current cursor position /// Current cursor position
row_number: usize, row_number: usize,

View File

@ -60,7 +60,7 @@ struct IntArrayVTab {
impl VTab<IntArrayVTabCursor> for IntArrayVTab { impl VTab<IntArrayVTabCursor> for IntArrayVTab {
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void, aux: *mut libc::c_void,
_args: &[*const libc::c_char]) _args: &[&[u8]])
-> Result<IntArrayVTab> { -> Result<IntArrayVTab> {
let array = unsafe { mem::transmute(aux) }; let array = unsafe { mem::transmute(aux) };
let vtab = IntArrayVTab { let vtab = IntArrayVTab {

View File

@ -1,7 +1,6 @@
//! Create virtual tables. //! Create virtual tables.
//! (See http://sqlite.org/vtab.html) //! (See http://sqlite.org/vtab.html)
use std::borrow::Cow; use std::borrow::Cow::{self, Borrowed, Owned};
use std::borrow::Cow::{Borrowed, Owned};
use std::ffi::CString; use std::ffi::CString;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
@ -45,7 +44,7 @@ pub trait VTab<C: VTabCursor<Self>>: Sized {
/// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement. /// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement.
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void, aux: *mut libc::c_void,
args: &[*const libc::c_char]) args: &[&[u8]])
-> Result<Self>; -> Result<Self>;
/// Determine the best way to access the virtual table. /// Determine the best way to access the virtual table.
fn best_index(&self, info: *mut ffi::sqlite3_index_info); fn best_index(&self, info: *mut ffi::sqlite3_index_info);
@ -186,10 +185,14 @@ unsafe extern "C" fn $create(db: *mut ffi::sqlite3,
err_msg: *mut *mut libc::c_char) err_msg: *mut *mut libc::c_char)
-> libc::c_int { -> libc::c_int {
use std::error::Error as StdError; use std::error::Error as StdError;
use std::ffi::CStr;
use std::slice; use std::slice;
use vtab::mprintf; use vtab::mprintf;
let args = slice::from_raw_parts(argv, argc as usize); let args = slice::from_raw_parts(argv, argc as usize);
match $vtab::create(db, aux, args) { let vec = args.iter().map(|cs| {
CStr::from_ptr(*cs).to_bytes()
}).collect::<Vec<_>>();
match $vtab::create(db, aux, &vec[..]) {
Ok(vtab) => { Ok(vtab) => {
let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab)); let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab; *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;