summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-08-11 22:36:39 +0000
committerrandomdan <randomdan@localhost>2010-08-11 22:36:39 +0000
commitc17492552fc781de33f38d56ee72eab52eb29268 (patch)
tree8bce0e7030d21584f19b5d30f6c5dbf42b461283
parentMinor fixes to text parsers (diff)
downloadproject2-c17492552fc781de33f38d56ee72eab52eb29268.tar.bz2
project2-c17492552fc781de33f38d56ee72eab52eb29268.tar.xz
project2-c17492552fc781de33f38d56ee72eab52eb29268.zip
Add gcc attrib to stringf
Extend sqlMerge to support mapping values from other tables during a merge
-rw-r--r--project2/sqlMergeTask.cpp63
-rw-r--r--project2/sqlMergeTask.h21
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 <misc.h>
#include <stdio.h>
+#include <stdexcept>
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<xmlpp::Element *>(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<xmlpp::Element *>(psi);
- keys.insert(e->get_child_text()->get_content());
+ keys.insert(static_cast<xmlpp::Element *>(psi)->get_child_text()->get_content());
}
BOOST_FOREACH(xmlpp::Node * psi, p->find("sql")) {
- xmlpp::Element * e = static_cast<xmlpp::Element *>(psi);
- if (e->get_child_text()) {
- sqls.push_back(e->get_child_text()->get_content());
- }
+ sqls.push_back(static_cast<xmlpp::Element *>(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<std::string> 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<Column> Columns;
- typedef Columns Keys;
+ class TargetColumn;
+ typedef boost::shared_ptr<TargetColumn> 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<TargetColumnPtr, TargetColumn::Sort> Columns;
+
+ typedef std::set<Column> Keys;
_SqlMergeTask(const xmlpp::Element * p);
virtual ~_SqlMergeTask();