From 4efd293d8de0834eadc018304986a6e1a3395c79 Mon Sep 17 00:00:00 2001
From: randomdan <randomdan@localhost>
Date: Fri, 18 Feb 2011 11:01:26 +0000
Subject: Don't require the (probably repeated) inclusion of datasource
 definitions, have CommonObjects load them once on demand Fix rdbmsDataSource
 closing transactions it didn't open Change XML to match the above changes

---
 project2/cgi/cgiAppEngine.cpp         |  1 -
 project2/commonObjects.cpp            | 18 ++++++++++++++++++
 project2/commonObjects.h              |  6 ++++--
 project2/console/consoleAppEngine.cpp |  1 -
 project2/rdbmsDataSource.cpp          | 15 ++++++++++-----
 project2/rdbmsDataSource.h            |  1 +
 project2/xmlObjectLoader.h            |  6 ++++--
 project2/xmlPresenter.cpp             |  1 -
 8 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index b273fda..345932a 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -152,7 +152,6 @@ CgiApplicationEngine::RequestStage::RequestStage(const CgiApplicationEngine * e,
 	present = requestRoot->get_attribute_value("present");
 
 	LoaderBase loader("http://project2.randomdan.homeip.net", true);
-	loader.supportedStorers.insert(Storer::into(&datasources));
 	loader.supportedStorers.insert(Storer::into(&parameterChecks));
 	loader.supportedStorers.insert(Storer::into(&rowSets));
 	loader.supportedStorers.insert(Storer::into(&tasks));
diff --git a/project2/commonObjects.cpp b/project2/commonObjects.cpp
index 31f81a9..2ca4846 100644
--- a/project2/commonObjects.cpp
+++ b/project2/commonObjects.cpp
@@ -1,4 +1,6 @@
 #include "commonObjects.h"
+#include <libxml++/parsers/domparser.h>
+#include <libxml/xinclude.h>
 
 RowSetPtr
 CommonObjects::getSource(const std::string & name) const
@@ -10,4 +12,20 @@ CommonObjects::getSource(const std::string & name) const
 	throw CommonObjects::DataSourceNotFound(name);
 }
 
