From 9b9c2539da7b54892d36dad47dbd5eb3636f96a6 Mon Sep 17 00:00:00 2001
From: randomdan <randomdan@localhost>
Date: Fri, 11 Jun 2010 12:30:06 +0000
Subject: Fix odbc select destructor when cursor not opened Add support for
 subqueries

---
 project2/envproc.cpp         | 11 ++---------
 project2/rdbmsDataSource.cpp |  1 -
 project2/sqlView.cpp         | 25 +++++++++++--------------
 project2/sqlView.h           | 10 +++++++---
 project2/xmlObjectLoader.h   | 16 ++++++----------
 5 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/project2/envproc.cpp b/project2/envproc.cpp
index e5c2a52..be864a5 100644
--- a/project2/envproc.cpp
+++ b/project2/envproc.cpp
@@ -21,20 +21,15 @@ EnvironmentProcessor::init()
 boost::shared_ptr<xmlpp::Document>
 EnvironmentProcessor::process() const
 {
-	fprintf(stderr, "parsing present .xml\n");
 	xmlpp::DomParser present("present/" + page + ".xml");
-	fprintf(stderr, "performing xincludes\n");
 	while (xmlXIncludeProcessFlags(present.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0);
-	fprintf(stderr, "getting root\n");
 	xmlpp::Element * presentRoot = present.get_document()->get_root_node();
 	// Collect datasources
-	fprintf(stderr, "collecting datasources\n");
 	RdbmsDataSources rdbmsDataSources;
-	collectAll<_RdbmsDataSource>(rdbmsDataSources, presentRoot, "rdbmsdatasource", &_Project2SourceObject::name);
+	collectAll<_RdbmsDataSource>(rdbmsDataSources, presentRoot, "rdbmsdatasource", &_Project2SourceObject::name, true, true);
 	// Collect views
-	fprintf(stderr, "collecting sqlviews\n");
 	SqlViews sqlViews;
-	collectAll<_SqlView>(sqlViews, presentRoot, "sqlview", &_SqlView::name);
+	collectAll<_SqlView>(sqlViews, presentRoot, "sqlview", &_SqlView::name, true, true);
 	//
 	boost::shared_ptr<xmlpp::Document> responseDoc = boost::shared_ptr<xmlpp::Document>(new xmlpp::Document("1.0"));
 	xmlpp::Element * responseRoot = responseDoc->create_root_node(presentRoot->get_attribute_value("root"));
@@ -45,7 +40,6 @@ EnvironmentProcessor::process() const
 	}
 	catch (...) {
 	}
-	fprintf(stderr, "done views\n");
 	// These were for debug... but why not pass them on?
 	xmlNewNs(responseRoot->cobj(), BAD_CAST "http://project2.randomdan.homeip.net/", BAD_CAST "project2");
 	responseRoot->add_child("fqdn", "project2")->set_child_text(http_host);
@@ -70,7 +64,6 @@ EnvironmentProcessor::process() const
 				xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf));
 	}
 	free(buf);
-	fprintf(stderr, "done style pi\n");
 	return responseDoc;
 }
 
diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp
index 10f6e75..d77d016 100644
--- a/project2/rdbmsDataSource.cpp
+++ b/project2/rdbmsDataSource.cpp
@@ -6,7 +6,6 @@ _RdbmsDataSource::_RdbmsDataSource(const xmlpp::Element * p) :
 	_Project2SourceObject(p),
 	masterDsn(xmlChildText(p, "masterdsn"))
 {
-	fprintf(stderr, "Created RDBMS Datasource %s (%s)\n", name.c_str(), masterDsn.c_str());
 }
 
 ODBC::Connection &
diff --git a/project2/sqlView.cpp b/project2/sqlView.cpp
index 7b75a81..71c4f71 100644
--- a/project2/sqlView.cpp
+++ b/project2/sqlView.cpp
@@ -13,7 +13,11 @@ _SqlView::_SqlView(const xmlpp::Element * p) :
 	dataSource(p->get_attribute_value("datasource")),
 	recordName(p->get_attribute_value("recordname"))
 {
-	collectAll<_Parameter>(parameters, p, "param", &_Parameter::bind);
+	xmlpp::NodeSet ps = p->find("parameters");
+	BOOST_FOREACH(xmlpp::Node * psi, ps) {
+		collectAll<_Parameter>(parameters, dynamic_cast<xmlpp::Element *>(psi), "param", &_Parameter::bind, true, true);
+	}
+	collectAll<_SqlView>(subQueries, p, "sqlview", &_Project2SourceObject::name, true, true);
 }
 
 _SqlView::_Parameter::_Parameter(const xmlpp::Element * p) :
@@ -23,7 +27,7 @@ _SqlView::_Parameter::_Parameter(const xmlpp::Element * p) :
 {
 }
 
