fixed export
This commit is contained in:
@@ -6,20 +6,35 @@ use crate::{i18n::Locale, tr};
|
||||
|
||||
use crate::definitions::table_structure::TableStructureResponse;
|
||||
|
||||
/// The columns a CSV carries, for an export and for the import that reads one
|
||||
/// back.
|
||||
///
|
||||
/// Both ends use this list, so a file the export writes is a file the import
|
||||
/// accepts. That only holds if every system column is left out: a row is
|
||||
/// inserted with `post_table_data`, which takes user columns and nothing else,
|
||||
/// so exporting `row_revision` or `created_at` produced a file whose own
|
||||
/// re-import the server answered with `Invalid column`. The names come from
|
||||
/// the server's declarations rather than a list spelled out here, so a system
|
||||
/// column added there is excluded here too.
|
||||
pub(crate) fn exportable_columns(schema: &TableStructureResponse) -> Vec<String> {
|
||||
schema
|
||||
.columns
|
||||
.iter()
|
||||
.filter(|column| {
|
||||
!column.is_primary_key
|
||||
&& column.name != "id"
|
||||
&& column.name != "deleted"
|
||||
&& column.name != "created_at"
|
||||
})
|
||||
.filter(|column| !column.is_primary_key && !is_system_column(&column.name))
|
||||
.map(|column| column.name.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Whether `name` is one of the columns the server puts on every managed
|
||||
/// table. The virtual `account` name is deliberately not checked: it is an
|
||||
/// alias a user may write to, not a column the server fills in.
|
||||
fn is_system_column(name: &str) -> bool {
|
||||
crate::system_column::LEADING_SYSTEM_COLUMNS
|
||||
.iter()
|
||||
.chain(crate::system_column::TRAILING_SYSTEM_COLUMNS.iter())
|
||||
.any(|column| column.name == name)
|
||||
}
|
||||
|
||||
pub(crate) fn column_types(schema: &TableStructureResponse) -> HashMap<String, String> {
|
||||
schema
|
||||
.columns
|
||||
@@ -67,3 +82,37 @@ pub(crate) fn csv_value(locale: Locale, raw: &str, data_type: &str) -> Result<Va
|
||||
};
|
||||
Ok(Value { kind: Some(kind) })
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::definitions::table_structure::TableColumn;
|
||||
|
||||
fn column(name: &str, is_primary_key: bool) -> TableColumn {
|
||||
TableColumn {
|
||||
name: name.to_string(),
|
||||
data_type: "TEXT".to_string(),
|
||||
is_primary_key,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// A row is inserted by name, and the insert takes user columns only, so a
|
||||
/// system column in the header is a file the import has to refuse. The
|
||||
/// export wrote one until `row_revision` was excluded here.
|
||||
#[test]
|
||||
fn no_system_column_reaches_the_csv() {
|
||||
let schema = TableStructureResponse {
|
||||
columns: vec![
|
||||
column("id", true),
|
||||
column("deleted", false),
|
||||
column("row_revision", false),
|
||||
column("number", false),
|
||||
column("created_at", false),
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(exportable_columns(&schema), vec!["number".to_string()]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user