From c17492552fc781de33f38d56ee72eab52eb29268 Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 11 Aug 2010 22:36:39 +0000 Subject: Add gcc attrib to stringf Extend sqlMerge to support mapping values from other tables during a merge --- project2/sqlMergeTask.cpp | 63 ++++++++++++++++++++++++++++++++++++++--------- project2/sqlMergeTask.h | 21 +++++++++++++--- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 5ecd113..d69d837 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -3,6 +3,7 @@ #include "rdbmsDataSource.h" #include #include +#include bool _SqlMergeTask::defaultUseTempTable = true; @@ -25,17 +26,18 @@ _SqlMergeTask::_SqlMergeTask(const xmlpp::Element * p) : BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column")) { xmlpp::Element * e = static_cast(psi); - cols.insert(e->get_child_text()->get_content()); + TargetColumnPtr tcp(new TargetColumn(e->get_child_text()->get_content())); + tcp->maptable = e->get_attribute_value("maptable"); + if (!tcp->maptable.empty()) { + tcp->mapcolumn = e->get_attribute_value("mapcolumn"); + } + cols.insert(tcp); } BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column[@key='true']")) { - xmlpp::Element * e = static_cast(psi); - keys.insert(e->get_child_text()->get_content()); + keys.insert(static_cast(psi)->get_child_text()->get_content()); } BOOST_FOREACH(xmlpp::Node * psi, p->find("sql")) { - xmlpp::Element * e = static_cast(psi); - if (e->get_child_text()) { - sqls.push_back(e->get_child_text()->get_content()); - } + sqls.push_back(static_cast(psi)->get_child_text()->get_content()); } } @@ -43,6 +45,18 @@ _SqlMergeTask::~_SqlMergeTask() { } +_SqlMergeTask::TargetColumn::TargetColumn(const Column & c) : + column(c), + mapcolumn(c) +{ +} + +bool +_SqlMergeTask::TargetColumn::Sort::operator()(const TargetColumnPtr & a, const TargetColumnPtr & b) const +{ + return a->column < b->column; +} + void _SqlMergeTask::execute() const { @@ -56,7 +70,11 @@ _SqlMergeTask::execute() const copyToTempTable(); createTempKey(); } - TablePatch tp(*destdb, dtablet, dtable, cols); + std::set colNames; + BOOST_FOREACH(const TargetColumnPtr & c, cols) { + colNames.insert(c->column); + } + TablePatch tp(*destdb, dtablet, dtable, colNames); foreach(Keys::const_iterator, keys, k) { tp.addKey(*k); } @@ -72,6 +90,14 @@ _SqlMergeTask::createTempTable() const "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s WHERE 0=1", dtablet.c_str(), dtable.c_str())).execute(); + BOOST_FOREACH(Columns::value_type c, cols) { + if (!c->maptable.empty()) { + ModifyCommand(*destdb, stringf( + "ALTER TABLE %s ADD COLUMN %s VARCHAR(1000)", + dtablet.c_str(), + c->mapcolumn.c_str())).execute(); + } + } tempTableCreated = true; } void @@ -117,7 +143,7 @@ _SqlMergeTask::insertCommand() const insC.append(", "); insV.append(", "); } - insC.appendf("%s", c->c_str()); + insC.append((*c)->mapcolumn); insV.append("?"); } Buffer res; @@ -180,17 +206,30 @@ _SqlMergeTask::copyToTempTable() const Buffer insV; insC.appendf("INSERT INTO %s(", dtablet.c_str()); insV.append(") SELECT "); - BOOST_FOREACH(const std::string & c, cols) { + BOOST_FOREACH(const TargetColumnPtr & c, cols) { if (c != *cols.begin()) { insC.append(", "); insV.append(", "); } - insC.append(c.c_str()); - insV.append(c.c_str()); + insC.append(c->column); + insV.append(c->column); } Buffer res; res.appendf("%s%s FROM (%s) tmp_src", insC.c_str(), insV.c_str(), sql.c_str()); ModifyCommand(*destdb, res.c_str()).execute(); } + BOOST_FOREACH(Columns::value_type c, cols) { + if (!c->maptable.empty()) { + ModifyCommand(*destdb, stringf( + "UPDATE %s d SET %s = (SELECT m.%s FROM %s m WHERE m.%s = d.%s) WHERE %s IS NULL", + dtablet.c_str(), + c->column.c_str(), + c->column.c_str(), + c->maptable.c_str(), + c->mapcolumn.c_str(), + c->mapcolumn.c_str(), + c->column.c_str())).execute(); + } + } } diff --git a/project2/sqlMergeTask.h b/project2/sqlMergeTask.h index be5f6fa..61cbe4e 100644 --- a/project2/sqlMergeTask.h +++ b/project2/sqlMergeTask.h @@ -17,9 +17,24 @@ class _SqlMergeTask : public _Task { public: typedef std::string Table; typedef std::string Column; - - typedef std::set Columns; - typedef Columns Keys; + class TargetColumn; + typedef boost::shared_ptr TargetColumnPtr; + class TargetColumn { + public: + class Sort { + public: + bool operator()(const TargetColumnPtr & a, const TargetColumnPtr & b) const; + }; + TargetColumn(const Column &); + + Column column; + Column mapcolumn; + Table maptable; + + }; + typedef std::set Columns; + + typedef std::set Keys; _SqlMergeTask(const xmlpp::Element * p); virtual ~_SqlMergeTask(); -- cgit v1.2.3