This Update is like 90% bugfixes.
authorMarcus Eggenberger <egs@quassel-irc.org>
Sun, 4 Nov 2007 16:04:37 +0000 (16:04 +0000)
committerMarcus Eggenberger <egs@quassel-irc.org>
Sun, 4 Nov 2007 16:04:37 +0000 (16:04 +0000)
 - IMPORTANT! - this version uses a new version of the SqlLite Schema (though only slitely different). The change to the schema _canno_ be done via an ALTER statement. Thus it is recommanded that you delete the current
quassel-storage.sqlite DB-File, so it gets created again.
 - SignalProxy got a new method which is basically just for debuging/info purposes. use SignalProxy::dumpProxyStat() to see some infos of the current proxy situation on STDERR.
 - fixed a bug causing Segfaults
 - fixed a minor bug where Quassel treated channelnames not casesensitive and thus created a second buffer for them

src/client/client.cpp
src/common/ircchannel.cpp
src/common/ircchannel.h
src/common/ircuser.cpp
src/common/ircuser.h
src/common/signalproxy.cpp
src/common/signalproxy.h
src/core/sqlitestorage.cpp

index 1d44fd6..2500b27 100644 (file)
@@ -354,7 +354,6 @@ void Client::updateCoreConnectionProgress() {
       if(! channel->initialized())
        numChannelsWaiting++;
     }
       if(! channel->initialized())
        numChannelsWaiting++;
     }
