summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/SqlDB/SqlDB.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2009-10-07 18:18:37 +0200
committerBenoit Foucher <benoit@zeroc.com>2009-10-07 18:18:37 +0200
commit5fc2dc27228263e4c56ba3a49852ab3f8c724299 (patch)
treea1340491094705a1e604a3df22ec4dad0c8d1a8e /cpp/src/IceGrid/SqlDB/SqlDB.cpp
parentBug 4251 - add IceUtil::Time double initializers (diff)
downloadice-5fc2dc27228263e4c56ba3a49852ab3f8c724299.tar.bz2
ice-5fc2dc27228263e4c56ba3a49852ab3f8c724299.tar.xz
ice-5fc2dc27228263e4c56ba3a49852ab3f8c724299.zip
- Bug 4286: added support for IceStorm/IceGrid database plugins
- Fixed IceGrid database code to first save to the database and then do state changes.
Diffstat (limited to 'cpp/src/IceGrid/SqlDB/SqlDB.cpp')
-rw-r--r--cpp/src/IceGrid/SqlDB/SqlDB.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/SqlDB/SqlDB.cpp b/cpp/src/IceGrid/SqlDB/SqlDB.cpp
new file mode 100644
index 00000000000..058783fc684
--- /dev/null
+++ b/cpp/src/IceGrid/SqlDB/SqlDB.cpp
@@ -0,0 +1,260 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/ArgVector.h>
+#include <Ice/Communicator.h>
+#include <Ice/Locator.h>
+#include <Ice/Instance.h>
+#include <IceDB/SqlTypes.h>
+#include <IceGrid/SqlDB/SqlDB.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTextCodec>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# ifdef _MSC_VER
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+# define S_ISREG(mode) ((mode) & _S_IFREG)
+# endif
+#else
+# include <unistd.h>
+#endif
+
+using namespace IceGrid;
+using namespace std;
+
+extern "C"
+{
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createSqlDB(const Ice::CommunicatorPtr& communicator, const string& name, const Ice::StringSeq& args)
+{
+ IceUtilInternal::ArgVector av(args);
+ return new IceGrid::SqlDBPlugin(communicator, av.argc, av.argv);
+}
+
+}
+
+namespace
+{
+
+//
+// SQL wrappers for SQL tables
+//
+
+class SqlApplicationsWrapper : public SqlDB::Wrapper<SqlStringApplicationInfoDict, std::string, ApplicationInfo>,
+ public ApplicationsWrapper
+{
+public:
+
+ SqlApplicationsWrapper(const SqlDB::DatabaseConnectionPtr& con, const SqlStringApplicationInfoDictPtr& table) :
+ SqlDB::Wrapper<SqlStringApplicationInfoDict, std::string, ApplicationInfo>(con, table)
+ {
+ }
+};
+
+class SqlAdaptersWrapper : public SqlDB::Wrapper<SqlStringAdapterInfoDict, std::string, AdapterInfo>,
+ public AdaptersWrapper
+{
+public:
+
+ SqlAdaptersWrapper(const SqlDB::DatabaseConnectionPtr& connection, const SqlStringAdapterInfoDictPtr& table) :
+ SqlDB::Wrapper<SqlStringAdapterInfoDict, std::string, AdapterInfo>(connection, table)
+ {
+ }
+
+ virtual std::vector<AdapterInfo>
+ findByReplicaGroupId(const std::string& name)
+ {
+ return _table->findByReplicaGroupId(_connection, name);
+ }
+};
+
+class SqlObjectsWrapper : public SqlDB::Wrapper<SqlIdentityObjectInfoDict, Ice::Identity, ObjectInfo>,
+ public ObjectsWrapper
+{
+public:
+
+ SqlObjectsWrapper(const SqlDB::DatabaseConnectionPtr& connection, const SqlIdentityObjectInfoDictPtr& table) :
+ SqlDB::Wrapper<SqlIdentityObjectInfoDict, Ice::Identity, ObjectInfo>(connection, table)
+ {
+ }
+
+ virtual std::vector<ObjectInfo>
+ findByType(const std::string& type)
+ {
+ return _table->findByType(_connection, type);
+ }
+};
+
+}
+
+SqlDatabaseCache::SqlDatabaseCache(const Ice::CommunicatorPtr& communicator,
+ const string& databaseType,
+ const string& databaseName,
+ const string& hostname,
+ const string& username,
+ const string& password,
+ const string& tablePrefix) :
+ SqlDB::DatabaseCache(communicator, databaseType, databaseName, hostname, username, password, true)
+{
+ IceDB::DatabaseConnectionPtr connection = getConnection();
+ IceDB::TransactionHolder txn(connection);
+
+ SqlDB::DatabaseConnectionPtr c = SqlDB::DatabaseConnectionPtr::dynamicCast(connection.get());
+
+ const_cast<SqlStringApplicationInfoDictPtr&>(_applications) =
+ new SqlStringApplicationInfoDict(c, tablePrefix + "Applications", communicator);
+ const_cast<SqlStringAdapterInfoDictPtr&>(_adapters) =
+ new SqlStringAdapterInfoDict(c, tablePrefix + "Adapters", communicator);
+ const_cast<SqlIdentityObjectInfoDictPtr&>(_objects) =
+ new SqlIdentityObjectInfoDict(c, tablePrefix + "Objects", communicator);
+ const_cast<SqlIdentityObjectInfoDictPtr&>(_internalObjects) =
+ new SqlIdentityObjectInfoDict(c, tablePrefix + "InternalObjects", communicator);
+
+ txn.commit();
+}
+
+SqlDatabaseCache::~SqlDatabaseCache()
+{
+}
+
+ApplicationsWrapperPtr
+SqlDatabaseCache::getApplications(const IceDB::DatabaseConnectionPtr& connection)
+{
+ return new SqlApplicationsWrapper(SqlDB::DatabaseConnectionPtr::dynamicCast(connection.get()), _applications);
+}
+
+AdaptersWrapperPtr
+SqlDatabaseCache::getAdapters(const IceDB::DatabaseConnectionPtr& connection)
+{
+ return new SqlAdaptersWrapper(SqlDB::DatabaseConnectionPtr::dynamicCast(connection.get()), _adapters);
+}
+
+ObjectsWrapperPtr
+SqlDatabaseCache::getObjects(const IceDB::DatabaseConnectionPtr& connection)
+{
+ return new SqlObjectsWrapper(SqlDB::DatabaseConnectionPtr::dynamicCast(connection.get()), _objects);
+}
+
+ObjectsWrapperPtr
+SqlDatabaseCache::getInternalObjects(const IceDB::DatabaseConnectionPtr& connection)
+{
+ return new SqlObjectsWrapper(SqlDB::DatabaseConnectionPtr::dynamicCast(connection.get()), _internalObjects);
+}
+
+SqlDBPlugin::SqlDBPlugin(const Ice::CommunicatorPtr& communicator, int argc, char** argv) :
+ _communicator(communicator), _qtApp(0)
+{
+ if(QCoreApplication::instance() == 0)
+ {
+ _qtApp = new QCoreApplication(argc, argv);
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+ }
+
+ Ice::PluginPtr(new Ice::ThreadHookPlugin(_communicator, new SqlDB::ThreadHook()));
+}
+
+SqlDBPlugin::~SqlDBPlugin()
+{
+ if(_qtApp != 0)
+ {
+ delete _qtApp;
+ _qtApp = 0;
+ }
+}
+
+void
+SqlDBPlugin::initialize()
+{
+ Ice::PropertiesPtr properties = _communicator->getProperties();
+ string databaseName;
+ string tablePrefix;
+ if(properties->getProperty("IceGrid.SQL.DatabaseType") == "QSQLITE")
+ {
+ string dbPath = properties->getProperty("IceGrid.Registry.Data");
+ if(dbPath.empty())
+ {
+ throw Ice::PluginInitializationException(__FILE__, __LINE__, "property `IceGrid.Registry.Data' is not set");
+ }
+ else
+ {
+ struct stat filestat;
+ if(stat(dbPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
+ {
+ ostringstream os;
+ Ice::SyscallException ex(__FILE__, __LINE__);
+ ex.error = IceInternal::getSystemErrno();
+ os << "property `IceGrid.Registry.Data' is set to an invalid path:\n" << ex;
+ throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str());
+ }
+ }
+ databaseName = dbPath + "/" + properties->getPropertyWithDefault("IceGrid.SQL.DatabaseName", "registry.db");
+ }
+ else
+ {
+ databaseName = properties->getProperty("IceGrid.SQL.DatabaseName");
+
+ string replicaName = properties->getPropertyWithDefault("IceGrid.Registry.ReplicaName", "Master");
+ string instanceName;
+ if(_communicator->getDefaultLocator())
+ {
+ instanceName = _communicator->getDefaultLocator()->ice_getIdentity().category;
+ }
+ else
+ {
+ instanceName = properties->getPropertyWithDefault("IceGrid.InstanceName", "IceGrid");
+ }
+
+ tablePrefix = instanceName + "_" + replicaName + "_";
+
+ replace(tablePrefix.begin(), tablePrefix.end(), '.', '_');
+ replace(tablePrefix.begin(), tablePrefix.end(), '-', '_');
+ replace(tablePrefix.begin(), tablePrefix.end(), ' ', '_');
+ replace(tablePrefix.begin(), tablePrefix.end(), ';', '_');
+ }
+
+ _databaseCache = new SqlDatabaseCache(_communicator,
+ properties->getProperty("IceGrid.SQL.DatabaseType"),
+ databaseName,
+ properties->getProperty("IceGrid.SQL.HostName"),
+ properties->getProperty("IceGrid.SQL.UserName"),
+ properties->getProperty("IceGrid.SQL.Password"),
+ tablePrefix);
+
+ SqlDB::ThreadHookPtr threadHook =
+ SqlDB::ThreadHookPtr::dynamicCast(IceInternal::getInstance(_communicator)->initializationData().threadHook);
+ assert(threadHook);
+ threadHook->setDatabaseCache(_databaseCache);
+}
+
+void
+SqlDBPlugin::destroy()
+{
+ //
+ // Break cyclic reference count (thread hook holds a reference on the cache and the cache holds
+ // a reference on the communicator through the SQL dictionaries).
+ //
+ SqlDB::ThreadHookPtr threadHook =
+ SqlDB::ThreadHookPtr::dynamicCast(IceInternal::getInstance(_communicator)->initializationData().threadHook);
+ assert(threadHook);
+ threadHook->setDatabaseCache(0);
+
+ _databaseCache = 0;
+}
+
+DatabaseCachePtr
+SqlDBPlugin::getDatabaseCache()
+{
+ return _databaseCache;
+}