src/SqlHandler.h
branchv_0
changeset 15 0ecde5272f8e
parent 14 eacacf060755
child 16 3c51a2c32c86
--- a/src/SqlHandler.h	Fri Oct 25 12:33:00 2019 +0200
+++ b/src/SqlHandler.h	Sat Oct 26 17:45:37 2019 +0200
@@ -150,6 +150,30 @@
 	std::unique_ptr<Connection> connection;
 	std::unique_ptr<PreparedStatement> currentInsert;
 
+	bool readNextSqlStatement(std::wistream* input, std::wstringstream* sql) {
+		sql->str(L"");
+		sql->clear();
+
+		for (wchar_t ch; *input >> ch;) {
+			*sql << ch;
+			if (ch == L';' && sqlite3_complete(convertor.to_bytes(sql->str()).c_str())) return true;
+		}
+
+		string_t remainingSql = sql->str();
+		for (wchar_t ch : remainingSql) if (ch != L' ' && ch != L'\n' && ch != L'\r' && ch != L'\t') throw SqlException(L"Unexpected EOF, missing „;“ after: „" + remainingSql + L"“");
+
+		return false;
+	}
+
+	void processSqlInput(std::wistream* input) {
+		if (input == nullptr) return;
+		*input >> std::ws >> std::noskipws;
+		for (std::wstringstream sql; readNextSqlStatement(input, &sql);) {
+			std::unique_ptr<PreparedStatement> prepared(connection->prepareStatement(convertor.to_bytes(sql.str()).c_str()));
+			while (prepared->next());
+		}
+	}
+
 	void processStatement(const Statement& statement) {
 		std::unique_ptr<PreparedStatement> prepared(connection->prepareStatement(convertor.to_bytes(statement.sql).c_str()));
 		int columnCount = prepared->getColumnCount();
@@ -300,9 +324,15 @@
 	}
 
 	void endOfPipe() {
+		// process optional SQL input
+		processSqlInput(configuration.sqlBeforeRelational);
+
 		// run the transformation – process all statements:
 		for (const Statement& statement : configuration.statements) processStatement(statement);
 
+		// process optional SQL input
+		processSqlInput(configuration.sqlAfterRelational);
+
 		// pass-through some relations:
 		if (configuration.dumpRelations.size()) dumpRelations();