diff options
| -rw-r--r-- | project2/Jamfile.jam | 2 | ||||
| -rw-r--r-- | project2/appEngine.cpp | 3 | ||||
| -rw-r--r-- | project2/appEngine.h | 5 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 28 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.h | 13 | ||||
| -rw-r--r-- | project2/config.cpp | 81 | ||||
| -rw-r--r-- | project2/config.h | 43 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.cpp | 25 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.h | 9 | ||||
| -rw-r--r-- | project2/sqlCheck.cpp | 6 | ||||
| -rw-r--r-- | project2/sqlCheck.h | 2 | ||||
| -rw-r--r-- | project2/sqlMergeTask.cpp | 4 | ||||
| -rw-r--r-- | project2/sqlMergeTask.h | 66 | ||||
| -rw-r--r-- | project2/sqlRows.cpp | 5 | ||||
| -rw-r--r-- | project2/sqlRows.h | 2 | ||||
| -rw-r--r-- | project2/sqlTask.cpp | 6 | ||||
| -rw-r--r-- | project2/sqlTask.h | 2 | ||||
| -rw-r--r-- | project2/variables.cpp | 21 | 
18 files changed, 272 insertions, 51 deletions
| diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index e2eaf42..d42e278 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -33,7 +33,7 @@ lib p2common :  	iterate.cpp paramChecker.cpp presenter.cpp rawView.cpp dumpTask.cpp  	sourceObject.cpp task.cpp variables.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp  	sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp -	rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp +	rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp config.cpp  	:  	<library>../libmisc//misc  	<library>libxmlpp diff --git a/project2/appEngine.cpp b/project2/appEngine.cpp index 3961ffe..1489cd1 100644 --- a/project2/appEngine.cpp +++ b/project2/appEngine.cpp @@ -3,7 +3,8 @@  ApplicationEngine * ApplicationEngine::currentEngine = NULL; -ApplicationEngine::ApplicationEngine() +ApplicationEngine::ApplicationEngine(const Glib::ustring & engineKeys) : +	Configuration(engineKeys)  {  	if (currentEngine) {  		throw std::runtime_error("One application at a time, please"); diff --git a/project2/appEngine.h b/project2/appEngine.h index 04fe486..2921b2d 100644 --- a/project2/appEngine.h +++ b/project2/appEngine.h @@ -4,10 +4,11 @@  #include "environment.h"  #include "session.h"  #include "presenter.h" +#include "config.h" -class ApplicationEngine { +class ApplicationEngine : public Configuration {  	public: -		ApplicationEngine(); +		ApplicationEngine(const Glib::ustring & engineKeys);  		virtual ~ApplicationEngine() = 0;  		virtual void process() const = 0; diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index d1c1579..3a9e362 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -7,6 +7,7 @@  #include "../xmlObjectLoader.h"  #include "../iterate.h"  #include <boost/bind.hpp> +#include <boost/regex.hpp>  #include "../sessionXml.h"  const std::string SESSIONID = "sessionID"; @@ -15,8 +16,10 @@ typedef std::string SValue;  SessionContainer * sessionsContainer = new SessionContainerXml(); +class UnknownDomain : public std::exception { }; +  CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) : -	ApplicationEngine(), +	ApplicationEngine("web/host"),  	_env(e),  	header(NULL)  { @@ -181,3 +184,26 @@ CgiApplicationEngine::session() const  	return sessionsContainer->GetSession(sessionID);  } +bool +CgiApplicationEngine::checkDomain(const CgiApplicationEngine::DomainPlatforms::value_type & i) const +{ +	const std::string & h = _env->getServerName(); +	return boost::regex_match(h.begin(), h.end(), boost::regex(i.first.raw())); +} + +Glib::ustring +CgiApplicationEngine::resolveCurrentConfig() const +{ +	DomainPlatforms::const_iterator i = std::find_if(domplat.begin(), domplat.end(), boost::bind(&CgiApplicationEngine::checkDomain, this, _1)); +	if (i != domplat.end()) { +		return i->second; +	} +	throw UnknownDomain(); +} + +void +CgiApplicationEngine::loadEngineSection(const xmlpp::Element * e) const +{ +	domplat.push_back(DomainPlatforms::value_type(e->get_attribute_value("name"), e->get_attribute_value("platform"))); +} + diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 532b74d..5a21e98 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -31,12 +31,22 @@ class CgiApplicationEngine : public ApplicationEngine {  		}  		const Environment * env() const;  		SessionPtr session() const; +		virtual Glib::ustring resolveCurrentConfig() const;  		void addAppData(const Presenter * p) const;  		const CgiEnvironment * _env; +  	protected:  		mutable cgicc::HTTPContentHeader * header; +  	private: +		typedef std::pair<Glib::ustring, Glib::ustring> DomainPlatform; +		typedef std::list<DomainPlatform> DomainPlatforms; +		mutable DomainPlatforms domplat; +		bool checkDomain(const DomainPlatforms::value_type & i) const; +		void loadEngineSection(const xmlpp::Element *) const; +  		mutable boost::shared_ptr<xmlpp::Document> doc; +  		class Stage;  		typedef boost::intrusive_ptr<Stage> StagePtr;  		class Stage : public virtual CommonObjects { @@ -47,6 +57,7 @@ class CgiApplicationEngine : public ApplicationEngine {  			protected:  				const CgiApplicationEngine * appEngine;  		}; +		  		class RequestStage : public Stage {  			public:  				RequestStage(const CgiApplicationEngine *, const std::string & id); @@ -57,12 +68,14 @@ class CgiApplicationEngine : public ApplicationEngine {  				OrderedParamCheckers parameterChecks;  				NoOutputExecutes tasks;  		}; +		  		class PresentStage : public Stage, public XmlPresenter {  			public:  				PresentStage(const CgiApplicationEngine *, const std::string & id);  				PresentStage(const CgiApplicationEngine *, const std::string & group, const std::string & id);  				virtual ~PresentStage();  				virtual StagePtr run(); +		  		};  		mutable StagePtr currentStage;  		mutable UUID sessionID; diff --git a/project2/config.cpp b/project2/config.cpp new file mode 100644 index 0000000..f973c05 --- /dev/null +++ b/project2/config.cpp @@ -0,0 +1,81 @@ +#include "config.h" +#include "exceptions.h" +#include <boost/filesystem/operations.hpp> +#include <boost/foreach.hpp> +#include <libxml/xinclude.h> +#include <libxml++/parsers/domparser.h> + +class NoSuchPlatform : public std::exception { }; +class NoSuchConfigurationValue : public std::exception { }; + +Configuration::Configuration(const Glib::ustring & ek) : +	loaded(false), +	engineKeys(ek) +{ +} + +void +Configuration::load() const +{ +	if (loaded) { +		return; +	} +	loaded = true; +	if (!boost::filesystem::exists("config.xml")) { +		return; +	} +	xmlpp::DomParser configxml("config.xml"); +	while (xmlXIncludeProcessFlags(configxml.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0); +	xmlpp::NodeSet ps(configxml.get_document()->get_root_node()->find("platform")); +	BOOST_FOREACH(const xmlpp::Node * p, ps) { +		const xmlpp::Element * pe = dynamic_cast<const xmlpp::Element *>(p); +		if (pe) { +			platforms[pe->get_attribute_value("name")] = new Platform(pe); +		} +	} +	xmlpp::NodeSet eks(configxml.get_document()->get_root_node()->find(engineKeys)); +	BOOST_FOREACH(const xmlpp::Node * ek, eks) { +		const xmlpp::Element * eke = dynamic_cast<const xmlpp::Element *>(ek); +		if (eke) { +			loadEngineSection(eke); +		} +	} +} + +Configuration::~Configuration() +{ +} + +Configuration::PlatformPtr +Configuration::getCurrentConfig() const +{ +	load(); +	Glib::ustring platformName(resolveCurrentConfig()); +	Platforms::const_iterator i = platforms.find(platformName); +	if (i == platforms.end()) { +		throw NoSuchPlatform(); +	} +	return i->second; +} + +const Glib::ustring & +Configuration::Platform::getValue(const Glib::ustring & key) const +{ +	Values::const_iterator i = values.find(key); +	if (i == values.end()) { +		throw NoSuchConfigurationValue(); +	} +	return i->second; +} + +Configuration::Platform::Platform(const xmlpp::Element * e) +{ +	xmlpp::NodeSet vs(e->find("variable")); +	BOOST_FOREACH(const xmlpp::Node * v, vs) { +		const xmlpp::Element * ve = dynamic_cast<const xmlpp::Element *>(v); +		if (ve) { +			values.insert(Values::value_type(ve->get_attribute_value("name"), ve->get_attribute_value("value"))); +		} +	} +} + diff --git a/project2/config.h b/project2/config.h new file mode 100644 index 0000000..9f6cd5d --- /dev/null +++ b/project2/config.h @@ -0,0 +1,43 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include <string> +#include <libxml++/nodes/element.h> +#include "intrusivePtrBase.h" +#include <boost/function.hpp> + +class Configuration { +	public: +		class Platform : public virtual IntrusivePtrBase { +			public: +				typedef std::map<Glib::ustring, const Glib::ustring> Values; + +				Platform(const xmlpp::Element * instanceRoot); +				const Glib::ustring & getValue(const Glib::ustring & key) const; + +			private: +				Values values; +		}; +		typedef boost::intrusive_ptr<const Platform> PlatformPtr; + +		typedef std::map<Glib::ustring, PlatformPtr> Platforms; + +		Configuration(const Glib::ustring & engineKeys); +		virtual ~Configuration() = 0; + +		PlatformPtr getCurrentConfig() const; + +	protected: +		virtual Glib::ustring resolveCurrentConfig() const = 0; +		void load() const; + +	private: +		virtual void loadEngineSection(const xmlpp::Element *) const = 0; + +		mutable bool loaded; +		mutable Platforms platforms; +		const Glib::ustring engineKeys; +}; + +#endif +		 diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index bd17458..43b58c9 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -3,6 +3,9 @@  #include "../iterate.h"  #include <stdexcept>  #include <libxml/xinclude.h> +#include <libxml++/parsers/domparser.h> + +class UnknownPlatformAlias : public std::exception { };  class ConsoleSession : public Session {  	public: @@ -49,7 +52,7 @@ class ConsoleSession : public Session {  };  ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, const boost::filesystem::path & f) : -	ApplicationEngine(), +	ApplicationEngine("console/environment"),  	_env(env),  	runtime(new ConsoleSession())  { @@ -138,3 +141,23 @@ ConsoleApplicationEngine::ConsolePresenter::popSub() const  	indent -= 2;  } +Glib::ustring +ConsoleApplicationEngine::resolveCurrentConfig() const +{ +	const char * e = getenv("P2_PLATFORM"); +	if (!e) { +		e = ""; +	} +	ConsolePlatforms::const_iterator i = conplat.find(e); +	if (i != conplat.end()) { +		return i->second; +	} +	throw UnknownPlatformAlias(); +} + +void +ConsoleApplicationEngine::loadEngineSection(const xmlpp::Element * e) const +{ +	conplat.insert(ConsolePlatforms::value_type(e->get_attribute_value("setting"), e->get_attribute_value("platform"))); +} + diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index 9d4ee96..abc471f 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -9,7 +9,6 @@  #include <boost/intrusive_ptr.hpp>  #include <boost/filesystem/path.hpp>  #include <libxml++/document.h> -#include <libxml++/parsers/domparser.h>  class ConsoleEnvironment; @@ -21,10 +20,17 @@ class ConsoleApplicationEngine : public ApplicationEngine, public CommonObjects  		void process() const;  		const Environment * env() const;  		SessionPtr session() const; +		virtual Glib::ustring resolveCurrentConfig() const;  		virtual void addAppData(const Presenter * p) const; +  	protected:  		const ConsoleEnvironment * _env; +  	private: +		typedef std::map<Glib::ustring, const Glib::ustring> ConsolePlatforms; +		mutable ConsolePlatforms conplat; +		void loadEngineSection(const xmlpp::Element *) const; +  		class ConsolePresenter : public Presenter {  			public:  				ConsolePresenter(const ConsoleApplicationEngine *, const std::string & id); @@ -37,6 +43,7 @@ class ConsoleApplicationEngine : public ApplicationEngine, public CommonObjects  			private:  				mutable unsigned int indent;  		}; +  		OrderedParamCheckers parameterChecks;  		NoOutputExecutes tasks;  		SessionPtr runtime; diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp index 3537134..9a5bb94 100644 --- a/project2/sqlCheck.cpp +++ b/project2/sqlCheck.cpp @@ -6,6 +6,7 @@  #include <boost/regex.hpp>  #include "commonObjects.h"  #include "sqlVariableBinder.h" +#include "genericVisitor.h"  ElementLoaderImpl<SqlCheck> sqlCheckLoader("sqlcheck"); @@ -13,7 +14,7 @@ SqlCheck::SqlCheck(const xmlpp::Element * p) :  	SourceObject(p),  	IHaveParameters(p),  	ParamChecker(p), -	dataSource(p->get_attribute_value("datasource")), +	dataSource(p, "datasource"),  	sql(xmlChildText(p, "sql")),  	testOp(p->get_attribute_value("testOp")),  	testValue(atof(p->get_attribute_value("testValue").c_str())), @@ -29,7 +30,8 @@ SqlCheck::~SqlCheck()  void  SqlCheck::loadComplete(const CommonObjects * co)  { -	query = new ODBC::SelectCommand(co->dataSource<RdbmsDataSource>(dataSource)->getReadonly(), sql); +	query = new ODBC::SelectCommand(LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( +					&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getReadonly(), sql);  }  bool diff --git a/project2/sqlCheck.h b/project2/sqlCheck.h index e4f79ee..bfc7b37 100644 --- a/project2/sqlCheck.h +++ b/project2/sqlCheck.h @@ -14,7 +14,7 @@ class SqlCheck : public IHaveParameters, public ParamChecker {  		virtual void loadComplete(const CommonObjects *);  		bool performCheck() const; -		const std::string dataSource; +		const Variable dataSource;  		const Glib::ustring sql;  		const std::string testOp;  		const double testValue; diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 2436f1f..6a5ebf7 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -49,7 +49,7 @@ SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) :  	tempTableCreated(false),  	insCmd(NULL),  	destdb(NULL), -	dataSource(p->get_attribute_value("datasource")), +	dataSource(p, "datasource"),  	dtable(p->get_attribute_value("targettable")),  	dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid()))  { @@ -89,7 +89,7 @@ SqlMergeTask::~SqlMergeTask()  void  SqlMergeTask::loadComplete(const CommonObjects * co)  { -	destdb = &co->dataSource<RdbmsDataSource>(dataSource)->getWritable(); +	destdb = &LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable();  	insCmd = insertCommand();  	BOOST_FOREACH(const Iterates::value_type & i, sources) {  		attach(i.second, insCmd); diff --git a/project2/sqlMergeTask.h b/project2/sqlMergeTask.h index 08246d0..c7a7e4e 100644 --- a/project2/sqlMergeTask.h +++ b/project2/sqlMergeTask.h @@ -15,9 +15,9 @@  #include <list>  class SqlMergeTask : public Task { -    public: -        typedef std::string Table; -        typedef std::string Column; +	public: +		typedef std::string Table; +		typedef std::string Column;  		class TargetColumn;  		typedef boost::intrusive_ptr<TargetColumn> TargetColumnPtr;  		class TargetColumn : public virtual IntrusivePtrBase { @@ -33,44 +33,44 @@ class SqlMergeTask : public Task {  				Table maptable;  		}; -        typedef std::set<TargetColumnPtr, TargetColumn::Sort> Columns; +		typedef std::set<TargetColumnPtr, TargetColumn::Sort> Columns; -        typedef std::set<Column> Keys; +		typedef std::set<Column> Keys; -        SqlMergeTask(const xmlpp::Element * p); -        virtual ~SqlMergeTask(); +		SqlMergeTask(const xmlpp::Element * p); +		virtual ~SqlMergeTask(); -		virtual void			loadComplete(const CommonObjects *); -        void					execute() const; -        Columns	           		cols; -        Keys                    keys; -        Keys                    indexes; -        const Variable			updateWhere; -        const std::string       patchOrder; -        const bool				earlyKeys; -		const bool				useView; +		virtual void loadComplete(const CommonObjects *); +		void execute() const; +		Columns cols; +		Keys keys; +		Keys indexes; +		const Variable updateWhere; +		const std::string patchOrder; +		const bool earlyKeys; +		const bool useView; -    private: -        virtual void            copyToTempTable() const; -        void                    createTempTable() const; -        void                    dropTempTable() const; -        void                    createTempKey() const; +	private: +		virtual void copyToTempTable() const; +		void createTempTable() const; +		void dropTempTable() const; +		void createTempKey() const; -        mutable bool            tempTableCreated; -		Iterates				sources; +		mutable bool tempTableCreated; +		Iterates sources;  		std::list<std::string>	sqls; -    protected: -        ModifyCommand *         insertCommand() const; -		ModifyCommand *			insCmd; +	protected: +		ModifyCommand * insertCommand() const; +		ModifyCommand * insCmd; -    public: -		ODBC::Connection *		destdb; -        const std::string 		dataSource; -        const Table             dtable; -        const Table             dtablet; +	public: +		ODBC::Connection * destdb; +		const Variable dataSource; +		const Table dtable; +		const Table dtablet; -        static unsigned int     defaultVerbosity; -        static bool             defaultUseTempTable; +		static unsigned int defaultVerbosity; +		static bool defaultUseTempTable;  };  #endif diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp index 31948df..f592337 100644 --- a/project2/sqlRows.cpp +++ b/project2/sqlRows.cpp @@ -9,6 +9,7 @@  #include "xmlObjectLoader.h"  #include "commonObjects.h"  #include "sqlVariableBinder.h" +#include "genericVisitor.h"  #include <boost/date_time/gregorian/gregorian_types.hpp>  ElementLoaderImpl<SqlRows> sqlviewLoader("sqlrows"); @@ -16,7 +17,7 @@ ElementLoaderImpl<SqlRows> sqlviewLoader("sqlrows");  SqlRows::SqlRows(const xmlpp::Element * p) :  	SourceObject(p),  	RowSet(p), -	dataSource(p->get_attribute_value("datasource")), +	dataSource(p, "datasource"),  	sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())),  	query(NULL),  	db(NULL) @@ -30,7 +31,7 @@ SqlRows::~SqlRows()  void  SqlRows::loadComplete(const CommonObjects * co)  { -	db = co->dataSource<RdbmsDataSource>(dataSource); +	db = LexicalCall<std::string, const RdbmsDataSource *>(boost::bind(&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource);  }  void diff --git a/project2/sqlRows.h b/project2/sqlRows.h index 9c6dadb..942da5d 100644 --- a/project2/sqlRows.h +++ b/project2/sqlRows.h @@ -25,7 +25,7 @@ class SqlRows : public RowSet {  		bool isNull(unsigned int col) const;  		bool isNull(const Glib::ustring & id) const; -		const std::string dataSource; +		const Variable dataSource;  	private:  		class SqlWriter; diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp index d5810be..3c54660 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -5,6 +5,7 @@  #include "rdbmsDataSource.h"  #include "commonObjects.h"  #include "sqlVariableBinder.h" +#include "genericVisitor.h"  ElementLoaderImpl<SqlTask> sqltaskLoader("sqltask"); @@ -12,7 +13,7 @@ SqlTask::SqlTask(const xmlpp::Element * p) :  	SourceObject(p),  	Task(p),  	IHaveParameters(p), -	dataSource(p->get_attribute_value("datasource")), +	dataSource(p, "datasource"),  	sql(xmlChildText(p, "sql")),  	modify(NULL)  { @@ -26,7 +27,8 @@ SqlTask::~SqlTask()  void  SqlTask::loadComplete(const CommonObjects * co)  { -	modify = new ODBC::ModifyCommand(co->dataSource<RdbmsDataSource>(dataSource)->getWritable(), sql); +	modify = new ODBC::ModifyCommand(LexicalCall<std::string, const RdbmsDataSource *>(boost::bind( +					&CommonObjects::dataSource<RdbmsDataSource>, co, _1), dataSource)->getWritable(), sql);  }  void diff --git a/project2/sqlTask.h b/project2/sqlTask.h index 3cd93c6..6432022 100644 --- a/project2/sqlTask.h +++ b/project2/sqlTask.h @@ -16,7 +16,7 @@ class SqlTask : public Task, public IHaveParameters {  		virtual void loadComplete(const CommonObjects *);  		virtual void execute() const; -		const std::string dataSource; +		const Variable dataSource;  		const std::string sql;  	protected:  		mutable ODBC::ModifyCommand * modify; diff --git a/project2/variables.cpp b/project2/variables.cpp index 130d210..20b4fa2 100644 --- a/project2/variables.cpp +++ b/project2/variables.cpp @@ -252,6 +252,25 @@ class VariableFixed : public VariableImpl {  		VariableType var;  }; +class VariableConfig : public VariableImplDyn { +	public: +		VariableConfig(const xmlpp::Element * e) : +			VariableImplDyn(e), +			name(e->get_attribute_value("name")) +		{ +		} +		const VariableType & value() const +		{ +			if (!cacheValid) { +				cache = ApplicationEngine::getCurrent()->getCurrentConfig()->getValue(name); +				cacheValid = true; +			} +			return cache; +		} +	private: +		const Glib::ustring name; +}; +  Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool required, VariableType def)  {  	xmlpp::Attribute * a = e->get_attribute(n); @@ -272,6 +291,8 @@ Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool requi  				var = new VariableUri(c);  			else if (source == "param")  				var = new VariableParam(c); +			else if (source == "config") +				var = new VariableConfig(c);  			else if (source == "literal" || source.empty())  				var = new VariableLiteral(c->get_attribute_value("value"), c->get_attribute_value("type"));  			else | 
