From c9572a06e7bee7a8f13dc27c79327efc680fe571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Duquette?= Date: Mon, 8 Apr 2024 12:00:43 -0400 Subject: [PATCH 1/2] Add a tool to compare translation with a base file --- Cargo.lock | 7 +++++ Cargo.toml | 3 ++- cirup_core/src/lib.rs | 4 +++ cirup_core/src/query.rs | 51 ++++++++++++++++++++++++++++++++++- cirup_core/src/triple.rs | 36 +++++++++++++++++++++++++ cirup_core/test/test_new.resx | 16 +++++++++++ cirup_core/test/test_old.resx | 7 +++++ diff_with_base/Cargo.toml | 15 +++++++++++ diff_with_base/main.rs | 30 +++++++++++++++++++++ 9 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 cirup_core/src/triple.rs create mode 100644 cirup_core/test/test_new.resx create mode 100644 cirup_core/test/test_old.resx create mode 100644 diff_with_base/Cargo.toml create mode 100644 diff_with_base/main.rs diff --git a/Cargo.lock b/Cargo.lock index 30d02e7..4924aef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,6 +188,13 @@ dependencies = [ "memchr", ] +[[package]] +name = "diff_with_base" +version = "0.1.0" +dependencies = [ + "cirup_core", +] + [[package]] name = "dirs-next" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 33e250d..3aff211 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "cirup_cli", - "cirup_core" + "cirup_core", + "diff_with_base" ] diff --git a/cirup_core/src/lib.rs b/cirup_core/src/lib.rs index f23899b..66fd1b2 100644 --- a/cirup_core/src/lib.rs +++ b/cirup_core/src/lib.rs @@ -24,6 +24,10 @@ extern crate lazy_static; mod resource; use resource::Resource; +mod triple; +use triple::Triple; + + pub mod config; mod error; mod shell; diff --git a/cirup_core/src/query.rs b/cirup_core/src/query.rs index 9f06348..14de2c9 100644 --- a/cirup_core/src/query.rs +++ b/cirup_core/src/query.rs @@ -7,7 +7,7 @@ use rusqlite::{Connection, Error, Statement}; use file::{save_resource_file, vfile_set}; use vtab::{create_db, init_db, register_table}; -use Resource; +use {Resource, Triple}; pub fn print_pretty(columns: Vec, values: &mut Rows) { let mut row = Row::empty(); @@ -112,6 +112,28 @@ pub fn execute_query_resource(db: &Connection, query: &str) -> Vec { resources } +pub fn execute_query_triple(db: &Connection, query: &str) -> Vec { + let mut resources: Vec = Vec::new(); + let mut statement = db.prepare(&query).unwrap(); + let mut response = statement.query(&[]).unwrap(); + + loop { + if let Some(v) = response.next() { + if let Some(res) = v.ok() { + let name = &res.get::(0); + let value = &res.get::(1); + let base = &res.get::(2); + let resource = Triple::new(name, value, base); + resources.push(resource); + } + } else { + break; + } + } + + resources +} + pub fn query_file(input: &str, table: &str, query: &str) { let db = init_db(table, input); execute_query(&db, query); @@ -140,6 +162,10 @@ impl CirupEngine { execute_query_resource(&self.db, query) } + pub fn query_triple(&self, query: &str) -> Vec { + execute_query_triple(&self.db, query) + } + pub fn query(&self, query: &str) { execute_query(&self.db, query); } @@ -285,3 +311,26 @@ fn test_query_subtract() { let actual = engine.query_resource("SELECT * FROM A WHERE A.key NOT IN (SELECT B.key FROM B)"); assert_eq!(actual, expected); } + +#[test] +fn test_query_diff_with_base() { + let engine = CirupEngine::new(); + engine.register_table_from_str("old", "test_old.resx", include_str!("../test/test_old.resx")); + engine.register_table_from_str("new", "test_new.resx", include_str!("../test/test_new.resx")); + engine.register_table_from_str("base", "test.resx", include_str!("../test/test.resx")); + + let triples = engine.query_triple(r"SELECT new.key, new.val, base.val + FROM new + LEFT OUTER JOIN old ON new.key = old.key + LEFT OUTER JOIN base ON new.key = base.key + WHERE (old.val IS NULL)"); + + for triple in triples.iter() { + println!("key: {}", triple.name); + println!("value: {}", triple.value); + println!("base: {}", triple.base); + println!(""); + }; + + assert_eq!(triples.len(), 2); +} \ No newline at end of file diff --git a/cirup_core/src/triple.rs b/cirup_core/src/triple.rs new file mode 100644 index 0000000..eda0b68 --- /dev/null +++ b/cirup_core/src/triple.rs @@ -0,0 +1,36 @@ +use std::fmt; + +#[derive(Clone)] +pub struct Triple { + pub name: String, + pub value: String, + pub base: String, +} + +impl fmt::Debug for Triple { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{},{},{}", self.name, self.value, self.base) + } +} + +impl fmt::Display for Triple { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{},{},{}", self.name, self.value, self.base) + } +} + +impl PartialEq for Triple { + fn eq(&self, other: &Triple) -> bool { + (self.name == other.name) && (self.value == other.value) + } +} + +impl Triple { + pub fn new(name: &str, value: &str, base: &str) -> Self { + Triple { + name: name.to_owned(), + value: value.to_owned(), + base: base.to_owned(), + } + } +} diff --git a/cirup_core/test/test_new.resx b/cirup_core/test/test_new.resx new file mode 100644 index 0000000..a816ca5 --- /dev/null +++ b/cirup_core/test/test_new.resx @@ -0,0 +1,16 @@ + + + + Je suis sur un bateau + + + Juste une vie a vivre + + + Qui a laissé les chiens sortir? + + + Francais seulement + + + diff --git a/cirup_core/test/test_old.resx b/cirup_core/test/test_old.resx new file mode 100644 index 0000000..ec8e37e --- /dev/null +++ b/cirup_core/test/test_old.resx @@ -0,0 +1,7 @@ + + + + Je suis sur un bateau + + + diff --git a/diff_with_base/Cargo.toml b/diff_with_base/Cargo.toml new file mode 100644 index 0000000..205e329 --- /dev/null +++ b/diff_with_base/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "diff_with_base" +version = "0.1.0" +authors = ["Sebastien Duquette "] +edition = "2018" + +[[bin]] +name = "diff_with_base" +path = "main.rs" + +[dependencies] + +[dependencies.cirup_core] +path = "../cirup_core" + diff --git a/diff_with_base/main.rs b/diff_with_base/main.rs new file mode 100644 index 0000000..9cd2d67 --- /dev/null +++ b/diff_with_base/main.rs @@ -0,0 +1,30 @@ +use std::env; + +use cirup_core::query::CirupEngine; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() != 4 { + println!("diff_with_base "); + return; + } + + let engine = CirupEngine::new(); + engine.register_table_from_file("old", &args[1]); + engine.register_table_from_file("new", &args[2]); + engine.register_table_from_file("base", &args[3]); + + let triples = engine.query_triple(r"SELECT new.key, new.val, base.val + FROM new + LEFT OUTER JOIN old ON new.key = old.key + INNER JOIN base ON new.key = base.key + WHERE (old.val IS NULL)"); + + for triple in triples.iter() { + println!("key: {}", triple.name); + println!("orig: {}", triple.base); + println!("trad: {}", triple.value); + println!(""); + }; +} \ No newline at end of file From fd27f352814eccc8b13e0a8c59c39aca279bcc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Duquette?= Date: Mon, 8 Apr 2024 18:17:46 -0400 Subject: [PATCH 2/2] Add diff-with-base as a cirup command --- Cargo.lock | 7 ---- Cargo.toml | 3 +- cirup_cli/src/cli.yml | 17 ++++++++- cirup_cli/src/main.rs | 13 +++++++ cirup_core/src/query.rs | 72 ++++++++++++++++++++++++++------------- cirup_core/src/sync.rs | 2 ++ diff_with_base/Cargo.toml | 15 -------- diff_with_base/main.rs | 30 ---------------- 8 files changed, 80 insertions(+), 79 deletions(-) delete mode 100644 diff_with_base/Cargo.toml delete mode 100644 diff_with_base/main.rs diff --git a/Cargo.lock b/Cargo.lock index 4924aef..30d02e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,13 +188,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "diff_with_base" -version = "0.1.0" -dependencies = [ - "cirup_core", -] - [[package]] name = "dirs-next" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 3aff211..33e250d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] members = [ "cirup_cli", - "cirup_core", - "diff_with_base" + "cirup_core" ] diff --git a/cirup_cli/src/cli.yml b/cirup_cli/src/cli.yml index 9e0f4b7..db0ac3b 100644 --- a/cirup_cli/src/cli.yml +++ b/cirup_cli/src/cli.yml @@ -139,4 +139,19 @@ subcommands: required: true - output: index: 3 - takes_value: true \ No newline at end of file + takes_value: true + - diff-with-base: + about: "output keys that have values in [new] but not in [old] with the value in [base]" + args: + - old: + index: 1 + takes_value: true + required: true + - new: + index: 2 + takes_value: true + required: true + - base: + index: 3 + takes_value: true + required: true \ No newline at end of file diff --git a/cirup_cli/src/main.rs b/cirup_cli/src/main.rs index d8eda42..def5686 100644 --- a/cirup_cli/src/main.rs +++ b/cirup_cli/src/main.rs @@ -60,6 +60,11 @@ fn sort(file_one: &str, out_file: Option<&str>) { } } +fn diff_with_base(old: &str, new: &str, base: &str) { + let query = query::query_diff_with_base(old, new, base); + query.run_triple_interactive(); +} + fn run(matches: &clap::ArgMatches, config: Option) -> Result<(), Box> { match matches.subcommand() { ("file-print", Some(args)) => { @@ -173,6 +178,14 @@ fn run(matches: &clap::ArgMatches, config: Option) -> Result<(), Box Err("configuration file required")?, }, + ("diff-with-base", Some(args)) => { + diff_with_base( + args.value_of("old").unwrap(), + args.value_of("new").unwrap(), + args.value_of("base").unwrap(), + ); + Ok(()) + } _ => Err("unrecognised subcommand")?, } } diff --git a/cirup_core/src/query.rs b/cirup_core/src/query.rs index 14de2c9..cea3927 100644 --- a/cirup_core/src/query.rs +++ b/cirup_core/src/query.rs @@ -54,6 +54,15 @@ pub fn print_resources_pretty(resources: &Vec) { println!("{}", table); } +pub fn print_triples_pretty(triples: &Vec) { + for triple in triples.iter() { + println!("name: {}", triple.name); + println!("base: {}", triple.base); + println!("value: {}", triple.value); + println!(""); + }; +} + fn get_statement_column_names(statement: &Statement) -> Vec { let mut column_names = Vec::new(); for column_name in statement.column_names().iter() { @@ -182,6 +191,12 @@ const DIFF_QUERY: &str = r" FROM A LEFT OUTER JOIN B ON A.key = B.key WHERE (B.val IS NULL)"; +const DIFF_WITH_BASE_QUERY: &str = r" + SELECT B.key, B.val, C.val + FROM B + LEFT OUTER JOIN A ON B.key = A.key + INNER JOIN C ON B.key = C.key + WHERE (A.val IS NULL)"; const CHANGE_QUERY: &str = r" SELECT A.key, A.val, B.val FROM A @@ -208,39 +223,43 @@ const CONVERT_QUERY: &str = "SELECT * FROM A"; const SORT_QUERY: &str = "SELECT * FROM A ORDER BY A.key"; pub fn query_print(file: &str) -> CirupQuery { - CirupQuery::new(PRINT_QUERY, file, None) + CirupQuery::new(PRINT_QUERY, file, None, None) } pub fn query_convert(file: &str) -> CirupQuery { - CirupQuery::new(CONVERT_QUERY, file, None) + CirupQuery::new(CONVERT_QUERY, file, None, None) } pub fn query_sort(file: &str) -> CirupQuery { - CirupQuery::new(SORT_QUERY, file, None) + CirupQuery::new(SORT_QUERY, file, None, None) } pub fn query_diff(file_one: &str, file_two: &str) -> CirupQuery { - CirupQuery::new(DIFF_QUERY, file_one, Some(file_two)) + CirupQuery::new(DIFF_QUERY, file_one, Some(file_two), None) +} + +pub fn query_diff_with_base(old: &str, new: &str, base: &str) -> CirupQuery { + CirupQuery::new(DIFF_WITH_BASE_QUERY, old, Some(new), Some(base)) } pub fn query_change(file_one: &str, file_two: &str) -> CirupQuery { - CirupQuery::new(CHANGE_QUERY, file_one, Some(file_two)) + CirupQuery::new(CHANGE_QUERY, file_one, Some(file_two), None) } pub fn query_merge(file_one: &str, file_two: &str) -> CirupQuery { - CirupQuery::new(MERGE_QUERY, file_one, Some(file_two)) + CirupQuery::new(MERGE_QUERY, file_one, Some(file_two), None) } pub fn query_intersect(file_one: &str, file_two: &str) -> CirupQuery { - CirupQuery::new(INTERSECT_QUERY, file_one, Some(file_two)) + CirupQuery::new(INTERSECT_QUERY, file_one, Some(file_two), None) } pub fn query_subtract(file_one: &str, file_two: &str) -> CirupQuery { - CirupQuery::new(SUBTRACT_QUERY, file_one, Some(file_two)) + CirupQuery::new(SUBTRACT_QUERY, file_one, Some(file_two), None) } impl CirupQuery { - pub fn new(query: &str, file_one: &str, file_two: Option<&str>) -> Self { + pub fn new(query: &str, file_one: &str, file_two: Option<&str>, file_three: Option<&str>) -> Self { let engine = CirupEngine::new(); engine.register_table_from_file("A", file_one); @@ -248,6 +267,10 @@ impl CirupQuery { engine.register_table_from_file("B", file_two.unwrap()); } + if file_two.is_some() { + engine.register_table_from_file("C", file_three.unwrap()); + } + CirupQuery { engine: engine, query: query.to_string(), @@ -258,6 +281,10 @@ impl CirupQuery { return self.engine.query_resource(&self.query); } + pub fn run_triple(&self) -> Vec { + return self.engine.query_triple(&self.query); + } + pub fn run_interactive(&self, out_file: Option<&str>) { let resources = self.run(); @@ -267,6 +294,11 @@ impl CirupQuery { print_resources_pretty(&resources); } } + + pub fn run_triple_interactive(&self) { + let triples = self.run_triple(); + print_triples_pretty(&triples); + } } #[cfg(test)] @@ -315,22 +347,14 @@ fn test_query_subtract() { #[test] fn test_query_diff_with_base() { let engine = CirupEngine::new(); - engine.register_table_from_str("old", "test_old.resx", include_str!("../test/test_old.resx")); - engine.register_table_from_str("new", "test_new.resx", include_str!("../test/test_new.resx")); - engine.register_table_from_str("base", "test.resx", include_str!("../test/test.resx")); - - let triples = engine.query_triple(r"SELECT new.key, new.val, base.val - FROM new - LEFT OUTER JOIN old ON new.key = old.key - LEFT OUTER JOIN base ON new.key = base.key - WHERE (old.val IS NULL)"); + engine.register_table_from_str("A", "test_old.resx", include_str!("../test/test_old.resx")); + engine.register_table_from_str("B", "test_new.resx", include_str!("../test/test_new.resx")); + engine.register_table_from_str("C", "test.resx", include_str!("../test/test.resx")); - for triple in triples.iter() { - println!("key: {}", triple.name); - println!("value: {}", triple.value); - println!("base: {}", triple.base); - println!(""); - }; + let triples = engine.query_triple(DIFF_WITH_BASE_QUERY); assert_eq!(triples.len(), 2); + assert_eq!(triples[0].name, String::from("lblYolo")); + assert_eq!(triples[0].base, String::from("You only live once")); + assert_eq!(triples[0].value, String::from("Juste une vie a vivre")); } \ No newline at end of file diff --git a/cirup_core/src/sync.rs b/cirup_core/src/sync.rs index 6376b3a..70b6fb2 100644 --- a/cirup_core/src/sync.rs +++ b/cirup_core/src/sync.rs @@ -276,6 +276,7 @@ impl Sync { query_string, &source_path_out.to_string_lossy(), Some(&translation_file.path.to_string_lossy()), + None ); let file_path = rev.append_to_file_name( Path::new(self.temp_dir.path()).join(&translation_file.file_name), @@ -380,6 +381,7 @@ impl Sync { query_string, &source_path_out.to_string_lossy(), Some(&file_path.to_string_lossy()), + None ); } diff --git a/diff_with_base/Cargo.toml b/diff_with_base/Cargo.toml deleted file mode 100644 index 205e329..0000000 --- a/diff_with_base/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "diff_with_base" -version = "0.1.0" -authors = ["Sebastien Duquette "] -edition = "2018" - -[[bin]] -name = "diff_with_base" -path = "main.rs" - -[dependencies] - -[dependencies.cirup_core] -path = "../cirup_core" - diff --git a/diff_with_base/main.rs b/diff_with_base/main.rs deleted file mode 100644 index 9cd2d67..0000000 --- a/diff_with_base/main.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::env; - -use cirup_core::query::CirupEngine; - -fn main() { - let args: Vec = env::args().collect(); - - if args.len() != 4 { - println!("diff_with_base "); - return; - } - - let engine = CirupEngine::new(); - engine.register_table_from_file("old", &args[1]); - engine.register_table_from_file("new", &args[2]); - engine.register_table_from_file("base", &args[3]); - - let triples = engine.query_triple(r"SELECT new.key, new.val, base.val - FROM new - LEFT OUTER JOIN old ON new.key = old.key - INNER JOIN base ON new.key = base.key - WHERE (old.val IS NULL)"); - - for triple in triples.iter() { - println!("key: {}", triple.name); - println!("orig: {}", triple.base); - println!("trad: {}", triple.value); - println!(""); - }; -} \ No newline at end of file