Fixes #552 - Don't try to use DBs with a too new schema version
authorMarcus Eggenberger <egs@quassel-irc.org>
Fri, 13 Feb 2009 13:41:47 +0000 (14:41 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Fri, 13 Feb 2009 13:41:47 +0000 (14:41 +0100)
src/core/abstractsqlstorage.cpp
src/core/abstractsqlstorage.h
src/core/core.cpp
src/core/core.h
src/core/storage.h

index c2d5e98..7e5dee5 100644 (file)
@@ -83,36 +83,39 @@ void AbstractSqlStorage::addConnectionToPool() {
   }
 }
 
   }
 }
 
-bool AbstractSqlStorage::init(const QVariantMap &settings) {
+Storage::State AbstractSqlStorage::init(const QVariantMap &settings) {
   Q_UNUSED(settings)
   Q_UNUSED(settings)
+
   QSqlDatabase db = logDb();
   if(!db.isValid() || !db.isOpen())
   QSqlDatabase db = logDb();
   if(!db.isValid() || !db.isOpen())
-    return false;
+    return NotAvailable;
 
   if(installedSchemaVersion() == -1) {
     qCritical() << "Storage Schema is missing!";
 
   if(installedSchemaVersion() == -1) {
     qCritical() << "Storage Schema is missing!";
-    return false;
+    return NeedsSetup;
   }
 
   if(installedSchemaVersion() > schemaVersion()) {
     qCritical() << "Installed Schema is newer then any known Version.";
   }
 
   if(installedSchemaVersion() > schemaVersion()) {
     qCritical() << "Installed Schema is newer then any known Version.";
-    return false;
+    return NotAvailable;
   }
   }
-  
+
   if(installedSchemaVersion() < schemaVersion()) {
     qWarning() << qPrintable(tr("Installed Schema (version %1) is not up to date. Upgrading to version %2...").arg(installedSchemaVersion()).arg(schemaVersion()));
   if(installedSchemaVersion() < schemaVersion()) {
     qWarning() << qPrintable(tr("Installed Schema (version %1) is not up to date. Upgrading to version %2...").arg(installedSchemaVersion()).arg(schemaVersion()));
-    if(!upgradeDb())
-      return false;
+    if(!upgradeDb()) {
+      qWarning() << qPrintable(tr("Upgrade failed..."));
+      return NotAvailable;
+    }
   }
   }
-  
+
   quInfo() << "Storage Backend is ready. Quassel Schema Version:" << installedSchemaVersion();
   quInfo() << "Storage Backend is ready. Quassel Schema Version:" << installedSchemaVersion();
-  return true;
+  return IsReady;
 }
 
 QString AbstractSqlStorage::queryString(const QString &queryName, int version) {
   if(version == 0)
     version = schemaVersion();
 }
 
 QString AbstractSqlStorage::queryString(const QString &queryName, int version) {
   if(version == 0)
     version = schemaVersion();
-    
+
   QFileInfo queryInfo(QString(":/SQL/%1/%2/%3.sql").arg(displayName()).arg(version).arg(queryName));
   if(!queryInfo.exists() || !queryInfo.isFile() || !queryInfo.isReadable()) {
     qCritical() << "Unable to read SQL-Query" << queryName << "for engine" << displayName();
   QFileInfo queryInfo(QString(":/SQL/%1/%2/%3.sql").arg(displayName()).arg(version).arg(queryName));
   if(!queryInfo.exists() || !queryInfo.isFile() || !queryInfo.isReadable()) {
     qCritical() << "Unable to read SQL-Query" << queryName << "for engine" << displayName();
@@ -124,7 +127,7 @@ QString AbstractSqlStorage::queryString(const QString &queryName, int version) {
     return QString();
   QString query = QTextStream(&queryFile).readAll();
   queryFile.close();
     return QString();
   QString query = QTextStream(&queryFile).readAll();
   queryFile.close();
-  
+
   return query.trimmed();
 }
 
   return query.trimmed();
 }
 
@@ -219,7 +222,7 @@ bool AbstractSqlStorage::watchQuery(QSqlQuery &query) {
     qCritical() << "               Error Message:"   << query.lastError().text();
     qCritical() << "              Driver Message:"   << query.lastError().driverText();
     qCritical() << "                  DB Message:"   << query.lastError().databaseText();
     qCritical() << "               Error Message:"   << query.lastError().text();
     qCritical() << "              Driver Message:"   << query.lastError().driverText();
     qCritical() << "                  DB Message:"   << query.lastError().databaseText();
-    
+
     return false;
   }
   return true;
     return false;
   }
   return true;
index e3a6481..e3b4ec4 100644 (file)
@@ -35,7 +35,7 @@ public:
   virtual ~AbstractSqlStorage();
 
 protected:
   virtual ~AbstractSqlStorage();
 
 protected:
-  virtual bool init(const QVariantMap &settings = QVariantMap());
+  virtual State init(const QVariantMap &settings = QVariantMap());
   inline virtual void sync() {};
   
   QSqlDatabase logDb();
   inline virtual void sync() {};
   
   QSqlDatabase logDb();
index aa1b7d4..e1a5360 100644 (file)
@@ -48,7 +48,9 @@ void Core::destroy() {
   instanceptr = 0;
 }
 
   instanceptr = 0;
 }
 
-Core::Core() : storage(0) {
+Core::Core()
+  : _storage(0)
+{
   _startTime = QDateTime::currentDateTime().toUTC();  // for uptime :)
 
   Quassel::loadTranslation(QLocale::system());
   _startTime = QDateTime::currentDateTime().toUTC();  // for uptime :)
 
   Quassel::loadTranslation(QLocale::system());
@@ -131,25 +133,23 @@ Core::Core() : storage(0) {
   // Register storage backends here!
   registerStorageBackend(new SqliteStorage(this));
 
   // Register storage backends here!
   registerStorageBackend(new SqliteStorage(this));
 
-  if(!_storageBackends.count()) {
-    qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting..."));
-    qWarning() << qPrintable(tr("Currently, Quassel only supports SQLite3. You need to build your\n"
-                                "Qt library with the sqlite plugin enabled in order for quasselcore\n"
-                                "to work."));
-    exit(1); // TODO make this less brutal (especially for mono client -> popup)
-  }
   connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
   _storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
 }
 
 void Core::init() {
   connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
   _storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
 }
 
 void Core::init() {
-  configured = false;
-
   CoreSettings cs;
   CoreSettings cs;
-
-  if(!(configured = initStorage(cs.storageSettings().toMap()))) {
+  _configured = initStorage(cs.storageSettings().toMap());
+
+  if(!_configured) {
+    if(!_storageBackends.count()) {
+      qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting..."));
+      qWarning() << qPrintable(tr("Currently, Quassel only supports SQLite3. You need to build your\n"
+                                 "Qt library with the sqlite plugin enabled in order for quasselcore\n"
+                                 "to work."));
+      exit(1); // TODO make this less brutal (especially for mono client -> popup)
+    }
     qWarning() << "Core is currently not configured! Please connect with a Quassel Client for basic setup.";
     qWarning() << "Core is currently not configured! Please connect with a Quassel Client for basic setup.";
-
   }
 
   connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
   }
 
   connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
@@ -178,7 +178,7 @@ void Core::saveState() {
 }
 
 void Core::restoreState() {
 }
 
 void Core::restoreState() {
-  if(!instance()->configured) {
+  if(!instance()->_configured) {
     // qWarning() << qPrintable(tr("Cannot restore a state for an unconfigured core!"));
     return;
   }
     // qWarning() << qPrintable(tr("Cannot restore a state for an unconfigured core!"));
     return;
   }
@@ -226,13 +226,14 @@ QString Core::setupCore(QVariantMap setupData) {
   if(user.isEmpty() || password.isEmpty()) {
     return tr("Admin user or password not set.");
   }
   if(user.isEmpty() || password.isEmpty()) {
     return tr("Admin user or password not set.");
   }
-  if(!initStorage(setupData, true)) {
+  _configured = initStorage(setupData, true);
+  if(!_configured) {
     return tr("Could not setup storage!");
   }
   CoreSettings s;
   s.setStorageSettings(setupData);
   quInfo() << qPrintable(tr("Creating admin user..."));
     return tr("Could not setup storage!");
   }
   CoreSettings s;
   s.setStorageSettings(setupData);
   quInfo() << qPrintable(tr("Creating admin user..."));
-  storage->addUser(user, password);
+  _storage->addUser(user, password);
   startListening();  // TODO check when we need this
   return QString();
 }
   startListening();  // TODO check when we need this
   return QString();
 }
@@ -257,42 +258,55 @@ void Core::unregisterStorageBackend(Storage *backend) {
 // old db settings:
 // "Type" => "sqlite"
 bool Core::initStorage(QVariantMap dbSettings, bool setup) {
 // old db settings:
 // "Type" => "sqlite"
 bool Core::initStorage(QVariantMap dbSettings, bool setup) {
+  _storage = 0;
+
   QString backend = dbSettings["Backend"].toString();
   if(backend.isEmpty()) {
   QString backend = dbSettings["Backend"].toString();
   if(backend.isEmpty()) {
-    //qWarning() << "No storage backend selected!";
-    return configured = false;
+    return false;
   }
 
   }
 
+  Storage *storage = 0;
   if(_storageBackends.contains(backend)) {
     storage = _storageBackends[backend];
   } else {
     qCritical() << "Selected storage backend is not available:" << backend;
   if(_storageBackends.contains(backend)) {
     storage = _storageBackends[backend];
   } else {
     qCritical() << "Selected storage backend is not available:" << backend;
-    return configured = false;
+    return false;
   }
   }
-  if(!storage->init(dbSettings)) {
-    if(!setup || !(storage->setup(dbSettings) && storage->init(dbSettings))) {
-      qCritical() << "Could not init storage!";
-      storage = 0;
-      return configured = false;
+
+  Storage::State storageState = storage->init(dbSettings);
+  switch(storageState) {
+  case Storage::NeedsSetup:
+    if(!setup)
+      return false; // trigger setup process
+    if(storage->setup(dbSettings))
+      return initStorage(dbSettings, false);
+    // if setup wasn't successfull we mark the backend as unavailable
+  case Storage::NotAvailable:
+    qCritical() << "Selected storage backend is not available:" << backend;
+    storage->deleteLater();
+    _storageBackends.remove(backend);
+    storage = 0;
+    return false;
+  case Storage::IsReady:
+    // delete all other backends
+    foreach(Storage *s, _storageBackends.values()) {
+      if(s != storage) s->deleteLater();
     }
     }
+    _storageBackends.clear();
+    connect(storage, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)), this, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)));
   }
   }
-  // delete all other backends
-  foreach(Storage *s, _storageBackends.values()) {
-    if(s != storage) s->deleteLater();
-  }
-  _storageBackends.clear();
-
-  connect(storage, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)), this, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)));
-  return configured = true;
+  _storage = storage;
+  return true;
 }
 
 void Core::syncStorage() {
 }
 
 void Core::syncStorage() {
-  if(storage) storage->sync();
+  if(_storage)
+    _storage->sync();
 }
 
 /*** Storage Access ***/
 bool Core::createNetwork(UserId user, NetworkInfo &info) {
 }
 
 /*** Storage Access ***/
 bool Core::createNetwork(UserId user, NetworkInfo &info) {
-  NetworkId networkId = instance()->storage->createNetwork(user, info);
+  NetworkId networkId = instance()->_storage->createNetwork(user, info);
   if(!networkId.isValid())
     return false;
 
   if(!networkId.isValid())
     return false;
 
@@ -405,7 +419,7 @@ void Core::incomingConnection() {
     blocksizes.insert(socket, (quint32)0);
     quInfo() << qPrintable(tr("Client connected from"))  << qPrintable(socket->peerAddress().toString());
 
     blocksizes.insert(socket, (quint32)0);
     quInfo() << qPrintable(tr("Client connected from"))  << qPrintable(socket->peerAddress().toString());
 
-    if(!configured) {
+    if(!_configured) {
       stopListening(tr("Closing server for basic setup."));
     }
   }
       stopListening(tr("Closing server for basic setup."));
     }
   }
