25 #include <Soprano/Model>
26 #include <Soprano/QueryResultIterator>
27 #include <Soprano/Vocabulary/NRL>
29 #include <QtCore/QTimer>
30 #include <Soprano/Vocabulary/NAO>
33 using namespace Soprano::Vocabulary;
34 using namespace Nepomuk2;
37 GraphMigrationJob::GraphMigrationJob(Soprano::Model* model,
QObject* parent)
45 QTimer::singleShot( 0,
this, SLOT(migrateData()) );
49 int fetchAppCount(Soprano::Model* model,
const QUrl& graph) {
50 QString query = QString::fromLatin1(
"select count(?app) as ?c where { %1 nao:maintainedBy ?app . }")
51 .arg( Soprano::Node::resourceToN3(graph) );
53 Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
55 return it[0].literal().toInt();
60 QUrl nepomukGraph(Soprano::Model* model) {
61 QString query = QString::fromLatin1(
"select ?r where { ?r a nrl:Graph ; nao:maintainedBy ?app ."
62 " ?app nao:identifier %1 . } LIMIT 1")
63 .arg( Soprano::Node::literalToN3(QLatin1String(
"nepomuk")) );
65 Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
73 void GraphMigrationJob::mergeAgents()
75 QString appQ = QString::fromLatin1(
"select distinct ?i where { ?r a %1 ; %2 ?i . }")
76 .arg( Soprano::Node::resourceToN3(NAO::Agent()),
77 Soprano::Node::resourceToN3(NAO::identifier()) );
79 Soprano::QueryResultIterator it = m_model->executeQuery( appQ, Soprano::Query::QueryLanguageSparqlNoInference );
81 QString identifier = it[0].literal().toString();
82 kDebug() << identifier;
84 QString aQuery = QString::fromLatin1(
"select distinct ?r where { ?r a nao:Agent ; nao:identifier %1. }")
85 .arg( Soprano::Node::literalToN3(identifier) );
87 Soprano::QueryResultIterator iter = m_model->executeQuery( aQuery, Soprano::Query::QueryLanguageSparqlNoInference );
90 apps << iter[0].uri();
96 void GraphMigrationJob::mergeAgents(
const QList< QUrl >& agents)
98 kDebug() <<
"Merging agents" << agents;
100 foreach(
const QUrl& app, agents) {
101 if( mainApp.isEmpty() ) {
106 QString insertCom = QString::fromLatin1(
"insert into ?g { ?r nao:maintainedBy %1 . }"
107 "where { graph ?g { ?r nao:maintainedBy %2. }")
108 .arg( Soprano::Node::resourceToN3(mainApp),
109 Soprano::Node::resourceToN3(app) );
111 m_model->removeAllStatements( app, QUrl(), QUrl() );
112 m_model->removeAllStatements( QUrl(), QUrl(), app );
117 void GraphMigrationJob::migrateData()
121 int graphCount = instanceBaseGraphCount();
122 int discardableGraphCount = discardableInstanceBaseGraphCount();
123 int totalCount = graphCount + discardableGraphCount;
126 kDebug() <<
"Total Count:" << totalCount;
128 m_nepomukGraph = nepomukGraph(m_model);
129 if( m_nepomukGraph.isEmpty() ) {
130 setErrorText(
"No nepomuk graph. Something is very wrong. Please report a bug");
134 QString appQ = QString::fromLatin1(
"select distinct ?r where { ?r a %1 ; %2 ?i . }")
135 .arg( Soprano::Node::resourceToN3(NAO::Agent()),
136 Soprano::Node::resourceToN3(NAO::identifier()) );
138 Soprano::QueryResultIterator it = m_model->executeQuery( appQ, Soprano::Query::QueryLanguageSparqlNoInference );
140 QUrl app = it[0].uri();
141 if( !app.isEmpty() ) {
143 kDebug() <<
"Inserting" << app;
147 if( m_apps.isEmpty() ) {
148 setErrorText(
"No application agents found. Data cannot be migrated" );
156 foreach(
const QUrl& app, m_apps) {
158 QString query = QString::fromLatin1(
"select ?g where { ?g a nrl:Graph ; nao:maintainedBy %1 ."
159 " FILTER NOT EXISTS { ?g a nrl:DiscardableInstanceBase . } }")
160 .arg( Soprano::Node::resourceToN3(app) );
162 it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
164 const QUrl graph = it[0].uri();
165 if( fetchAppCount(m_model, graph) == 1 ) {
166 graphCache.insert( app, graph );
168 emitPercent( count, totalCount );
173 query = QString::fromLatin1(
"select ?g where { ?g a nrl:DiscardableInstanceBase ; nao:maintainedBy %1 .}")
174 .arg( Soprano::Node::resourceToN3(app) );
176 it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
178 const QUrl graph = it[0].uri();
179 if( fetchAppCount(m_model, graph) == 1 ) {
180 discardableGraphCache.insert( app, graph );
182 emitPercent( count, totalCount );
187 kDebug() <<
"Fetched graph cache:" << graphCache.size();
188 kDebug() <<
"Fetched discardable graph cache:" << discardableGraphCache.size();
191 QString query = QString::fromLatin1(
"select distinct ?g where { ?g a %1. "
192 "FILTER NOT EXISTS { ?g a %2 . } }")
193 .arg( Soprano::Node::resourceToN3(NRL::InstanceBase()),
194 Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
196 it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
198 const QUrl graph = it[0].uri();
199 if( graphCache.contains(graph) )
202 migrateGraph( graph, graphCache );
204 emitPercent( count, totalCount );
208 QString gquery = QString::fromLatin1(
"select distinct ?g where { ?g a %1. }")
209 .arg( Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
211 it = m_model->executeQuery( gquery, Soprano::Query::QueryLanguageSparqlNoInference );
213 const QUrl graph = it[0].uri();
214 if( discardableGraphCache.contains(graph) )
217 migrateGraph( graph, discardableGraphCache );
219 emitPercent( count, totalCount );
222 emitPercent( totalCount, totalCount );
228 void GraphMigrationJob::migrateGraph(
const QUrl& graph,
const QHash<QUrl, QUrl>& graphCache)
230 QString query = QString::fromLatin1(
"select distinct ?app where { %1 %2 ?app . }")
231 .arg( Soprano::Node::resourceToN3(graph),
232 Soprano::Node::resourceToN3(NAO::maintainedBy()) );
235 Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
240 if( apps.isEmpty() ) {
242 apps << m_nepomukGraph;
245 foreach(
const QUrl& app, apps) {
246 QUrl finalGraph = graphCache.value(app);
247 Q_ASSERT( !finalGraph.isEmpty() );
249 copyStatements( graph, finalGraph );
250 deleteGraph( graph );
255 void GraphMigrationJob::copyStatements(
const QUrl& from,
const QUrl& to)
257 kDebug() << from <<
"-->" << to;
258 QString insertQ = QString::fromLatin1(
"insert into %1 { ?r ?p ?o. } where { graph %2 { ?r ?p ?o. } }")
259 .arg( Soprano::Node::resourceToN3(to),
260 Soprano::Node::resourceToN3(from) );
261 m_model->executeQuery( insertQ, Soprano::Query::QueryLanguageSparqlNoInference );
264 void GraphMigrationJob::deleteGraph(
const QUrl& g)
267 m_model->removeContext( g );
270 QString metaQ = QString::fromLatin1(
"select ?mg where { ?mg %1 %2 . }")
271 .arg( Soprano::Node::resourceToN3(NRL::coreGraphMetadataFor()),
272 Soprano::Node::resourceToN3(g) );
274 Soprano::QueryResultIterator it = m_model->executeQuery( metaQ, Soprano::Query::QueryLanguageSparqlNoInference );
276 m_model->removeContext( it[0] );
281 int GraphMigrationJob::discardableInstanceBaseGraphCount()
283 QString query = QString::fromLatin1(
"select count(distinct ?g) where { ?g a %1 . }")
284 .arg( Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
286 Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
288 return it[0].literal().toInt();
292 int GraphMigrationJob::instanceBaseGraphCount()
294 QString query = QString::fromLatin1(
"select count(distinct ?g) where { ?g a %1. "
295 "FILTER NOT EXISTS { ?g a %2 . } }")
296 .arg( Soprano::Node::resourceToN3(NRL::InstanceBase()),
297 Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
299 Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
301 return it[0].literal().toInt();