mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 13:58:55 +08:00 
			
		
		
		
	Fix CSVTab::create method.
This commit is contained in:
		| @@ -1,7 +1,9 @@ | ||||
| //! CSV Virtual Table | ||||
| extern crate csv; | ||||
| use std::ffi::CStr; | ||||
| use std::fs::File; | ||||
| use std::mem; | ||||
| use std::str; | ||||
| use libc; | ||||
|  | ||||
| use {Connection, Error, Result}; | ||||
| @@ -9,8 +11,6 @@ use ffi; | ||||
| use types::Null; | ||||
| use vtab::{declare_vtab, VTab, VTabCursor}; | ||||
|  | ||||
| use self::csv::Reader; | ||||
|  | ||||
| pub fn load_module(conn: &Connection) -> Result<()> { | ||||
|     let aux: Option<()> = None; | ||||
|     conn.create_module("csv", &CSV_MODULE, aux) | ||||
| @@ -33,23 +33,77 @@ struct CSVTab { | ||||
|  | ||||
| impl VTab<CSVTabCursor> for CSVTab { | ||||
|     fn create(db: *mut ffi::sqlite3, | ||||
|               aux: *mut libc::c_void, | ||||
|               argc: libc::c_int, | ||||
|               _argv: *const *const libc::c_char) | ||||
|               _aux: *mut libc::c_void, | ||||
|               args: &[*const libc::c_char]) | ||||
|               -> Result<CSVTab> { | ||||
|         if argc < 4 { | ||||
|         if args.len() < 4 { | ||||
|             return Err(Error::ModuleError(format!("no CSV file specified"))); | ||||
|         } | ||||
|         //let filename = ; | ||||
|         let reader = try!(csv::Reader::from_file("FIXME")); | ||||
|         // pull out name of csv file (remove quotes) | ||||
|         let mut c_filename = unsafe { CStr::from_ptr(args[3]).to_bytes() }; | ||||
|         if c_filename[0] == b'\'' { | ||||
|             c_filename = &c_filename[1..c_filename.len() - 1]; | ||||
|         } | ||||
|         let filename = try!(str::from_utf8(c_filename)); | ||||
|         let mut reader = try!(csv::Reader::from_file(filename)).has_headers(false); // TODO flexible ? | ||||
|         let mut cols = Vec::new(); | ||||
|  | ||||
|         let args = &args[4..]; | ||||
|         for c_arg in args { | ||||
|             let c_slice = unsafe { CStr::from_ptr(*c_arg).to_bytes() }; | ||||
|             if c_slice.len() == 1 { | ||||
|                 reader = reader.delimiter(c_slice[0]); | ||||
|             } else if c_slice.len() == 3 && c_slice[0] == b'\'' { | ||||
|                 reader = reader.delimiter(c_slice[1]); | ||||
|             } else { | ||||
|                 let arg = try!(str::from_utf8(c_slice)); | ||||
|                 let uc = arg.to_uppercase(); | ||||
|                 if uc.contains("HEADER") { | ||||
|                     reader = reader.has_headers(true); | ||||
|                 } else if uc.contains("NO_QUOTE") { | ||||
|                     reader = reader.quote(0); | ||||
|                 } else { | ||||
|                     cols.push(String::from(arg)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         let mut offset_first_row = 0; | ||||
|         if reader.has_headers  { | ||||
|             let headers = try!(reader.headers()); | ||||
|             offset_first_row = reader.byte_offset(); | ||||
|             // headers ignored if cols is not empty | ||||
|             if cols.is_empty() { | ||||
|                 cols = headers; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if cols.is_empty() { | ||||
|             return Err(Error::ModuleError(format!("no column name specified"))); | ||||
|         } | ||||
|  | ||||
|         let mut sql = String::from("CREATE TABLE x("); | ||||
|         for (i, col) in cols.iter().enumerate() { | ||||
|             if col.is_empty() { | ||||
|                 return Err(Error::ModuleError(format!("no column name found"))); | ||||
|             } | ||||
|             sql.push('"'); | ||||
|             sql.push_str(col); | ||||
|             sql.push('"'); | ||||
|             if i == cols.len() - 1 { | ||||
|                 sql.push_str(");"); | ||||
|             } else { | ||||
|                 sql.push_str(", "); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         let vtab = CSVTab { | ||||
|             base: Default::default(), | ||||
|             reader: reader, | ||||
|             offset_first_row: 0, | ||||
|             cols: vec![], // FIXME | ||||
|             offset_first_row: offset_first_row, | ||||
|             cols: cols, | ||||
|         }; | ||||
|         unimplemented!(); | ||||
|         try!(declare_vtab(db, "CREATE TABLE x FIXME")); | ||||
|         try!(declare_vtab(db, &sql)); | ||||
|         Ok(vtab) | ||||
|     } | ||||
|  | ||||
| @@ -102,7 +156,7 @@ impl VTabCursor<CSVTab> for CSVTabCursor { | ||||
|     } | ||||
|     fn eof(&self) -> bool { | ||||
|         let vtab = self.vtab(); | ||||
|         unsafe { (*vtab).reader.done() } | ||||
|         vtab.reader.done() | ||||
|     } | ||||
|     fn column(&self, ctx: *mut ffi::sqlite3_context, col: libc::c_int) -> Result<()> { | ||||
|         use functions::ToResult; | ||||
|   | ||||
| @@ -46,8 +46,7 @@ struct IntArrayVTab { | ||||
| impl VTab<IntArrayVTabCursor> for IntArrayVTab { | ||||
|     fn create(db: *mut ffi::sqlite3, | ||||
|               aux: *mut libc::c_void, | ||||
|               _argc: libc::c_int, | ||||
|               _argv: *const *const libc::c_char) | ||||
|               _args: &[*const libc::c_char]) | ||||
|               -> Result<IntArrayVTab> { | ||||
|         let array = unsafe { mem::transmute(aux) }; | ||||
|         let vtab = IntArrayVTab { | ||||
|   | ||||
| @@ -40,10 +40,9 @@ use ffi; | ||||
| pub trait VTab<C: VTabCursor<Self>>: Sized { | ||||
|     fn create(db: *mut ffi::sqlite3, | ||||
|               aux: *mut libc::c_void, | ||||
|               _argc: libc::c_int, | ||||
|               _argv: *const *const libc::c_char) | ||||
|               args: &[*const libc::c_char]) | ||||
|               -> Result<Self>; | ||||
|     fn best_index(&self, _info: *mut ffi::sqlite3_index_info); | ||||
|     fn best_index(&self, info: *mut ffi::sqlite3_index_info); | ||||
|     fn open(&self) -> Result<C>; | ||||
| } | ||||
|  | ||||
| @@ -52,7 +51,7 @@ pub trait VTabCursor<V: VTab<Self>>: Sized { | ||||
|     fn filter(&mut self) -> Result<()>; | ||||
|     fn next(&mut self) -> Result<()>; | ||||
|     fn eof(&self) -> bool; | ||||
|     fn column(&self, ctx: *mut ffi::sqlite3_context, _i: libc::c_int) -> Result<()>; | ||||
|     fn column(&self, ctx: *mut ffi::sqlite3_context, i: libc::c_int) -> Result<()>; | ||||
|     fn rowid(&self) -> Result<i64>; | ||||
| } | ||||
|  | ||||
| @@ -156,8 +155,10 @@ unsafe extern "C" fn $create(db: *mut ffi::sqlite3, | ||||
|                               err_msg: *mut *mut libc::c_char) | ||||
|                               -> libc::c_int { | ||||
|     use std::error::Error as StdError; | ||||
|     use std::slice; | ||||
|     use vtab::mprintf; | ||||
|     match $vtab::create(db, aux, argc, argv) { | ||||
|     let args = slice::from_raw_parts(argv, argc as usize); | ||||
|     match $vtab::create(db, aux, args) { | ||||
|         Ok(vtab) => { | ||||
|             let boxed_vtab: *mut $vtab = Box::into_raw(Box::new(vtab)); | ||||
|             *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user