From 9b9c2539da7b54892d36dad47dbd5eb3636f96a6 Mon Sep 17 00:00:00 2001 From: randomdan 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 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 responseDoc = boost::shared_ptr(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(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 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 SqlViews; + class _SqlView : public _Project2SourceObject { public: class _Parameter { @@ -21,15 +26,14 @@ class _SqlView : public _Project2SourceObject { typedef std::map 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 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 void collectAll(std::map & 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(objs, dynamic_cast(child), name, id); + collectAll(objs, dynamic_cast(child), name, id, false, recursive); } } } -- cgit v1.2.3