Hello community,

here is the log from the commit of package akonadi-runtime for openSUSE:Factory 
checked in at 2013-12-12 11:16:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/akonadi-runtime (Old)
 and      /work/SRC/openSUSE:Factory/.akonadi-runtime.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "akonadi-runtime"

Changes:
--------
--- /work/SRC/openSUSE:Factory/akonadi-runtime/akonadi-runtime.changes  
2013-12-02 12:36:46.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.akonadi-runtime.new/akonadi-runtime.changes     
2013-12-12 11:16:26.000000000 +0100
@@ -1,0 +2,6 @@
+Fri Nov 29 22:29:45 UTC 2013 - [email protected]
+
+- Update to 1.11.0
+  * Fixed joined UPDATE queries failing with SQLite
+
+-------------------------------------------------------------------

Old:
----
  akonadi-1.10.80.tar.bz2

New:
----
  akonadi-1.11.0.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ akonadi-runtime.spec ++++++
--- /var/tmp/diff_new_pack.rKNRBo/_old  2013-12-12 11:16:26.000000000 +0100
+++ /var/tmp/diff_new_pack.rKNRBo/_new  2013-12-12 11:16:26.000000000 +0100
@@ -17,14 +17,15 @@
 
 
 Name:           akonadi-runtime
-Version:        1.10.80
+Version:        1.11.0
 Release:        0
 %define rversion %{version}
+%define rname   akonadi
 Summary:        PIM Storage Service
 License:        LGPL-2.1+
 Group:          System/GUI/KDE
 Url:            http://akonadi-project.org
-Source:         
http://download.kde.org/stable/akonadi/src/akonadi-%{version}.tar.bz2
+Source:         
http://download.kde.org/stable/%{rname}/src/%{rname}-%{version}.tar.bz2
 BuildRequires:  boost-devel
 BuildRequires:  cmake >= 2.8.8
 BuildRequires:  fdupes
@@ -83,7 +84,7 @@
 service.
 
 %prep
-%setup -q -n akonadi-%{rversion}
+%setup -q -n %{rname}-%{rversion}
 
 %build
   %cmake_kde4 -d build -- -DCONFIG_INSTALL_DIR=/etc 
-DINSTALL_QSQLITE_IN_QT_PREFIX=TRUE

++++++ akonadi-1.10.80.tar.bz2 -> akonadi-1.11.0.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/akonadi-1.10.80/CMakeLists.txt 
new/akonadi-1.11.0/CMakeLists.txt
--- old/akonadi-1.10.80/CMakeLists.txt  2013-11-05 10:28:38.000000000 +0100
+++ new/akonadi-1.11.0/CMakeLists.txt   2013-11-28 15:25:03.000000000 +0100
@@ -57,8 +57,8 @@
 ############### The Akonadi version (used in AkonadiConfig.cmake) 
###############
 
 set(AKONADI_VERSION_MAJOR "1")
-set(AKONADI_VERSION_MINOR "10")
-set(AKONADI_VERSION_PATCH "80")
+set(AKONADI_VERSION_MINOR "11")
+set(AKONADI_VERSION_PATCH "0")
 set(AKONADI_VERSION 
"${AKONADI_VERSION_MAJOR}.${AKONADI_VERSION_MINOR}.${AKONADI_VERSION_PATCH}")
 set(AKONADI_VERSION_STRING "${AKONADI_VERSION}")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/akonadi-1.10.80/NEWS new/akonadi-1.11.0/NEWS
--- old/akonadi-1.10.80/NEWS    2013-11-05 10:28:38.000000000 +0100
+++ new/akonadi-1.11.0/NEWS     2013-11-28 15:25:03.000000000 +0100
@@ -1,3 +1,7 @@
+1.11.0                       28-November-2013
+----------------------------------------------
+- fix joined UPDATE queries failing with SQLite
+
 1.10.80                       05-November-2013
 ----------------------------------------------
 - Servser-side notification filtering
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/akonadi-1.10.80/server/src/storage/querybuilder.cpp 
new/akonadi-1.11.0/server/src/storage/querybuilder.cpp
--- old/akonadi-1.10.80/server/src/storage/querybuilder.cpp     2013-11-05 
10:28:38.000000000 +0100
+++ new/akonadi-1.11.0/server/src/storage/querybuilder.cpp      2013-11-28 
15:25:03.000000000 +0100
@@ -142,7 +142,42 @@
   return mQuery;
 }
 
