diff options
| author | randomdan <randomdan@localhost> | 2010-08-11 22:36:39 +0000 | 
|---|---|---|
| committer | randomdan <randomdan@localhost> | 2010-08-11 22:36:39 +0000 | 
| commit | c17492552fc781de33f38d56ee72eab52eb29268 (patch) | |
| tree | 8bce0e7030d21584f19b5d30f6c5dbf42b461283 | |
| parent | Minor fixes to text parsers (diff) | |
| download | project2-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.cpp | 63 | ||||
| -rw-r--r-- | 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 <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(); | 
