implemented FROM next to the link for other table columns
This commit is contained in:
Submodule client-gui2 updated: 0a536189bb...0461f0f602
Binary file not shown.
2
server
2
server
Submodule server updated: 66ce287729...41a34de46f
@@ -74,6 +74,20 @@ impl Destination {
|
||||
.map(|column| column.name.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn is_verification(&self, name: &str) -> bool {
|
||||
self.columns
|
||||
.iter()
|
||||
.any(|column| column.name == name && column.verification)
|
||||
}
|
||||
|
||||
fn writable_types(&self) -> HashMap<String, String> {
|
||||
self.types
|
||||
.iter()
|
||||
.filter(|(name, _)| !self.is_verification(name))
|
||||
.map(|(name, data_type)| (name.clone(), data_type.clone()))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /admin/import
|
||||
@@ -625,7 +639,8 @@ async fn prepared(
|
||||
read_mapping(locale, &chosen, &source).map_err(|message| reject(headers, message))?;
|
||||
let prepared_names = destination.prepared_names(&assignments);
|
||||
let mut prepared = prepare(&assignments, &source, &prepared_names);
|
||||
normalize_dates(locale, &mut prepared, &destination.types, form.date_format)
|
||||
let writable_types = destination.writable_types();
|
||||
normalize_dates(locale, &mut prepared, &writable_types, form.date_format)
|
||||
.map_err(|message| reject(headers, message))?;
|
||||
Ok((destination, source, prepared))
|
||||
}
|
||||
@@ -657,7 +672,8 @@ fn source_options(locale: Locale, source: &Source) -> Vec<SourceOption> {
|
||||
}
|
||||
|
||||
/// One prepared row as the staged import takes it: values under their destination
|
||||
/// names, converted to the column's type.
|
||||
/// names. Writable values are converted to their column type; projection
|
||||
/// assertions retain the CSV cell's exact text.
|
||||
fn import_row(
|
||||
locale: Locale,
|
||||
destination: &Destination,
|
||||
@@ -666,6 +682,21 @@ fn import_row(
|
||||
) -> Result<TableDataImportRow, String> {
|
||||
let mut data = HashMap::new();
|
||||
for (index, column) in columns.iter().enumerate() {
|
||||
let raw = row.get(index).map(String::as_str).unwrap_or_default();
|
||||
if destination.is_verification(column) {
|
||||
let kind = if raw.is_empty() {
|
||||
prost_types::value::Kind::NullValue(prost_types::NullValue::NullValue as i32)
|
||||
} else {
|
||||
prost_types::value::Kind::StringValue(raw.to_string())
|
||||
};
|
||||
data.insert(
|
||||
column.clone(),
|
||||
prost_types::Value {
|
||||
kind: Some(kind),
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let data_type = destination.types.get(column).ok_or_else(|| {
|
||||
tr!(
|
||||
locale,
|
||||
@@ -673,11 +704,7 @@ fn import_row(
|
||||
"column" => column.clone(),
|
||||
)
|
||||
})?;
|
||||
let value = csv_value(
|
||||
locale,
|
||||
row.get(index).map(String::as_str).unwrap_or_default(),
|
||||
data_type,
|
||||
)?;
|
||||
let value = csv_value(locale, raw, data_type)?;
|
||||
data.insert(column.clone(), value);
|
||||
}
|
||||
Ok(TableDataImportRow { data, link_display_columns: Vec::new() })
|
||||
@@ -773,6 +800,9 @@ fn unavailable(headers: &HeaderMap, message: String) -> Response {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use prost_types::value::Kind;
|
||||
|
||||
use crate::pages::import_export::import::destination::DestinationKey;
|
||||
|
||||
fn source() -> Source {
|
||||
read_source(
|
||||
@@ -801,4 +831,48 @@ mod tests {
|
||||
|
||||
assert!(options[3].label.contains('4'), "{}", options[3].label);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn projection_assertions_keep_exact_csv_text() {
|
||||
let destination = Destination {
|
||||
table_name: "orders".to_string(),
|
||||
table_revision: 1,
|
||||
columns: vec![
|
||||
DestinationColumn {
|
||||
key: DestinationKey::Column(1),
|
||||
name: "projected_amount".to_string(),
|
||||
required: false,
|
||||
verification: true,
|
||||
},
|
||||
DestinationColumn {
|
||||
key: DestinationKey::Column(2),
|
||||
name: "ordinary_number".to_string(),
|
||||
required: false,
|
||||
verification: false,
|
||||
},
|
||||
],
|
||||
types: HashMap::from([
|
||||
("projected_amount".to_string(), "NUMERIC".to_string()),
|
||||
("ordinary_number".to_string(), "BIGINT".to_string()),
|
||||
]),
|
||||
};
|
||||
|
||||
let row = import_row(
|
||||
Locale::default(),
|
||||
&destination,
|
||||
&["projected_amount".to_string(), "ordinary_number".to_string()],
|
||||
&["10.00".to_string(), "001".to_string()],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
row.data["projected_amount"].kind,
|
||||
Some(Kind::StringValue("10.00".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
row.data["ordinary_number"].kind,
|
||||
Some(Kind::NumberValue(1.0))
|
||||
);
|
||||
assert!(!destination.writable_types().contains_key("projected_amount"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user