-bool QueryBuilder::exec()
+void QueryBuilder::sqliteAdaptUpdateJoin( Query::Condition &condition )
+{
+  // FIXME: This does not cover all cases by far. It however can handle most
+  // (probably all) of the update-join queries we do in Akonadi and convert 
them
+  // properly into a SQLite-compatible query. Better than nothing ;-)
+
+  if ( !condition.mSubConditions.isEmpty() ) {
+    for ( int i = condition.mSubConditions.count() - 1; i >= 0; --i ) {
+      sqliteAdaptUpdateJoin( condition.mSubConditions[i] );
+    }
+    return;
+  }
+
+  QString table;
+  if ( condition.mColumn.contains( QLatin1Char( '.' ) ) ) {
+    table = condition.mColumn.left( condition.mColumn.indexOf( QLatin1Char( 
'.' ) ) );
+  } else {
+    return;
+  }
+
+  if ( !mJoinedTables.contains( table ) ) {
+    return;
+  }
+
+  const QPair<JoinType, Query::Condition> joinCondition = mJoins.value( table 
);
+
+  QueryBuilder qb( table, Select );
+  qb.addColumn( condition.mColumn );
+  qb.addCondition( joinCondition.second );
+
+  // Convert the subquery to string
+  condition.mColumn = QLatin1String( "( " ) + qb.buildQuery() + QLatin1String( 
" )" );
+}
+
+
+QString QueryBuilder::buildQuery()
 {
   QString statement;
 
@@ -200,12 +235,16 @@
   }
   case Update:
   {
-    ///TODO: fix joined Update tables for SQLite by using subqueries
     // put the ON condition into the WHERE part of the UPDATE query
-    Q_FOREACH ( const QString &table, mJoinedTables ) {
-      QPair< JoinType, Query::Condition > join = mJoins.value( table );
-      Q_ASSERT( join.first == InnerJoin );
-      whereCondition.addCondition( join.second );
+    if ( mDatabaseType != DbType::Sqlite ) {
+      Q_FOREACH ( const QString &table, mJoinedTables ) {
+        const QPair< JoinType, Query::Condition > &join = mJoins.value( table 
);
+        Q_ASSERT( join.first == InnerJoin );
+        whereCondition.addCondition( join.second );
+      }
+    } else {
+      // Note: this will modify the whereCondition
+      sqliteAdaptUpdateJoin( whereCondition );
     }
 
     statement += QLatin1String( "UPDATE " );
@@ -279,6 +318,13 @@
     statement += QLatin1Literal( " LIMIT " ) + QString::number( mLimit );
   }
 
+  return statement;
+}
+
+bool QueryBuilder::exec()
+{
+  const QString statement = buildQuery();
+
 #ifndef QUERYBUILDER_UNITTEST
   if ( QueryCache::contains( statement ) ) {
     mQuery = QueryCache::query( statement );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/akonadi-1.10.80/server/src/storage/querybuilder.h 
new/akonadi-1.11.0/server/src/storage/querybuilder.h
--- old/akonadi-1.10.80/server/src/storage/querybuilder.h       2013-11-05 
10:28:38.000000000 +0100
+++ new/akonadi-1.11.0/server/src/storage/querybuilder.h        2013-11-28 
15:25:03.000000000 +0100
@@ -233,9 +233,16 @@
     qint64 insertId();
 
   private:
+    QString buildQuery();
     QString bindValue( const QVariant &value );
     QString buildWhereCondition( const Query::Condition &cond );
 
+    /**
+     * SQLite does not support JOINs with UPDATE, so we have to convert it into
+     * subqueries
+     */
+    void sqliteAdaptUpdateJoin( Query::Condition &cond );
+
   private:
     QString mTable;
     DbType::Type mDatabaseType;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/akonadi-1.10.80/server/tests/unittest/querybuildertest.cpp 
new/akonadi-1.11.0/server/tests/unittest/querybuildertest.cpp
--- old/akonadi-1.10.80/server/tests/unittest/querybuildertest.cpp      
2013-11-05 10:28:38.000000000 +0100
+++ new/akonadi-1.11.0/server/tests/unittest/querybuildertest.cpp       
2013-11-28 15:25:03.000000000 +0100
@@ -245,7 +245,24 @@
     qb.setDatabaseType( DbType::Sqlite );
     mBuilders << qb;
     QTest::newRow( "update inner join SQLite" ) << mBuilders.count()
-        << QString( "UPDATE table1 SET col = :0 FROM table2 WHERE ( ( SELECT 
table2.answer WHERE table2.t1_id = table1.id ) <> ( :2 ) )" ) << bindVals;
+        << QString( "UPDATE table1 SET col = :0 WHERE ( ( SELECT table2.answer 
FROM table2 WHERE ( ( table2.t1_id = table1.id ) ) ) <> ( :1 ) )" ) << bindVals;
+
+
+    qb = qbTpl;
+    qb.setDatabaseType( DbType::Sqlite );
+    Query::Condition condition;
+    condition.addValueCondition( "table2.col2", Query::Equals, 666 );
+    condition.addValueCondition( "table1.col3", Query::Equals, "text" );
+    qb.addCondition( condition );
+    qb.addValueCondition( "table1.id", Query::Equals, 10 );
+    mBuilders << qb;
+    bindVals << 666 << "text" << 10;
+    QTest::newRow( "update inner join SQLite with subcondition" ) << 
mBuilders.count()
+        << QString( "UPDATE table1 SET col = :0 WHERE ( ( SELECT table2.answer 
FROM table2 WHERE "
+                    "( ( table2.t1_id = table1.id ) ) ) <> ( :1 ) AND "
+                    "( ( SELECT table2.col2 FROM table2 WHERE ( ( table2.t1_id 
= table1.id ) ) ) = :2 AND table1.col3 = ( :3 ) ) AND "
+                    "table1.id = :4 )" ) << bindVals;
+
   }
 }
 
@@ -258,7 +275,6 @@
   --qbId;
 
   QVERIFY( mBuilders[qbId].exec() );
-  QEXPECT_FAIL( "update inner join SQLite", "SubQuery not yet implemented as 
Join-alternative in SQLite", Abort );
   QCOMPARE( mBuilders[qbId].mStatement, sql );
   QCOMPARE( mBuilders[qbId].mBindValues, bindValues );
 }

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to