-
   }
 
   if(numNetsWaiting > 0) {
   }
 
   if(numNetsWaiting > 0) {
@@ -377,6 +376,12 @@ void Client::updateCoreConnectionProgress() {
 
   emit coreConnectionProgress(1,1);
   emit connected();
 
   emit coreConnectionProgress(1,1);
   emit connected();
+
+  foreach(NetworkInfo *net, networkInfos()) {
+    disconnect(net, 0, this, SLOT(updateCoreConnectionProgress()));
+  }
+  
+  // signalProxy()->dumpProxyStats();
 }
 
 void Client::recvSessionData(const QString &key, const QVariant &data) {
 }
 
 void Client::recvSessionData(const QString &key, const QVariant &data) {
index b9caebd..29b618f 100644 (file)
@@ -107,6 +107,7 @@ void IrcChannel::join(IrcUser *ircuser) {
   if(!_userModes.contains(ircuser) && ircuser) {
     _userModes[ircuser] = QString();
     ircuser->joinChannel(name());
   if(!_userModes.contains(ircuser) && ircuser) {
     _userModes[ircuser] = QString();
     ircuser->joinChannel(name());
+    connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
     // no emit here since the join is propagated by IrcUser
   }
 }
     // no emit here since the join is propagated by IrcUser
   }
 }
@@ -175,10 +176,10 @@ void IrcChannel::removeUserMode(const QString &nick, const QString &mode) {
 // INIT SET USER MODES
 QVariantMap IrcChannel::initUserModes() const {
   QVariantMap usermodes;
 // INIT SET USER MODES
 QVariantMap IrcChannel::initUserModes() const {
   QVariantMap usermodes;
-  QHashIterator<IrcUser *, QString> iter(_userModes);
-  while(iter.hasNext()) {
-    iter.next();
+  QHash<IrcUser *, QString>::const_iterator iter = _userModes.constBegin();
+  while(iter != _userModes.constEnd()) {
     usermodes[iter.key()->nick()] = iter.value();
     usermodes[iter.key()->nick()] = iter.value();
+    iter++;
   }
   return usermodes;
 }
   }
   return usermodes;
 }
@@ -194,7 +195,7 @@ void IrcChannel::initSetUserModes(const QVariantMap &usermodes) {
 void IrcChannel::ircUserDestroyed() {
   IrcUser *ircUser = static_cast<IrcUser *>(sender());
   Q_ASSERT(ircUser);
 void IrcChannel::ircUserDestroyed() {
   IrcUser *ircUser = static_cast<IrcUser *>(sender());
   Q_ASSERT(ircUser);
-  part(ircUser);
+  _userModes.remove(ircUser);
 }
 
 void IrcChannel::setInitialized() {
 }
 
 void IrcChannel::setInitialized() {
index 2b43876..40ed3fb 100644 (file)
@@ -77,8 +77,6 @@ public slots:
   // init seters
   void initSetUserModes(const QVariantMap &usermodes);
   
   // init seters
   void initSetUserModes(const QVariantMap &usermodes);
   
-  void ircUserDestroyed();
-  
   void setInitialized();
 
 signals:
   void setInitialized();
 
 signals:
@@ -88,7 +86,10 @@ signals:
   void userModeRemoved(QString nick, QString mode);
 
   void initDone();
   void userModeRemoved(QString nick, QString mode);
 
   void initDone();
-  
+
+private slots:
+   void ircUserDestroyed();
+
 private:
   bool _initialized;
   QString _name;
 private:
   bool _initialized;
   QString _name;
index 665b10f..bc34143 100644 (file)
@@ -38,6 +38,9 @@ IrcUser::IrcUser(const QString &hostmask, NetworkInfo *networkinfo)
   setObjectName(QString::number(networkInfo->networkId()) + "/" + IrcUser::hostmask());
 }
 
   setObjectName(QString::number(networkInfo->networkId()) + "/" + IrcUser::hostmask());
 }
 
+IrcUser::~IrcUser() {
+}
+
 // ====================
 //  PUBLIC:
 // ====================
 // ====================
 //  PUBLIC:
 // ====================
index 4fe3f37..93ec9eb 100644 (file)
@@ -43,6 +43,7 @@ class IrcUser : public QObject {
   
 public:
   IrcUser(const QString &hostmask, NetworkInfo *networkInfo);
   
 public:
   IrcUser(const QString &hostmask, NetworkInfo *networkInfo);
+  virtual ~IrcUser();
 
   bool initialized() const;
 
 
   bool initialized() const;
 
index 290e517..c8f753d 100644 (file)
@@ -50,6 +50,8 @@ public:
   int qt_metacall(QMetaObject::Call _c, int _id, void **_a);
 
   void attachSignal(int methodId, const QByteArray &func);
   int qt_metacall(QMetaObject::Call _c, int _id, void **_a);
 
   void attachSignal(int methodId, const QByteArray &func);
+
+  int sigCount() const;
   
 private:
   SignalProxy* proxy;
   
 private:
   SignalProxy* proxy;
@@ -87,6 +89,11 @@ int SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
   return _id;
 }
 
   return _id;
 }
 
+int SignalRelay::sigCount() const {
+  // only for debuging purpose
+  return sigNames.count();
+}
+
 void SignalRelay::attachSignal(int methodId, const QByteArray &func) {
   // we ride without safetybelts here... all checking for valid method etc pp has to be done by the caller
   // all connected methodIds are offset by the standard methodCount of QObject
 void SignalRelay::attachSignal(int methodId, const QByteArray &func) {
   // we ride without safetybelts here... all checking for valid method etc pp has to be done by the caller
   // all connected methodIds are offset by the standard methodCount of QObject
@@ -111,22 +118,19 @@ void SignalRelay::attachSignal(int methodId, const QByteArray &func) {
 // ====================
 SignalProxy::SignalProxy(QObject* parent)
   : QObject(parent),
 // ====================
 SignalProxy::SignalProxy(QObject* parent)
   : QObject(parent),
-    _proxyMode(Client),
-    _maxClients(-1)
+    _proxyMode(Client)
 {
 }
 
 SignalProxy::SignalProxy(ProxyMode mode, QObject* parent)
   : QObject(parent),
 {
 }
 
 SignalProxy::SignalProxy(ProxyMode mode, QObject* parent)
   : QObject(parent),
-    _proxyMode(mode),
-    _maxClients(-1)
+    _proxyMode(mode)
 {
 }
 
 SignalProxy::SignalProxy(ProxyMode mode, QIODevice* device, QObject* parent)
   : QObject(parent),
 {
 }
 
 SignalProxy::SignalProxy(ProxyMode mode, QIODevice* device, QObject* parent)
   : QObject(parent),
-    _proxyMode(mode),
-    _maxClients(-1)
+    _proxyMode(mode)
 {
   addPeer(device);
 } 
 {
   addPeer(device);
 } 
@@ -152,17 +156,6 @@ SignalProxy::ProxyMode SignalProxy::proxyMode() const {
   return _proxyMode;
 }
 
   return _proxyMode;
 }
 
-bool SignalProxy::maxPeersReached() {
-  if(_peerByteCount.empty())
-    return false;
-  if(proxyMode() != Server)
-    return true;
-  if(_maxClients == -1)
-    return false;
-
-  return (_maxClients <= _peerByteCount.count());
-}
-
 bool SignalProxy::addPeer(QIODevice* iodev) {
   if(!iodev)
     return false;
 bool SignalProxy::addPeer(QIODevice* iodev) {
   if(!iodev)
     return false;
@@ -170,8 +163,8 @@ bool SignalProxy::addPeer(QIODevice* iodev) {
   if(_peerByteCount.contains(iodev))
     return true;
 
   if(_peerByteCount.contains(iodev))
     return true;
 
-  if(maxPeersReached()) {
-    qWarning("SignalProxy: max peer count reached");
+  if(proxyMode() == Client && !_peerByteCount.isEmpty()) {
+    qWarning("SignalProxy: only one peer allowed in client mode!");
     return false;
   }
 
     return false;
   }
 
@@ -330,6 +323,7 @@ bool SignalProxy::attachSlot(const QByteArray& sigName, QObject* recv, const cha
 
 void SignalProxy::detachSender() {
   // this is a slot so we can bypass the QueuedConnection
 
 void SignalProxy::detachSender() {
   // this is a slot so we can bypass the QueuedConnection
+  // and if someone is forcing direct connection in a multithreaded environment he's just nuts...
   _detachSignals(sender());
   _detachSlots(sender());
 }
   _detachSignals(sender());
   _detachSlots(sender());
 }
@@ -348,18 +342,18 @@ void SignalProxy::detachSignals(QObject* sender) {
                            Q_ARG(QObject*, sender));
 }
 
                            Q_ARG(QObject*, sender));
 }
 
-void SignalProxy::_detachSignals(QObject* sender) {
-  if(!_relayHash.contains(sender))
-    return;
-  _relayHash.take(sender)->deleteLater();
-}
-
 void SignalProxy::detachSlots(QObject* receiver) {
   QMetaObject::invokeMethod(this, "_detachSlots",
                            Qt::QueuedConnection,
                            Q_ARG(QObject*, receiver));
 }
 
 void SignalProxy::detachSlots(QObject* receiver) {
   QMetaObject::invokeMethod(this, "_detachSlots",
                            Qt::QueuedConnection,
                            Q_ARG(QObject*, receiver));
 }
 
+void SignalProxy::_detachSignals(QObject* sender) {
+  if(!_relayHash.contains(sender))
+    return;
+  _relayHash.take(sender)->deleteLater();
+}
+
 void SignalProxy::_detachSlots(QObject* receiver) {
   SlotHash::iterator slotIter = _attachedSlots.begin();
   while(slotIter != _attachedSlots.end()) {
 void SignalProxy::_detachSlots(QObject* receiver) {
   SlotHash::iterator slotIter = _attachedSlots.begin();
   while(slotIter != _attachedSlots.end()) {
@@ -370,7 +364,6 @@ void SignalProxy::_detachSlots(QObject* receiver) {
   }
 }
 
   }
 }
 
-
 void SignalProxy::call(const char*  signal, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) {
   QByteArray func = QMetaObject::normalizedSignature(signal);
   QVariantList params;
 void SignalProxy::call(const char*  signal, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) {
   QByteArray func = QMetaObject::normalizedSignature(signal);
   QVariantList params;
@@ -409,16 +402,11 @@ void SignalProxy::receivePeerSignal(const QVariant &packedFunc) {
 }
 
 void SignalProxy::dataAvailable() {
 }
 
 void SignalProxy::dataAvailable() {
+  // yet again. it's a private slot. no need for checks.
   QIODevice* ioDev = qobject_cast<QIODevice* >(sender());
   QIODevice* ioDev = qobject_cast<QIODevice* >(sender());
-  Q_ASSERT(ioDev);
-  if(!_peerByteCount.contains(ioDev)) {
-    qWarning() << "SignalProxy: Unrecognized client object connected to dataAvailable";
-    return;
-  } else {
-    QVariant var;
-    while(readDataFromDevice(ioDev, _peerByteCount[ioDev], var))
-      receivePeerSignal(var);
-  }
+  QVariant var;
+  while(readDataFromDevice(ioDev, _peerByteCount[ioDev], var))
+    receivePeerSignal(var);
 }
 
 void SignalProxy::writeDataToDevice(QIODevice *dev, const QVariant &item) {
 }
 
 void SignalProxy::writeDataToDevice(QIODevice *dev, const QVariant &item) {
@@ -451,3 +439,22 @@ bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVarian
   blockSize = 0;
   return true;
 }
   blockSize = 0;
   return true;
 }
+
+void SignalProxy::dumpProxyStats() {
+  QString mode;
+  if(proxyMode() == Server)
+    mode = "Server";
+  else
+    mode = "Client";
+
+  int sigCount = 0;
+  foreach(SignalRelay *relay, _relayHash.values())
+    sigCount += relay->sigCount();
+
+  qDebug() << this;
+  qDebug() << "              Proxy Mode:" << mode;
+  qDebug() << "attached sending Objects:" << _relayHash.count();
+  qDebug() << "       Number of Signals:" << sigCount;
+  qDebug() << "          attached Slots:" << _attachedSlots.count();
+  qDebug() << "number of Classes cached:" << _classInfo.count();
+}
index 0b51125..ebc4ae7 100644 (file)
@@ -57,8 +57,6 @@ public:
   void setProxyMode(ProxyMode mode);
   ProxyMode proxyMode() const;
 
   void setProxyMode(ProxyMode mode);
   ProxyMode proxyMode() const;
 
-  bool maxPeersReached();
-  
   bool addPeer(QIODevice *iodev);
   void removePeer(QIODevice *iodev = 0);
 
   bool addPeer(QIODevice *iodev);
   void removePeer(QIODevice *iodev = 0);
 
@@ -86,6 +84,8 @@ public:
     MethodNameHash methodNames;
     // QHash<int, int> syncMap
   };
     MethodNameHash methodNames;
     // QHash<int, int> syncMap
   };
+
+  void dumpProxyStats();
   
 private slots:
   void dataAvailable();
   
 private slots:
   void dataAvailable();
@@ -123,7 +123,6 @@ private:
   QHash<QIODevice*, quint32> _peerByteCount;
 
   ProxyMode _proxyMode;
   QHash<QIODevice*, quint32> _peerByteCount;
 
   ProxyMode _proxyMode;
-  int _maxClients;
 };
 
 
 };
 
 
index 21d67cd..d8dc9ba 100644 (file)
@@ -56,7 +56,7 @@ SqliteStorage::SqliteStorage() {
   getBufferInfoQuery = new QSqlQuery(logDb);
   getBufferInfoQuery->prepare("SELECT bufferid FROM buffer "
                             "JOIN network ON buffer.networkid = network.networkid "
   getBufferInfoQuery = new QSqlQuery(logDb);
   getBufferInfoQuery->prepare("SELECT bufferid FROM buffer "
                             "JOIN network ON buffer.networkid = network.networkid "
-                            "WHERE network.networkname = :networkname AND buffer.userid = :userid AND buffer.buffername = :buffername ");
+                            "WHERE network.networkname = :networkname AND buffer.userid = :userid AND lower(buffer.buffername) = lower(:buffername)");
 
   logMessageQuery = new QSqlQuery(logDb);
   logMessageQuery->prepare("INSERT INTO backlog (time, bufferid, type, flags, senderid, message) "
 
   logMessageQuery = new QSqlQuery(logDb);
   logMessageQuery->prepare("INSERT INTO backlog (time, bufferid, type, flags, senderid, message) "
@@ -163,7 +163,7 @@ void SqliteStorage::initDb() {
              "type INTEGER NOT NULL,"
              "flags INTEGER NOT NULL,"
              "senderid INTEGER NOT NULL,"
              "type INTEGER NOT NULL,"
              "flags INTEGER NOT NULL,"
              "senderid INTEGER NOT NULL,"
-             "message TEXT NOT NULL)");
+             "message TEXT)");
   
   logDb.exec("CREATE TABLE coreinfo ("
              "updateid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
   
   logDb.exec("CREATE TABLE coreinfo ("
              "updateid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
@@ -311,6 +311,7 @@ uint SqliteStorage::getNetworkId(UserId user, const QString &network) {
 
 BufferInfo SqliteStorage::getBufferInfo(UserId user, const QString &network, const QString &buffer) {
   BufferInfo bufferid;
 
 BufferInfo SqliteStorage::getBufferInfo(UserId user, const QString &network, const QString &buffer) {
   BufferInfo bufferid;
+  // TODO: get rid of this hackaround
   uint networkId = getNetworkId(user, network);
   getBufferInfoQuery->bindValue(":networkname", network);
   getBufferInfoQuery->bindValue(":userid", user);
   uint networkId = getNetworkId(user, network);
   getBufferInfoQuery->bindValue(":networkname", network);
   getBufferInfoQuery->bindValue(":userid", user);
@@ -319,6 +320,8 @@ BufferInfo SqliteStorage::getBufferInfo(UserId user, const QString &network, con
 
   if(!getBufferInfoQuery->first()) {
     createBuffer(user, network, buffer);
 
   if(!getBufferInfoQuery->first()) {
     createBuffer(user, network, buffer);
+    // TODO: get rid of this hackaround
+    networkId = getNetworkId(user, network);
     getBufferInfoQuery->exec();
     if(getBufferInfoQuery->first()) {
       bufferid = BufferInfo(getBufferInfoQuery->value(0).toUInt(), networkId, 0, network, buffer);
     getBufferInfoQuery->exec();
     if(getBufferInfoQuery->first()) {
       bufferid = BufferInfo(getBufferInfoQuery->value(0).toUInt(), networkId, 0, network, buffer);