• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • sources
  • kde-4.12
  • kdelibs
  • nepomuk-core
  • services
  • storage
graphmigrationjob.cpp
Go to the documentation of this file.
1 /*
2  * <one line to give the library's name and an idea of what it does.>
3  * Copyright 2013 Vishesh Handa <me@vhanda.in>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License or (at your option) version 3 or any later version
9  * accepted by the membership of KDE e.V. (or its successor approved
10  * by the membership of KDE e.V.), which shall act as a proxy
11  * defined in Section 14 of version 3 of the license.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "graphmigrationjob.h"
24 
25 #include <Soprano/Model>
26 #include <Soprano/QueryResultIterator>
27 #include <Soprano/Vocabulary/NRL>
28 
29 #include <QtCore/QTimer>
30 #include <Soprano/Vocabulary/NAO>
31 #include <KDebug>
32 
33 using namespace Soprano::Vocabulary;
34 using namespace Nepomuk2;
35 
36 
37 GraphMigrationJob::GraphMigrationJob(Soprano::Model* model, QObject* parent)
38  : KJob(parent)
39  , m_model(model)
40 {
41 }
42 
43 void GraphMigrationJob::start()
44 {
45  QTimer::singleShot( 0, this, SLOT(migrateData()) );
46 }
47 
48 namespace {
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) );
52 
53  Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
54  if( it.next() )
55  return it[0].literal().toInt();
56 
57  return 0;
58  }
59 
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")) );
64 
65  Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
66  if( it.next() )
67  return it[0].uri();
68 
69  return QUrl();
70  }
71 }
72 
73 void GraphMigrationJob::mergeAgents()
74 {
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()) );
78 
79  Soprano::QueryResultIterator it = m_model->executeQuery( appQ, Soprano::Query::QueryLanguageSparqlNoInference );
80  while( it.next() ) {
81  QString identifier = it[0].literal().toString();
82  kDebug() << identifier;
83 
84  QString aQuery = QString::fromLatin1("select distinct ?r where { ?r a nao:Agent ; nao:identifier %1. }")
85  .arg( Soprano::Node::literalToN3(identifier) );
86 
87  Soprano::QueryResultIterator iter = m_model->executeQuery( aQuery, Soprano::Query::QueryLanguageSparqlNoInference );
88  QList<QUrl> apps;
89  while( iter.next() )
90  apps << iter[0].uri();
91 
92  mergeAgents( apps );
93  }
94 }
95 
96 void GraphMigrationJob::mergeAgents(const QList< QUrl >& agents)
97 {
98  kDebug() << "Merging agents" << agents;
99  QUrl mainApp;
100  foreach(const QUrl& app, agents) {
101  if( mainApp.isEmpty() ) {
102  mainApp = app;
103  continue;
104  }
105 
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) );
110 
111  m_model->removeAllStatements( app, QUrl(), QUrl() );
112  m_model->removeAllStatements( QUrl(), QUrl(), app );
113  }
114 }
115 
116 
117 void GraphMigrationJob::migrateData()
118 {
119  mergeAgents();
120 
121  int graphCount = instanceBaseGraphCount();
122  int discardableGraphCount = discardableInstanceBaseGraphCount();
123  int totalCount = graphCount + discardableGraphCount;
124  int count = 0;
125 
126  kDebug() << "Total Count:" << totalCount;
127 
128  m_nepomukGraph = nepomukGraph(m_model);
129  if( m_nepomukGraph.isEmpty() ) {
130  setErrorText("No nepomuk graph. Something is very wrong. Please report a bug");
131  emitResult();
132  }
133 
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()) );
137 
138  Soprano::QueryResultIterator it = m_model->executeQuery( appQ, Soprano::Query::QueryLanguageSparqlNoInference );
139  if( it.next() ) {
140  QUrl app = it[0].uri();
141  if( !app.isEmpty() ) {
142  m_apps << app;
143  kDebug() << "Inserting" << app;
144  }
145  }
146 
147  if( m_apps.isEmpty() ) {
148  setErrorText( "No application agents found. Data cannot be migrated" );
149  emitResult();
150  }
151 
152  // Fetch a graph for each application
153  QHash<QUrl, QUrl> graphCache;
154  QHash<QUrl, QUrl> discardableGraphCache;
155 
156  foreach(const QUrl& app, m_apps) {
157  // Normal Graph
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) );
161 
162  it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
163  while (it.next()) {
164  const QUrl graph = it[0].uri();
165  if( fetchAppCount(m_model, graph) == 1 ) {
166  graphCache.insert( app, graph );
167  count++;
168  emitPercent( count, totalCount );
169  }
170  }
171 
172  // Discardable Graphs
173  query = QString::fromLatin1("select ?g where { ?g a nrl:DiscardableInstanceBase ; nao:maintainedBy %1 .}")
174  .arg( Soprano::Node::resourceToN3(app) );
175 
176  it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
177  while (it.next()) {
178  const QUrl graph = it[0].uri();
179  if( fetchAppCount(m_model, graph) == 1 ) {
180  discardableGraphCache.insert( app, graph );
181  count++;
182  emitPercent( count, totalCount );
183  }
184  }
185  }
186 
187  kDebug() << "Fetched graph cache:" << graphCache.size();
188  kDebug() << "Fetched discardable graph cache:" << discardableGraphCache.size();
189 
190  // Start migrating the data
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()) );
195 
196  it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
197  while( it.next() ) {
198  const QUrl graph = it[0].uri();
199  if( graphCache.contains(graph) )
200  continue;
201 
202  migrateGraph( graph, graphCache );
203  count++;
204  emitPercent( count, totalCount );
205  }
206 
207  // Discardbale Data
208  QString gquery = QString::fromLatin1("select distinct ?g where { ?g a %1. }")
209  .arg( Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
210 
211  it = m_model->executeQuery( gquery, Soprano::Query::QueryLanguageSparqlNoInference );
212  while( it.next() ) {
213  const QUrl graph = it[0].uri();
214  if( discardableGraphCache.contains(graph) )
215  continue;
216 
217  migrateGraph( graph, discardableGraphCache );
218  count++;
219  emitPercent( count, totalCount );
220  }
221 
222  emitPercent( totalCount, totalCount );
223  emitResult();
224 }
225 
226 
227 
228 void GraphMigrationJob::migrateGraph(const QUrl& graph, const QHash<QUrl, QUrl>& graphCache)
229 {
230  QString query = QString::fromLatin1("select distinct ?app where { %1 %2 ?app . }")
231  .arg( Soprano::Node::resourceToN3(graph),
232  Soprano::Node::resourceToN3(NAO::maintainedBy()) );
233 
234  QList<QUrl> apps;
235  Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
236  while( it.next() ) {
237  apps << it[0].uri();
238  }
239 
240  if( apps.isEmpty() ) {
241  // If empty, then push into the Nepomuk Graph
242  apps << m_nepomukGraph;
243  }
244 
245  foreach(const QUrl& app, apps) {
246  QUrl finalGraph = graphCache.value(app);
247  Q_ASSERT( !finalGraph.isEmpty() );
248 
249  copyStatements( graph, finalGraph );
250  deleteGraph( graph );
251  }
252 }
253 
254 
255 void GraphMigrationJob::copyStatements(const QUrl& from, const QUrl& to)
256 {
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 );
262 }
263 
264 void GraphMigrationJob::deleteGraph(const QUrl& g)
265 {
266  kDebug() << g;
267  m_model->removeContext( g );
268 
269  // Fetch and remove the metadata graph
270  QString metaQ = QString::fromLatin1("select ?mg where { ?mg %1 %2 . }")
271  .arg( Soprano::Node::resourceToN3(NRL::coreGraphMetadataFor()),
272  Soprano::Node::resourceToN3(g) );
273 
274  Soprano::QueryResultIterator it = m_model->executeQuery( metaQ, Soprano::Query::QueryLanguageSparqlNoInference );
275  while( it.next() ) {
276  m_model->removeContext( it[0] );
277  }
278 
279 }
280 
281 int GraphMigrationJob::discardableInstanceBaseGraphCount()
282 {
283  QString query = QString::fromLatin1("select count(distinct ?g) where { ?g a %1 . }")
284  .arg( Soprano::Node::resourceToN3(NRL::DiscardableInstanceBase()) );
285 
286  Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
287  if( it.next() )
288  return it[0].literal().toInt();
289  return 0;
290 }
291 
292 int GraphMigrationJob::instanceBaseGraphCount()
293 {
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()) );
298 
299  Soprano::QueryResultIterator it = m_model->executeQuery( query, Soprano::Query::QueryLanguageSparqlNoInference );
300  if( it.next() )
301  return it[0].literal().toInt();
302  return 0;
303 }
304 
QHash
QObject
Nepomuk2::GraphMigrationJob::start
virtual void start()
Definition: graphmigrationjob.cpp:43
graphmigrationjob.h
KJob
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Nepomuk-Core

Skip menu "Nepomuk-Core"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal