add option to create DB in a file and to keep that file v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 30 Jul 2019 17:06:41 +0200
branchv_0
changeset 5 cbc7817a3346
parent 4 925b15fb5c63
child 6 32b4293307f4
add option to create DB in a file and to keep that file
src/CLIParser.h
src/Configuration.h
src/SqlHandler.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<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.");
+		}
 	}
 
 };