# HG changeset patch # User František Kučera # Date 1670701300 -3600 # Node ID 8a30971d285f934102801024144cf1a3f05e5a5a # Parent 4c0366e1b4dfb29690124b60bd0af003b56bd66e insert multiple records at once – first version diff -r 4c0366e1b4df -r 8a30971d285f src/Configuration.h --- a/src/Configuration.h Wed Dec 07 01:38:50 2022 +0100 +++ b/src/Configuration.h Sat Dec 10 20:41:40 2022 +0100 @@ -28,8 +28,15 @@ class Configuration { public: + + enum class InsertMode { + SINGLE, + MULTI, + }; + relpipe::reader::boolean_t writeHeader = true; relpipe::reader::boolean_t writeTypes = false; + InsertMode insertMode = InsertMode::MULTI; // TODO: per-relation mode virtual ~Configuration() { } diff -r 4c0366e1b4df -r 8a30971d285f src/SQLHandler.h --- a/src/SQLHandler.h Wed Dec 07 01:38:50 2022 +0100 +++ b/src/SQLHandler.h Sat Dec 10 20:41:40 2022 +0100 @@ -84,6 +84,15 @@ // output << "-- Record count: " << recordCount << std::endl; } + void endRelation() { + + if (configuration.insertMode == Configuration::InsertMode::MULTI) { + output << std::endl << ";" << std::endl; + } + + writeRecordCount(); + } + public: SQLHandler(std::ostream& output, Configuration& configuration) : output(output), configuration(configuration) { @@ -104,7 +113,7 @@ // TODO: share code/behavior with relpipe-tr-sql (but it uses parametrized statements) if (currentTable.size()) { - writeRecordCount(); + endRelation(); output << std::endl; } @@ -145,9 +154,41 @@ // TODO: custom line-ends + indentation // TODO: optionally write also the column names recordCount++; - output << "INSERT INTO "; - writeIdentifier(output, convertor.to_bytes(currentTable)); - output << " VALUES ("; + + if (configuration.insertMode == Configuration::InsertMode::SINGLE) { + output << "INSERT INTO "; + writeIdentifier(output, convertor.to_bytes(currentTable)); + + output << " ("; + for (size_t i = 0, limit = currentAttributes.size(); i < limit; i++) { + writeIdentifier(output, convertor.to_bytes(currentAttributes[i].getAttributeName())); + if (i < (limit - 1)) output << ", "; + } + output << ")"; + + output << " VALUES ("; + } else if (configuration.insertMode == Configuration::InsertMode::MULTI) { + if (recordCount == 1) { + // -------- + output << "INSERT INTO "; + writeIdentifier(output, convertor.to_bytes(currentTable)); + + output << "\n\t("; + for (size_t i = 0, limit = currentAttributes.size(); i < limit; i++) { + writeIdentifier(output, convertor.to_bytes(currentAttributes[i].getAttributeName())); + if (i < (limit - 1)) output << ", "; + } + output << ")"; + // -------- + + output << std::endl << "VALUES" << std::endl; + } else { + output << "," << std::endl; + } + output << "\t("; + } else { + throw RelpipeSQLWriterException(L"Unsupported InsertMode: " + std::to_wstring((int) configuration.insertMode)); + } } valueCount++; @@ -163,14 +204,20 @@ if (valueCount % currentAttributes.size()) { output << ", "; } else { - output << ");" << std::endl; + if (configuration.insertMode == Configuration::InsertMode::SINGLE) { + output << ");" << std::endl; + } else if (configuration.insertMode == Configuration::InsertMode::MULTI) { + output << ")"; + } else { + throw RelpipeSQLWriterException(L"Unsupported InsertMode: " + std::to_wstring((int) configuration.insertMode)); + } valueCount = 0; } } void endOfPipe() { if (currentTable.size()) { - writeRecordCount(); + endRelation(); } output.flush(); }