-void _SqlView::execute(RdbmsDataSources s, xmlpp::Element * par, const EnvironmentProcessor * ep) const
+void _SqlView::execute(RdbmsDataSources s, xmlpp::Element * par, const EnvironmentProcessor * ep, const ODBC::SelectCommand * parent) const
 {
 	typedef std::map<std::string, xmlpp::Element *> Columns;
 	ODBC::SelectCommand query(s[dataSource]->getReadonly(), sql);
@@ -34,6 +38,9 @@ void _SqlView::execute(RdbmsDataSources s, xmlpp::Element * par, const Environme
 		else if (p.second->source == "query") {
 			query.bindParamS(p.second->bind, ep->getParamQuery(p.second->id));
 		}
+		else if (parent && p.second->source == "parent") {
+			(*parent)[p.second->id].rebind(&query, p.second->bind);
+		}
 	}
 	xmlpp::Element * set = par->add_child(name);
 	while (query.fetch()) {
@@ -80,19 +87,9 @@ void _SqlView::execute(RdbmsDataSources s, xmlpp::Element * par, const Environme
 			free(name);
 			free(attr);
 		}
-		/*
-		ODBC::SelectCommand queries(wdb,
-				"SELECT d.id AS dsn, q.id AS query, q.sql, q.name, q.recordname, pq.id \
-				FROM dsn d, page_query pq, query q \
-				WHERE pq.parent = ? \
-				AND q.id = pq.query \
-				AND d.id = q.dsn");
-		queries.bindParamI(0, pqid);
-		while (queries.fetch()) {
-			addQueryResultsToXml(wdb, cp, record, queries["dsn"],
-					queries["sql"], queries["name"], queries["recordname"], queries["id"], &query, elems, qs);
+		BOOST_FOREACH(SqlViews::value_type sq, subQueries) {
+			sq.second->execute(s, record, ep, &query);
 		}
-		*/
 	}
 }
 
diff --git a/project2/sqlView.h b/project2/sqlView.h
index 81f759b..9f132bc 100644
--- a/project2/sqlView.h
+++ b/project2/sqlView.h
@@ -8,6 +8,11 @@
 #include "rdbmsDataSource.h"
 
 class EnvironmentProcessor;
+namespace ODBC { class SelectCommand; }
+class _SqlView;
+typedef boost::shared_ptr<_SqlView> SqlView;
+typedef std::map<std::string, SqlView> SqlViews;
+
 class _SqlView : public _Project2SourceObject {
 	public:
 		class _Parameter {
@@ -21,15 +26,14 @@ class _SqlView : public _Project2SourceObject {
 		typedef std::map<unsigned int, Parameter> Parameters;
 
 		_SqlView(const xmlpp::Element * p);
-		void execute(RdbmsDataSources s, xmlpp::Element *, const EnvironmentProcessor *) const;
+		void execute(RdbmsDataSources s, xmlpp::Element *, const EnvironmentProcessor *, const ODBC::SelectCommand * parent = NULL) const;
 		const Glib::ustring sql;
 		const Glib::ustring dataSource;
 		const Glib::ustring recordName;
 	private:
 		Parameters parameters;
+		SqlViews subQueries;
 };
-typedef boost::shared_ptr<_SqlView> SqlView;
-typedef std::map<std::string, SqlView> SqlViews;
 
 #endif
 
diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h
index ecc97fa..6664018 100644
--- a/project2/xmlObjectLoader.h
+++ b/project2/xmlObjectLoader.h
@@ -12,30 +12,26 @@
 template <class ObjectType, class ContainerType, class IDType, class ObjectBase>
 void
 collectAll(std::map<IDType, ContainerType> & objs, const xmlpp::Element * node, const Glib::ustring & name,
-		const IDType ObjectBase::*id)
+		const IDType ObjectBase::*id, bool childrenOnly, bool recursive)
 {
 	if (!node) {
 		return;
 	}
-	if (name == node->get_name()) {
-		fprintf(stderr, "Found a %s\n", name.c_str());
+	if (!childrenOnly && name == node->get_name()) {
 		try {
 			ContainerType c = ContainerType(new ObjectType(node));
 			objs[(*c).*id] = c;
-			fprintf(stderr, "Load succeeded\n");
 		}
 		catch (const std::exception & e) {
-			// Assume the XML node is what we thought it was
-			fprintf(stderr, "Load failed (%s)\n", e.what());
+			// Assume the XML node is not what we thought it was
 		}
 		catch (...) {
-			// Assume the XML node is what we thought it was
-			fprintf(stderr, "Load failed\n");
+			// Assume the XML node is not what we thought it was
 		}
 	}
-	else {
+	else if (recursive || childrenOnly) {
 		BOOST_FOREACH(xmlpp::Node * child, node->get_children()) {
-			collectAll<ObjectType, ContainerType>(objs, dynamic_cast<const xmlpp::Element *>(child), name, id);
+			collectAll<ObjectType, ContainerType>(objs, dynamic_cast<const xmlpp::Element *>(child), name, id, false, recursive);
 		}
 	}
 }
-- 
cgit v1.2.3