Skip to content

Commit 86a406c

Browse files
committed
Add 'seri' option to create an auto-incrementing integer column
1 parent 55b16fe commit 86a406c

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/main.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::io::{Read, Write, BufReader, BufRead, stdin, stdout};
22
use std::fs::{File, OpenOptions};
33
use std::path::Path;
44
use std::env;
5-
use std::cell::RefCell;
5+
use std::cell::{ Cell, RefCell };
66
use std::time::Instant;
77
use std::default::Default;
88
use std::collections::HashMap;
@@ -106,6 +106,7 @@ impl<'a> Domain<'a> {
106106
struct Column<'a> {
107107
name: String,
108108
path: String,
109+
serial: Option<Cell<u64>>,
109110
datatype: String,
110111
value: RefCell<String>,
111112
attr: Option<&'a str>,
@@ -239,11 +240,21 @@ fn add_table<'a>(name: &str, rowpath: &str, outfile: Option<&str>, settings: &Se
239240
let mut table = Table::new(name, rowpath, outfile, settings);
240241
for col in colspec {
241242
let colname = col["name"].as_str().unwrap_or_else(|| fatalerr!("Error: column has no 'name' entry in configuration file"));
242-
let colpath = col["path"].as_str().unwrap_or_else(|| fatalerr!("Error: column has no 'path' entry in configuration file"));
243+
let colpath = match col["seri"].as_bool() {
244+
Some(true) => "/",
245+
_ => col["path"].as_str().unwrap_or_else(|| fatalerr!("Error: column has no 'path' entry in configuration file"))
246+
};
243247
let mut path = String::from(&table.path);
244248
if !colpath.is_empty() && !colpath.starts_with('/') { path.push('/'); }
245249
path.push_str(colpath);
246250
if path.ends_with('/') { path.pop(); }
251+
let serial = match col["seri"].as_bool() {
252+
Some(true) => {
253+
if *col != colspec[0] { eprintln!("Notice: a 'seri' column usually needs to be the first column; {} in table {} is not", colname, table.name); }
254+
Some(Cell::new(0))
255+
},
256+
_ => None
257+
};
247258
let mut datatype = col["type"].as_str().unwrap_or("text").to_string();
248259
let mut subtable: Option<Table> = match col["cols"].is_badvalue() {
249260
true => None,
@@ -304,7 +315,7 @@ fn add_table<'a>(name: &str, rowpath: &str, outfile: Option<&str>, settings: &Se
304315
eprintln!("Warning: the bbox option has no function without conversion type 'gml-to-ekwb'");
305316
}
306317

307-
let column = Column { name: colname.to_string(), path, datatype, value: RefCell::new(String::new()), attr, hide, include, exclude, trim, convert, find, replace, aggr, subtable, domain, bbox, multitype };
318+
let column = Column { name: colname.to_string(), path, serial, datatype, value: RefCell::new(String::new()), attr, hide, include, exclude, trim, convert, find, replace, aggr, subtable, domain, bbox, multitype };
308319
table.columns.push(column);
309320
}
310321

@@ -490,6 +501,14 @@ fn main() {
490501
for i in 0..table.columns.len() {
491502
if path == table.columns[i].path { // This start tag matches one of the defined columns
492503

504+
// Handle the 'seri' case where this column is a virtual auto-incrementing serial
505+
if let Some(ref serial) = table.columns[i].serial {
506+
let id = serial.get();
507+
table.columns[i].value.borrow_mut().push_str(&id.to_string());
508+
serial.set(id+1);
509+
continue;
510+
}
511+
493512
// Handle 'subtable' case (the 'cols' entry has 'cols' of its own)
494513
if table.columns[i].subtable.is_some() {
495514
tables.push(table);
@@ -565,7 +584,7 @@ fn main() {
565584
}
566585
for i in 0..table.columns.len() {
567586
if path == table.columns[i].path {
568-
if table.columns[i].attr.is_some() { break; }
587+
if table.columns[i].attr.is_some() || table.columns[i].serial.is_some() { break; }
569588
if !table.columns[i].value.borrow().is_empty() {
570589
if !allow_iteration(&table.columns[i], &settings) { break; }
571590
}
@@ -610,7 +629,9 @@ fn main() {
610629
else {
611630

612631
if !tables.is_empty() { // This is a subtable; write the first column value of the parent table as the first column of the subtable (for use as a foreign key)
613-
table.write(&tables.last().unwrap().columns[0].value.borrow());
632+
let key = tables.last().unwrap().columns[0].value.borrow();
633+
if key.is_empty() && !settings.hush_warning { println!("Warning: subtable {} has no foreign key for parent (you may need to add a 'seri' column)", table.name); }
634+
table.write(&key);
614635
if let Some(domain) = table.domain.as_ref() {
615636
let mut domain = domain.borrow_mut();
616637
let found = match domain.map.get(&table.columns[0].value.borrow().to_string()) {

0 commit comments

Comments
 (0)