improve --keep-file option: default is auto = file will be kept, if it was present before the transformation
--- a/src/CLIParser.h Tue Oct 22 16:04:23 2019 +0200
+++ b/src/CLIParser.h Tue Oct 22 16:04:56 2019 +0200
@@ -70,7 +70,11 @@
} else if (option == OPTION_FILE) {
c.file = readNext(arguments, i);
} else if (option == OPTION_KEEP_FILE) {
- c.keepFile = true;
+ string_t value = readNext(arguments, i);
+ if (value == L"auto") c.keepFile = KeepFile::Automatic;
+ else if (value == L"true") c.keepFile = KeepFile::Always;
+ else if (value == L"false") c.keepFile = KeepFile::Never;
+ else throw relpipe::cli::RelpipeCLIException(L"Unsupported keep-file value: " + value + L" Expecting: true, false, auto", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
} else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
addQuery(c, currentQuery); // last relation
--- a/src/Configuration.h Tue Oct 22 16:04:23 2019 +0200
+++ b/src/Configuration.h Tue Oct 22 16:04:56 2019 +0200
@@ -49,6 +49,15 @@
std::vector<Parameter> parameters;
};
+enum class KeepFile {
+ /** The file will be kept even if it was created during this transformation, so all the input data will stay on the disk. */
+ Always,
+ /** The file will be deleted at the end of this transformation – even if the file already existed. This is potentially dangerous, because we can unintentionally delete a database file. */
+ Never,
+ /** The file will be kept only if it was already present before the transformation. */
+ Automatic
+};
+
class Configuration {
public:
@@ -61,9 +70,9 @@
relpipe::writer::string_t file;
/**
- * If true, the file (if any was created) will not be deleted when this transformation finishes.
+ * see KeepFile documentation
*/
- relpipe::writer::boolean_t keepFile = false;
+ KeepFile keepFile = KeepFile::Automatic;
std::vector<Statement> statements;
--- a/src/SqlHandler.h Tue Oct 22 16:04:23 2019 +0200
+++ b/src/SqlHandler.h Tue Oct 22 16:04:56 2019 +0200
@@ -24,6 +24,7 @@
#include <codecvt>
#include <unistd.h>
#include <cassert>
+#include <sys/stat.h>
#include <sqlite3.h>
@@ -140,6 +141,7 @@
class SqlHandler : public RelationalReaderValueHandler {
private:
Configuration configuration;
+ boolean_t fileAlreadyExisted = false;
writer::RelationalWriter* relationalWriter;
std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings
vector<AttributeMetadata> currentReaderMetadata;
@@ -186,7 +188,17 @@
public:
SqlHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration) : relationalWriter(relationalWriter), configuration(configuration) {
- std::string file = configuration.file.size() ? convertor.to_bytes(configuration.file) : ":memory:";
+ std::string file;
+ if (configuration.file.size()) {
+ file = convertor.to_bytes(configuration.file);
+
+ // in C++17 we can use: std::filesystem::exists()
+ struct stat fileStat;
+ fileAlreadyExisted = (stat(file.c_str(), &fileStat) == 0);
+ } else {
+ file = ":memory:";
+ }
+
connection.reset(new Connection(file.c_str()));
}
@@ -255,7 +267,7 @@
default:
throw SqlException(L"Unsupported type in attribute()");
}
-
+
if (currentAttributeIndex % currentReaderMetadata.size() == 0) {
currentInsert->next();
currentInsert->reset();
@@ -264,12 +276,17 @@
}
void endOfPipe() {
+ // run the transformation – process all statements:
for (const Statement& statement : configuration.statements) processStatement(statement);
- if (configuration.file.size() && !configuration.keepFile) {
- int result = unlink(convertor.to_bytes(configuration.file).c_str());
- if (result) throw SqlException(L"Unable to delete SQLite file.");
- }
+ // delete or keep the file:
+ if (configuration.file.size()) {
+ if (configuration.keepFile == KeepFile::Never || (configuration.keepFile == KeepFile::Automatic && !fileAlreadyExisted)) {
+ std::wcerr << L"will unlink file" << std::endl;
+ int result = unlink(convertor.to_bytes(configuration.file).c_str());
+ if (result) throw SqlException(L"Unable to delete SQLite file.");
+ }
+ } // else: we had no file, everything was in memory
}
};