From 09aaaccacecc2117e13ed5a6402d3f95a9e5cedd Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 20 Feb 2021 19:07:52 +0100 Subject: [PATCH] Import: Add import-csv option to command line to import CSV files The argument can be passed several times and all the CSV files are added to the Import CSV dialog. When no database to open is passed in the command line, the CSV files are imported into a new in-memory database, which could later be saved as a file, if desired. This option could be used as basis for adding a file association to CSV files for DB4S. See issue #2589. --- src/Application.cpp | 16 ++++++++++++++-- src/MainWindow.cpp | 35 ++++++++++++++++++++++------------- src/MainWindow.h | 3 ++- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 4d70679c..914e4ee7 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -117,6 +117,7 @@ Application::Application(int& argc, char** argv) : // Parse command line QString fileToOpen; std::vector tableToBrowse; + std::vector csvToImport; QStringList sqlToExecute; bool readOnly = false; m_showMainWindow = true; @@ -137,6 +138,8 @@ Application::Application(int& argc, char** argv) : tr("Exit application after running scripts")); printArgument(QString("-s, --sql <%1>").arg(tr("file")), tr("Execute this SQL file after opening the DB")); + printArgument(QString("--import-csv <%1>").arg(tr("file")), + tr("Import this CSV file into the passed DB or into a new DB")); printArgument(QString("-t, --table <%1>").arg(tr("table")), tr("Browse this table after opening the DB")); printArgument(QString("-R, --read-only"), @@ -160,16 +163,23 @@ Application::Application(int& argc, char** argv) : } else if(arguments().at(i) == "-s" || arguments().at(i) == "--sql") { // Run SQL file: If file exists add it to list of scripts to execute if(++i >= arguments().size()) - qWarning() << qPrintable(tr("The -s/--sql option requires an argument")); + qWarning() << qPrintable(tr("The %1 option requires an argument").arg("-s/--sql")); else if(!QFile::exists(arguments().at(i))) qWarning() << qPrintable(tr("The file %1 does not exist").arg(arguments().at(i))); else sqlToExecute.append(arguments().at(i)); } else if(arguments().at(i) == "-t" || arguments().at(i) == "--table") { if(++i >= arguments().size()) - qWarning() << qPrintable(tr("The -t/--table option requires an argument")); + qWarning() << qPrintable(tr("The %1 option requires an argument").arg("-t/--table")); else tableToBrowse.push_back(arguments().at(i)); + } else if(arguments().at(i) == "--import-csv") { + if(++i >= arguments().size()) + qWarning() << qPrintable(tr("The %1 option requires an argument").arg("--import-csv")); + else if(!QFile::exists(arguments().at(i))) + qWarning() << qPrintable(tr("The file %1 does not exist").arg(arguments().at(i))); + else + csvToImport.push_back(arguments().at(i)); } else if(arguments().at(i) == "-q" || arguments().at(i) == "--quit") { m_showMainWindow = false; } else if(arguments().at(i) == "-R" || arguments().at(i) == "--read-only") { @@ -248,6 +258,8 @@ Application::Application(int& argc, char** argv) : m_mainWindow->refresh(); } } + if(!csvToImport.empty()) + m_mainWindow->importCSVfiles(csvToImport); } Application::~Application() diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index f7553987..cebd1f8c 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -601,7 +601,7 @@ void MainWindow::fileNew() } } -void MainWindow::fileNewInMemoryDatabase() +void MainWindow::fileNewInMemoryDatabase(bool open_create_dialog) { // Open an in-memory database. We use open() instead of create() here because the extra work create() does is not needed // when no files are stored on disk. @@ -615,7 +615,8 @@ void MainWindow::fileNewInMemoryDatabase() refreshTableBrowsers(); if(ui->tabSqlAreas->count() == 0) openSqlTab(true); - createTable(); + if(open_create_dialog) + createTable(); } void MainWindow::populateStructure(const std::vector& old_tables) @@ -1343,8 +1344,24 @@ void MainWindow::mainTabSelected(int /*tabindex*/) } } +void MainWindow::importCSVfiles(const std::vector& inputFiles) +{ + if (!inputFiles.empty()) + { + // Allow importing to a new in-memory database that can be saved later. + if(!db.isOpen()) + fileNewInMemoryDatabase(/* open_create_dialog */ false); + + ImportCsvDialog dialog(inputFiles, &db, this); + if (dialog.exec()) + refreshTableBrowsers(); + } +} + void MainWindow::importTableFromCSV() { + std::vector validFiles; + // Are we importing from a file or from the clipboard? if(sender() == ui->fileImportCSVAction) { @@ -1364,18 +1381,11 @@ void MainWindow::importTableFromCSV() tr("Choose text files"), file_filter.join(";;")); - std::vector validFiles; for(const auto& file : wFiles) { if (QFile::exists(file)) validFiles.push_back(file); } - if (!validFiles.empty()) - { - ImportCsvDialog dialog(validFiles, &db, this); - if (dialog.exec()) - refreshTableBrowsers(); - } } else if(sender() == ui->actionFileImportCsvClipboard) { // Save clipboard content to temporary file @@ -1384,11 +1394,10 @@ void MainWindow::importTableFromCSV() QClipboard* clipboard = QGuiApplication::clipboard(); temp.write(clipboard->text().toUtf8()); temp.close(); - - ImportCsvDialog dialog({temp.fileName()}, &db, this); - if (dialog.exec()) - refreshTableBrowsers(); + validFiles.push_back(temp.fileName()); } + + importCSVfiles(validFiles); } void MainWindow::exportTableToCSV() diff --git a/src/MainWindow.h b/src/MainWindow.h index cd845523..d1a07922 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -158,13 +158,14 @@ public slots: void fileDetachTreeViewSelected(QTreeView* treeView); void reloadSettings(); bool closeFiles(); + void importCSVfiles(const std::vector& inputFiles); private slots: void createTreeContextMenu(const QPoint & qPoint); void createSchemaDockContextMenu(const QPoint & qPoint); void changeTreeSelection(); void fileNew(); - void fileNewInMemoryDatabase(); + void fileNewInMemoryDatabase(bool open_create_dialog = true); void refreshTableBrowsers(bool force_refresh = false); bool fileClose(); bool fileSaveAs();