diff --git a/src/csv/inference.rs b/src/csv/inference.rs index 3d2acce..a1ec83f 100644 --- a/src/csv/inference.rs +++ b/src/csv/inference.rs @@ -21,6 +21,16 @@ impl ColumnInference { ColumnInference { columns_to_types } } + /// build column 'inference' with every column artificially inferred as a String + pub fn default_inference(csv: &CsvData) -> ColumnInference { + let mut columns_to_types: HashMap = HashMap::new(); + for header in csv.headers.iter() { + columns_to_types.insert(String::from(header), CsvType::String); + } + debug!("Using default column type of string for all columns in file {}: {:?} ", csv.filename, columns_to_types); + ColumnInference { columns_to_types } + } + /// get the type of a column, referenced by its string name pub fn get_type(&self, s: String) -> Option<&CsvType> { self.columns_to_types.get(s.as_str()) @@ -58,12 +68,12 @@ mod test { } #[test] fn it_should_recognize_integer_column() { + let filename: String = String::from("foo.csv"); let headers = StringRecord::from(vec!["foo", "bar"]); let records = vec![ StringRecord::from(vec!["entry1", "1"]), StringRecord::from(vec!["entry2", "2"]), ]; - let filename = String::from("foo.csv"); let inference = ColumnInference::from_csv(&CsvData { headers, records, filename }); assert_eq!( inference.get_type(String::from("foo")), @@ -74,4 +84,23 @@ mod test { Some(&CsvType::Numeric) ); } + + #[test] + fn it_should_use_default_column_type_if_inference_disabled() { + let headers = StringRecord::from(vec!["foo", "bar"]); + let filename: String = String::from("foo.csv"); + let records = vec![ + StringRecord::from(vec!["entry1", "1"]), + StringRecord::from(vec!["entry2", "2"]), + ]; + let inference = ColumnInference::default_inference(&CsvData { headers, records, filename }); + assert_eq!( + inference.get_type(String::from("foo")), + Some(&CsvType::String) + ); + assert_eq!( + inference.get_type(String::from("bar")), + Some(&CsvType::String) + ); + } } diff --git a/src/main.rs b/src/main.rs index 59ddfae..54b421d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,8 @@ struct Opts { delimiter: char, #[clap(long)] trim: bool, + #[clap(long)] + textonly: bool, } fn main() -> Result<(), Box> { @@ -26,7 +28,8 @@ fn main() -> Result<(), Box> { let query = opts.query; let delimiter = opts.delimiter; let trim = opts.trim; - let options = Options{delimiter, trim}; + let textonly = opts.textonly; + let options = Options{delimiter, trim, textonly}; let results = execute_query(query.as_str(), &options)?; write_to_stdout(results)?; Ok(()) diff --git a/src/qsv.rs b/src/qsv.rs index 59da086..38901f2 100644 --- a/src/qsv.rs +++ b/src/qsv.rs @@ -16,7 +16,8 @@ use log::debug; type Rows = Vec>; pub struct Options { pub delimiter: char, - pub trim: bool + pub trim: bool, + pub textonly: bool, } ///Executes a query, possibly returning Rows @@ -53,7 +54,11 @@ fn maybe_load_file( debug!("Attempting to load identifier from SQL as file: {}", filename); let table_name = path.file_stem(); //TODO: should we canonicalize path? let table_name = sanitize(table_name).unwrap_or_else(|| Uuid::new_v4().to_string()); - let inference = ColumnInference::from_csv(&csv); + let inference = if options.textonly { + ColumnInference::default_inference(&csv) + } else { + ColumnInference::from_csv(&csv) + }; let table_parameters = to_table_parameters(&csv, &inference); let table_parameters: Vec<&str> = table_parameters.iter().map(|s| s.as_str()).collect(); let table_name = table_name.as_str(); diff --git a/testdata/sortable_columns.csv b/testdata/sortable_columns.csv new file mode 100644 index 0000000..2415790 --- /dev/null +++ b/testdata/sortable_columns.csv @@ -0,0 +1,4 @@ +column +12 +99 +9 \ No newline at end of file diff --git a/tests/integration.rs b/tests/integration.rs index d2efae1..ac45464 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -102,3 +102,12 @@ fn it_will_run_with_trim() -> Result<(), Box> { cmd.assert().success(); Ok(()) } + +#[test] +fn it_will_run_with_textonly() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("qsv")?; + cmd.arg("select md5(column) from testdata/sortable_columns.csv"); + cmd.arg("--textonly"); + cmd.assert().success(); + Ok(()) +}