diff --git a/nepomuk/core/resourcefiltermodel.cpp b/nepomuk/core/resourcefiltermodel.cpp index e091ffc797..21b2364a51 100644 --- a/nepomuk/core/resourcefiltermodel.cpp +++ b/nepomuk/core/resourcefiltermodel.cpp @@ -1,244 +1,329 @@ + /* * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "resourcefiltermodel.h" #include "resourcemanager.h" #include #include #include #include #include #include #include +#include #include +#include + +#include +// IDEA: Remember the last used named graph for N seconds and reuse it. + using namespace Soprano; uint qHash( const Soprano::Node& node ) { return qHash( node.toString() ); } class Nepomuk::ResourceFilterModel::Private { public: }; Nepomuk::ResourceFilterModel::ResourceFilterModel( Soprano::Model* model ) : Soprano::FilterModel( model ), d( 0 ) { } Nepomuk::ResourceFilterModel::~ResourceFilterModel() { } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::updateProperty( const QUrl& resource, const QUrl& property, const Node& value ) { StatementIterator it = listStatements( Statement( resource, property, Node() ) ); if ( it.next() ) { Statement s = it.current(); it.close(); if ( s.object() == value ) { // nothing to do. Yey! return Error::ErrorNone; } else { removeStatement( s ); } } // FIXME: provedence data! QUrl newContext = ResourceManager::instance()->generateUniqueUri(); Error::ErrorCode c = addStatement( Statement( resource, property, value, newContext ) ); if ( c == Error::ErrorNone ) { c = addStatement( Statement( newContext, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::InstanceBase() ) ); + c = addStatement( Statement( newContext, Soprano::Vocabulary::NAO::created(), LiteralValue( QDateTime::currentDateTime() ) ) ); } return c; } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::updateProperty( const QUrl& resource, const QUrl& property, const QList& values ) { QList existingValues = listStatements( Statement( resource, property, Node() ) ).iterateObjects().allNodes(); Error::ErrorCode c = Error::ErrorNone; foreach( Node node, existingValues.toSet() - values.toSet() ) { if ( ( c = removeAllStatements( Statement( resource, property, node ) ) ) != Error::ErrorNone ) { return c; } } QSet newNodes = values.toSet() - existingValues.toSet(); if ( !newNodes.isEmpty() ) { QUrl newContext = ResourceManager::instance()->generateUniqueUri(); foreach( Node node, newNodes ) { if ( ( c = addStatement( Statement( resource, property, node, newContext ) ) ) != Error::ErrorNone ) { return c; } } if ( ( c = addStatement( Statement( newContext, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::InstanceBase() ) ) ) != Error::ErrorNone ) { return c; } - // FIXME: provedence data! + + // provedence data! + c = addStatement( Statement( newContext, Soprano::Vocabulary::NAO::created(), LiteralValue( QDateTime::currentDateTime() ) ) ); } return c; } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::removeProperty( const QUrl& resource, const QUrl& property ) { // get all graphs that contain our data QList graphs = executeQuery( QString("select distinct ?g where { graph ?g { <%1> <%2> ?v . } }") .arg( QString::fromAscii( resource.toEncoded() ) ) .arg( property.toString() ), Query::QueryLanguageSparql ).iterateBindings( "g" ).allNodes(); // remove the data Soprano::Error::ErrorCode c = removeAllStatements( Statement( resource, property, Node() ) ); if ( c != Soprano::Error::ErrorNone ) { return c; } - // remove dangling graphs -// for( QList::const_iterator it = graphs.constBegin(); it != graphs.constEnd(); ++it ) { -// if ( ( c = removeGraphIfEmpty( *it ) ) != Error::ErrorNone ) { -// return c; -// } -// } - return Error::ErrorNone; } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::ensureResource( const QUrl& resource, const QUrl& type ) { // FIXME: graph! if ( !containsAnyStatement( Statement( resource, Vocabulary::RDF::type(), type ) ) ) { return addStatement( Statement( resource, Vocabulary::RDF::type(), type ) ); } else { clearError(); return Error::ErrorNone; } } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::removeStatement( const Statement &statement ) { Soprano::Error::ErrorCode c = FilterModel::removeStatement( statement ); if ( c == Error::ErrorNone && !statement.context().isEmpty() ) { return removeGraphIfEmpty( statement.context() ); } else { return c; } } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::removeAllStatements( const Statement &statement ) { // This is slow. :( // We should really do this on storage level! QList statementsToRemove = listStatements( statement ).allStatements(); // remove the statements Soprano::Error::ErrorCode c = FilterModel::removeAllStatements( statement ); // remove dangling graphs if ( c == Error::ErrorNone ) { + QSet contexts; for ( QList::const_iterator it = statementsToRemove.constBegin(); it != statementsToRemove.constEnd(); ++it ) { - if ( ( c = removeGraphIfEmpty( (*it).context() ) ) != Error::ErrorNone ) { + contexts.insert( it->context().uri() ); + } + for ( QSet::const_iterator it = contexts.constBegin(); it != contexts.constEnd(); ++it ) { + if ( ( c = removeGraphIfEmpty( *it ) ) != Error::ErrorNone ) { return c; } } } return Error::ErrorNone; } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::removeGraphIfEmpty( const Node& graph ) { if ( graph.isEmpty() ) { return Error::ErrorNone; } Soprano::Error::ErrorCode c = Error::ErrorNone; // metadata graphs contain type information about themselves. They do not count as "real" content. if ( !executeQuery( QString("ask where { graph <%1> { ?s ?p ?o . } . FILTER(?s != <%1>) .}") .arg( QString::fromAscii( graph.uri().toEncoded() ) ), Query::QueryLanguageSparql ).boolValue() ) { // remove the graph itself (do not use the direct call which will result in a recursion) if ( ( c = parentModel()->removeContext( graph ) ) != Error::ErrorNone ) { setError( parentModel()->lastError() ); return c; } // remove the graph metadata if ( ( c = parentModel()->removeAllStatements( graph, Node(), Node() ) ) != Error::ErrorNone ) { setError( parentModel()->lastError() ); return c; } // remove a dangling metadata graph QueryResultIterator metaIt = executeQuery( QString("select ?mg where { ?mg <%1> <%2> . }") .arg( Soprano::Vocabulary::NRL::graphMetadataFor().toString() ) .arg( QString::fromAscii( graph.uri().toEncoded() ) ), Query::QueryLanguageSparql ); if ( metaIt.next() ) { Node g = metaIt.binding( "mg" ); metaIt.close(); return removeGraphIfEmpty( g ); } } return c; } Soprano::Error::ErrorCode Nepomuk::ResourceFilterModel::addStatements( const QList& statements ) { QUrl newContext = ResourceManager::instance()->generateUniqueUri(); QList newStatements; QList::const_iterator end = statements.constEnd(); for ( QList::const_iterator it = statements.constBegin(); it != end; ++it ) { Statement s( *it ); s.setContext( newContext ); newStatements.append( s ); } Soprano::Error::ErrorCode r = FilterModel::addStatements( newStatements ); if ( r == Error::ErrorNone ) { r = addStatement( Statement( newContext, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::InstanceBase() ) ); + r = addStatement( Statement( newContext, Soprano::Vocabulary::NAO::created(), LiteralValue( QDateTime::currentDateTime() ) ) ); } return r; } + + +Soprano::QueryResultIterator Nepomuk::ResourceFilterModel::instanceQuery( const QString& query, const QDateTime& start, const QDateTime& end ) +{ + QString newQuery; + int pos = query.indexOf( '{' ); + if ( pos < 0 ) { + kDebug() << "No opening bracket found."; + return 0; + } + + // keep the select part + newQuery = query.left( pos+1 ); + + // extract the graph patterns (we need them to be separated by space + dot + int endPos = query.lastIndexOf( '}' ); + QStringList patterns = query.mid( pos+1, endPos-pos-1 ).simplified().split( " .", QString::SkipEmptyParts ); + + // create the new graph patterns + QStringList graphPatterns; + int graphIndex = 1; + for ( int i = 0; i < patterns.count(); ++i ) { + graphPatterns << QString( "graph ?g%1 { %2 . }" ).arg(graphIndex++).arg( patterns[i].simplified() ); + } + + // create graph pattern for nrl:InstanceBase + graphIndex = 1; + for ( int i = 0; i < patterns.count(); ++i ) { + graphPatterns << QString( "?g%1 a <%2>" ).arg(graphIndex++).arg( Soprano::Vocabulary::NRL::InstanceBase().toString() ); + } + + // create date nao:created graph patterns for matching the creation date in the filters + if ( start.isValid() || end.isValid() ) { + graphIndex = 1; + for ( int i = 0; i < patterns.count(); ++i ) { + graphPatterns << QString( "?g%1 <%2> ?d%1" ).arg(graphIndex++).arg( Soprano::Vocabulary::NAO::created().toString() ); + } + } + + // create optional additional filters + QStringList filters; + + // create start filter + if ( start.isValid() ) { + QString filter = "FILTER( "; + graphIndex = 1; + Soprano::LiteralValue startLiteral( start ); + for ( int i = 0; i < patterns.count(); ++i ) { + filter += QString( "?d%1 >= '%2'^^<%3>" ).arg( graphIndex++ ).arg( startLiteral.toString() ).arg( startLiteral.dataTypeUri().toString() ); + if ( i+1 < patterns.count() ) { + filter += " || "; + } + } + filter += " )"; + filters << filter; + } + + // create end filter + if ( end.isValid() ) { + QString filter = "FILTER( "; + graphIndex = 1; + Soprano::LiteralValue endLiteral( end ); + for ( int i = 0; i < patterns.count(); ++i ) { + filter += QString( "?d%1 <= '%2'^^<%3>" ).arg( graphIndex++ ).arg( endLiteral.toString() ).arg( endLiteral.dataTypeUri().toString() ); + if ( i+1 < patterns.count() ) { + filter += " || "; + } + } + filter += " )"; + filters << filter; + } + + newQuery += ' ' + ( graphPatterns + filters ).join( " . " ); + newQuery += " . }"; + + return executeQuery( newQuery, Soprano::Query::QueryLanguageSparql ); +} diff --git a/nepomuk/core/resourcefiltermodel.h b/nepomuk/core/resourcefiltermodel.h index fc5898b733..16e453e958 100644 --- a/nepomuk/core/resourcefiltermodel.h +++ b/nepomuk/core/resourcefiltermodel.h @@ -1,97 +1,119 @@ /* * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _NEPOMUK_RESOURCE_FILTER_MODEL_H_ #define _NEPOMUK_RESOURCE_FILTER_MODEL_H_ #include #include #include #include +#include namespace Nepomuk { /** * Filter model that provides a set of convinience methods * for maintaining resource properties. * * It does automatic NRL named graph handling, i.e. provedance * data is created and deleted automatically. * * \warning This model assumes that no property value is stored twice, * i.e. in two different named graphs. */ class ResourceFilterModel : public Soprano::FilterModel { public: ResourceFilterModel( Soprano::Model* model = 0 ); ~ResourceFilterModel(); /** * Update a property. This means an existing property is replaced if it differs from * the provided value. Otherwise nothing is done. * * This method assumes that the cardinality or property is 1. */ Soprano::Error::ErrorCode updateProperty( const QUrl& resource, const QUrl& property, const Soprano::Node& value ); /** * Update a property with a cardinality > 1. * This method optmizes the add and remove actions necessary. */ Soprano::Error::ErrorCode updateProperty( const QUrl& resource, const QUrl& property, const QList& values ); /** * Remove a property from a resource and make sure no dangling graphs are left */ Soprano::Error::ErrorCode removeProperty( const QUrl& resource, const QUrl& property ); /** * Ensures that resoruce exists with type. */ Soprano::Error::ErrorCode ensureResource( const QUrl& resource, const QUrl& type = Soprano::Vocabulary::RDFS::Resource() ); /** * Adds the statements into a new nrl:InstanceBase context. */ Soprano::Error::ErrorCode addStatements( const QList& statements ); /** * Reimplemented to remove metadata about graphs. */ Soprano::Error::ErrorCode removeStatement( const Soprano::Statement &statement ); /** * Reimplemented to remove metadata about graphs. */ Soprano::Error::ErrorCode removeAllStatements( const Soprano::Statement &statement ); + /** + * Perform a query on instance base graphs. The resource filter model will take care of all graph matching. + * Thus, queries have a rather restricted form which do not include any "graph" keywords. Basically + * queries look like: + * + * \code + * select ?v1 ?v2 .... where { ?v1 foo ?v2 . ?v2 bar 'xxx' . ... } + * \endcode + * + * \param start The results can be filtered on creation date. If the start date is set no results created + * before that date are returned. + * \param end If the end date is set no results created after that date are returned. + * + * \return An iterator iterating over the bindings requested in the original query filteres by nrl:InstanceBase + * and optionally nao:created. + * + * \warning This is a temporary method used until Soprano provides a full query API which does not + * rely on query strings. + */ + Soprano::QueryResultIterator instanceQuery( const QString& query, const QDateTime& start = QDateTime(), const QDateTime& end = QDateTime() ); + private: Soprano::Error::ErrorCode removeGraphIfEmpty( const Soprano::Node& graph ); class Private; Private* const d; }; } uint qHash( const Soprano::Node& node ); #endif diff --git a/nepomuk/core/test/CMakeLists.txt b/nepomuk/core/test/CMakeLists.txt index edb1c90f0d..3a2620efdd 100644 --- a/nepomuk/core/test/CMakeLists.txt +++ b/nepomuk/core/test/CMakeLists.txt @@ -1,59 +1,68 @@ set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) project(kmetadata_tests) include_directories( ${kmetadata_SOURCE_DIR} ${libkmetadata_SOURCE_DIR} ${libkmetadata_SOURCE_DIR}/generated ${kmetadata_ui_SOURCE_DIR} ) include_directories( ${KDE4_KDEUI_INCLUDES} ) include_directories( ${QT_INCLUDES} ${SOPRANO_INCLUDE_DIR} ) # The basis of all the tests handling statements #kde4_add_library(kmetadata_testbase STATIC testbase.cpp) #target_link_libraries(kmetadata_testbase knepomuk ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY}) # tests #kde4_add_unit_test(resourcetest resourcetest.cpp) #target_link_libraries(resourcetest # kmetadata_testbase # kmetadata # ${QT_QTCORE_LIBRARY} # ${QT_QTDBUS_LIBRARY} # ${QT_QTTEST_LIBRARY} # ${QT_QTGUI_LIBRARY} # ${KDE4_KDECORE_LIBRARY}) #kde4_add_unit_test(varianttest varianttest.cpp) #target_link_libraries(varianttest kmetadata ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTTEST_LIBRARY}) kde4_add_unit_test(speedtest speedtest.cpp) target_link_libraries(speedtest nepomuk ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTTEST_LIBRARY} ${SOPRANO_LIBRARIES} ${KDE4_KDECORE_LIBRARY}) #set(datatest_SRC # resourcedatatest.cpp # ../kmetadata/resourcedata.cpp #) #kde4_add_unit_test(resourcedatatest ${datatest_SRC}) #target_link_libraries(resourcedatatest # kmetadata_testbase # kmetadata # knepomuk # konto # ${QT_QTCORE_LIBRARY} # ${QT_QTDBUS_LIBRARY} # ${QT_QTTEST_LIBRARY} # ${QT_QTGUI_LIBRARY} # ${KDE4_KDECORE_LIBRARY}) +kde4_add_unit_test(resourcefiltermodeltest resourcefiltermodeltest.cpp ../resourcefiltermodel.cpp) +target_link_libraries(resourcefiltermodeltest + nepomuk + ${QT_QTCORE_LIBRARY} + ${QT_QTDBUS_LIBRARY} + ${QT_QTTEST_LIBRARY} + ${SOPRANO_LIBRARIES} + ${KDE4_KDECORE_LIBRARY}) + # Not a real test, just a simple app for testing a widget manually kde4_add_executable(tagcloudtest TEST tagcloudtest.cpp) target_link_libraries(tagcloudtest nepomuk) diff --git a/nepomuk/core/test/resourcefiltermodeltest.cpp b/nepomuk/core/test/resourcefiltermodeltest.cpp index 2bf0fbb0a7..5a7fd8f3c7 100644 --- a/nepomuk/core/test/resourcefiltermodeltest.cpp +++ b/nepomuk/core/test/resourcefiltermodeltest.cpp @@ -1,89 +1,159 @@ /* * * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $ * * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING.LIB" for the exact licensing terms. */ #include "resourcefiltermodeltest.h" #include #include #include "../resourcefiltermodel.h" +#include +#include +#include + + +class TestModel : public Soprano::Util::DummyModel +{ +public: + TestModel() + : DummyModel() { + } + + QString lastQuery() const { return m_lastQuery; } + + Soprano::QueryResultIterator executeQuery( const QString& query, + Soprano::Query::QueryLanguage language, + const QString& userQueryLanguage ) const { + m_lastQuery = query; + return 0; + } + +private: + mutable QString m_lastQuery; +}; + void ResourceFilterModelTest::testEnsureResource() { // ensure a resource // check that we have a new graph that is an InstanceBase // ensure the same resource // check that nothing changed } void ResourceFilterModelTest::testUpdateProperty1() { // add a resource // add a property // check that we have a new graph which is an InstanceBase and contains the new property // check that we have a new graph that is a GraphMetadata and contains info about the InstanceBase } void ResourceFilterModelTest::testUpdateProperty2() { // do the same thing as above, except add multiple properties } void ResourceFilterModelTest::testRemoveStatement() { // add data manually including the graph (2 statements) // remove one statement // make sure the graph still exists // remove the second statement // make sure the graph is gone - QUrl dataGraph( "http://www.nepomuk.org/test/dataGraph" ); - QUrl metadataGraph( "http://www.nepomuk.org/test/metadataGraph" ); +// QUrl dataGraph( "http://www.nepomuk.org/test/dataGraph" ); +// QUrl metadataGraph( "http://www.nepomuk.org/test/metadataGraph" ); - QUrl res1 = "http://www.nepomuk.org/test/res1"; - QUrl res2 = "http://www.nepomuk.org/test/res2"; +// QUrl res1 = "http://www.nepomuk.org/test/res1"; +// QUrl res2 = "http://www.nepomuk.org/test/res2"; - QUrl prop1 = Soprano::Vocabulary::RDFS::label(); - QUrl prop2 = Soprano::Vocabulary::RDFS::label(); +// QUrl prop1 = Soprano::Vocabulary::RDFS::label(); +// QUrl prop2 = Soprano::Vocabulary::RDFS::label(); - Soprano::LiteralValue val1( "test1" ); - Soprano::LiteralValue val2( "test2" ); +// Soprano::LiteralValue val1( "test1" ); +// Soprano::LiteralValue val2( "test2" ); - Soprano::Model* model = Soprano::createModel(); - Q_VERIFY( model ); - Nepomuk::ResourceFilterModel fm( model ); +// Soprano::Model* model = Soprano::createModel(); +// Q_VERIFY( model ); +// Nepomuk::ResourceFilterModel fm( model ); - model->addStatement( res1, prop1, val1, dataGraph ); - model->addStatement( res1, prop2, val2, dataGraph ); +// model->addStatement( res1, prop1, val1, dataGraph ); +// model->addStatement( res1, prop2, val2, dataGraph ); - // metadata - model->addStatement( dataGraph, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::InstanceBase(), metadataGraph ); - model->addStatement( metadataGraph, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::GraphMetadata(), metadataGraph ); +// // metadata +// model->addStatement( dataGraph, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::InstanceBase(), metadataGraph ); +// model->addStatement( metadataGraph, Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::NRL::GraphMetadata(), metadataGraph ); } void ResourceFilterModelTest::testRemoveAllStatements() { } + +void ResourceFilterModelTest::testInstanceQuery() +{ + TestModel testModel; + Nepomuk::ResourceFilterModel resFilterModel( &testModel ); + + QString query1 = "select ?r where { ?r ?p ?o . }"; + QString query2 = QString( "select ?r where { ?r <%1> \"Horst\"^^<%2> . }" ) + .arg( Soprano::Vocabulary::RDFS::label().toString() ) + .arg( Soprano::Vocabulary::XMLSchema::string().toString() ); + QString query3 = "select ?r ?n where { ?r nco:phoneNumber ?o . ?o nco:number ?n . }"; + + // test without data ranges + resFilterModel.instanceQuery( query1 ); + qDebug() << query1 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query2 ); + qDebug() << query2 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query3 ); + qDebug() << query3 << "->" << testModel.lastQuery(); + + // test with start date range + resFilterModel.instanceQuery( query1, QDateTime::currentDateTime() ); + qDebug() << query1 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query2, QDateTime::currentDateTime() ); + qDebug() << query2 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query3, QDateTime::currentDateTime() ); + qDebug() << query3 << "->" << testModel.lastQuery(); + + // test with end date range + resFilterModel.instanceQuery( query1, QDateTime(), QDateTime::currentDateTime() ); + qDebug() << query1 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query2, QDateTime(), QDateTime::currentDateTime() ); + qDebug() << query2 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query3, QDateTime(), QDateTime::currentDateTime() ); + qDebug() << query3 << "->" << testModel.lastQuery(); + + // test with start and end date ranges + resFilterModel.instanceQuery( query1, QDateTime::currentDateTime(), QDateTime::currentDateTime() ); + qDebug() << query1 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query2, QDateTime::currentDateTime(), QDateTime::currentDateTime() ); + qDebug() << query2 << "->" << testModel.lastQuery(); + resFilterModel.instanceQuery( query3, QDateTime::currentDateTime(), QDateTime::currentDateTime() ); + qDebug() << query3 << "->" << testModel.lastQuery(); +} + QTEST_KDEMAIN(ResourceFilterModelTest, NoGUI) #include "resourcefiltermodeltest.moc" diff --git a/nepomuk/core/test/resourcefiltermodeltest.h b/nepomuk/core/test/resourcefiltermodeltest.h index 8a9efaf701..79e10e0284 100644 --- a/nepomuk/core/test/resourcefiltermodeltest.h +++ b/nepomuk/core/test/resourcefiltermodeltest.h @@ -1,32 +1,33 @@ /* * * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $ * * This file is part of the Nepomuk KDE project. * Copyright (C) 2006-2007 Sebastian Trueg * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING.LIB" for the exact licensing terms. */ #ifndef _RESOURCE_FILTER_MODEL_TEST_H_ #define _RESOURCE_FILTER_MODEL_TEST_H_ #include class ResourceFilterModelTest : public QObject { Q_OBJECT private Q_SLOTS: void testEnsureResource(); void testUpdateProperty1(); void testUpdateProperty2(); void testRemoveStatement(); void testRemoveAllStatements(); + void testInstanceQuery(); }; #endif