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())
|
.map(|column| column.name.clone())
|
||||||
.collect()
|
.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
|
/// GET /admin/import
|
||||||
@@ -625,7 +639,8 @@ async fn prepared(
|
|||||||
read_mapping(locale, &chosen, &source).map_err(|message| reject(headers, message))?;
|
read_mapping(locale, &chosen, &source).map_err(|message| reject(headers, message))?;
|
||||||
let prepared_names = destination.prepared_names(&assignments);
|
let prepared_names = destination.prepared_names(&assignments);
|
||||||
let mut prepared = prepare(&assignments, &source, &prepared_names);
|
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))?;
|
.map_err(|message| reject(headers, message))?;
|
||||||
Ok((destination, source, prepared))
|
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
|
/// 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(
|
fn import_row(
|
||||||
locale: Locale,
|
locale: Locale,
|
||||||
destination: &Destination,
|
destination: &Destination,
|
||||||
@@ -666,6 +682,21 @@ fn import_row(
|
|||||||
) -> Result<TableDataImportRow, String> {
|
) -> Result<TableDataImportRow, String> {
|
||||||
let mut data = HashMap::new();
|
let mut data = HashMap::new();
|
||||||
for (index, column) in columns.iter().enumerate() {
|
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(|| {
|
let data_type = destination.types.get(column).ok_or_else(|| {
|
||||||
tr!(
|
tr!(
|
||||||
locale,
|
locale,
|
||||||
@@ -673,11 +704,7 @@ fn import_row(
|
|||||||
"column" => column.clone(),
|
"column" => column.clone(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let value = csv_value(
|
let value = csv_value(locale, raw, data_type)?;
|
||||||
locale,
|
|
||||||
row.get(index).map(String::as_str).unwrap_or_default(),
|
|
||||||
data_type,
|
|
||||||
)?;
|
|
||||||
data.insert(column.clone(), value);
|
data.insert(column.clone(), value);
|
||||||
}
|
}
|
||||||
Ok(TableDataImportRow { data, link_display_columns: Vec::new() })
|
Ok(TableDataImportRow { data, link_display_columns: Vec::new() })
|
||||||
@@ -773,6 +800,9 @@ fn unavailable(headers: &HeaderMap, message: String) -> Response {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use prost_types::value::Kind;
|
||||||
|
|
||||||
|
use crate::pages::import_export::import::destination::DestinationKey;
|
||||||
|
|
||||||
fn source() -> Source {
|
fn source() -> Source {
|
||||||
read_source(
|
read_source(
|
||||||
@@ -801,4 +831,48 @@ mod tests {
|
|||||||
|
|
||||||
assert!(options[3].label.contains('4'), "{}", options[3].label);
|
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