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]
