summaryrefslogtreecommitdiff
path: root/slicer/db/sqlTablePatchSerializer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'slicer/db/sqlTablePatchSerializer.cpp')
-rw-r--r--slicer/db/sqlTablePatchSerializer.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/slicer/db/sqlTablePatchSerializer.cpp b/slicer/db/sqlTablePatchSerializer.cpp
new file mode 100644
index 0000000..20b0d82
--- /dev/null
+++ b/slicer/db/sqlTablePatchSerializer.cpp
@@ -0,0 +1,64 @@
+#include "sqlTablePatchSerializer.h"
+#include "sqlInsertSerializer.h"
+#include <slicer/metadata.h>
+#include <compileTimeFormatter.h>
+#include <scopeExit.h>
+
+namespace Slicer {
+ const std::string md_pkey = "db:pkey";
+ const std::string ignore = "ignore";
+
+ AdHocFormatter(ttname, "slicer_tmp_%?");
+ SqlTablePatchSerializer::SqlTablePatchSerializer(DB::Connection * db, DB::TablePatch & tp) :
+ db(db),
+ tablePatch(tp)
+ {
+ tablePatch.src = ttname::get(this);
+ }
+
+ SqlTablePatchSerializer::~SqlTablePatchSerializer()
+ {
+ }
+
+ void
+ SqlTablePatchSerializer::Serialize(Slicer::ModelPartForRootPtr mpr)
+ {
+ tablePatch.pk.clear();
+ tablePatch.cols.clear();
+
+ createTemporaryTable();
+ AdHoc::ScopeExit tidy(boost::bind(&SqlTablePatchSerializer::dropTemporaryTable, this));
+
+ SqlInsertSerializer ins(db, tablePatch.src);
+ ins.Serialize(mpr);
+
+ auto mp = mpr->GetContainedModelPart();
+ mp->OnEachChild([this](const auto & name, const auto &, const auto & h) {
+ if (metaDataFlagSet(h->GetMetadata(), md_pkey)) {
+ tablePatch.pk.insert(name);
+ }
+ });
+ mp->OnEachChild([this](const auto & name, const auto &, const auto & h) {
+ if (metaDataFlagNotSet(h->GetMetadata(), ignore)) {
+ tablePatch.cols.insert(name);
+ }
+ });
+
+ db->patchTable(&tablePatch);
+ }
+
+ AdHocFormatter(createTmpTable, "CREATE TEMPORARY TABLE %? AS SELECT * FROM %? WHERE 1 = 0");
+ void
+ SqlTablePatchSerializer::createTemporaryTable()
+ {
+ db->execute(createTmpTable::get(tablePatch.src, tablePatch.dest));
+ }
+
+ AdHocFormatter(dropTmpTable, "DROP TABLE %?");
+ void
+ SqlTablePatchSerializer::dropTemporaryTable()
+ {
+ db->execute(dropTmpTable::get(tablePatch.src));
+ }
+}
+