Hello community, here is the log from the commit of package soprano for openSUSE:Factory checked in at Sat Apr 24 11:43:00 CEST 2010. -------- --- soprano/soprano-backend-sesame.changes 2010-03-10 00:08:11.000000000 +0100 +++ /mounts/work_src_done/STABLE/soprano/soprano-backend-sesame.changes 2010-04-21 17:02:32.000000000 +0200 @@ -1,0 +2,12 @@ +Wed Apr 21 14:53:12 UTC 2010 - bitshuffler@opensuse.org + +- Update to 2.4.2 + * LocalSocketClient and TcpClient: do not re-establish a + connection on model deletion. + (This fixes a crash when using a client as a global static) + * Properly protect ErrorCache from multithread clashes. + (Thanks to Andreas Hartmetz for the patch) + * Slight optimizations in the Virtuoso backend. + * Do not crash in ClientModel when the connection is lost. + +------------------------------------------------------------------- soprano-backend-virtuoso.changes: same change soprano.changes: same change calling whatdependson for head-i586 Old: ---- soprano-2.4.1.tar.bz2 New: ---- soprano-2.4.2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ soprano-backend-sesame.spec ++++++ --- /var/tmp/diff_new_pack.2P88U5/_old 2010-04-24 11:42:32.000000000 +0200 +++ /var/tmp/diff_new_pack.2P88U5/_new 2010-04-24 11:42:32.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package soprano-backend-sesame (Version 2.4.1) +# spec file for package soprano-backend-sesame (Version 2.4.2) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -29,15 +29,15 @@ # COMMON1-BEGIN BuildRequires: cmake kde4-filesystem libqt4-devel libraptor-devel libredland-devel BuildRequires: clucene-core-devel doxygen raptor -Version: 2.4.1 +Version: 2.4.2 Release: 1 Source: soprano-%{version}.tar.bz2 Source2: baselibs.conf # COMMON1-END # COMMON1-END -Provides: soprano_backend = %version -Provides: backend-sesame2 = %version -Requires: libsoprano4 = %version +Provides: soprano_backend = %{version} +Provides: backend-sesame2 = %{version} +Requires: libsoprano4 = %{version} %description This package provides a Sesame based backend for Soprano. @@ -61,14 +61,14 @@ cd backends/sesame2 %makeinstall %if %suse_version > 1020 - %fdupes -s $RPM_BUILD_ROOT/usr/include + %fdupes -s %{buildroot}%{_includedir} %endif cd .. %files %defattr(-,root,root) -/usr/share/soprano/sesame2 -%_libdir/soprano/libsoprano_sesame2backend.so -/usr/share/soprano/plugins/sesame2backend.desktop +%{_datadir}/soprano/sesame2 +%{_libdir}/soprano/libsoprano_sesame2backend.so +%{_datadir}/soprano/plugins/sesame2backend.desktop %changelog ++++++ soprano-backend-virtuoso.spec ++++++ --- /var/tmp/diff_new_pack.2P88U5/_old 2010-04-24 11:42:32.000000000 +0200 +++ /var/tmp/diff_new_pack.2P88U5/_new 2010-04-24 11:42:32.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package soprano-backend-virtuoso (Version 2.4.1) +# spec file for package soprano-backend-virtuoso (Version 2.4.2) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -29,15 +29,15 @@ # COMMON1-BEGIN BuildRequires: cmake kde4-filesystem libqt4-devel libraptor-devel libredland-devel BuildRequires: clucene-core-devel doxygen raptor -Version: 2.4.1 +Version: 2.4.2 Release: 1 Source: soprano-%{version}.tar.bz2 Source2: baselibs.conf # COMMON1-END # COMMON1-END -Provides: soprano_backend = %version -Provides: backend-virtuso = %version -Requires: libsoprano4 = %version +Provides: soprano_backend = %{version} +Provides: backend-virtuso = %{version} +Requires: libsoprano4 = %{version} Requires: virtuoso-server %description @@ -61,13 +61,13 @@ cd backends/virtuoso %makeinstall %if %suse_version > 1020 - %fdupes -s $RPM_BUILD_ROOT/usr/include + %fdupes -s %{buildroot}%{_includedir} %endif cd .. %files %defattr(-,root,root) -%_libdir/soprano/libsoprano_virtuosobackend.so -/usr/share/soprano/plugins/virtuosobackend.desktop +%{_libdir}/soprano/libsoprano_virtuosobackend.so +%{_datadir}/soprano/plugins/virtuosobackend.desktop %changelog ++++++ soprano.spec ++++++ --- /var/tmp/diff_new_pack.2P88U5/_old 2010-04-24 11:42:32.000000000 +0200 +++ /var/tmp/diff_new_pack.2P88U5/_new 2010-04-24 11:42:32.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package soprano (Version 2.4.1) +# spec file for package soprano (Version 2.4.2) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -20,19 +20,19 @@ Name: soprano Url: http://soprano.sourceforge.net/ BuildRequires: fdupes -License: GPLv2+ ; LGPLv2.1+ +License: LGPLv2.1+ Group: Development/Libraries/C and C++ Summary: C++/Qt based interface library for RDF # COMMON1-BEGIN BuildRequires: cmake kde4-filesystem libqt4-devel libraptor-devel libredland-devel BuildRequires: clucene-core-devel doxygen raptor -Version: 2.4.1 +Version: 2.4.2 Release: 1 Source: soprano-%{version}.tar.bz2 Source2: baselibs.conf # COMMON1-END Requires: libsoprano4 = %{version} -Recommends: soprano_backend = %version +Recommends: soprano_backend = %{version} Recommends: soprano-backend-virtuoso BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -125,7 +125,7 @@ cd build %makeinstall %if %suse_version > 1020 - %fdupes -s $RPM_BUILD_ROOT/usr/include + %fdupes -s %{buildroot}%{_includedir} %endif %post -n libsoprano4 -p /sbin/ldconfig @@ -135,57 +135,57 @@ %files %defattr(-,root,root) %doc AUTHORS TODO -/usr/bin/onto2vocabularyclass -/usr/bin/sopranocmd -/usr/bin/sopranod -/usr/share/dbus-1/interfaces/org.soprano.Model.xml -/usr/share/dbus-1/interfaces/org.soprano.NodeIterator.xml -/usr/share/dbus-1/interfaces/org.soprano.QueryResultIterator.xml -/usr/share/dbus-1/interfaces/org.soprano.Server.xml -/usr/share/dbus-1/interfaces/org.soprano.StatementIterator.xml -%dir /usr/share/soprano -%dir /usr/share/soprano/rules -%dir /usr/share/soprano/plugins -/usr/share/soprano/rules/* -/usr/share/soprano/plugins/nquadparser.desktop -/usr/share/soprano/plugins/nquadserializer.desktop -/usr/share/soprano/plugins/raptorparser.desktop -/usr/share/soprano/plugins/raptorserializer.desktop -%dir %_libdir/soprano -%_libdir/soprano/libsoprano_nquadparser.so -%_libdir/soprano/libsoprano_nquadserializer.so -%_libdir/soprano/libsoprano_raptorparser.so -%_libdir/soprano/libsoprano_raptorserializer.so +%{_bindir}/onto2vocabularyclass +%{_bindir}/sopranocmd +%{_bindir}/sopranod +%{_datadir}/dbus-1/interfaces/org.soprano.Model.xml +%{_datadir}/dbus-1/interfaces/org.soprano.NodeIterator.xml +%{_datadir}/dbus-1/interfaces/org.soprano.QueryResultIterator.xml +%{_datadir}/dbus-1/interfaces/org.soprano.Server.xml +%{_datadir}/dbus-1/interfaces/org.soprano.StatementIterator.xml +%dir %{_datadir}/soprano +%dir %{_datadir}/soprano/rules +%dir %{_datadir}/soprano/plugins +%{_datadir}/soprano/rules/* +%{_datadir}/soprano/plugins/nquadparser.desktop +%{_datadir}/soprano/plugins/nquadserializer.desktop +%{_datadir}/soprano/plugins/raptorparser.desktop +%{_datadir}/soprano/plugins/raptorserializer.desktop +%dir %{_libdir}/soprano +%{_libdir}/soprano/libsoprano_nquadparser.so +%{_libdir}/soprano/libsoprano_nquadserializer.so +%{_libdir}/soprano/libsoprano_raptorparser.so +%{_libdir}/soprano/libsoprano_raptorserializer.so %files -n libsoprano4 %defattr(-,root,root) -%_libdir/libsopranoclient.so.1 -%_libdir/libsopranoclient.so.1.2.0 -%_libdir/libsopranoserver.so.1 -%_libdir/libsopranoserver.so.1.2.0 -%_libdir/libsoprano.so.4 -%_libdir/libsoprano.so.4.3.0 -%_libdir/libsopranoindex.so.1 -%_libdir/libsopranoindex.so.1.1.0 +%{_libdir}/libsopranoclient.so.1 +%{_libdir}/libsopranoclient.so.1.2.0 +%{_libdir}/libsopranoserver.so.1 +%{_libdir}/libsopranoserver.so.1.2.0 +%{_libdir}/libsoprano.so.4 +%{_libdir}/libsoprano.so.4.3.0 +%{_libdir}/libsopranoindex.so.1 +%{_libdir}/libsopranoindex.so.1.1.0 %files -n libsoprano-devel %defattr(-,root,root) -/usr/include/soprano -/usr/include/Soprano -%_libdir/libsoprano.so -%_libdir/libsopranoindex.so -%_libdir/libsopranoclient.so -%_libdir/libsopranoserver.so -%_libdir/pkgconfig/soprano.pc -%_libdir/pkgconfig/sopranoclient.pc -%_libdir/pkgconfig/sopranoindex.pc -%_libdir/pkgconfig/sopranoserver.pc -%dir /usr/share/soprano/cmake -/usr/share/soprano/cmake/SopranoAddOntology.cmake +%{_includedir}/soprano +%{_includedir}/Soprano +%{_libdir}/libsoprano.so +%{_libdir}/libsopranoindex.so +%{_libdir}/libsopranoclient.so +%{_libdir}/libsopranoserver.so +%{_libdir}/pkgconfig/soprano.pc +%{_libdir}/pkgconfig/sopranoclient.pc +%{_libdir}/pkgconfig/sopranoindex.pc +%{_libdir}/pkgconfig/sopranoserver.pc +%dir %{_datadir}/soprano/cmake +%{_datadir}/soprano/cmake/SopranoAddOntology.cmake %files backend-redland %defattr(-,root,root) -%_libdir/soprano/libsoprano_redlandbackend.so -/usr/share/soprano/plugins/redlandbackend.desktop +%{_libdir}/soprano/libsoprano_redlandbackend.so +%{_datadir}/soprano/plugins/redlandbackend.desktop %changelog ++++++ soprano-2.4.1.tar.bz2 -> soprano-2.4.2.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/CMakeLists.txt new/soprano-2.4.2/CMakeLists.txt --- old/soprano-2.4.1/CMakeLists.txt 2010-03-01 10:58:45.000000000 +0100 +++ new/soprano-2.4.2/CMakeLists.txt 2010-03-08 10:06:42.000000000 +0100 @@ -7,7 +7,7 @@ ################## Soprano version ################################ set(CMAKE_SOPRANO_VERSION_MAJOR 2) set(CMAKE_SOPRANO_VERSION_MINOR 4) -set(CMAKE_SOPRANO_VERSION_RELEASE 61) +set(CMAKE_SOPRANO_VERSION_RELEASE 2) set(CMAKE_SOPRANO_VERSION_STRING "${CMAKE_SOPRANO_VERSION_MAJOR}.${CMAKE_SOPRANO_VERSION_MINOR}.${CMAKE_SOPRANO_VERSION_RELEASE}") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/ChangeLog new/soprano-2.4.2/ChangeLog --- old/soprano-2.4.1/ChangeLog 2010-02-11 13:40:16.000000000 +0100 +++ new/soprano-2.4.2/ChangeLog 2010-04-12 14:50:10.000000000 +0200 @@ -1,3 +1,23 @@ +2.4.2 + * LocalSocketClient and TcpClient: do not re-establish a connection on model deletion. + (This fixes a crash when using a client as a global static) + * Properly protect ErrorCache from multithread clashes. (Thanks to Andreas Hartmetz for the patch) + * Slight optimizations in the Virtuoso backend. + * Do not crash in ClientModel when the connection is lost. + +2.4.1 + * Virtuoso backend: + - new parameter "forcedstart" which when set will make the backend shut down + any running Virtuoso instance already accessing the storage dir (does not work on Windows). + - Shut down Virtuoso using the SIGINT signal (not available on Windows) to ensure + a checkpoint. + * Allow to build Soprano with -fvisibility=hidden -fvisibility-inlines-hidden (thanks to + Modestas Vainius of Debian for the patch) + * PkgConfig files for sopranoclient, sopranoserver, and sopranoindex. + +2.4.0.1 + * Fixed a bug in the ClientConnection where mutex was deleted before it had been unlocked. + 2.4.0 * New methods Client::SparqlModel::listStatementsAsync and Client::SparqlModel::listContextsAsync * Automatic query prefix expansion in NRLModel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/Mainpage.dox new/soprano-2.4.2/Mainpage.dox --- old/soprano-2.4.1/Mainpage.dox 2010-02-27 19:27:29.000000000 +0100 +++ new/soprano-2.4.2/Mainpage.dox 2009-06-30 10:57:50.000000000 +0200 @@ -2,18 +2,18 @@ * \mainpage Soprano (aka QRDF) - A modular RDF storage framework * * %Soprano is a <a href="http://www.qtsoftware.com/">Qt</a>-based pluggable framework for <a href="http://www.w3.org/RDF/">RDF</a> - * storage and parsing. It tries to provide a highly usable interface to several Resource Description Framework (RDF) storage solutions. + * storage and parsing. It tries to provide a highly usable interface to several RDF storage solutions. * * \section overview Overview * * %Soprano centers around the Soprano::Model class which represents one storage set. A Soprano::Model is basically a set of * RDF quadruples, i.e. Soprano::Statement. The actual storage is done via Soprano::Backend plugins. All - * query operations return Soprano::Iterator instances. Iterator is an explicitly shared class which is very + * query operations return Soprano::Iterator instances. Iterator is a explicitely shared class which is very * easy to understand and use. * * %Soprano makes the distinction between two types of Models: Soprano::StorageModel and Soprano::FilterModel. - * The former is intended to be the basic Model which actually stores the data while the latter can be - * stacked on top of a Soprano::StorageModel to perform certain filter operations. These filter operations can range + * The former one is intended to be the basic Model which actually stores the data while the latter ones can be + * stacked on top of a Soprano::StorageModel to perform certain filter operations. Thes filter operations can range * from very basic things such as disallowing any write operation (Soprano::Util::ReadOnlyModel) to more complex * things such as full text indexing of all literal statements (Soprano::Index::IndexFilterModel) or exporting * the Model via D-Bus (Soprano::Server::DBusExportModel). @@ -21,7 +21,7 @@ * Apart from storage %Soprano provides a system for RDF parser and serializer plugins. For more details on parsing * or serializing RDF data see the Soprano::Parser and Soprano::Serializer classes. * - * %Soprano comes with a built in \link Soprano::Server Server \endlink and \link Soprano::Client Client \endlink implementations allowing remote repositories to be built quickly. + * %Soprano comes with a builtin \link Soprano::Server Server \endlink and \link Soprano::Client Client \endlink implementations allowing to build remote repositories quickly. * Soprano::Client::SparqlModel provides a client to arbitrary <a href="http://www.w3.org/TR/rdf-sparql-protocol/">SPARQL (SPARQL Protocol and RDF Query Language)</a> * Http services. * @@ -85,7 +85,7 @@ * * Model instances are mostly created by the plugin implementations through the * Soprano::Backend::createModel() methods. In the most simple case one does not need to bother - * with Soprano::Backend though, as the basic methods are duplicated in the Soprano + * with Soprano::Backend though as the basic methods are duplicated in the Soprano * namespace. Thus, to create a simple memory model using the default %Soprano backend: * * \code @@ -111,7 +111,7 @@ /** * \page soprano_backends Soprano Backends * - * %Soprano is plugin based and comes with three backend plugins which can be used directly + * %Soprano is plug-in based and comes with three backend plug-ins which can be used directly * (if they have been built): * * \li \subpage soprano_backend_redland @@ -145,8 +145,8 @@ * } * \endcode * - * For methods that do not return an immediate error status, Soprano::Error::Error evaluates to a boolean. Thus, one can easily - * check if an error occurred as follows: + * For methods that do not return an immediate error status Soprano::Error::Error evalutes to a boolean. Thus, one can easily + * check if an error occured as follows: * * \code * Soprano::StatementIterator it = model->listStatements(); @@ -190,7 +190,7 @@ * }; * \endcode * - * In the implementation file, export the plugin so that it can be picked up by the + * In the implementation file export the plugin so it can be picked up by the * plugin loading framework: * * \code @@ -388,7 +388,7 @@ * * \subsection cmake Using CMake with Soprano * - * Using cmake is simple. Find required packages \em Qt4 and \em PkgConfig, look for %Soprano via PkgConfig and link to both + * Using cmake is as simple. Find required packages \em Qt4 and \em PkgConfig, look for %Soprano via PkgConfig and link to both * %Soprano and QtCore: * * \code @@ -400,12 +400,12 @@ * target_link_libraries(sopranotest ${Soprano_LIBRARIES} ${QT_QTCORE_LIBRARY}) * \endcode * - * \warning PkgConfig is not available on Windows. For platform independent development use a typical cmake module like + * \warning PkgConfig is not available on Windows. For platform independant development use a typical cmake module like * KDE's <a href="http://websvn.kde.org:80/%2Acheckout%2A/trunk/KDE/kdelibs/cmake/modules/FindSoprano.cmake">FindSoprano.cmake</a>. * * \subsubsection cmake_magic Some CMake Magic * - * %Soprano provides the simple \ref onto2vocabularyclass tool which can generate convenience namespaces such as Soprano::Vocabulary::RDF + * %Soprano provides the simple \ref onto2vocabularyclass tool which can generate convinience namespaces such as Soprano::Vocabulary::RDF * from ontology files. With CMake it is very simple to generate these namespaces on-the-fly instead of packaging the generated files by * using the SopranoAddOntology macro provided by %Soprano: * @@ -418,7 +418,7 @@ * [VISIBLITY VISIBILITY_NAME]) * \endcode * - * Imagine one's code contains an ontology description in rdf+xml format named Foo (Foo Object Ontology) and you want to make its classes and + * Imagine ones code contains an ontology description in rdf+xml format named Foo (Foo Object Ontology) and you want to make it's classes and * properties accessible in the <em>MyStuff::Foo</em> namespace. One simply includes the cmake macro provided by Soprano: * * \code diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/odbcqueryresult.cpp new/soprano-2.4.2/backends/virtuoso/odbcqueryresult.cpp --- old/soprano-2.4.1/backends/virtuoso/odbcqueryresult.cpp 2009-11-09 11:36:35.000000000 +0100 +++ new/soprano-2.4.2/backends/virtuoso/odbcqueryresult.cpp 2010-04-12 13:58:24.000000000 +0200 @@ -205,21 +205,25 @@ return Node(); } - QUrl type = QUrl::fromEncoded( QByteArray::fromRawData( reinterpret_cast<const char*>( typeBuf ), typeBufLen ), QUrl::StrictMode ); - QString lang = QString::fromLatin1( reinterpret_cast<const char*>( langBuf ), langBufLen ); const char* str = reinterpret_cast<const char*>( data ); + const char* typeStr = reinterpret_cast<const char*>( typeBuf ); - if ( type == Virtuoso::fakeBooleanType() ) { - node = Node( LiteralValue( !qstrcmp( "true", str ) ) ); + if ( typeBufLen > 0 ) { + if ( !qstrncmp( typeStr, Virtuoso::fakeBooleanTypeString(), typeBufLen ) ) { + node = Node( LiteralValue( !qstrcmp( "true", str ) ) ); + } + else { + QUrl type; + if ( !qstrncmp( typeStr, Virtuoso::fakeBase64BinaryTypeString(), typeBufLen ) ) + type = Soprano::Vocabulary::XMLSchema::base64Binary(); + else + type = QUrl::fromEncoded( QByteArray::fromRawData( typeStr, typeBufLen ), QUrl::StrictMode ); + node = Node( LiteralValue::fromString( QString::fromUtf8( str ), type ) ); + } } else { - if ( type == Virtuoso::fakeBase64BinaryType() ) - type = Soprano::Vocabulary::XMLSchema::base64Binary(); - - if ( type.isEmpty() ) - node = Node( LiteralValue::createPlainLiteral( QString::fromUtf8( str ), lang ) ); - else - node = Node( LiteralValue::fromString( QString::fromUtf8( str ), type ) ); + QString lang = QString::fromLatin1( reinterpret_cast<const char*>( langBuf ), langBufLen ); + node = Node( LiteralValue::createPlainLiteral( QString::fromUtf8( str ), lang ) ); } break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/virtuosoconfigurator.cpp new/soprano-2.4.2/backends/virtuoso/virtuosoconfigurator.cpp --- old/soprano-2.4.1/backends/virtuoso/virtuosoconfigurator.cpp 2009-10-28 12:15:13.000000000 +0100 +++ new/soprano-2.4.2/backends/virtuoso/virtuosoconfigurator.cpp 2010-04-12 13:58:24.000000000 +0200 @@ -1,7 +1,7 @@ /* * This file is part of Soprano Project * - * Copyright (C) 2009 Sebastian Trueg <trueg@kde.org> + * Copyright (C) 2009-2010 Sebastian Trueg <trueg@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -178,7 +178,7 @@ // set the batch updating behaviour: // for sync updating batch updating needs to be disabled (second param "OFF") // for batch updating the third parameter specifies the interval in minutes. - return( m_connection->executeCommand( QString( "DB.DBA.VT_BATCH_UPDATE ('DB.DBA.RDF_OBJ', '%1', %2)" ) + return( m_connection->executeCommand( QString::fromLatin1( "DB.DBA.VT_BATCH_UPDATE ('DB.DBA.RDF_OBJ', '%1', %2)" ) .arg( ( enableIndexing && !syncUpdating ) ? QLatin1String( "ON" ) : QLatin1String( "OFF" ) ) .arg( ( enableIndexing && updateIntervalSpecified ) ? state : QLatin1String( "null" ) ) ) == Error::ErrorNone ); @@ -187,7 +187,8 @@ bool Soprano::Virtuoso::DatabaseConfigurator::updateFulltextIndexRules( bool enable ) { - QString query = QLatin1String( "SELECT ROFR_REASON FROM DB.DBA.RDF_OBJ_FT_RULES WHERE ROFR_G=null AND ROFR_P=null" ); + // while we are using "null" as parameters to the rule procedures below the table actually stores empty strings + QString query = QLatin1String( "SELECT ROFR_REASON FROM DB.DBA.RDF_OBJ_FT_RULES WHERE ROFR_G='' AND ROFR_P=''" ); bool haveRule = false; @@ -206,10 +207,10 @@ } if ( enable && !haveRule ) { - return m_connection->executeCommand( QString( "DB.DBA.RDF_OBJ_FT_RULE_ADD( null, null, '%1' )" ).arg( ruleName ) ) == Error::ErrorNone; + return m_connection->executeCommand( QString::fromLatin1( "DB.DBA.RDF_OBJ_FT_RULE_ADD( null, null, '%1' )" ).arg( ruleName ) ) == Error::ErrorNone; } else if ( !enable && haveRule ) { - return m_connection->executeCommand( QString( "DB.DBA.RDF_OBJ_FT_RULE_DEL( null, null, '%1' )" ).arg( ruleName ) ) == Error::ErrorNone; + return m_connection->executeCommand( QString::fromLatin1( "DB.DBA.RDF_OBJ_FT_RULE_DEL( null, null, '%1' )" ).arg( ruleName ) ) == Error::ErrorNone; } else { return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/virtuosomodel.cpp new/soprano-2.4.2/backends/virtuoso/virtuosomodel.cpp --- old/soprano-2.4.1/backends/virtuoso/virtuosomodel.cpp 2009-12-02 14:50:11.000000000 +0100 +++ new/soprano-2.4.2/backends/virtuoso/virtuosomodel.cpp 2010-04-12 13:58:24.000000000 +0200 @@ -1,7 +1,7 @@ /* * This file is part of Soprano Project * - * Copyright (C) 2008-2009 Sebastian Trueg <trueg@kde.org> + * Copyright (C) 2008-2010 Sebastian Trueg <trueg@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -52,28 +52,28 @@ QString query; if ( withContext ) { - query += "graph "; + query += QLatin1String( "graph " ); if ( s.context().isValid() ) { query += nodeToN3( s.context() ); } else { - query += "?g"; + query += QLatin1String( "?g" ); } - query += " { "; + query += QLatin1String( " { " ); } if ( s.subject().isValid() ) { query += nodeToN3( s.subject() ) + ' '; } else { - query += "?s "; + query += QLatin1String( "?s " ); } if ( s.predicate().isValid() ) { query += nodeToN3( s.predicate() ) + ' '; } else { - query += "?p "; + query += QLatin1String( "?p " ); } if ( s.object().isValid() ) { @@ -87,16 +87,18 @@ query += nodeToN3( s.object() ); } else { - query += "?o"; + query += QLatin1String( "?o" ); } if ( withContext ) { - query += " . }"; + query += QLatin1String( " . }" ); } return query; } + // there is still a bug in Virtuoso which makes the define prefix unusable: if a query defines the + // graph the result will be empty if the exclude graph is specified. const char* s_queryPrefix = "sparql "; // "define input:default-graph-exclude <http://www.openlinksw.com/schemas/virtrdf#> " @@ -146,7 +148,7 @@ s.setContext( Virtuoso::defaultGraph() ); } - QString insert = QString("sparql insert into %1") + QString insert = QString::fromLatin1("sparql insert into %1") .arg( statementToConstructGraphPattern( s, true ) ); if ( ODBC::Connection* conn = d->connectionPool->connection() ) { @@ -175,11 +177,11 @@ { // qDebug() << Q_FUNC_INFO; - return executeQuery( QString( "select distinct ?g where { " - "graph ?g { ?s ?p ?o . } . " - "FILTER(?g != %1 && ?g != %2) . }" ) - .arg( Node::resourceToN3( Virtuoso::defaultGraph() ) ) - .arg( Node::resourceToN3( Virtuoso::openlinkVirtualGraph() ) ) ) + return executeQuery( QString::fromLatin1( "select distinct ?g where { " + "graph ?g { ?s ?p ?o . } . " + "FILTER(?g != <%1> && ?g != <%2>) . }" ) + .arg( QLatin1String( Virtuoso::defaultGraphString() ), + QLatin1String( Virtuoso::openlinkVirtualGraphString() ) ) ) .iterateBindings( 0 ); } @@ -207,9 +209,9 @@ QString query; if ( statement.context().isValid() ) - query = QString( "ask from %1 where { %2 . }" ).arg( statement.context().toN3(), statementToConstructGraphPattern( statement, false ) ); + query = QString::fromLatin1( "ask from %1 where { %2 . }" ).arg( statement.context().toN3(), statementToConstructGraphPattern( statement, false ) ); else - query = QString( "ask where { %1 . }" ).arg( statementToConstructGraphPattern( statement, true ) ); + query = QString::fromLatin1( "ask where { %1 . }" ).arg( statementToConstructGraphPattern( statement, true ) ); // if ( VirtuosoStatementHandler* sh = d->connection.execute( "sparql " + query ) ) { // bool b = sh->fetchScroll(); // delete sh; @@ -227,11 +229,12 @@ // we cannot use a construct query due to missing graph support QString query; if ( partial.context().isValid() ) - query = QString( "select * from %1 where { %2 . }" ).arg( partial.context().toN3(), statementToConstructGraphPattern( partial, false ) ); + query = QString::fromLatin1( "select * from %1 where { %2 . }" ) + .arg( partial.context().toN3(), statementToConstructGraphPattern( partial, false ) ); else - query = QString( "select * where { %1 . FILTER(?g != %2) . }" ) - .arg( statementToConstructGraphPattern( partial, true ) ) - .arg( Node::resourceToN3( Virtuoso::openlinkVirtualGraph() ) ); + query = QString::fromLatin1( "select * where { %1 . FILTER(?g != <%2>) . }" ) + .arg( statementToConstructGraphPattern( partial, true ), + QLatin1String( Virtuoso::openlinkVirtualGraphString() ) ); // qDebug() << "List Statements Query" << query; return executeQuery( query, Query::QueryLanguageSparql ) .iterateStatementsFromBindings( partial.subject().isValid() ? QString() : QString( 's' ), @@ -260,11 +263,11 @@ return Error::ErrorInvalidArgument; } - QString query = QString( "delete from %1" ) + QString query = QString::fromLatin1( "delete from %1" ) .arg( statementToConstructGraphPattern( s, true ) ); // qDebug() << "removeStatement query:" << query; if ( ODBC::Connection* conn = d->connectionPool->connection() ) { - if ( conn->executeCommand( "sparql " + query ) == Error::ErrorNone ) { + if ( conn->executeCommand( QLatin1String( "sparql " ) + query ) == Error::ErrorNone ) { // FIXME: can this be done with SQL/RDF views? emit statementRemoved( statement ); emit statementsRemoved(); @@ -294,16 +297,16 @@ !statement.predicate().isValid() && !statement.object().isValid() ) { // Virtuoso docu says this might be faster - query = QString( "clear graph %1" ).arg( statement.context().toN3() ); + query = QString::fromLatin1( "clear graph %1" ).arg( statement.context().toN3() ); } else { - query = QString( "delete from %1 { %2 } where { %3 }" ) + query = QString::fromLatin1( "delete from %1 { %2 } where { %3 }" ) .arg( statement.context().isValid() ? statement.context().toN3() : QString( "?g" ) ) .arg( statementToConstructGraphPattern( statement, false ) ) .arg( statementToConstructGraphPattern( statement, true ) ); } - qDebug() << "removeAllStatements query:" << query; +// qDebug() << "removeAllStatements query:" << query; if ( ODBC::Connection* conn = d->connectionPool->connection() ) { if ( conn->executeCommand( "sparql " + query ) == Error::ErrorNone ) { // FIXME: can this be done with SQL/RDF views? @@ -319,9 +322,9 @@ } else { // FIXME: do this in a fancy way, maybe an inner sql query or something - QList<Node> allContexts = executeQuery( QString( "select distinct ?g where { %1 . FILTER(?g != %2) . }" ) + QList<Node> allContexts = executeQuery( QString::fromLatin1( "select distinct ?g where { %1 . FILTER(?g != <%2>) . }" ) .arg( statementToConstructGraphPattern( statement, true ) ) - .arg( Node::resourceToN3( Virtuoso::openlinkVirtualGraph() ) ) ) + .arg( QLatin1String( Virtuoso::openlinkVirtualGraphString() ) ) ) .iterateBindings( 0 ).allNodes(); foreach( const Node& node, allContexts ) { Statement s( statement ); @@ -338,12 +341,12 @@ #if 0 QStringList conditions; if ( statement.subject().isValid() ) - conditions << QString( "s=iri_to_id ('')" ).arg( QString::fromAscii( statement.subject().uri().toEncoded() ) ); + conditions << QString::fromLatin1( "s=iri_to_id ('')" ).arg( QString::fromAscii( statement.subject().uri().toEncoded() ) ); if ( statement.predicate().isValid() ) - conditions << QString( "p=iri_to_id ('')" ).arg( QString::fromAscii( statement.predicate().uri().toEncoded() ) ); + conditions << QString::fromLatin1( "p=iri_to_id ('')" ).arg( QString::fromAscii( statement.predicate().uri().toEncoded() ) ); if ( statement.object().isValid() ) { if ( statement.object().isResource() ) { - conditions << QString( "o=iri_to_id ('')" ).arg( QString::fromAscii( statement.object().uri().toEncoded() ) ); + conditions << QString::fromLatin1( "o=iri_to_id ('')" ).arg( QString::fromAscii( statement.object().uri().toEncoded() ) ); } else { Q_ASSERT( 0 ); @@ -376,10 +379,10 @@ { // qDebug() << Q_FUNC_INFO; - QueryResultIterator it = executeQuery( QString( "select count(*) where { " - "graph ?g { ?s ?p ?o . } . " - "FILTER(?g != %1) . }" ) - .arg( Node::resourceToN3( Virtuoso::openlinkVirtualGraph() ) ) ); + QueryResultIterator it = executeQuery( QString::fromLatin1( "select count(*) where { " + "graph ?g { ?s ?p ?o . } . " + "FILTER(?g != <%1>) . }" ) + .arg( QLatin1String( Virtuoso::openlinkVirtualGraphString() ) ) ); if ( it.isValid() && it.next() ) { return it.binding( 0 ).literal().toInt(); } @@ -402,15 +405,20 @@ { // qDebug() << Q_FUNC_INFO << query; + QString finalQuery( query ); + if ( language != Soprano::Query::QueryLanguageSparql ) { - setError( Error::Error( QString( "Unsupported query language %1." ) + setError( Error::Error( QString::fromLatin1( "Unsupported query language %1." ) .arg( Query::queryLanguageToString( language, userQueryLanguage ) ) ) ); return QueryResultIterator(); } - // exclude the default system graph via defines from s_queryPrefix + finalQuery.prepend( QLatin1String( s_queryPrefix ) + ' ' ); + +// qDebug() << Q_FUNC_INFO << finalQuery; + if ( ODBC::Connection* conn = d->connectionPool->connection() ) { - ODBC::QueryResult* result = conn->executeQuery( QLatin1String( s_queryPrefix ) + ' ' + query ); + ODBC::QueryResult* result = conn->executeQuery( finalQuery ); if ( result ) { clearError(); Virtuoso::QueryResultIteratorBackend* backend = new Virtuoso::QueryResultIteratorBackend( result ); @@ -419,7 +427,7 @@ return backend; } else { - qDebug() << "Query failed:" << query; + qDebug() << "Query failed:" << finalQuery; setError( conn->lastError() ); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/virtuosoqueryresultiteratorbackend.cpp new/soprano-2.4.2/backends/virtuoso/virtuosoqueryresultiteratorbackend.cpp --- old/soprano-2.4.1/backends/virtuoso/virtuosoqueryresultiteratorbackend.cpp 2009-11-06 22:08:20.000000000 +0100 +++ new/soprano-2.4.2/backends/virtuoso/virtuosoqueryresultiteratorbackend.cpp 2010-04-12 13:58:24.000000000 +0200 @@ -56,11 +56,10 @@ d->bindingCachedFlags = QBitArray( d->bindingNames.count(), false ); d->bindingCache.resize( d->bindingNames.count() ); - // ASK queries are rather easy to detect // ===================================== if ( d->bindingNames.count() == 1 && - d->bindingNames[0] == "__ASK_RETVAL" ) { + d->bindingNames[0] == QLatin1String( "__ASK_RETVAL" ) ) { d->m_resultType = QueryResultIteratorBackendPrivate::AskResult; // cache the result // virtuoso returns an empty result set for false boolean results @@ -78,7 +77,8 @@ // Graph queries are a little trickier // ===================================== else if ( d->bindingNames.count() == 1 && - d->bindingNames[0] == "callret-0" ) { + ( d->bindingNames[0] == QLatin1String( "callret-0" ) || + d->bindingNames[0] == QLatin1String( "fmtaggret-" ) ) ) { // try to be 6.1.1 compatible if ( d->m_queryResult->fetchRow() ) { Node node = d->m_queryResult->getData( 1 ); if ( !d->m_queryResult->lastError() ) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/virtuosotools.cpp new/soprano-2.4.2/backends/virtuoso/virtuosotools.cpp --- old/soprano-2.4.1/backends/virtuoso/virtuosotools.cpp 2009-10-13 11:33:33.000000000 +0200 +++ new/soprano-2.4.2/backends/virtuoso/virtuosotools.cpp 2010-04-12 13:58:24.000000000 +0200 @@ -1,7 +1,7 @@ /* * This file is part of Soprano Project * - * Copyright (C) 2008 Sebastian Trueg <trueg@kde.org> + * Copyright (C) 2008-2010 Sebastian Trueg <trueg@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,11 +23,6 @@ #include <QtCore/QString> -// we have no support for a real default/empty graph, thus we fake one, hoping that nobody will ever use this otherwise -static const char* s_defaultGraph = "sopranofakes:/DEFAULTGRAPH"; -static const char* s_openlinkVirtualGraph = "http://www.openlinksw.com/schemas/virtrdf#"; - - Soprano::Error::Error Soprano::Virtuoso::convertSqlError( SQLSMALLINT handleType, SQLHANDLE handle, const QString& extraMessage ) { SQLTCHAR buf[513]; @@ -62,25 +57,75 @@ } +namespace { + // we have no support for a real default/empty graph, thus we fake one, hoping that nobody will ever use this otherwise + const char* s_defaultGraph = "sopranofakes:/DEFAULTGRAPH"; + const char* s_openlinkVirtualGraph = "http://www.openlinksw.com/schemas/virtrdf#"; + const char* s_fakeBooleanType = "sopranofakes:/booleanHackUntilVirtuosoProblemIsResolved"; + const char* s_fakeBase64Type = "sopranofakes:/base64BinaryHackUntilVirtuosoProblemIsResolved"; + + class VirtuosoUriCache { + public: + VirtuosoUriCache() + : defaultGraph( QUrl::fromEncoded( s_defaultGraph, QUrl::StrictMode ) ), + openlinkVirtualGraph( QUrl::fromEncoded( s_openlinkVirtualGraph, QUrl::StrictMode ) ), + fakeBooleanType( QUrl::fromEncoded( s_fakeBooleanType, QUrl::StrictMode ) ), + fakeBase64BinaryType( QUrl::fromEncoded( s_fakeBase64Type, QUrl::StrictMode ) ) { + } + + QUrl defaultGraph; + QUrl openlinkVirtualGraph; + QUrl fakeBooleanType; + QUrl fakeBase64BinaryType; + }; +} + +Q_GLOBAL_STATIC( VirtuosoUriCache, virtuosoUriCache ) + + QUrl Soprano::Virtuoso::defaultGraph() { - return QUrl::fromEncoded( s_defaultGraph, QUrl::StrictMode ); + return virtuosoUriCache()->defaultGraph; } QUrl Soprano::Virtuoso::openlinkVirtualGraph() { - return QUrl::fromEncoded( s_openlinkVirtualGraph, QUrl::StrictMode ); + return virtuosoUriCache()->openlinkVirtualGraph; } QUrl Soprano::Virtuoso::fakeBooleanType() { - return QUrl::fromEncoded( "sopranofakes:/booleanHackUntilVirtuosoProblemIsResolved", QUrl::StrictMode ); + return virtuosoUriCache()->fakeBooleanType; } QUrl Soprano::Virtuoso::fakeBase64BinaryType() { - return QUrl::fromEncoded( "sopranofakes:/base64BinaryHackUntilVirtuosoProblemIsResolved", QUrl::StrictMode ); + return virtuosoUriCache()->fakeBase64BinaryType; +} + + +const char* Soprano::Virtuoso::defaultGraphString() +{ + return s_defaultGraph; +} + + +const char* Soprano::Virtuoso::openlinkVirtualGraphString() +{ + return s_openlinkVirtualGraph; +} + + +const char* Soprano::Virtuoso::fakeBooleanTypeString() +{ + return s_fakeBooleanType; +} + + +const char* Soprano::Virtuoso::fakeBase64BinaryTypeString() +{ + return s_fakeBase64Type; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/backends/virtuoso/virtuosotools.h new/soprano-2.4.2/backends/virtuoso/virtuosotools.h --- old/soprano-2.4.1/backends/virtuoso/virtuosotools.h 2009-12-08 17:12:38.000000000 +0100 +++ new/soprano-2.4.2/backends/virtuoso/virtuosotools.h 2010-04-12 13:58:24.000000000 +0200 @@ -40,6 +40,11 @@ QUrl openlinkVirtualGraph(); QUrl fakeBooleanType(); QUrl fakeBase64BinaryType(); + + const char* defaultGraphString(); + const char* openlinkVirtualGraphString(); + const char* fakeBooleanTypeString(); + const char* fakeBase64BinaryTypeString(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/clientconnection.cpp new/soprano-2.4.2/client/clientconnection.cpp --- old/soprano-2.4.1/client/clientconnection.cpp 2010-02-11 10:25:44.000000000 +0100 +++ new/soprano-2.4.2/client/clientconnection.cpp 2010-04-12 14:50:10.000000000 +0200 @@ -22,7 +22,6 @@ #include "clientconnection.h" #include "clientconnection_p.h" #include "commands.h" -#include "socketdevice.h" #include "datastream.h" #include "node.h" @@ -74,6 +73,7 @@ d->socketMutex.lock(); // the sockets need to be deleted in their respective threads. // this is what d->socketStorage does. We only close them here. + // FIXME: QThreadStorage does NOT delete the local data in its destructor! foreach( QIODevice* socket, d->sockets ) { socket->close(); } @@ -82,16 +82,16 @@ } -QIODevice* Soprano::Client::ClientConnection::socket() +QIODevice* Soprano::Client::ClientConnection::socketForCurrentThread() { - if ( d->socketStorage.hasLocalData() && - isConnected( d->socketStorage.localData()->socket() ) ) { + if ( isConnectedInCurrentThread() ) { return d->socketStorage.localData()->socket(); } else if ( QIODevice* socket = newConnection() ) { - QMutexLocker lock( &d->socketMutex ); + d->socketMutex.lock(); SocketHandler* cleaner = new SocketHandler( d, socket ); d->sockets.append( socket ); + d->socketMutex.unlock(); d->socketStorage.setLocalData( cleaner ); return socket; } @@ -104,13 +104,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::createModel)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return 0; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_CREATE_MODEL ); stream.writeString( name ); Q_UNUSED( settings ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return 0; } @@ -131,12 +134,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::removeModel)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_REMOVE_MODEL ); stream.writeString( name ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return; } @@ -154,11 +160,14 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::supportedFeatures)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return BackendFeatureNone; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_SUPPORTED_FEATURES ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return 0; } @@ -179,13 +188,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::addStatement)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Error::convertErrorCode( lastError().code() ); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_ADD_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( statement ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Error::ErrorUnknown; } @@ -205,14 +217,17 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::listContexts)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return 0; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_LIST_CONTEXTS ); stream.writeUnsignedInt32( ( quint32 )modelId ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); - return Error::ErrorUnknown; + return 0; } quint32 itId; @@ -230,7 +245,10 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::executeQuery)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return 0; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_QUERY ); stream.writeUnsignedInt32( ( quint32 )modelId ); @@ -238,9 +256,9 @@ stream.writeUnsignedInt16( ( quint16 )type ); stream.writeString( userQueryLanguage ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); - return Error::ErrorUnknown; + return 0; } quint32 itId; @@ -258,15 +276,18 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::listStatements)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return 0; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_LIST_STATEMENTS ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( partial ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); - return Error::ErrorUnknown; + return 0; } quint32 itId; @@ -284,13 +305,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::removeAllStatements)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Error::convertErrorCode( lastError().code() ); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_ALL_STATEMENTS ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( statement ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Error::ErrorUnknown; } @@ -310,13 +334,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::removeStatement)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Error::convertErrorCode( lastError().code() ); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( statement ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Error::ErrorUnknown; } @@ -336,14 +363,17 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::statementCount)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return -1; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_STATEMENT_COUNT ); stream.writeUnsignedInt32( ( quint32 )modelId ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); - return Error::ErrorUnknown; + return -1; } qint32 count; @@ -361,13 +391,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::containsStatement)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( statement ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -387,13 +420,16 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::containsAnyStatement)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_ANY_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )modelId ); stream.writeStatement( statement ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -413,12 +449,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::isEmpty)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_IS_EMPTY ); stream.writeUnsignedInt32( ( quint32 )modelId ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -438,12 +477,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::createBlankNode)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Node(); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_MODEL_CREATE_BLANK_NODE ); stream.writeUnsignedInt32( ( quint32 )modelId ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Node(); } @@ -463,12 +505,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::iteratorNext)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_NEXT ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -488,12 +533,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::nodeIteratorCurrent)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Node(); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_NODE ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Node(); } @@ -513,12 +561,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::statementIteratorCurrent)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Statement(); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Statement(); } @@ -538,12 +589,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::queryIteratorCurrent)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return BindingSet(); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_BINDINGSET ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return BindingSet(); } @@ -563,12 +617,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::queryIteratorCurrentStatement)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return Statement(); + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return Statement(); } @@ -587,12 +644,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::queryIteratorType)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return 0; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_TYPE ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return 0; } @@ -612,12 +672,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::queryIteratorBoolValue)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_BOOL_VALUE ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -636,12 +699,15 @@ { //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::iteratorClose)"; - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_ITERATOR_CLOSE ); stream.writeUnsignedInt32( ( quint32 )id ); - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return; } @@ -656,13 +722,16 @@ bool Soprano::Client::ClientConnection::checkProtocolVersion() { - DataStream stream( socket() ); + QIODevice* socket = socketForCurrentThread(); + if ( !socket ) + return false; + DataStream stream( socket ); stream.writeUnsignedInt16( COMMAND_SUPPORTS_PROTOCOL_VERSION ); stream.writeUnsignedInt32( ( quint32 )PROTOCOL_VERSION ); // wait for a reply, but not forever, in case we are connected to something unknown - if ( !socket()->waitForReadyRead(s_defaultTimeout) ) { + if ( !socket->waitForReadyRead(s_defaultTimeout) ) { setError( "Command timed out." ); return false; } @@ -680,10 +749,16 @@ } -bool Soprano::Client::ClientConnection::testConnection() +bool Soprano::Client::ClientConnection::connectInCurrentThread() +{ + return( socketForCurrentThread() != 0 ); +} + + +bool Soprano::Client::ClientConnection::isConnectedInCurrentThread() { - QIODevice* s = socket(); - return s ? isConnected( s ) : false; + return ( d->socketStorage.hasLocalData() && + isConnected( d->socketStorage.localData()->socket() ) ); } #include "clientconnection.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/clientconnection.h new/soprano-2.4.2/client/clientconnection.h --- old/soprano-2.4.1/client/clientconnection.h 2009-11-22 14:55:25.000000000 +0100 +++ new/soprano-2.4.2/client/clientconnection.h 2010-04-12 14:50:10.000000000 +0200 @@ -84,7 +84,11 @@ bool checkProtocolVersion(); - bool testConnection(); + /// trueg: this is an awful design which simply grew over time. + /// At some point this needs fixing a lot. Maybe by simply not + /// Using Qt for communication. + bool connectInCurrentThread(); + bool isConnectedInCurrentThread(); protected: /** @@ -95,7 +99,7 @@ virtual bool isConnected( QIODevice* dev ) = 0; private: - QIODevice* socket(); + QIODevice* socketForCurrentThread(); ClientConnectionPrivate* const d; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/clientmodel.cpp new/soprano-2.4.2/client/clientmodel.cpp --- old/soprano-2.4.1/client/clientmodel.cpp 2009-11-22 14:55:25.000000000 +0100 +++ new/soprano-2.4.2/client/clientmodel.cpp 2010-04-12 14:50:10.000000000 +0200 @@ -1,7 +1,7 @@ /* * This file is part of Soprano Project. * - * Copyright (C) 2007 Sebastian Trueg <trueg@kde.org> + * Copyright (C) 2007-2010 Sebastian Trueg <trueg@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,6 +31,8 @@ #include "statementiterator.h" #include "queryresultiterator.h" +#include <QtCore/QMutexLocker> + Soprano::Client::ClientModel::ClientModel( const Backend* backend, int modelId, ClientConnection* client ) : StorageModel( backend ), @@ -42,8 +44,16 @@ Soprano::Client::ClientModel::~ClientModel() { - for ( int i = 0; i < m_openIterators.count(); ++i ) { - m_client->iteratorClose( m_openIterators[i] ); + // + // No need to close iterators if we are no longer + // connected. In that case the iterators have been + // closed by the server anyway. + // + QMutexLocker locker( &m_openIteratorsMutex ); + if ( m_client->isConnectedInCurrentThread() ) { + for ( int i = 0; i < m_openIterators.count(); ++i ) { + m_client->iteratorClose( m_openIterators[i] ); + } } } @@ -67,6 +77,7 @@ if ( m_client ) { int itId = m_client->listContexts( m_modelId ); if ( itId > 0 ) { + QMutexLocker locker( &m_openIteratorsMutex ); m_openIterators.append( itId ); } setError( m_client->lastError() ); @@ -89,6 +100,7 @@ if ( m_client ) { int itId = m_client->executeQuery( m_modelId, query, language, userQueryLanguage ); if ( itId > 0 ) { + QMutexLocker locker( &m_openIteratorsMutex ); m_openIterators.append( itId ); } setError( m_client->lastError() ); @@ -111,6 +123,7 @@ if ( m_client ) { int itId = m_client->listStatements( m_modelId, partial ); if ( itId > 0 ) { + QMutexLocker locker( &m_openIteratorsMutex ); m_openIterators.append( itId ); } setError( m_client->lastError() ); @@ -216,6 +229,7 @@ { if ( m_client ) { clearError(); + QMutexLocker locker( &m_openIteratorsMutex ); if ( m_openIterators.contains( id ) ) { m_client->iteratorClose( id ); m_openIterators.removeAll( id ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/clientmodel.h new/soprano-2.4.2/client/clientmodel.h --- old/soprano-2.4.1/client/clientmodel.h 2009-11-22 14:55:25.000000000 +0100 +++ new/soprano-2.4.2/client/clientmodel.h 2010-04-12 14:50:10.000000000 +0200 @@ -1,7 +1,7 @@ -/* +/* * This file is part of Soprano Project. * - * Copyright (C) 2007 Sebastian Trueg <trueg@kde.org> + * Copyright (C) 2007-2010 Sebastian Trueg <trueg@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,6 +25,7 @@ #include "storagemodel.h" #include <QtCore/QList> +#include <QtCore/QMutex> #include <QtCore/QPointer> #include "clientconnection.h" @@ -58,6 +59,7 @@ private: int m_modelId; mutable QList<int> m_openIterators; + mutable QMutex m_openIteratorsMutex; QPointer<ClientConnection> m_client; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/localsocketclient.cpp new/soprano-2.4.2/client/localsocketclient.cpp --- old/soprano-2.4.1/client/localsocketclient.cpp 2010-01-19 16:19:53.000000000 +0100 +++ new/soprano-2.4.2/client/localsocketclient.cpp 2010-03-08 15:44:58.000000000 +0100 @@ -126,9 +126,18 @@ bool Soprano::Client::LocalSocketClient::connect( const QString& name ) { if ( !isConnected() ) { - disconnect(); // for cleanup - d->connection = new LocalSocketClientConnection( name, this ); - if ( d->connection->testConnection() && + // + // trueg: This is a hack: we do not disconnect since we essentially re-connect + // in every thread anyway. Thus, the whole connect/disconnect API is sort of a lie. + // This is something that grew over time and needs to be fixed. The best solution + // I see at the moment is to drop Qt for socket communication. QObject is just too + // heavy for that. + // Another solution would be for Soprano 3 to simply make the client non-thread-safe. + // Then each client thread would need to create its own connection manually. + // + if ( !d->connection ) + d->connection = new LocalSocketClientConnection( name, this ); + if ( d->connection->connectInCurrentThread() && d->connection->checkProtocolVersion() ) { return true; } @@ -146,7 +155,7 @@ bool Soprano::Client::LocalSocketClient::isConnected() const { - return d->connection ? d->connection->testConnection() : false; + return d->connection ? d->connection->isConnectedInCurrentThread() : false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/client/tcpclient.cpp new/soprano-2.4.2/client/tcpclient.cpp --- old/soprano-2.4.1/client/tcpclient.cpp 2010-01-19 16:19:53.000000000 +0100 +++ new/soprano-2.4.2/client/tcpclient.cpp 2010-03-08 15:44:58.000000000 +0100 @@ -115,9 +115,9 @@ bool Soprano::Client::TcpClient::connect( const QHostAddress& address, int port ) { if ( !isConnected() ) { - disconnect(); // for cleanup - d->connection = new TcpClientConnection( address, port, this ); - if ( d->connection->testConnection() && + if ( !d->connection ) + d->connection = new TcpClientConnection( address, port, this ); + if ( d->connection->connectInCurrentThread() && d->connection->checkProtocolVersion() ) { return true; } @@ -135,7 +135,7 @@ bool Soprano::Client::TcpClient::isConnected() { - return d->connection ? d->connection->testConnection() : false; + return d->connection ? d->connection->isConnectedInCurrentThread() : false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/cmake/modules/FindRedland.cmake new/soprano-2.4.2/cmake/modules/FindRedland.cmake --- old/soprano-2.4.1/cmake/modules/FindRedland.cmake 2010-02-12 20:24:14.000000000 +0100 +++ new/soprano-2.4.2/cmake/modules/FindRedland.cmake 2009-12-18 15:33:44.000000000 +0100 @@ -115,7 +115,7 @@ endif(NOT WIN32) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Redland DEFAULT_MSG REDLAND_CONFIG_EXECUTABLE REDLAND_LIBRARIES REDLAND_LIBRARIES _REDLAND_VERSION_OK) +find_package_handle_standard_args(Redland DEFAULT_MSG REDLAND_LIBRARIES REDLAND_LIBRARIES _REDLAND_VERSION_OK) mark_as_advanced(REDLAND_INCLUDE_DIR_TMP REDLAND_INCLUDE_DIR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/soprano/error.cpp new/soprano-2.4.2/soprano/error.cpp --- old/soprano-2.4.1/soprano/error.cpp 2009-02-05 20:02:14.000000000 +0100 +++ new/soprano-2.4.2/soprano/error.cpp 2010-04-12 12:25:41.000000000 +0200 @@ -22,10 +22,12 @@ #include "error.h" #include "locator.h" +#include <QtCore/QCoreApplication> +#include <QtCore/QDebug> #include <QtCore/QHash> +#include <QtCore/QMutex> +#include <QtCore/QMutexLocker> #include <QtCore/QThread> -#include <QtCore/QDebug> -#include <QtCore/QCoreApplication> namespace Soprano { @@ -185,6 +187,7 @@ { public: QHash<QThread*, Error> errorMap; + QMutex errorMapMutex; }; @@ -202,6 +205,7 @@ Soprano::Error::Error Soprano::Error::ErrorCache::lastError() const { + QMutexLocker locker( &d->errorMapMutex ); return d->errorMap.value( QThread::currentThread() ); } @@ -218,7 +222,7 @@ #endif : QString( "(Soprano)" ) ) << "Error in thread" << QThread::currentThreadId() << ":" << error; - + QMutexLocker locker( &d->errorMapMutex ); d->errorMap[QThread::currentThread()] = error; } else { @@ -235,6 +239,7 @@ void Soprano::Error::ErrorCache::clearError() const { + QMutexLocker locker( &d->errorMapMutex ); if ( !d->errorMap.isEmpty() ) d->errorMap[QThread::currentThread()] = Error(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/soprano-2.4.1/soprano/nrlmodel.cpp new/soprano-2.4.2/soprano/nrlmodel.cpp --- old/soprano-2.4.1/soprano/nrlmodel.cpp 2009-10-28 12:15:58.000000000 +0100 +++ new/soprano-2.4.2/soprano/nrlmodel.cpp 2010-04-12 18:51:21.000000000 +0200 @@ -284,9 +284,7 @@ foreach ( const Node& mg, metadataGraphs ) { // we can only use removeAllStatements(Statement) here since all other variants will come back to // our version below which in turn calls us again - Error::ErrorCode c = FilterModel::removeAllStatements( Statement( Node(), Node(), Node(), mg ) ); - if ( c != Error::ErrorNone ) - return c; + FilterModel::removeAllStatements( Statement( Node(), Node(), Node(), mg ) ); } // this is where we do not want to be called recursively return FilterModel::removeAllStatements( Statement( Node(), Node(), Node(), graph ) ); ++++++ soprano-backend-sesame.spec.in ++++++ --- /var/tmp/diff_new_pack.2P88U5/_old 2010-04-24 11:42:33.000000000 +0200 +++ /var/tmp/diff_new_pack.2P88U5/_new 2010-04-24 11:42:33.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package soprano-backend-sesame (Version 2.3.0) +# spec file for package soprano-backend-sesame (Version 2.4.2) # # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -27,9 +27,9 @@ Requires: java-devel # COMMON1-BEGIN # COMMON1-END -Provides: soprano_backend = %version -Provides: backend-sesame2 = %version -Requires: libsoprano4 = %version +Provides: soprano_backend = %{version} +Provides: backend-sesame2 = %{version} +Requires: libsoprano4 = %{version} %description This package provides a Sesame based backend for Soprano. @@ -50,15 +50,15 @@ cd backends/sesame2 %makeinstall %if %suse_version > 1020 - %fdupes -s $RPM_BUILD_ROOT/usr/include + %fdupes -s %{buildroot}%{_includedir} %endif cd .. %files %defattr(-,root,root) -/usr/share/soprano/sesame2 -%_libdir/soprano/libsoprano_sesame2backend.so -/usr/share/soprano/plugins/sesame2backend.desktop +%{_datadir}/soprano/sesame2 +%{_libdir}/soprano/libsoprano_sesame2backend.so +%{_datadir}/soprano/plugins/sesame2backend.desktop %changelog ++++++ soprano-backend-virtuoso.spec.in ++++++ --- /var/tmp/diff_new_pack.2P88U5/_old 2010-04-24 11:42:33.000000000 +0200 +++ /var/tmp/diff_new_pack.2P88U5/_new 2010-04-24 11:42:34.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package soprano-backend-virtuoso (Version 2.3.0) +# spec file for package soprano-backend-virtuoso (Version 2.4.2) # # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -27,9 +27,9 @@ BuildRequires: libiodbc-devel # COMMON1-BEGIN # COMMON1-END -Provides: soprano_backend = %version -Provides: backend-virtuso = %version -Requires: libsoprano4 = %version +Provides: soprano_backend = %{version} +Provides: backend-virtuso = %{version} +Requires: libsoprano4 = %{version} Requires: virtuoso-server %description @@ -50,14 +50,14 @@ cd backends/virtuoso %makeinstall %if %suse_version > 1020 - %fdupes -s $RPM_BUILD_ROOT/usr/include + %fdupes -s %{buildroot}%{_includedir} %endif cd .. %files %defattr(-,root,root) -%_libdir/soprano/libsoprano_virtuosobackend.so -/usr/share/soprano/plugins/virtuosobackend.desktop +%{_libdir}/soprano/libsoprano_virtuosobackend.so +%{_datadir}/soprano/plugins/virtuosobackend.desktop %changelog ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org