# HG changeset patch # User František Kučera # Date 1564499201 -7200 # Node ID cbc7817a3346abe71b06e399593a2d6d2643c9ea # Parent 925b15fb5c630603dd8be2fd4a6459aa412f5b74 add option to create DB in a file and to keep that file diff -r 925b15fb5c63 -r cbc7817a3346 src/CLIParser.h --- a/src/CLIParser.h Tue Jul 30 15:51:35 2019 +0200 +++ b/src/CLIParser.h Tue Jul 30 17:06:41 2019 +0200 @@ -50,6 +50,8 @@ static const string_t OPTION_RELATION; static const string_t OPTION_PARAMETER; + static const string_t OPTION_FILE; + static const string_t OPTION_KEEP_FILE; Configuration parse(const std::vector& arguments) { Configuration c; @@ -66,6 +68,10 @@ Parameter parameter; parameter.value = readNext(arguments, i); currentQuery.parameters.push_back(parameter); + } else if (option == OPTION_FILE) { + c.file = readNext(arguments, i); + } else if (option == OPTION_KEEP_FILE) { + c.keepFile = true; } else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); } addQuery(c, currentQuery); // last relation @@ -79,11 +85,12 @@ // relpipe-tr-sql --relation "tabulka" "SELECT * FROM fstab WHERE id = ?" --parameter "123" -// TODO: --file db.sqlite --keep-file // TODO: --type string/integer/boolean (default is string) const string_t CLIParser::OPTION_RELATION = L"--relation"; const string_t CLIParser::OPTION_PARAMETER = L"--parameter"; +const string_t CLIParser::OPTION_FILE = L"--file"; +const string_t CLIParser::OPTION_KEEP_FILE = L"--keep-file"; } } diff -r 925b15fb5c63 -r cbc7817a3346 src/Configuration.h --- a/src/Configuration.h Tue Jul 30 15:51:35 2019 +0200 +++ b/src/Configuration.h Tue Jul 30 17:06:41 2019 +0200 @@ -53,6 +53,19 @@ class Configuration { public: + + /** + * By default, this transformation runs in-memory. + * If 'file' is not empty, this transformation will operate on an .sqlite file. + * The file will be created if it does not exist. + */ + relpipe::writer::string_t file; + + /** + * If true, the file (if any was created) will not be deleted when this transformation finishes. + */ + relpipe::writer::boolean_t keepFile = false; + std::vector statements; virtual ~Configuration() { diff -r 925b15fb5c63 -r cbc7817a3346 src/SqlHandler.h --- a/src/SqlHandler.h Tue Jul 30 15:51:35 2019 +0200 +++ b/src/SqlHandler.h Tue Jul 30 17:06:41 2019 +0200 @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -100,7 +101,10 @@ Connection(const char* filename) { int result = sqlite3_open(filename, &db); - if (result != SQLITE_OK) throw SqlException(L"Unable to open SQLite database."); + if (result != SQLITE_OK) { + sqlite3_close(db); + throw SqlException(L"Unable to open SQLite database."); + } } virtual ~Connection() { @@ -134,6 +138,7 @@ } std::vector metadata; + // TODO: support also other data types for (int i = 0; i < columnCount; i++) metadata.push_back({convertor.from_bytes(prepared.getColumName(i).c_str()), relpipe::writer::TypeId::STRING}); relationalWriter->startRelation(statement.relation, metadata, true); @@ -147,7 +152,8 @@ public: SqlHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration) : relationalWriter(relationalWriter), configuration(configuration) { - connection.reset(new Connection(":memory:")); + std::string file = configuration.file.size() ? convertor.to_bytes(configuration.file) : ":memory:"; + connection.reset(new Connection(file.c_str())); } virtual ~SqlHandler() { @@ -163,6 +169,11 @@ void endOfPipe() { 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."); + } } };