fixes #636 - Sqlite error when merging buffer
[quassel.git] / src / core / sqlitestorage.cpp
index 056cddd..5fd191b 100644 (file)
@@ -120,7 +120,7 @@ UserId SqliteStorage::addUser(const QString &user, const QString &password) {
   return uid;
 }
 
-void SqliteStorage::updateUser(UserId user, const QString &password) {
+bool SqliteStorage::updateUser(UserId user, const QString &password) {
   QSqlDatabase db = logDb();
   db.transaction();
 
@@ -130,8 +130,10 @@ void SqliteStorage::updateUser(UserId user, const QString &password) {
   query.bindValue(":password", cryptedPassword(password));
   lockForWrite();
   safeExec(query);
+  bool success = query.numRowsAffected() != 0;
   db.commit();
   unlock();
+  return success;
 }
 
 void SqliteStorage::renameUser(UserId user, const QString &newName) {
@@ -150,36 +152,71 @@ void SqliteStorage::renameUser(UserId user, const QString &newName) {
 }
 
 UserId SqliteStorage::validateUser(const QString &user, const QString &password) {
-  QSqlQuery query(logDb());
-  query.prepare(queryString("select_authuser"));
-  query.bindValue(":username", user);
-  query.bindValue(":password", cryptedPassword(password));
+  UserId userId;
+
+  // this scope ensures that the query is freed in sqlite before we call unlock()
+  // this ensures that our thread doesn't hold a internal after unlock is called
+  // (see sqlites doc on implicit locking for details)
+  {
+    QSqlQuery query(logDb());
+    query.prepare(queryString("select_authuser"));
+    query.bindValue(":username", user);
+    query.bindValue(":password", cryptedPassword(password));
+
+    lockForRead();
+    safeExec(query);
+
+    if(query.first()) {
+      userId = query.value(0).toInt();
+    }
+  }
+  unlock();
 
-  lockForRead();
-  safeExec(query);
+  return userId;
+}
 
-  if(query.first()) {
-    unlock();
-    return query.value(0).toInt();
-  } else {
-    unlock();
-    return 0;
+UserId SqliteStorage::getUserId(const QString &username) {
+  UserId userId;
+
+  // this scope ensures that the query is freed in sqlite before we call unlock()
+  // this ensures that our thread doesn't hold a internal after unlock is called
+  // (see sqlites doc on implicit locking for details)
+  {
+    QSqlQuery query(logDb());
+    query.prepare(queryString("select_userid"));
+    query.bindValue(":username", username);
+
+    lockForRead();
+    safeExec(query);
+
+    if(query.first()) {
+      userId = query.value(0).toInt();
+    }
   }
+  unlock();
+
+  return userId;
 }
 
 UserId SqliteStorage::internalUser() {
-  QSqlQuery query(logDb());
-  query.prepare(queryString("select_internaluser"));
-  lockForRead();
-  safeExec(query);
-
-  if(query.first()) {
-    unlock();
-    return query.value(0).toInt();
-  } else {
-    unlock();
-    return 0;
+  UserId userId;
+
+  // this scope ensures that the query is freed in sqlite before we call unlock()
+  // this ensures that our thread doesn't hold a internal after unlock is called
+  // (see sqlites doc on implicit locking for details)
+  {
+    QSqlQuery query(logDb());
+    query.prepare(queryString("select_internaluser"));
+    lockForRead();
+    safeExec(query);
+
+    if(query.first()) {
+      userId = query.value(0).toInt();
+    }
   }
+  unlock();
+
+  return userId;
 }
 
 void SqliteStorage::delUser(UserId user) {
@@ -423,7 +460,7 @@ QList<CoreIdentity> SqliteStorage::identities(UserId user) {
   QList<CoreIdentity> identities;
   QSqlDatabase db = logDb();
   db.transaction();
-  
+
   QSqlQuery query(db);
   query.prepare(queryString("select_identities"));
   query.bindValue(":userid", user.toInt());
@@ -479,7 +516,7 @@ NetworkId SqliteStorage::createNetwork(UserId user, const NetworkInfo &info) {
 
   QSqlDatabase db = logDb();
   db.transaction();
-  
+
   QSqlQuery query(db);
   query.prepare(queryString("insert_network"));
   query.bindValue(":userid", user.toInt());
@@ -507,7 +544,7 @@ NetworkId SqliteStorage::createNetwork(UserId user, const NetworkInfo &info) {
       return NetworkId();
     }
   }
-  
+
   db.commit();
   unlock();
   return networkId;
@@ -519,16 +556,16 @@ void SqliteStorage::bindNetworkInfo(QSqlQuery &query, const NetworkInfo &info) {
   query.bindValue(":encodingcodec", QString(info.codecForEncoding));
   query.bindValue(":decodingcodec", QString(info.codecForDecoding));
   query.bindValue(":servercodec", QString(info.codecForServer));
-  query.bindValue(":userandomserver", info.useRandomServer);
+  query.bindValue(":userandomserver", info.useRandomServer ? 1 : 0);
   query.bindValue(":perform", info.perform.join("\n"));
-  query.bindValue(":useautoidentify", info.useAutoIdentify);
+  query.bindValue(":useautoidentify", info.useAutoIdentify ? 1 : 0);
   query.bindValue(":autoidentifyservice", info.autoIdentifyService);
   query.bindValue(":autoidentifypassword", info.autoIdentifyPassword);
-  query.bindValue(":useautoreconnect", info.useAutoReconnect);
+  query.bindValue(":useautoreconnect", info.useAutoReconnect ? 1 : 0);
   query.bindValue(":autoreconnectinterval", info.autoReconnectInterval);
   query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
-  query.bindValue(":unlimitedconnectretries", info.unlimitedReconnectRetries);
-  query.bindValue(":rejoinchannels", info.rejoinChannels);
+  query.bindValue(":unlimitedconnectretries", info.unlimitedReconnectRetries ? 1 : 0);
+  query.bindValue(":rejoinchannels", info.rejoinChannels ? 1 : 0);
   if(info.networkId.isValid())
     query.bindValue(":networkid", info.networkId.toInt());
 }
@@ -537,9 +574,9 @@ void SqliteStorage::bindServerInfo(QSqlQuery &query, const Network::Server &serv
   query.bindValue(":hostname", server.host);
   query.bindValue(":port", server.port);
   query.bindValue(":password", server.password);
-  query.bindValue(":ssl", server.useSsl);
+  query.bindValue(":ssl", server.useSsl ? 1 : 0);
   query.bindValue(":sslversion", server.sslVersion);
-  query.bindValue(":useproxy", server.useProxy);
+  query.bindValue(":useproxy", server.useProxy ? 1 : 0);
   query.bindValue(":proxytype", server.proxyType);
   query.bindValue(":proxyhost", server.proxyHost);
   query.bindValue(":proxyport", server.proxyPort);
@@ -722,7 +759,7 @@ QList<NetworkId> SqliteStorage::connectedNetworks(UserId user) {
 
   QSqlDatabase db = logDb();
   db.transaction();
-  
+
   QSqlQuery query(db);
   query.prepare(queryString("select_connected_networks"));
   query.bindValue(":userid", user.toInt());
@@ -1109,6 +1146,7 @@ bool SqliteStorage::mergeBuffersPermanently(const UserId &user, const BufferId &
   QSqlQuery delBufferQuery(db);
   delBufferQuery.prepare(queryString("delete_buffer_for_bufferid"));
   delBufferQuery.bindValue(":bufferid", bufferId2.toInt());
+  delBufferQuery.bindValue(":userid", user.toInt());
   safeExec(delBufferQuery);
   if(!watchQuery(delBufferQuery)) {
     db.rollback();
@@ -1217,7 +1255,7 @@ bool SqliteStorage::logMessages(MessageList &msgs) {
   QSqlDatabase db = logDb();
   db.transaction();
 
-  QSet<QString> senders;  
+  QSet<QString> senders;
 
   QSqlQuery addSenderQuery(db);
   addSenderQuery.prepare(queryString("insert_sender"));