From 5a1d33864740e0f48705852c659aea3bf6aa3df9 Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Wed, 24 Oct 2018 13:36:24 +0200 Subject: [PATCH] Allow specifying an ON CONFLICT strategy in the Import CSV dialog Add a new dropdown box to the Import CSV dialog to set an ON CONFLICT strategy when importing into an existing table. You can now choose between the old and still default behaviour of aborting the import in case of a conflict, ignoring the conflicting row from the CSV file, and replacing the existing row in the table. See issue #1585. --- src/ImportCsvDialog.cpp | 17 +++++++- src/ImportCsvDialog.h | 2 + src/ImportCsvDialog.ui | 97 ++++++++++++++++++++++++++++------------- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/ImportCsvDialog.cpp b/src/ImportCsvDialog.cpp index 3d5da3c6..23ede69d 100644 --- a/src/ImportCsvDialog.cpp +++ b/src/ImportCsvDialog.cpp @@ -606,7 +606,7 @@ bool ImportCsvDialog::importCsv(const QString& fileName, const QString& name) } // Prepare the INSERT statement. The prepared statement can then be reused for each row to insert - QString sQuery = QString("INSERT INTO %1 VALUES(").arg(sqlb::escapeIdentifier(tableName)); + QString sQuery = QString("INSERT %1 INTO %2 VALUES(").arg(currentOnConflictStrategy()).arg(sqlb::escapeIdentifier(tableName)); for(size_t i=1;i<=fieldList.size();i++) sQuery.append(QString("?%1,").arg(i)); sQuery.chop(1); // Remove last comma @@ -780,6 +780,19 @@ QString ImportCsvDialog::currentEncoding() const return ui->comboEncoding->currentText(); } +QString ImportCsvDialog::currentOnConflictStrategy() const +{ + switch(ui->comboOnConflictStrategy->currentIndex()) + { + case 1: + return "OR IGNORE"; + case 2: + return "OR REPLACE"; + default: + return QString(); + } +} + void ImportCsvDialog::toggleAdvancedSection(bool show) { ui->labelNoTypeDetection->setVisible(show); @@ -788,4 +801,6 @@ void ImportCsvDialog::toggleAdvancedSection(bool show) ui->checkFailOnMissing->setVisible(show); ui->labelIgnoreDefaults->setVisible(show); ui->checkIgnoreDefaults->setVisible(show); + ui->labelOnConflictStrategy->setVisible(show); + ui->comboOnConflictStrategy->setVisible(show); } diff --git a/src/ImportCsvDialog.h b/src/ImportCsvDialog.h index f8ca0e27..41ddc022 100644 --- a/src/ImportCsvDialog.h +++ b/src/ImportCsvDialog.h @@ -54,6 +54,8 @@ private: void setEncoding(const QString& sEnc); QString currentEncoding() const; + + QString currentOnConflictStrategy() const; }; #endif diff --git a/src/ImportCsvDialog.ui b/src/ImportCsvDialog.ui index ebf08fc0..9947d3bb 100644 --- a/src/ImportCsvDialog.ui +++ b/src/ImportCsvDialog.ui @@ -292,14 +292,14 @@ - + Activate this option to stop the import when trying to import an empty value into a NOT NULL column without a default value. - + Fail on missing values @@ -314,6 +314,9 @@ Disable data type detection + + checkNoTypeDetection + @@ -323,6 +326,38 @@ + + + + When importing into an existing table with a primary key, unique constraints or a unique index there is a chance for a conflict. This option allows you to select a strategy for that case: By default the import is aborted and rolled back but you can also choose to ignore and not import conflicting rows or to replace the existing row in the table. + + + + Abort import + + + + + Ignore row + + + + + Replace existing row + + + + + + + + Conflict strategy + + + comboOnConflictStrategy + + + @@ -432,7 +467,9 @@ checkBoxSeparateTables buttonAdvanced checkIgnoreDefaults + checkNoTypeDetection checkFailOnMissing + comboOnConflictStrategy filePicker toggleSelected matchSimilar @@ -449,8 +486,8 @@ updatePreview() - 232 - 99 + 245 + 92 445 @@ -481,8 +518,8 @@ updatePreview() - 478 - 99 + 511 + 92 577 @@ -497,8 +534,8 @@ updatePreview() - 478 - 132 + 511 + 126 530 @@ -513,8 +550,8 @@ updatePreview() - 495 - 165 + 524 + 160 540 @@ -529,8 +566,8 @@ updatePreview() - 184 - 191 + 192 + 182 368 @@ -545,8 +582,8 @@ updatePreview() - 263 - 183 + 271 + 160 572 @@ -561,8 +598,8 @@ updatePreview() - 184 - 60 + 192 + 56 354 @@ -577,8 +614,8 @@ updateSelection(bool) - 780 - 337 + 777 + 385 368 @@ -593,8 +630,8 @@ updatePreview() - 232 - 132 + 245 + 126 350 @@ -609,8 +646,8 @@ accept() - 272 - 677 + 281 + 707 157 @@ -625,8 +662,8 @@ reject() - 340 - 677 + 349 + 707 286 @@ -641,8 +678,8 @@ checkInput() - 194 - 236 + 192 + 206 368 @@ -657,8 +694,8 @@ matchSimilar() - 780 - 378 + 777 + 418 368 @@ -673,8 +710,8 @@ toggleAdvancedSection(bool) - 214 - 259 + 265 + 241 393