From 56baa35cf26c42c248ac384cba3b5fcc39d44db5 Mon Sep 17 00:00:00 2001 From: Priec Date: Sat, 15 Aug 2026 16:21:19 +0200 Subject: [PATCH] fixed export --- web/locales/cs/main.ftl | 2 +- web/locales/en/main.ftl | 2 +- web/locales/sk/main.ftl | 2 +- web/src/pages/import_export/common/schema.rs | 61 ++++++++++++++++++-- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/web/locales/cs/main.ftl b/web/locales/cs/main.ftl index 2603077c..a227249b 100644 --- a/web/locales/cs/main.ftl +++ b/web/locales/cs/main.ftl @@ -163,7 +163,7 @@ td-presentation-title = Zobrazení sloupců td-add-columns-to = Přidat sloupce do td-append-hint = Sloupce se přidávají na konec. Nic, co už existuje, se nemění a nové sloupce lze indexovat hned při přidání. td-rename-column = Aliasy a pořadí sloupců -td-rename-hint = Přejmenovává se jen zobrazený název, ne fyzický sloupec pod ním, takže uložená data a skripty zůstávají nedotčené. Možné jen dokud tabulka nemá žádné řádky. +td-rename-hint = Přejmenovává se jen zobrazený název, ne fyzický sloupec pod ním, takže uložená data a skripty zůstávají nedotčené. td-column-label = Sloupec td-choose-column = Vyberte sloupec td-new-name = Nový název diff --git a/web/locales/en/main.ftl b/web/locales/en/main.ftl index 167996df..3a7716fb 100644 --- a/web/locales/en/main.ftl +++ b/web/locales/en/main.ftl @@ -165,7 +165,7 @@ td-presentation-title = Column presentation td-add-columns-to = Add columns to td-append-hint = Columns are appended. Nothing that already exists is changed, and the new columns can be indexed as they are added. td-rename-column = Column aliases and order -td-rename-hint = Renames what the column is called, not the physical column underneath, so stored data and scripts are untouched. Only possible while the table has no rows. +td-rename-hint = Renames what the column is called, not the physical column underneath, so stored data and scripts are untouched. td-column-label = Column td-choose-column = Choose a column td-new-name = New name diff --git a/web/locales/sk/main.ftl b/web/locales/sk/main.ftl index dc151772..4637dc1e 100644 --- a/web/locales/sk/main.ftl +++ b/web/locales/sk/main.ftl @@ -163,7 +163,7 @@ td-presentation-title = Zobrazenie stĺpcov td-add-columns-to = Pridať stĺpce do td-append-hint = Stĺpce sa pridávajú na koniec. Nič, čo už existuje, sa nemení a nové stĺpce možno indexovať hneď pri pridaní. td-rename-column = Aliasy a poradie stĺpcov -td-rename-hint = Premenúva sa len zobrazený názov, nie fyzický stĺpec pod ním, takže uložené údaje a skripty zostávajú nedotknuté. Možné len kým tabuľka nemá žiadne riadky. +td-rename-hint = Premenúva sa len zobrazený názov, nie fyzický stĺpec pod ním, takže uložené údaje a skripty zostávajú nedotknuté. td-column-label = Stĺpec td-choose-column = Vyberte stĺpec td-new-name = Nový názov diff --git a/web/src/pages/import_export/common/schema.rs b/web/src/pages/import_export/common/schema.rs index c4e5d2a7..bd955d1c 100644 --- a/web/src/pages/import_export/common/schema.rs +++ b/web/src/pages/import_export/common/schema.rs @@ -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 { 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 { schema .columns @@ -67,3 +82,37 @@ pub(crate) fn csv_value(locale: Locale, raw: &str, data_type: &str) -> Result 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()]); + } +}