+DataSources::index<bySOName>::type::const_iterator
+CommonObjects::loadDataSource(const std::string & name) const
+{
+	xmlpp::DomParser xml("datasources/" + name + ".xml");
+	while (xmlXIncludeProcessFlags(xml.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
+
+	LoaderBase loader("http://project2.randomdan.homeip.net", true);
+	loader.supportedStorers.insert(Storer::into(&datasources));
+	loader.collectAll(xml.get_document()->get_root_node(), false);
+
+	DataSources::index<bySOName>::type::const_iterator i = datasources.get<bySOName>().find(name);
+	if (i == datasources.get<bySOName>().end()) {
+		throw DataSourceNotFound(name);
+	}
+	return i;
+}
 
diff --git a/project2/commonObjects.h b/project2/commonObjects.h
index e3c0d37..a15a8da 100644
--- a/project2/commonObjects.h
+++ b/project2/commonObjects.h
@@ -15,7 +15,7 @@ class CommonObjects : public virtual IntrusivePtrBase {
 		{
 			DataSources::index<bySOName>::type::const_iterator i = datasources.get<bySOName>().find(name);
 			if (i == datasources.get<bySOName>().end()) {
-				throw DataSourceNotFound(name);
+				i = loadDataSource(name);
 			}
 			const DataSourceType * s = dynamic_cast<const DataSourceType *>(i->get());
 			if (!s) {
@@ -25,7 +25,9 @@ class CommonObjects : public virtual IntrusivePtrBase {
 		}
 	protected:
 		RowSets rowSets;
-		DataSources datasources;
+		mutable DataSources datasources;
+	private:
+		DataSources::index<bySOName>::type::const_iterator loadDataSource(const std::string & name) const;
 };
 
 #endif
diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp
index be88638..3c99f74 100644
--- a/project2/console/consoleAppEngine.cpp
+++ b/project2/console/consoleAppEngine.cpp
@@ -62,7 +62,6 @@ ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * en
 	while (xmlXIncludeProcessFlags(request.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
 
 	LoaderBase loader("http://project2.randomdan.homeip.net", true);
-	loader.supportedStorers.insert(Storer::into(&datasources));
 	loader.supportedStorers.insert(Storer::into(&parameterChecks));
 	loader.supportedStorers.insert(Storer::into(&tasks));
 	loader.supportedStorers.insert(Storer::into(&rowSets));
diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp
index 8a095c7..9ffcc93 100644
--- a/project2/rdbmsDataSource.cpp
+++ b/project2/rdbmsDataSource.cpp
@@ -64,6 +64,9 @@ RdbmsDataSource::RdbmsDataSource(const xmlpp::Element * p) :
 
 RdbmsDataSource::~RdbmsDataSource()
 {
+	BOOST_FOREACH(DBHosts::value_type & h, dbhosts) {
+		h.second->connection->finish();
+	}
 }
 
 void
@@ -75,8 +78,9 @@ const DB::Connection &
 RdbmsDataSource::getWritable() const
 {
 	ConnectionPtr master = connectTo(masterDsn);
-	if (!master->connection->inTx()) {
+	if (!master->txOpen) {
 		master->connection->beginTx();
+		master->txOpen = true;
 	}
 	changedDSNs.insert(name);
 	return *master->connection;
@@ -127,9 +131,9 @@ void
 RdbmsDataSource::commit()
 {
 	DBHosts::const_iterator m = dbhosts.find(masterDsn);
-	if (m != dbhosts.end() && m->second->connection->inTx()) {
+	if (m != dbhosts.end() && m->second->txOpen) {
 		m->second->connection->commitTx();
-		m->second->connection->finish();
+		m->second->txOpen = false;
 	}
 }
 
@@ -137,9 +141,9 @@ void
 RdbmsDataSource::rollback()
 {
 	DBHosts::const_iterator m = dbhosts.find(masterDsn);
-	if (m != dbhosts.end() && m->second->connection->inTx()) {
+	if (m != dbhosts.end() && m->second->txOpen) {
 		m->second->connection->rollbackTx();
-		m->second->connection->finish();
+		m->second->txOpen = false;
 	}
 	changedDSNs.erase(name);
 }
@@ -183,6 +187,7 @@ RdbmsDataSource::connectTo(const ConnectionInfo & dsn)
 
 RdbmsDataSource::RdbmsConnection::RdbmsConnection(const DB::Connection * con, time_t kat) :
 	connection(con),
+	txOpen(false),
 	lastUsedTime(0),
 	keepAliveTime(kat)
 {
diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h
index 04c4b88..f105eed 100644
--- a/project2/rdbmsDataSource.h
+++ b/project2/rdbmsDataSource.h
@@ -18,6 +18,7 @@ class RdbmsDataSource : public DataSource {
 				void touch() const;
 				bool isExpired() const;
 				const DB::Connection * const connection;
+				bool txOpen;
 
 			private:
 				mutable time_t lastUsedTime;
diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h
index d1209c7..4568124 100644
--- a/project2/xmlObjectLoader.h
+++ b/project2/xmlObjectLoader.h
@@ -57,8 +57,10 @@ class StorerImpl : public Storer {
 		bool save(SourceObjectPtr obj) const {
 			boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(obj);
 			if (O) {
-				map->insert(O);
-				return true;
+				if (map->insert(O).second) {
+					return true;
+				}
+				throw StoreFailed(obj->name);
 			}
 			return false;
 		}
diff --git a/project2/xmlPresenter.cpp b/project2/xmlPresenter.cpp
index dcee298..68368ec 100644
--- a/project2/xmlPresenter.cpp
+++ b/project2/xmlPresenter.cpp
@@ -15,7 +15,6 @@ XmlPresenter::XmlPresenter(const std::string & group, const std::string & file)
 	while (xmlXIncludeProcessFlags(present.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
 
 	LoaderBase loader("http://project2.randomdan.homeip.net", true);
-	loader.supportedStorers.insert(Storer::into(&datasources));
 	loader.supportedStorers.insert(Storer::into(&rowSets));
 	loader.supportedStorers.insert(Storer::into(&views));
 	loader.supportedStorers.insert(Storer::into(&parameterChecks));
-- 
cgit v1.2.3