/* * Copyright (C) 2009 Emweb bvba, Kessel-Lo, Belgium. * * See the LICENSE file for terms of use. */ #ifdef WTDBO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //Post directives class Configuration; class ConfigurationBool; class ConfigurationDouble; class ConfigurationFloat; class ConfigurationInt; class ConfigurationString; //Configuration Keys structure struct ConfigurationKeys { std::string Name; std::string Application; ConfigurationKeys(); ConfigurationKeys(std::string Name, std::string Application); bool operator< (const ConfigurationKeys& other) const; bool operator== (const ConfigurationKeys& other) const; }; //Overloaded operator<< for Configuration Keys structure std::ostream& operator<< (std::ostream& o, const ConfigurationKeys& c); namespace Wt { namespace Dbo { //Overloaded Wt::Dbo::field() for Configuration Keys structure template void field(Action& action, ConfigurationKeys& Keys, const std::string& name, int size = -1) { field(action, Keys.Name, "Name", 255); field(action, Keys.Application, "Application", 255); } //Overloaded dbo_traits for Configuration DBO template<> struct dbo_traits<::Configuration> : public dbo_default_traits { typedef ConfigurationKeys IdType; static IdType invalidId(); static const char *surrogateIdField(); }; //Overloaded dbo_traits for ConfigurationBool DBO template<> struct dbo_traits : public dbo_default_traits { static const char *surrogateIdField(); }; //Overloaded dbo_traits for ConfigurationDouble DBO template<> struct dbo_traits : public dbo_default_traits { static const char *surrogateIdField(); }; //Overloaded dbo_traits for ConfigurationFloat DBO template<> struct dbo_traits : public dbo_default_traits { static const char *surrogateIdField(); }; //Overloaded dbo_traits for ConfigurationInt DBO template<> struct dbo_traits : public dbo_default_traits { static const char *surrogateIdField(); }; //Overloaded dbo_traits for ConfigurationString DBO template<> struct dbo_traits : public dbo_default_traits { static const char *surrogateIdField(); }; } }; //Configuration DBO class class Configuration { public: enum ValueTypes { Bool = 0, Double = 1, Float = 2, Int = 3, String = 4, }; //hasMany relations Wt::Dbo::collection< Wt::Dbo::ptr > ConfigurationBoolDbo; Wt::Dbo::collection< Wt::Dbo::ptr > ConfigurationDoubleDbo; Wt::Dbo::collection< Wt::Dbo::ptr > ConfigurationFloatDbo; Wt::Dbo::collection< Wt::Dbo::ptr > ConfigurationIntDbo; Wt::Dbo::collection< Wt::Dbo::ptr > ConfigurationStringDbo; //Fields ConfigurationKeys Id; std::string Title; ValueTypes Type; boost::optional Details; //Persistence Method template void persist(Action& a) { Wt::Dbo::id(a, Id, "Id"); Wt::Dbo::field(a, Title, "Title"); Wt::Dbo::field(a, Type, "Type"); Wt::Dbo::field(a, Details, "Details"); Wt::Dbo::hasMany(a, ConfigurationBoolDbo, Wt::Dbo::ManyToOne, "Configuration"); Wt::Dbo::hasMany(a, ConfigurationDoubleDbo, Wt::Dbo::ManyToOne, "Configuration"); Wt::Dbo::hasMany(a, ConfigurationFloatDbo, Wt::Dbo::ManyToOne, "Configuration"); Wt::Dbo::hasMany(a, ConfigurationIntDbo, Wt::Dbo::ManyToOne, "Configuration"); Wt::Dbo::hasMany(a, ConfigurationStringDbo, Wt::Dbo::ManyToOne, "Configuration"); } }; //ConfigurationBool DBO Class class ConfigurationBool { public: //belongsTo Wt::Dbo::ptr ConfigurationDbo; bool Value; templatevoid persist(Action& a) { Wt::Dbo::field(a, Value, "Value"); Wt::Dbo::belongsTo(a, ConfigurationDbo, "Configuration", Wt::Dbo::OnUpdateCascade | Wt::Dbo::OnDeleteCascade); } }; //ConfigurationDouble DBO Class class ConfigurationDouble { public: //belongsTo Wt::Dbo::ptr ConfigurationDbo; double Value; templatevoid persist(Action& a) { Wt::Dbo::field(a, Value, "Value"); Wt::Dbo::belongsTo(a, ConfigurationDbo, "Configuration", Wt::Dbo::OnUpdateCascade | Wt::Dbo::OnDeleteCascade); } }; //ConfigurationFloat DBO Class class ConfigurationFloat { public: //belongsTo Wt::Dbo::ptr ConfigurationDbo; float Value; templatevoid persist(Action& a) { Wt::Dbo::field(a, Value, "Value"); Wt::Dbo::belongsTo(a, ConfigurationDbo, "Configuration", Wt::Dbo::OnUpdateCascade | Wt::Dbo::OnDeleteCascade); } }; //ConfigurationInt DBO Class class ConfigurationInt { public: //belongsTo Wt::Dbo::ptr ConfigurationDbo; int Value; templatevoid persist(Action& a) { Wt::Dbo::field(a, Value, "Value"); Wt::Dbo::belongsTo(a, ConfigurationDbo, "Configuration", Wt::Dbo::OnUpdateCascade | Wt::Dbo::OnDeleteCascade); } }; //ConfigurationString DBO Class class ConfigurationString { public: //belongsTo Wt::Dbo::ptr ConfigurationDbo; boost::optional Value; templatevoid persist(Action& a) { Wt::Dbo::field(a, Value, "Value"); Wt::Dbo::belongsTo(a, ConfigurationDbo, "Configuration", Wt::Dbo::OnUpdateCascade | Wt::Dbo::OnDeleteCascade); } }; //Configuration Keys ConfigurationKeys::ConfigurationKeys() : Name(std::string()), Application(std::string()) { } ConfigurationKeys::ConfigurationKeys(std::string Name, std::string Application) : Name(Name), Application(Application) { } bool ConfigurationKeys::operator== (const ConfigurationKeys& other) const { return Name == other.Name && Application == other.Application; } bool ConfigurationKeys::operator< (const ConfigurationKeys& other) const { if(Application < other.Application) { return true; } else if(Name == other.Name) { return Name < other.Name; } else { return false; } } std::ostream& operator<< (std::ostream& o, const ConfigurationKeys& c) { return o << "(" << c.Name << ", " << c.Application << ")"; } //Overloaded dbo_trait for Configuration DBO Wt::Dbo::dbo_traits::IdType Wt::Dbo::dbo_traits::invalidId() { return Wt::Dbo::dbo_traits::IdType(); } const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } //Remove ID field from Configuration related DBOs const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } const char* Wt::Dbo::dbo_traits::surrogateIdField() { return 0; } class Configurations; //SQL Connection Wt::Dbo::FixedSqlConnectionPool *SQLPool; //Global Configurations Configurations *Config; class Configurations { public: typedef boost::unordered_map< const std::string, boost::unordered_map< const std::string, Wt::Dbo::ptr > > ConfigurationBoolMaps; typedef boost::unordered_map< const std::string, boost::unordered_map< const std::string, Wt::Dbo::ptr > > ConfigurationDoubleMaps; typedef boost::unordered_map< const std::string, boost::unordered_map< const std::string, Wt::Dbo::ptr > > ConfigurationFloatMaps; typedef boost::unordered_map< const std::string, boost::unordered_map< const std::string, Wt::Dbo::ptr > > ConfigurationIntMaps; typedef boost::unordered_map< const std::string, boost::unordered_map< const std::string, Wt::Dbo::ptr > > ConfigurationStringMaps; typedef boost::tuple< Wt::Dbo::ptr, Wt::Dbo::ptr > ConfigurationBoolTuples; typedef boost::tuple< Wt::Dbo::ptr, Wt::Dbo::ptr > ConfigurationDoubleTuples; typedef boost::tuple< Wt::Dbo::ptr, Wt::Dbo::ptr > ConfigurationFloatTuples; typedef boost::tuple< Wt::Dbo::ptr, Wt::Dbo::ptr > ConfigurationIntTuples; typedef boost::tuple< Wt::Dbo::ptr, Wt::Dbo::ptr > ConfigurationStringTuples; Configurations(); void Install(); void Uninstall(); void FetchAll(); template bool GetBool(const std::string& Name, const std::string& Application, Source Default); bool GetBool(const std::string& Name, const std::string& Application, bool Default = false); template double GetDouble(const std::string& Name, const std::string& Application, Source Default); double GetDouble(const std::string& Name, const std::string& Application, double Default = 0); template float GetFloat(const std::string& Name, const std::string& Application, Source Default); float GetFloat(const std::string& Name, const std::string& Application, float Default = 0); template int GetInt(const std::string& Name, const std::string& Application, Source Default); int GetInt(const std::string& Name, const std::string& Application, int Default = 0); template std::string GetStr(const std::string& Name, const std::string& Application, Source Default); std::string GetStr(const std::string& Name, const std::string& Application, std::string Default = ""); long long GetLoadDurationinMS() const; int GetConfigurationsCount() const; protected: ConfigurationBoolMaps ConfigurationBoolMap; ConfigurationDoubleMaps ConfigurationDoubleMap; ConfigurationFloatMaps ConfigurationFloatMap; ConfigurationIntMaps ConfigurationIntMap; ConfigurationStringMaps ConfigurationStringMap; boost::posix_time::time_duration LoadDuration; int ConfigurationsCount; private: mutable boost::shared_mutex mutex; Wt::Dbo::Session Session; Wt::Dbo::Query FetchBoolQuery; Wt::Dbo::Query FetchDoubleQuery; Wt::Dbo::Query FetchFloatQuery; Wt::Dbo::Query FetchIntQuery; Wt::Dbo::Query FetchStringQuery; }; #define READ_LOCK boost::shared_lock lock(mutex) #define WRITE_LOCK boost::lock_guard lock(mutex) Configurations::Configurations() { ConfigurationsCount = 0; LoadDuration = boost::posix_time::time_duration(0, 0, 0); Session.setConnectionPool(*SQLPool); //Map DBOs Session.mapClass("configuration"); Session.mapClass("configurationbool"); Session.mapClass("configurationdouble"); Session.mapClass("configurationfloat"); Session.mapClass("configurationint"); Session.mapClass("configurationstring"); //Define the query to fetch and join all rows FetchBoolQuery = Session.query(std::string("SELECT") + " \"configuration\", \"configurationbool\"" + " FROM \"configuration\"" + " LEFT JOIN \"configurationbool\" ON \"configuration\".\"Name\" = \"configurationbool\".\"Name\" AND \"configuration\".\"Application\" = \"configurationbool\".\"Application\" " + " WHERE \"configuration\".\"Type\" = 0"); FetchDoubleQuery = Session.query(std::string("SELECT") + " \"configuration\", \"configurationdouble\"" + " FROM \"configuration\"" + " LEFT JOIN \"configurationdouble\" ON \"configuration\".\"Name\" = \"configurationdouble\".\"Name\" AND \"configuration\".\"Application\" = \"configurationdouble\".\"Application\" " + " WHERE \"configuration\".\"Type\" = 1"); FetchFloatQuery = Session.query(std::string("SELECT") + " \"configuration\", \"configurationfloat\"" + " FROM \"configuration\"" + " LEFT JOIN \"configurationfloat\" ON \"configuration\".\"Name\" = \"configurationfloat\".\"Name\" AND \"configuration\".\"Application\" = \"configurationfloat\".\"Application\" " + " WHERE \"configuration\".\"Type\" = 2"); FetchIntQuery = Session.query(std::string("SELECT") + " \"configuration\", \"configurationint\"" + " FROM \"configuration\"" + " LEFT JOIN \"configurationint\" ON \"configuration\".\"Name\" = \"configurationint\".\"Name\" AND \"configuration\".\"Application\" = \"configurationint\".\"Application\" " + " WHERE \"configuration\".\"Type\" = 3"); FetchStringQuery = Session.query(std::string("SELECT") + " \"configuration\", \"configurationstring\"" + " FROM \"configuration\"" + " LEFT JOIN \"configurationstring\" ON \"configuration\".\"Name\" = \"configurationstring\".\"Name\" AND \"configuration\".\"Application\" = \"configurationstring\".\"Application\" " + " WHERE \"configuration\".\"Type\" = 4"); } void Configurations::Install() { Session.createTables(); Wt::Dbo::Transaction transaction(Session); //BaseURL Wt::Dbo::ptr BaseUrl = Session.add(new Configuration()); Wt::Dbo::ptr BaseUrlVal = Session.add(new ConfigurationString()); BaseUrl.modify()->Id.Name = "BaseURL"; BaseUrl.modify()->Id.Application = "Server"; BaseUrl.modify()->Title = "Base URL of the website"; BaseUrl.modify()->Type = Configuration::String; BaseUrl.modify()->Details = "This is the base URL that the user can see when browsing. For example, http://www.mywebsite.com/wt .\nThis field may be left empty."; BaseUrlVal.modify()->Value = ""; BaseUrl.modify()->ConfigurationStringDbo.insert(BaseUrlVal); //DosPuzzle Wt::Dbo::ptr DosPuzzle = Session.add(new Configuration()); Wt::Dbo::ptr DosPuzzleVal = Session.add(new ConfigurationBool()); DosPuzzle.modify()->Id.Name = "DosPuzzle"; DosPuzzle.modify()->Id.Application = "Server"; DosPuzzle.modify()->Title = "Denial-of-Service protection puzzle"; DosPuzzle.modify()->Type = Configuration::Bool; DosPuzzle.modify()->Details = "When enabled the server adds a puzzle to validate Ajax sessions in the first Ajax request. This is a simple measure which avoids Denial-of-Service attacks on Ajax sessions.\n\nDefault value: Off"; DosPuzzleVal.modify()->Value = false; DosPuzzle.modify()->ConfigurationBoolDbo.insert(DosPuzzleVal); //JavascriptDebug Wt::Dbo::ptr JavascriptDebug = Session.add(new Configuration()); Wt::Dbo::ptr JavascriptDebugVal = Session.add(new ConfigurationInt()); JavascriptDebug.modify()->Id.Name = "JavascriptDebug"; JavascriptDebug.modify()->Id.Application = "Server"; JavascriptDebug.modify()->Title = "Debug javascript mode"; JavascriptDebug.modify()->Type = Configuration::Int; JavascriptDebug.modify()->Details = "Enable this only if you are a developer and to debug javascript.\n\nPossible values:\n1 = (Off)JavaScript errors are caught and a simple error message is printed to indicate that something is terribly wrong(default, recommended)\n2 = (On)JavaScript errors are caught but also a stack trace is printed, useful for diagnosing a problem in production\n3 = (On)JavaScript errors are not caught but the browser built-in debug options are used"; JavascriptDebugVal.modify()->Value = 1; JavascriptDebug.modify()->ConfigurationIntDbo.insert(JavascriptDebugVal); //MaxRequestSize Wt::Dbo::ptr MaxRequestSize = Session.add(new Configuration()); Wt::Dbo::ptr MaxRequestSizeVal = Session.add(new ConfigurationInt()); MaxRequestSize.modify()->Id.Name = "MaxRequestSize"; MaxRequestSize.modify()->Id.Application = "Server"; MaxRequestSize.modify()->Title = "Max request size"; MaxRequestSize.modify()->Type = Configuration::Int; MaxRequestSize.modify()->Details = "Maximum request size in kilobytes. This has to be increased to allow uploading larger sized files."; MaxRequestSizeVal.modify()->Value = 128; MaxRequestSize.modify()->ConfigurationIntDbo.insert(MaxRequestSizeVal); //ReverseProxy Wt::Dbo::ptr ReverseProxy = Session.add(new Configuration()); Wt::Dbo::ptr ReverseProxyVal = Session.add(new ConfigurationBool()); ReverseProxy.modify()->Id.Name = "ReverseProxy"; ReverseProxy.modify()->Id.Application = "Server"; ReverseProxy.modify()->Title = "Behind reverse proxy"; ReverseProxy.modify()->Type = Configuration::Bool; ReverseProxy.modify()->Details = "Enable this if the server is behind a reverse proxy. If you do not know what this means then disable it.\n\nDefault Value: Off"; ReverseProxyVal.modify()->Value = false; ReverseProxy.modify()->ConfigurationBoolDbo.insert(ReverseProxyVal); //SessionTimeout Wt::Dbo::ptr SessionTimeout = Session.add(new Configuration()); Wt::Dbo::ptr SessionTimeoutVal = Session.add(new ConfigurationInt()); SessionTimeout.modify()->Id.Name = "SessionTimeout"; SessionTimeout.modify()->Id.Application = "Server"; SessionTimeout.modify()->Title = "Session timeout delay"; SessionTimeout.modify()->Type = Configuration::Int; SessionTimeout.modify()->Details = "Session timeout delay in seconds. When a session remains inactive for this amount of time, it will be cleaned up.\nRecommended value: 600 (1 minute)"; SessionTimeoutVal.modify()->Value = 600; SessionTimeout.modify()->ConfigurationIntDbo.insert(SessionTimeoutVal); //SessionTracking Wt::Dbo::ptr SessionTracking = Session.add(new Configuration()); Wt::Dbo::ptr SessionTrackingVal = Session.add(new ConfigurationInt()); SessionTracking.modify()->Id.Name = "SessionTracking"; SessionTracking.modify()->Id.Application = "Server"; SessionTracking.modify()->Title = "Session tracking strategy"; SessionTracking.modify()->Type = Configuration::Int; SessionTracking.modify()->Details = "Possible values:\n1 = Cookies are used if available, otherwise URL rewriting for tracking session(default)\n2 = Only URL rewriting for tracking session"; SessionTrackingVal.modify()->Value = 1; SessionTracking.modify()->ConfigurationIntDbo.insert(SessionTrackingVal); //LogDebugLevel Wt::Dbo::ptr LogDebugLevel = Session.add(new Configuration()); Wt::Dbo::ptr LogDebugLevelVal = Session.add(new ConfigurationBool()); LogDebugLevel.modify()->Id.Name = "LogDebugLevel"; LogDebugLevel.modify()->Id.Application = "Logging"; LogDebugLevel.modify()->Title = "Log debugging messages"; LogDebugLevel.modify()->Type = Configuration::Bool; LogDebugLevel.modify()->Details = "When enabled debugging events/messages will be included in the log file. These notices only gives information for developers and might not be meaningful to end users.\n\nRecommended Value: Off"; LogDebugLevelVal.modify()->Value = false; LogDebugLevel.modify()->ConfigurationBoolDbo.insert(LogDebugLevelVal); //LogDirectory Wt::Dbo::ptr LogDirectory = Session.add(new Configuration()); Wt::Dbo::ptr LogDirectoryVal = Session.add(new ConfigurationString()); LogDirectory.modify()->Id.Name = "LogDirectory"; LogDirectory.modify()->Id.Application = "Logging"; LogDirectory.modify()->Title = "Logging file directory"; LogDirectory.modify()->Type = Configuration::String; LogDirectory.modify()->Details = "Location to where the file in which logs will be created is. Can be a full path or even a relative path.\n\nWhen this is left empty, no log file will be created but disabling file logging is highly not recommended.\nDefault Value: ./logs"; LogDirectoryVal.modify()->Value = "./logs"; LogDirectory.modify()->ConfigurationStringDbo.insert(LogDirectoryVal); //LogErrorLevel Wt::Dbo::ptr LogErrorLevel = Session.add(new Configuration()); Wt::Dbo::ptr LogErrorLevelVal = Session.add(new ConfigurationBool()); LogErrorLevel.modify()->Id.Name = "LogErrorLevel"; LogErrorLevel.modify()->Id.Application = "Logging"; LogErrorLevel.modify()->Title = "Log error messages"; LogErrorLevel.modify()->Type = Configuration::Bool; LogErrorLevel.modify()->Details = "When enabled errors will be included in the log file. \n\nRecommended Value: On"; LogErrorLevelVal.modify()->Value = true; LogErrorLevel.modify()->ConfigurationBoolDbo.insert(LogErrorLevelVal); //LogInfoLevel Wt::Dbo::ptr LogInfoLevel = Session.add(new Configuration()); Wt::Dbo::ptr LogInfoLevelVal = Session.add(new ConfigurationBool()); LogInfoLevel.modify()->Id.Name = "LogInfoLevel"; LogInfoLevel.modify()->Id.Application = "Logging"; LogInfoLevel.modify()->Title = "Log informational notices"; LogInfoLevel.modify()->Type = Configuration::Bool; LogInfoLevel.modify()->Details = "When enabled informational notices will be included in the log file. These notices only gives information rather than reporting a warning or an error."; LogInfoLevelVal.modify()->Value = false; LogInfoLevel.modify()->ConfigurationBoolDbo.insert(LogInfoLevelVal); //LogSecureLevel Wt::Dbo::ptr LogSecureLevel = Session.add(new Configuration()); Wt::Dbo::ptr LogSecureLevelVal = Session.add(new ConfigurationBool()); LogSecureLevel.modify()->Id.Name = "LogSecureLevel"; LogSecureLevel.modify()->Id.Application = "Logging"; LogSecureLevel.modify()->Title = "Log security events"; LogSecureLevel.modify()->Type = Configuration::Bool; LogSecureLevel.modify()->Details = "When enabled security related messages will be included in the log file.\n\nRecommended Value: On"; LogSecureLevelVal.modify()->Value = true; LogSecureLevel.modify()->ConfigurationBoolDbo.insert(LogInfoLevelVal); //LogWarnLevel Wt::Dbo::ptr LogWarnLevel = Session.add(new Configuration()); Wt::Dbo::ptr LogWarnLevelVal = Session.add(new ConfigurationBool()); LogWarnLevel.modify()->Id.Name = "LogWarnLevel"; LogWarnLevel.modify()->Id.Application = "Logging"; LogWarnLevel.modify()->Title = "Log warnings"; LogWarnLevel.modify()->Type = Configuration::Bool; LogWarnLevel.modify()->Details = "When enabled warnings will be included in the log file. These warnings indicate that there was something could have caused an error and should be considered.\n\nRecommended Value: On"; LogWarnLevelVal.modify()->Value = true; LogWarnLevel.modify()->ConfigurationBoolDbo.insert(LogWarnLevelVal); try { transaction.commit(); } catch(Wt::Dbo::Exception& e) { throw e; } } void Configurations::Uninstall() { try { Session.dropTables(); } catch(Wt::Dbo::Exception& e) { throw e; } } void Configurations::FetchAll() { WRITE_LOCK; //Time at start boost::posix_time::ptime PTStart = boost::posix_time::microsec_clock::local_time(); Wt::Dbo::Transaction transaction(Session); try { ConfigurationsCount = 0; typedef Wt::Dbo::collection< ConfigurationBoolTuples > BoolCollections; typedef Wt::Dbo::collection< ConfigurationDoubleTuples > DoubleCollections; typedef Wt::Dbo::collection< ConfigurationFloatTuples > FloatCollections; typedef Wt::Dbo::collection< ConfigurationIntTuples > IntCollections; typedef Wt::Dbo::collection< ConfigurationStringTuples > StringCollections; BoolCollections BoolCollection; DoubleCollections DoubleCollection; FloatCollections FloatCollection; IntCollections IntCollection; StringCollections StringCollection; //Fetch em all Wt::Dbo::Transaction transaction(Session); BoolCollection = FetchBoolQuery.resultList(); for(BoolCollections::const_iterator itr = BoolCollection.begin(); itr != BoolCollection.end(); itr++, ConfigurationsCount++) { std::cerr << itr->get<0>()->Id.Name << std::endl; ConfigurationBoolMap[itr->get<0>()->Id.Application][itr->get<0>()->Id.Name] = itr->get<1>(); } DoubleCollection = FetchDoubleQuery.resultList(); for(DoubleCollections::const_iterator itr = DoubleCollection.begin(); itr != DoubleCollection.end(); itr++, ConfigurationsCount++) { std::cerr << itr->get<0>()->Id.Name << std::endl; ConfigurationDoubleMap[itr->get<0>()->Id.Application][itr->get<0>()->Id.Name] = itr->get<1>(); } FloatCollection = FetchFloatQuery.resultList(); for(FloatCollections::const_iterator itr = FloatCollection.begin(); itr != FloatCollection.end(); itr++, ConfigurationsCount++) { std::cerr << itr->get<0>()->Id.Name << std::endl; ConfigurationFloatMap[itr->get<0>()->Id.Application][itr->get<0>()->Id.Name] = itr->get<1>(); } IntCollection = FetchIntQuery.resultList(); for(IntCollections::const_iterator itr = IntCollection.begin(); itr != IntCollection.end(); itr++, ConfigurationsCount++) { std::cerr << itr->get<0>()->Id.Name << std::endl; ConfigurationIntMap[itr->get<0>()->Id.Application][itr->get<0>()->Id.Name] = itr->get<1>(); } StringCollection = FetchStringQuery.resultList(); for(StringCollections::const_iterator itr = StringCollection.begin(); itr != StringCollection.end(); itr++, ConfigurationsCount++) { std::cerr << itr->get<0>()->Id.Name << std::endl; ConfigurationStringMap[itr->get<0>()->Id.Application][itr->get<0>()->Id.Name] = itr->get<1>(); } transaction.commit(); } catch(Wt::Dbo::Exception& e) { throw e; } //Time at end boost::posix_time::ptime PTEnd = boost::posix_time::microsec_clock::local_time(); LoadDuration = boost::posix_time::time_duration(PTEnd - PTStart); } //Boolean getter template<> bool Configurations::GetBool(const std::string& Name, const std::string& Application, bool Default) { READ_LOCK; return ConfigurationBoolMap[Application][Name] ? ConfigurationBoolMap[Application][Name]->Value : Default; } //Double getter template<> double Configurations::GetDouble(const std::string& Name, const std::string& Application, double Default) { READ_LOCK; return ConfigurationDoubleMap[Application][Name] ? ConfigurationDoubleMap[Application][Name]->Value : Default; } //Float getter template<> float Configurations::GetFloat(const std::string& Name, const std::string& Application, float Default) { READ_LOCK; return ConfigurationFloatMap[Application][Name] ? ConfigurationFloatMap[Application][Name]->Value : Default; } //Integer getter template<> int Configurations::GetInt(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; return ConfigurationIntMap[Application][Name] ? ConfigurationIntMap[Application][Name]->Value : Default; } //String getter template<> std::string Configurations::GetStr(const std::string& Name, const std::string& Application, std::string Default) { READ_LOCK; if(!ConfigurationStringMap[Application][Name]) { return Default; } if(!ConfigurationStringMap[Application][Name]->Value.is_initialized()) { return ""; } return *ConfigurationStringMap[Application][Name]->Value; } //Boolean alternative source getters template<> bool Configurations::GetBool(const std::string& Name, const std::string& Application, double Default) { READ_LOCK; return GetDouble(Name, Application, Default) > 0; } template<> bool Configurations::GetBool(const std::string& Name, const std::string& Application, float Default) { READ_LOCK; return GetFloat(Name, Application, Default) > 0; } template<> bool Configurations::GetBool(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; return GetInt(Name, Application, Default) > 0; } template<> bool Configurations::GetBool(const std::string& Name, const std::string& Application, std::string Default) { READ_LOCK; return ConfigurationStringMap[Application][Name]; } bool Configurations::GetBool(const std::string& Name, const std::string& Application, bool Default) { READ_LOCK; return GetBool(Name, Application, Default); } //Double alternative source getters template<> double Configurations::GetDouble(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; return (double)GetInt(Name, Application, Default); } double Configurations::GetDouble(const std::string& Name, const std::string& Application, double Default) { READ_LOCK; return GetDouble(Name, Application, Default); } //Float alternative source getters template<> float Configurations::GetFloat(const std::string& Name, const std::string& Application, double Default) { READ_LOCK; return (float)GetDouble(Name, Application, Default); } template<> float Configurations::GetFloat(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; return (float)GetInt(Name, Application, Default); } float Configurations::GetFloat(const std::string& Name, const std::string& Application, float Default) { READ_LOCK; return GetFloat(Name, Application, Default); } //Integer alternative source getters template<> int Configurations::GetInt(const std::string& Name, const std::string& Application, bool Default) { READ_LOCK; return GetBool(Name, Application, Default) ? 1 : 0; } int Configurations::GetInt(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; return GetInt(Name, Application, Default); } //String alternative source getters template<> std::string Configurations::GetStr(const std::string& Name, const std::string& Application, double Default) { READ_LOCK; std::ostringstream ss; ss << GetDouble(Name, Application, Default); return ss.str(); } template<> std::string Configurations::GetStr(const std::string& Name, const std::string& Application, float Default) { READ_LOCK; std::ostringstream ss; ss << GetFloat(Name, Application, Default); return ss.str(); } template<> std::string Configurations::GetStr(const std::string& Name, const std::string& Application, int Default) { READ_LOCK; std::ostringstream ss; ss << GetInt(Name, Application, Default); return ss.str(); } std::string Configurations::GetStr(const std::string& Name, const std::string& Application, std::string Default) { READ_LOCK; return GetStr(Name, Application, Default); } long long Configurations::GetLoadDurationinMS() const { READ_LOCK; return LoadDuration.total_milliseconds(); } int Configurations::GetConfigurationsCount() const { READ_LOCK; return ConfigurationsCount; } BOOST_AUTO_TEST_CASE( dbo_test1 ) { //Loading Start Time boost::posix_time::ptime PTStart = boost::posix_time::microsec_clock::local_time(); //Create starting logger Wt::WLogger StartLogger; StartLogger.configure("* -debug"); StartLogger.addField("datetime", false); StartLogger.addField("type", false); StartLogger.addField("message", true); StartLogger.entry("info"); StartLogger.entry("info") << Wt::WLogger::timestamp << Wt::WLogger::sep << '[' << "notice" << ']' << Wt::WLogger::sep << "Starting up server!"; /* ************************************************************************* * ************************ Initialize Database ************************** * *************************************************************************/ //Start SQL Connection try { //Wt::Dbo::SqlConnection *SQLConnection = new Wt::Dbo::backend::MySQL("wt", "root", "root", "127.0.0.1"); Wt::Dbo::SqlConnection *SQLConnection = new Wt::Dbo::backend::Sqlite3(":memory:"); SQLConnection->setProperty("show-queries", "true"); SQLPool = new Wt::Dbo::FixedSqlConnectionPool(SQLConnection, 1); } catch(Wt::Dbo::Exception& e) { StartLogger.entry("fatal") << Wt::WLogger::timestamp << Wt::WLogger::sep << '[' << "fatal error" << ']' << Wt::WLogger::sep << e.what(); exit(EXIT_FAILURE); } catch(std::exception &e) { StartLogger.entry("fatal") << Wt::WLogger::timestamp << Wt::WLogger::sep << '[' << "fatal error" << ']' << Wt::WLogger::sep << e.what(); exit(EXIT_FAILURE); } /* ************************************************************************* * ************************ Load Configurations ************************** * *************************************************************************/ Config = new Configurations; try { //Config->Uninstall(); Config->Install(); Config->FetchAll(); } catch(Wt::Dbo::Exception& e) { std::cerr << e.what(); //test } StartLogger.entry("info") << Wt::WLogger::timestamp << Wt::WLogger::sep << '[' << "notice" << ']' << Wt::WLogger::sep << Config->GetConfigurationsCount() << " Configurations Loaded in " << Config->GetLoadDurationinMS() << " Ms"; //Deallocate delete Config; delete SQLPool; //Also deletes SQLConnection } #endif