--- 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<string_t>& 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";
}
}
--- 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<Statement> statements;
virtual ~Configuration() {
--- 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 <vector>
#include <locale>
#include <codecvt>
+#include <unistd.h>
#include <sqlite3.h>
@@ -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<relpipe::writer::AttributeMetadata> 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.");
+ }
}
};