Skip to content

Commit c344e37

Browse files
committed
Support many-to-one subtables with a 'seri' column
This will deduplicate the subtable based on the values of all columns except the 'seri' column itself. This is not great for performance, but should be fairly rare.
1 parent 6d8438d commit c344e37

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/main.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ fn process_event(event: &Event, mut state: &mut State) -> Step {
689689
if state.path == table.columns[i].path { // This start tag matches one of the defined columns
690690
// Handle the 'seri' case where this column is a virtual auto-incrementing serial
691691
if let Some(ref serial) = table.columns[i].serial {
692+
// if table.cardinality == Cardinality::ManyToOne { continue; }
692693
if table.columns[i].value.borrow().is_empty() {
693694
let id = serial.get()+1;
694695
let idstr = id.to_string();
@@ -837,10 +838,14 @@ fn process_event(event: &Event, mut state: &mut State) -> Step {
837838
let rowid;
838839
if let Some(domain) = table.domain.as_ref() {
839840
let mut domain = domain.borrow_mut();
840-
if !domain.map.contains_key(&table.lastid.borrow().to_string()) {
841+
let key = match table.columns[0].serial {
842+
Some(_) => table.columns[1..].iter().map(|c| c.value.borrow().to_string()).collect::<String>(),
843+
None => table.lastid.borrow().to_string()
844+
};
845+
if !domain.map.contains_key(&key) {
841846
domain.lastid += 1;
842847
rowid = domain.lastid;
843-
domain.map.insert(table.lastid.borrow().to_string(), rowid);
848+
domain.map.insert(key, rowid);
844849
if table.columns.len() == 1 {
845850
domain.table.write(&format!("{}\t", rowid));
846851
}
@@ -869,7 +874,7 @@ fn process_event(event: &Event, mut state: &mut State) -> Step {
869874
}
870875
domain.table.write("\n");
871876
}
872-
else { rowid = *domain.map.get(&table.lastid.borrow().to_string()).unwrap(); }
877+
else { rowid = *domain.map.get(&key).unwrap(); }
873878
if table.columns.len() == 1 { // Single column many-to-many subtable; needs the id from the domain map
874879
table.write(&format!("{}" , rowid));
875880
}
@@ -884,17 +889,32 @@ fn process_event(event: &Event, mut state: &mut State) -> Step {
884889
}
885890
}
886891
else { // Many-to-one relation; write the id of this subtable into the parent table
887-
state.parentcol.unwrap().value.borrow_mut().push_str(&table.lastid.borrow());
888892
if let Some(domain) = table.domain.as_ref() {
889893
let mut domain = domain.borrow_mut();
890-
if domain.map.contains_key(&table.lastid.borrow().to_string()) {
894+
let key = match table.columns[0].serial {
895+
Some(_) => table.columns[1..].iter().map(|c| c.value.borrow().to_string()).collect::<String>(),
896+
None => table.lastid.borrow().to_string()
897+
};
898+
if domain.map.contains_key(&key) {
899+
if table.columns[0].serial.is_some() {
900+
state.parentcol.unwrap().value.borrow_mut().push_str(&format!("{}", *domain.map.get(&key).unwrap()));
901+
}
902+
else { state.parentcol.unwrap().value.borrow_mut().push_str(&table.lastid.borrow()); }
891903
table.clear_columns();
892904
state.table = state.tables.pop().unwrap();
893905
return Step::Repeat;
894906
}
895-
domain.map.insert(table.lastid.borrow().to_string(), 0);
907+
domain.lastid += 1;
908+
let id = domain.lastid;
909+
domain.map.insert(key, id);
896910
// The for loop below will now write out the new row
897911
}
912+
if state.parentcol.unwrap().value.borrow().is_empty() {
913+
state.parentcol.unwrap().value.borrow_mut().push_str(&table.lastid.borrow());
914+
}
915+
else if allow_iteration(state.parentcol.unwrap(), &state.settings) {
916+
// TODO: make it do something...
917+
}
898918
}
899919
}
900920
// Now write out the other column values

0 commit comments

Comments
 (0)