--- a/src/SqlHandler.h Sat Apr 23 18:49:25 2022 +0200
+++ b/src/SqlHandler.h Sun Aug 28 18:03:13 2022 +0200
@@ -160,6 +160,11 @@
else return L"text";
}
+ bool isInsertable(const relpipe::writer::string_t& tableName) {
+ for (Connection::TablePrivilege tp : connection->getTablePrivileges()) if (tp.name == tableName && tp.privilege == L"INSERT") return true;
+ return false;
+ }
+
void writeIdentifier(std::wstringstream& output, relpipe::writer::string_t identifier) {
output << L'"';
for (auto & ch : identifier) {
@@ -169,6 +174,23 @@
output << L'"';
}
+ void createTable(const string_t& name, const std::vector<AttributeMetadata>& attributes) {
+ std::wstringstream sql;
+ sql << L"CREATE TABLE ";
+ writeIdentifier(sql, name);
+ sql << L" (\n";
+ for (int i = 0; i < attributes.size(); i++) {
+ sql << L"\t";
+ writeIdentifier(sql, attributes[i].getAttributeName());
+ sql << L" " << toSQLType(attributes[i].getTypeId());
+ if (i < attributes.size() - 1) sql << L",\n";
+ }
+ sql << L"\n)";
+
+ std::unique_ptr<PreparedStatement> createTable(connection->prepareStatement(sql.str()));
+ createTable->executeUpdate();
+ }
+
Connection* getConnection() {
if (configuration.dataSourceName.size()) return driverManager->getConnectionByDSN(configuration.dataSourceName);
else if (configuration.dataSourceString.size()) return driverManager->getConnectionByString(configuration.dataSourceString);
@@ -191,27 +213,25 @@
currentReaderMetadata = attributes;
// CREATE TABLE:
- std::wstringstream sql;
- // TODO: if already exist just append new columns
- sql << L"CREATE TABLE ";
- writeIdentifier(sql, name);
- sql << L" (\n";
- for (int i = 0; i < attributes.size(); i++) {
- sql << L"\t";
- writeIdentifier(sql, attributes[i].getAttributeName());
- sql << L" " << toSQLType(attributes[i].getTypeId());
- if (i < attributes.size() - 1) sql << L",\n";
+ if (configuration.onDuplicateRelation == OnDuplicateRelation::Fail) {
+ createTable(name, attributes); // duplicate will cause exception
+ } else if (configuration.onDuplicateRelation == OnDuplicateRelation::Insert) {
+ if (isInsertable(name)); // nothing needs to be created; we will just append new records to the existing table
+ else createTable(name, attributes);
+ } else {
+ throw SqlException(L"Unsupported OnDuplicateRelation mode: " + std::to_wstring((int) configuration.onDuplicateRelation));
}
- sql << L"\n)";
-
- std::unique_ptr<PreparedStatement> createTable(connection->prepareStatement(sql.str()));
- createTable->executeUpdate();
// prepare INSERT:
- sql = wstringstream();
+ std::wstringstream sql;
sql << L"INSERT INTO ";
writeIdentifier(sql, name);
- sql << L" VALUES (";
+ sql << L" (";
+ for (int i = 0; i < attributes.size(); i++) {
+ writeIdentifier(sql, attributes[i].getAttributeName());
+ if (i < attributes.size() - 1) sql << L",";
+ }
+ sql << L") VALUES (";
for (int i = 0; i < attributes.size(); i++) {
sql << L"?";
if (i < attributes.size() - 1) sql << L",";