@@ -480,7 +494,7 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) {
     reply["LoginEnabled"] = true;
 
     // check if we are configured, start wizard otherwise
     reply["LoginEnabled"] = true;
 
     // check if we are configured, start wizard otherwise
-    if(!configured) {
+    if(!_configured) {
       reply["Configured"] = false;
       QList<QVariant> backends;
       foreach(Storage *backend, _storageBackends.values()) {
       reply["Configured"] = false;
       QList<QVariant> backends;
       foreach(Storage *backend, _storageBackends.values()) {
@@ -536,7 +550,7 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) {
       SignalProxy::writeDataToDevice(socket, reply);
     } else if(msg["MsgType"] == "ClientLogin") {
       QVariantMap reply;
       SignalProxy::writeDataToDevice(socket, reply);
     } else if(msg["MsgType"] == "ClientLogin") {
       QVariantMap reply;
-      UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString());
+      UserId uid = _storage->validateUser(msg["User"].toString(), msg["Password"].toString());
       if(uid == 0) {
         reply["MsgType"] = "ClientLoginReject";
         reply["Error"] = tr("<b>Invalid username or password!</b><br>The username/password combination you supplied could not be found in the database.");
       if(uid == 0) {
         reply["MsgType"] = "ClientLoginReject";
         reply["Error"] = tr("<b>Invalid username or password!</b><br>The username/password combination you supplied could not be found in the database.");
@@ -588,7 +602,7 @@ void Core::clientDisconnected() {
 
 
   // make server listen again if still not configured
 
 
   // make server listen again if still not configured
-  if (!configured) {
+  if (!_configured) {
     startListening();
   }
 
     startListening();
   }
 
@@ -613,12 +627,12 @@ void Core::setupClientSession(QTcpSocket *socket, UserId uid) {
 }
 
 void Core::setupInternalClientSession(SignalProxy *proxy) {
 }
 
 void Core::setupInternalClientSession(SignalProxy *proxy) {
-  if(!configured) {
+  if(!_configured) {
     stopListening();
     setupCoreForInternalUsage();
   }
 
     stopListening();
     setupCoreForInternalUsage();
   }
 
-  UserId uid = storage->internalUser();
+  UserId uid = _storage->internalUser();
 
   // Find or create session for validated user
   SessionThread *sess;
 
   // Find or create session for validated user
   SessionThread *sess;
index c0916c9..2c1fa07 100644 (file)
@@ -65,7 +65,7 @@ class Core : public QObject {
    * \param data         The Value
    */
   static inline void setUserSetting(UserId userId, const QString &settingName, const QVariant &data) {
    * \param data         The Value
    */
   static inline void setUserSetting(UserId userId, const QString &settingName, const QVariant &data) {
-    instance()->storage->setUserSetting(userId, settingName, data);
+    instance()->_storage->setUserSetting(userId, settingName, data);
   }
 
   //! Retrieve a persistent user setting
   }
 
   //! Retrieve a persistent user setting
@@ -76,21 +76,21 @@ class Core : public QObject {
    * \return the Value of the Setting or the default value if it is unset.
    */
   static inline QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &data = QVariant()) {
    * \return the Value of the Setting or the default value if it is unset.
    */
   static inline QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &data = QVariant()) {
-    return instance()->storage->getUserSetting(userId, settingName, data);
+    return instance()->_storage->getUserSetting(userId, settingName, data);
   }
 
   /* Identity handling */
   static inline IdentityId createIdentity(UserId user, CoreIdentity &identity) {
   }
 
   /* Identity handling */
   static inline IdentityId createIdentity(UserId user, CoreIdentity &identity) {
-    return instance()->storage->createIdentity(user, identity);
+    return instance()->_storage->createIdentity(user, identity);
   }
   static bool updateIdentity(UserId user, const CoreIdentity &identity) {
   }
   static bool updateIdentity(UserId user, const CoreIdentity &identity) {
-    return instance()->storage->updateIdentity(user, identity);
+    return instance()->_storage->updateIdentity(user, identity);
   }
   static void removeIdentity(UserId user, IdentityId identityId) {
   }
   static void removeIdentity(UserId user, IdentityId identityId) {
-    instance()->storage->removeIdentity(user, identityId);
+    instance()->_storage->removeIdentity(user, identityId);
   }
   static QList<CoreIdentity> identities(UserId user) {
   }
   static QList<CoreIdentity> identities(UserId user) {
-    return instance()->storage->identities(user);
+    return instance()->_storage->identities(user);
   }
 
   //! Create a Network in the Storage and store it's Id in the given NetworkInfo
   }
 
   //! Create a Network in the Storage and store it's Id in the given NetworkInfo
@@ -110,7 +110,7 @@ class Core : public QObject {
    *  \return true if successfull.
    */
   static inline bool updateNetwork(UserId user, const NetworkInfo &info) {
    *  \return true if successfull.
    */
   static inline bool updateNetwork(UserId user, const NetworkInfo &info) {
-    return instance()->storage->updateNetwork(user, info);
+    return instance()->_storage->updateNetwork(user, info);
   }
 
   //! Permanently remove a Network and all the data associated with it.
   }
 
   //! Permanently remove a Network and all the data associated with it.
@@ -121,7 +121,7 @@ class Core : public QObject {
    *  \return true if successfull.
    */
   static inline bool removeNetwork(UserId user, const NetworkId &networkId) {
    *  \return true if successfull.
    */
   static inline bool removeNetwork(UserId user, const NetworkId &networkId) {
-    return instance()->storage->removeNetwork(user, networkId);
+    return instance()->_storage->removeNetwork(user, networkId);
   }
 
   //! Returns a list of all NetworkInfos for the given UserId user
   }
 
   //! Returns a list of all NetworkInfos for the given UserId user
@@ -131,7 +131,7 @@ class Core : public QObject {
    *  \return QList<NetworkInfo>.
    */
   static inline QList<NetworkInfo> networks(UserId user) {
    *  \return QList<NetworkInfo>.
    */
   static inline QList<NetworkInfo> networks(UserId user) {
-    return instance()->storage->networks(user);
+    return instance()->_storage->networks(user);
   }
 
   //! Get the NetworkId for a network name.
   }
 
   //! Get the NetworkId for a network name.
@@ -142,7 +142,7 @@ class Core : public QObject {
    *  \return The NetworkId corresponding to the given network.
    */
   static inline NetworkId networkId(UserId user, const QString &network) {
    *  \return The NetworkId corresponding to the given network.
    */
   static inline NetworkId networkId(UserId user, const QString &network) {
-    return instance()->storage->getNetworkId(user, network);
+    return instance()->_storage->getNetworkId(user, network);
   }
 
   //! Get a list of Networks to restore
   }
 
   //! Get a list of Networks to restore
@@ -152,7 +152,7 @@ class Core : public QObject {
    *  \param user  The User Id in question
    */
   static inline QList<NetworkId> connectedNetworks(UserId user) {
    *  \param user  The User Id in question
    */
   static inline QList<NetworkId> connectedNetworks(UserId user) {
-    return instance()->storage->connectedNetworks(user);
+    return instance()->_storage->connectedNetworks(user);
   }
 
   //! Update the connected state of a network
   }
 
   //! Update the connected state of a network
@@ -163,7 +163,7 @@ class Core : public QObject {
    *  \param isConnected whether the network is connected or not
    */
   static inline void setNetworkConnected(UserId user, const NetworkId &networkId, bool isConnected) {
    *  \param isConnected whether the network is connected or not
    */
   static inline void setNetworkConnected(UserId user, const NetworkId &networkId, bool isConnected) {
-    return instance()->storage->setNetworkConnected(user, networkId, isConnected);
+    return instance()->_storage->setNetworkConnected(user, networkId, isConnected);
   }
 
   //! Get a hash of channels with their channel keys for a given network
   }
 
   //! Get a hash of channels with their channel keys for a given network
@@ -174,7 +174,7 @@ class Core : public QObject {
    *  \param networkId  The Id of the network
    */
   static inline QHash<QString, QString> persistentChannels(UserId user, const NetworkId &networkId) {
    *  \param networkId  The Id of the network
    */
   static inline QHash<QString, QString> persistentChannels(UserId user, const NetworkId &networkId) {
-    return instance()->storage->persistentChannels(user, networkId);
+    return instance()->_storage->persistentChannels(user, networkId);
   }
 
   //! Update the connected state of a channel
   }
 
   //! Update the connected state of a channel
@@ -186,7 +186,7 @@ class Core : public QObject {
    *  \param isJoined   whether the channel is connected or not
    */
   static inline void setChannelPersistent(UserId user, const NetworkId &networkId, const QString &channel, bool isJoined) {
    *  \param isJoined   whether the channel is connected or not
    */
   static inline void setChannelPersistent(UserId user, const NetworkId &networkId, const QString &channel, bool isJoined) {
-    return instance()->storage->setChannelPersistent(user, networkId, channel, isJoined);
+    return instance()->_storage->setChannelPersistent(user, networkId, channel, isJoined);
   }
 
   //! Update the key of a channel
   }
 
   //! Update the key of a channel
@@ -198,7 +198,7 @@ class Core : public QObject {
    *  \param key        The key of the channel (possibly empty)
    */
   static inline void setPersistentChannelKey(UserId user, const NetworkId &networkId, const QString &channel, const QString &key) {
    *  \param key        The key of the channel (possibly empty)
    */
   static inline void setPersistentChannelKey(UserId user, const NetworkId &networkId, const QString &channel, const QString &key) {
-    return instance()->storage->setPersistentChannelKey(user, networkId, channel, key);
+    return instance()->_storage->setPersistentChannelKey(user, networkId, channel, key);
   }
 
   //! retrieve last known away message for session restore
   }
 
   //! retrieve last known away message for session restore
@@ -208,7 +208,7 @@ class Core : public QObject {
    *  \param networkId  The Id of the network
    */
   static inline QString awayMessage(UserId user, NetworkId networkId) {
    *  \param networkId  The Id of the network
    */
   static inline QString awayMessage(UserId user, NetworkId networkId) {
-    return instance()->storage->awayMessage(user, networkId);
+    return instance()->_storage->awayMessage(user, networkId);
   }
 
   //! Make away message persistent for session restore
   }
 
   //! Make away message persistent for session restore
@@ -219,7 +219,7 @@ class Core : public QObject {
    *  \param awayMsg    The current away message of own user
    */
   static inline void setAwayMessage(UserId user, NetworkId networkId, const QString &awayMsg) {
    *  \param awayMsg    The current away message of own user
    */
   static inline void setAwayMessage(UserId user, NetworkId networkId, const QString &awayMsg) {
-    return instance()->storage->setAwayMessage(user, networkId, awayMsg);
+    return instance()->_storage->setAwayMessage(user, networkId, awayMsg);
   }
 
   //! retrieve last known user mode for session restore
   }
 
   //! retrieve last known user mode for session restore
@@ -229,7 +229,7 @@ class Core : public QObject {
    *  \param networkId  The Id of the network
    */
   static inline QString userModes(UserId user, NetworkId networkId) {
    *  \param networkId  The Id of the network
    */
   static inline QString userModes(UserId user, NetworkId networkId) {
-    return instance()->storage->userModes(user, networkId);
+    return instance()->_storage->userModes(user, networkId);
   }
 
   //! Make our user modes persistent for session restore
   }
 
   //! Make our user modes persistent for session restore
@@ -240,7 +240,7 @@ class Core : public QObject {
    *  \param userModes  The current user modes of own user
    */
   static inline void setUserModes(UserId user, NetworkId networkId, const QString &userModes) {
    *  \param userModes  The current user modes of own user
    */
   static inline void setUserModes(UserId user, NetworkId networkId, const QString &userModes) {
-    return instance()->storage->setUserModes(user, networkId, userModes);
+    return instance()->_storage->setUserModes(user, networkId, userModes);
   }
 
   //! Get the unique BufferInfo for the given combination of network and buffername for a user.
   }
 
   //! Get the unique BufferInfo for the given combination of network and buffername for a user.
@@ -254,7 +254,7 @@ class Core : public QObject {
    *  \return The BufferInfo corresponding to the given network and buffer name, or 0 if not found
    */
   static inline BufferInfo bufferInfo(UserId user, const NetworkId &networkId, BufferInfo::Type type, const QString &buffer = "", bool create = true) {
    *  \return The BufferInfo corresponding to the given network and buffer name, or 0 if not found
    */
   static inline BufferInfo bufferInfo(UserId user, const NetworkId &networkId, BufferInfo::Type type, const QString &buffer = "", bool create = true) {
-    return instance()->storage->bufferInfo(user, networkId, type, buffer, create);
+    return instance()->_storage->bufferInfo(user, networkId, type, buffer, create);
   }
 
   //! Get the unique BufferInfo for a bufferId
   }
 
   //! Get the unique BufferInfo for a bufferId
@@ -264,7 +264,7 @@ class Core : public QObject {
    *  \return The BufferInfo corresponding to the given buffer id, or an invalid BufferInfo if not found.
    */
   static inline BufferInfo getBufferInfo(UserId user, const BufferId &bufferId) {
    *  \return The BufferInfo corresponding to the given buffer id, or an invalid BufferInfo if not found.
    */
   static inline BufferInfo getBufferInfo(UserId user, const BufferId &bufferId) {
-    return instance()->storage->getBufferInfo(user, bufferId);
+    return instance()->_storage->getBufferInfo(user, bufferId);
   }
 
   //! Store a Message in the backlog.
   }
 
   //! Store a Message in the backlog.
@@ -274,7 +274,7 @@ class Core : public QObject {
    *  \return The globally unique id for the stored message
    */
   static inline MsgId storeMessage(const Message &message) {
    *  \return The globally unique id for the stored message
    */
   static inline MsgId storeMessage(const Message &message) {
-    return instance()->storage->logMessage(message);
+    return instance()->_storage->logMessage(message);
   }
 
   //! Request a certain number messages stored in a given buffer.
   }
 
   //! Request a certain number messages stored in a given buffer.
@@ -285,7 +285,7 @@ class Core : public QObject {
    *  \return The requested list of messages
    */
   static inline QList<Message> requestMsgs(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, int limit = -1) {
    *  \return The requested list of messages
    */
   static inline QList<Message> requestMsgs(UserId user, BufferId bufferId, MsgId first = -1, MsgId last = -1, int limit = -1) {
-    return instance()->storage->requestMsgs(user, bufferId, first, last, limit);
+    return instance()->_storage->requestMsgs(user, bufferId, first, last, limit);
   }
 
   //! Request a certain number of messages across all buffers
   }
 
   //! Request a certain number of messages across all buffers
@@ -295,7 +295,7 @@ class Core : public QObject {
    *  \return The requested list of messages
    */
   static inline QList<Message> requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1) {
    *  \return The requested list of messages
    */
   static inline QList<Message> requestAllMsgs(UserId user, MsgId first = -1, MsgId last = -1, int limit = -1) {
-    return instance()->storage->requestAllMsgs(user, first, last, limit);
+    return instance()->_storage->requestAllMsgs(user, first, last, limit);
   }
 
   //! Request a list of all buffers known to a user.
   }
 
   //! Request a list of all buffers known to a user.
@@ -306,7 +306,7 @@ class Core : public QObject {
    *  \return A list of the BufferInfos for all buffers as requested
    */
   static inline QList<BufferInfo> requestBuffers(UserId user) {
    *  \return A list of the BufferInfos for all buffers as requested
    */
   static inline QList<BufferInfo> requestBuffers(UserId user) {
-    return instance()->storage->requestBuffers(user);
+    return instance()->_storage->requestBuffers(user);
   }
 
   //! Request a list of BufferIds for a given NetworkId
   }
 
   //! Request a list of BufferIds for a given NetworkId
@@ -317,7 +317,7 @@ class Core : public QObject {
    *  \return List of BufferIds belonging to the Network
    */
   static inline QList<BufferId> requestBufferIdsForNetwork(UserId user, NetworkId networkId) {
    *  \return List of BufferIds belonging to the Network
    */
   static inline QList<BufferId> requestBufferIdsForNetwork(UserId user, NetworkId networkId) {
-    return instance()->storage->requestBufferIdsForNetwork(user, networkId);
+    return instance()->_storage->requestBufferIdsForNetwork(user, networkId);
   }
 
   //! Remove permanently a buffer and it's content from the storage backend
   }
 
   //! Remove permanently a buffer and it's content from the storage backend
@@ -329,7 +329,7 @@ class Core : public QObject {
    *  \return true if successfull
    */
   static inline bool removeBuffer(const UserId &user, const BufferId &bufferId) {
    *  \return true if successfull
    */
   static inline bool removeBuffer(const UserId &user, const BufferId &bufferId) {
-    return instance()->storage->removeBuffer(user, bufferId);
+    return instance()->_storage->removeBuffer(user, bufferId);
   }
 
   //! Rename a Buffer
   }
 
   //! Rename a Buffer
@@ -340,7 +340,7 @@ class Core : public QObject {
    *  \return true if successfull
    */
   static inline bool renameBuffer(const UserId &user, const BufferId &bufferId, const QString &newName) {
    *  \return true if successfull
    */
   static inline bool renameBuffer(const UserId &user, const BufferId &bufferId, const QString &newName) {
-    return instance()->storage->renameBuffer(user, bufferId, newName);
+    return instance()->_storage->renameBuffer(user, bufferId, newName);
   }
 
   //! Merge the content of two Buffers permanently. This cannot be reversed!
   }
 
   //! Merge the content of two Buffers permanently. This cannot be reversed!
@@ -351,7 +351,7 @@ class Core : public QObject {
    *  \return true if successfulln
    */
   static inline bool mergeBuffersPermanently(const UserId &user, const BufferId &bufferId1, const BufferId &bufferId2) {
    *  \return true if successfulln
    */
   static inline bool mergeBuffersPermanently(const UserId &user, const BufferId &bufferId1, const BufferId &bufferId2) {
-    return instance()->storage->mergeBuffersPermanently(user, bufferId1, bufferId2);
+    return instance()->_storage->mergeBuffersPermanently(user, bufferId1, bufferId2);
   }
 
   //! Update the LastSeenDate for a Buffer
   }
 
   //! Update the LastSeenDate for a Buffer
@@ -363,7 +363,7 @@ class Core : public QObject {
    * \param MsgId     The Message id of the message that has been just seen
    */
   static inline void setBufferLastSeenMsg(UserId user, const BufferId &bufferId, const MsgId &msgId) {
    * \param MsgId     The Message id of the message that has been just seen
    */
   static inline void setBufferLastSeenMsg(UserId user, const BufferId &bufferId, const MsgId &msgId) {
-    return instance()->storage->setBufferLastSeenMsg(user, bufferId, msgId);
+    return instance()->_storage->setBufferLastSeenMsg(user, bufferId, msgId);
   }
 
   //! Get a Hash of all last seen message ids
   }
 
   //! Get a Hash of all last seen message ids
@@ -373,7 +373,7 @@ class Core : public QObject {
    * \param user      The Owner of the buffers
    */
   static inline QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user) {
    * \param user      The Owner of the buffers
    */
   static inline QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user) {
-    return instance()->storage->bufferLastSeenMsgIds(user);
+    return instance()->_storage->bufferLastSeenMsgIds(user);
   }
 
   const QDateTime &startTime() const { return _startTime; }
   }
 
   const QDateTime &startTime() const { return _startTime; }
@@ -424,7 +424,7 @@ private:
   void unregisterStorageBackend(Storage *);
 
   QHash<UserId, SessionThread *> sessions;
   void unregisterStorageBackend(Storage *);
 
   QHash<UserId, SessionThread *> sessions;
-  Storage *storage;
+  Storage *_storage;
   QTimer _storageSyncTimer;
 
 #ifdef HAVE_SSL
   QTimer _storageSyncTimer;
 
 #ifdef HAVE_SSL
@@ -440,7 +440,7 @@ private:
 
   QDateTime _startTime;
 
 
   QDateTime _startTime;
 
-  bool configured;
+  bool _configured;
 };
 
 #endif
 };
 
 #endif
index cc3d039..1cb2ee8 100644 (file)
 class Storage : public QObject {
   Q_OBJECT
 
 class Storage : public QObject {
   Q_OBJECT
 
-  public:
+public:
   Storage(QObject *parent = 0);
   virtual ~Storage() {};
 
   Storage(QObject *parent = 0);
   virtual ~Storage() {};
 
+  enum State {
+    IsReady,        // ready to go
+    NeedsSetup,     // need basic setup (ask the user for input)
+    NotAvailable    // remove the storage backend from the list of avaliable backends
+  };
+
 public slots:
   /* General */
 
 public slots:
   /* General */
 
@@ -62,9 +68,9 @@ public slots:
 
   //! Initialize the storage provider
   /** \param settings   Hostname, port, username, password, ...  
 
   //! Initialize the storage provider
   /** \param settings   Hostname, port, username, password, ...  
-   *  \return True if and only if the storage provider was initialized successfully.
+   *  \return the State the storage backend is now in (see Storage::State)
    */
    */
-  virtual bool init(const QVariantMap &settings = QVariantMap()) = 0;
+  virtual State init(const QVariantMap &settings = QVariantMap()) = 0;
 
   //! Makes temp data persistent
   /** This Method is periodically called by the Quassel Core to make temporary
 
   //! Makes temp data persistent
   /** This Method is periodically called by the Quassel Core to make temporary