00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "BasicStore.h"
00035 #include "RDFException.h"
00036
00037 #include <redland.h>
00038
00039 #include <QThread>
00040 #include <QMutex>
00041 #include <QMutexLocker>
00042 #include <QMap>
00043 #include <QUrl>
00044 #include <QCryptographicHash>
00045
00046 #include "Debug.h"
00047
00048 #include <iostream>
00049
00050 namespace Dataquay
00051 {
00052
00053 class BasicStore::D
00054 {
00055 public:
00056 D() : m_storage(0), m_model(0), m_counter(0) {
00057 m_baseUri = "#";
00058 m_prefixes[""] = m_baseUri;
00059 m_prefixes["rdf"] = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
00060 m_prefixes["xsd"] = "http://www.w3.org/2001/XMLSchema#";
00061 clear();
00062 }
00063
00064 ~D() {
00065 QMutexLocker locker(&m_mutex);
00066 if (m_model) librdf_free_model(m_model);
00067 if (m_storage) librdf_free_storage(m_storage);
00068 }
00069
00070 void setBaseUri(QString baseUri) {
00071 QMutexLocker locker(&m_mutex);
00072 m_baseUri = baseUri;
00073 m_prefixes[""] = m_baseUri;
00074 }
00075
00076 QString getBaseUri() const {
00077 return m_baseUri;
00078 }
00079
00080 void clear() {
00081 QMutexLocker locker(&m_mutex);
00082 DEBUG << "BasicStore::clear" << endl;
00083 if (m_model) librdf_free_model(m_model);
00084 if (m_storage) librdf_free_storage(m_storage);
00085 m_storage = librdf_new_storage(m_w.getWorld(), "trees", 0, 0);
00086 if (!m_storage) {
00087 DEBUG << "Failed to create RDF trees storage, falling back to default storage type" << endl;
00088 m_storage = librdf_new_storage(m_w.getWorld(), 0, 0, 0);
00089 if (!m_storage) throw RDFException("Failed to create RDF data storage");
00090 }
00091 m_model = librdf_new_model(m_w.getWorld(), m_storage, 0);
00092 if (!m_model) throw RDFException("Failed to create RDF data model");
00093 }
00094
00095 void addPrefix(QString prefix, QString uri) {
00096 QMutexLocker locker(&m_mutex);
00097 m_prefixes[prefix] = uri;
00098 }
00099
00100 bool add(Triple t) {
00101 QMutexLocker locker(&m_mutex);
00102 DEBUG << "BasicStore::add: " << t << endl;
00103 return doAdd(t);
00104 }
00105
00106 bool remove(Triple t) {
00107 QMutexLocker locker(&m_mutex);
00108 DEBUG << "BasicStore::remove: " << t << endl;
00109 if (t.a.type == Node::Nothing ||
00110 t.b.type == Node::Nothing ||
00111 t.c.type == Node::Nothing) {
00112 Triples tt = doMatch(t);
00113 if (tt.empty()) return false;
00114 for (int i = 0; i < tt.size(); ++i) {
00115 if (!doRemove(tt[i])) {
00116 throw RDFException("Failed to remove matched statement in remove() with wildcards");
00117 }
00118 }
00119 return true;
00120 } else {
00121 return doRemove(t);
00122 }
00123 }
00124
00125 void change(ChangeSet cs) {
00126 QMutexLocker locker(&m_mutex);
00127 DEBUG << "BasicStore::change: " << cs.size() << " changes" << endl;
00128 for (int i = 0; i < cs.size(); ++i) {
00129 ChangeType type = cs[i].first;
00130 switch (type) {
00131 case AddTriple:
00132 if (!doAdd(cs[i].second)) {
00133 throw RDFException("Change add failed due to duplication");
00134 }
00135 break;
00136 case RemoveTriple:
00137 if (!doRemove(cs[i].second)) {
00138 throw RDFException("Change remove failed due to absence");
00139 }
00140 break;
00141 }
00142 }
00143 }
00144
00145 void revert(ChangeSet cs) {
00146 QMutexLocker locker(&m_mutex);
00147 DEBUG << "BasicStore::revert: " << cs.size() << " changes" << endl;
00148 for (int i = cs.size()-1; i >= 0; --i) {
00149 ChangeType type = cs[i].first;
00150 switch (type) {
00151 case AddTriple:
00152 if (!doRemove(cs[i].second)) {
00153 throw RDFException("Change revert add failed due to absence");
00154 }
00155 break;
00156 case RemoveTriple:
00157 if (!doAdd(cs[i].second)) {
00158 throw RDFException("Change revert remove failed due to duplication");
00159 }
00160 break;
00161 }
00162 }
00163 }
00164
00165 bool contains(Triple t) const {
00166 QMutexLocker locker(&m_mutex);
00167 DEBUG << "BasicStore::contains: " << t << endl;
00168 librdf_statement *statement = tripleToStatement(t);
00169 if (!checkComplete(statement)) {
00170 librdf_free_statement(statement);
00171 throw RDFException("Failed to test for triple (statement is incomplete)");
00172 }
00173 if (!librdf_model_contains_statement(m_model, statement)) {
00174 librdf_free_statement(statement);
00175 return false;
00176 } else {
00177 librdf_free_statement(statement);
00178 return true;
00179 }
00180 }
00181
00182 Triples match(Triple t) const {
00183 QMutexLocker locker(&m_mutex);
00184 DEBUG << "BasicStore::match: " << t << endl;
00185 Triples result = doMatch(t);
00186 #ifndef NDEBUG
00187 DEBUG << "BasicStore::match result (size " << result.size() << "):" << endl;
00188 for (int i = 0; i < result.size(); ++i) {
00189 DEBUG << i << ". " << result[i] << endl;
00190 }
00191 #endif
00192 return result;
00193 }
00194
00195 Triple matchFirst(Triple t) const {
00196 if (t.c != Node() && t.b != Node() && t.a != Node()) {
00197
00198 if (contains(t)) return t;
00199 else return Triple();
00200 }
00201 QMutexLocker locker(&m_mutex);
00202 DEBUG << "BasicStore::matchFirst: " << t << endl;
00203 Triples result = doMatch(t, true);
00204 #ifndef NDEBUG
00205 DEBUG << "BasicStore::matchFirst result:" << endl;
00206 for (int i = 0; i < result.size(); ++i) {
00207 DEBUG << i << ". " << result[i] << endl;
00208 }
00209 #endif
00210 if (result.empty()) return Triple();
00211 else return result[0];
00212 }
00213
00214 ResultSet query(QString sparql) const {
00215 QMutexLocker locker(&m_mutex);
00216 DEBUG << "BasicStore::query: " << sparql << endl;
00217 ResultSet rs = runQuery(sparql);
00218 return rs;
00219 }
00220
00221 Node queryFirst(QString sparql, QString bindingName) const {
00222 QMutexLocker locker(&m_mutex);
00223 DEBUG << "BasicStore::queryFirst: " << bindingName << " from " << sparql << endl;
00224 ResultSet rs = runQuery(sparql);
00225 if (rs.empty()) return Node();
00226 for (ResultSet::const_iterator i = rs.begin(); i != rs.end(); ++i) {
00227 Dictionary::const_iterator j = i->find(bindingName);
00228 if (j == i->end()) continue;
00229 if (j->type == Node::Nothing) continue;
00230 return *j;
00231 }
00232 return Node();
00233 }
00234
00235 QUrl getUniqueUri(QString prefix) const {
00236 QMutexLocker locker(&m_mutex);
00237 DEBUG << "BasicStore::getUniqueUri: prefix " << prefix << endl;
00238 int base = (int)(long)this;
00239 bool good = false;
00240 QString uri;
00241 while (!good) {
00242 int n = base + m_counter;
00243 m_counter++;
00244 QString hashed =
00245 QString::fromLocal8Bit
00246 (QCryptographicHash::hash(QString("%1").arg(n).toLocal8Bit(),
00247 QCryptographicHash::Sha1).toHex())
00248 .left(12);
00249 uri = prefix + hashed;
00250 Triples t =
00251 doMatch(Triple(Node(Node::URI, uri), Node(), Node()), true);
00252 if (t.empty()) good = true;
00253 }
00254 return expand(uri);
00255 }
00256
00257 QUrl expand(QString uri) const {
00258 return QUrl(prefixExpand(uri));
00259 }
00260
00261 void save(QString filename) const {
00262
00263 QMutexLocker locker(&m_mutex);
00264
00265 librdf_uri *base_uri = stringToUri(m_baseUri);
00266 QByteArray b = filename.toLocal8Bit();
00267 const char *lname = b.data();
00268
00269 librdf_serializer *s = librdf_new_serializer(m_w.getWorld(), "turtle", 0, 0);
00270 if (!s) throw RDFException("Failed to construct RDF serializer");
00271 for (PrefixMap::const_iterator i = m_prefixes.begin();
00272 i != m_prefixes.end(); ++i) {
00273 QByteArray b = i.key().toUtf8();
00274 librdf_serializer_set_namespace(s, stringToUri(i.value()), b.data());
00275 }
00276 librdf_serializer_set_namespace(s, stringToUri(m_baseUri), "");
00277
00278 if (librdf_serializer_serialize_model_to_file(s, lname, base_uri, m_model)) {
00279 librdf_free_serializer(s);
00280 throw RDFException("Failed to export RDF model to file", filename);
00281 } else {
00282 librdf_free_serializer(s);
00283 }
00284 }
00285
00286 void import(QString url, ImportDuplicatesMode idm) {
00287
00288 QMutexLocker locker(&m_mutex);
00289
00290 librdf_uri *luri = stringToUri(url);
00291 librdf_uri *base_uri = stringToUri(m_baseUri);
00292
00293 librdf_parser *parser = librdf_new_parser
00294 (m_w.getWorld(), "guess", NULL, NULL);
00295 if (!parser) {
00296 throw RDFException("Failed to construct RDF parser");
00297 }
00298
00299 if (idm == ImportPermitDuplicates) {
00300
00301 if (librdf_parser_parse_into_model
00302 (parser, luri, base_uri, m_model)) {
00303 librdf_free_parser(parser);
00304 throw RDFException("Failed to import model from URL", url);
00305 }
00306 } else {
00307
00308
00309
00310
00311
00312
00313
00314 librdf_storage *is = librdf_new_storage(m_w.getWorld(), "trees", 0, 0);
00315 if (!is) is = librdf_new_storage(m_w.getWorld(), 0, 0, 0);
00316 if (!is) {
00317 librdf_free_parser(parser);
00318 throw RDFException("Failed to create import RDF data storage");
00319 }
00320 librdf_model *im = librdf_new_model(m_w.getWorld(), is, 0);
00321 if (!im) {
00322 librdf_free_storage(is);
00323 librdf_free_parser(parser);
00324 throw RDFException("Failed to create import RDF data model");
00325 }
00326
00327 librdf_stream *stream = 0;
00328 librdf_statement *all = 0;
00329
00330 try {
00331
00332 if (librdf_parser_parse_into_model(parser, luri, base_uri, im)) {
00333 throw RDFException("Failed to import model from URL", url);
00334 }
00335 all = tripleToStatement(Triple());
00336
00337 if (idm == ImportFailOnDuplicates) {
00338
00339 stream = librdf_model_find_statements(im, all);
00340 if (!stream) {
00341 throw RDFException("Failed to list imported RDF model in duplicates check");
00342 }
00343 while (!librdf_stream_end(stream)) {
00344 librdf_statement *current = librdf_stream_get_object(stream);
00345 if (!current) continue;
00346 if (librdf_model_contains_statement(m_model, current)) {
00347 throw RDFDuplicateImportException("Duplicate statement encountered on import in ImportFailOnDuplicates mode");
00348 }
00349 librdf_stream_next(stream);
00350 }
00351 librdf_free_stream(stream);
00352 stream = 0;
00353 }
00354
00355
00356
00357 stream = librdf_model_find_statements(im, all);
00358 if (!stream) {
00359 throw RDFException("Failed to list imported RDF model");
00360 }
00361 while (!librdf_stream_end(stream)) {
00362 librdf_statement *current = librdf_stream_get_object(stream);
00363 if (!current) continue;
00364 if (!librdf_model_contains_statement(m_model, current)) {
00365 librdf_model_add_statement(m_model, current);
00366 }
00367 librdf_stream_next(stream);
00368 }
00369 librdf_free_stream(stream);
00370 stream = 0;
00371
00372 } catch (...) {
00373 if (stream) librdf_free_stream(stream);
00374 if (all) librdf_free_statement(all);
00375 librdf_free_parser(parser);
00376 librdf_free_model(im);
00377 librdf_free_storage(is);
00378 throw;
00379 }
00380
00381 librdf_free_model(im);
00382 librdf_free_storage(is);
00383 }
00384
00385 int namespaces = librdf_parser_get_namespaces_seen_count(parser);
00386 DEBUG << "Parser found " << namespaces << " namespaces" << endl;
00387 for (int i = 0; i < namespaces; ++i) {
00388 const char *pfx = librdf_parser_get_namespaces_seen_prefix(parser, i);
00389 librdf_uri *uri = librdf_parser_get_namespaces_seen_uri(parser, i);
00390 QString qpfx = QString::fromUtf8(pfx);
00391 QString quri = uriToString(uri);
00392 DEBUG << "namespace " << i << ": " << qpfx << " -> " << quri << endl;
00393 if (qpfx == "" && quri != "#") {
00394
00395 if (m_baseUri == "#") {
00396 std::cerr << "BasicStore::import: NOTE: Loading file into store with no base URI; setting base URI to <" << quri.toStdString() << "> from file" << std::endl;
00397 m_baseUri = quri;
00398 m_prefixes[""] = m_baseUri;
00399 } else {
00400 if (quri != m_baseUri) {
00401 std::cerr << "BasicStore::import: NOTE: Base URI of loaded file differs from base URI of store (<" << quri.toStdString() << "> != <" << m_baseUri.toStdString() << ">)" << std::endl;
00402 }
00403 }
00404 }
00405
00406
00407
00408
00409 if (m_prefixes.find(qpfx) == m_prefixes.end()) {
00410 m_prefixes[qpfx] = quri;
00411 }
00412 }
00413
00414 librdf_free_parser(parser);
00415 }
00416
00417 private:
00418 class World
00419 {
00420 public:
00421 World() {
00422 QMutexLocker locker(&m_mutex);
00423 if (!m_world) {
00424 m_world = librdf_new_world();
00425 librdf_world_open(m_world);
00426 }
00427 ++m_refcount;
00428 }
00429 ~World() {
00430 QMutexLocker locker(&m_mutex);
00431 if (--m_refcount == 0) {
00432 DEBUG << "Freeing world" << endl;
00433 librdf_free_world(m_world);
00434 m_world = 0;
00435 }
00436 }
00437
00438 librdf_world *getWorld() const { return m_world; }
00439
00440 private:
00441 static QMutex m_mutex;
00442 static librdf_world *m_world;
00443 static int m_refcount;
00444 };
00445
00446 World m_w;
00447 librdf_storage *m_storage;
00448 librdf_model *m_model;
00449 QString m_baseUri;
00450 typedef QMap<QString, QString> PrefixMap;
00451 PrefixMap m_prefixes;
00452 static QMutex m_mutex;
00453 mutable int m_counter;
00454
00455 bool doAdd(Triple t) {
00456 librdf_statement *statement = tripleToStatement(t);
00457 if (!checkComplete(statement)) {
00458 librdf_free_statement(statement);
00459 throw RDFException("Failed to add triple (statement is incomplete)");
00460 }
00461 if (librdf_model_contains_statement(m_model, statement)) {
00462 librdf_free_statement(statement);
00463 return false;
00464 }
00465 if (librdf_model_add_statement(m_model, statement)) {
00466 librdf_free_statement(statement);
00467 throw RDFException("Failed to add statement to model");
00468 }
00469 librdf_free_statement(statement);
00470 return true;
00471 }
00472
00473 bool doRemove(Triple t) {
00474 librdf_statement *statement = tripleToStatement(t);
00475 if (!checkComplete(statement)) {
00476 librdf_free_statement(statement);
00477 throw RDFException("Failed to remove triple (statement is incomplete)");
00478 }
00479
00480
00481
00482 if (!librdf_model_contains_statement(m_model, statement)) {
00483 librdf_free_statement(statement);
00484 return false;
00485 }
00486 librdf_model_remove_statement(m_model, statement);
00487 librdf_free_statement(statement);
00488 return true;
00489 }
00490
00491 librdf_uri *stringToUri(QString uri) const {
00492 librdf_uri *luri = librdf_new_uri
00493 (m_w.getWorld(), (const unsigned char *)uri.toUtf8().data());
00494 if (!luri) throw RDFException("Failed to construct URI from string", uri);
00495 return luri;
00496 }
00497
00498 QString uriToString(librdf_uri *u) const {
00499 const char *s = (const char *)librdf_uri_as_string(u);
00500 if (s) return QString::fromUtf8(s);
00501 else return "";
00502 }
00503
00504 QString prefixExpand(const QString uri) const {
00505 if (uri == "a") return prefixExpand("rdf:type");
00506 QUrl qu(uri);
00507 QString expanded(uri);
00508 QString maybePrefix = qu.scheme();
00509 if (maybePrefix != "") {
00510 if (m_prefixes.find(maybePrefix) != m_prefixes.end()) {
00511 expanded = m_prefixes[maybePrefix] +
00512 uri.right(uri.length() - (maybePrefix.length() + 1));
00513 }
00514 } else {
00515 if (uri.startsWith(':')) {
00516 expanded = m_baseUri + uri.right(uri.length() - 1);
00517 }
00518 }
00519
00520 return expanded;
00521 }
00522
00523 librdf_node *nodeToLrdfNode(Node v) const {
00524 librdf_node *node = 0;
00525 switch (v.type) {
00526 case Node::Nothing:
00527 return 0;
00528 case Node::Blank:
00529 throw RDFException("Not equipped to add blank nodes");
00530 case Node::URI: {
00531 QString value = prefixExpand(v.value);
00532 librdf_uri *uri = stringToUri(value);
00533 if (!uri) throw RDFException("Failed to construct URI from value string", v.value);
00534 node = librdf_new_node_from_uri(m_w.getWorld(), uri);
00535 if (!node) throw RDFException("Failed to construct node from URI");
00536 }
00537 break;
00538 case Node::Literal: {
00539 QByteArray b = v.value.toUtf8();
00540 const unsigned char *literal = (const unsigned char *)b.data();
00541 if (v.datatype != "") {
00542 QString dtu = prefixExpand(v.datatype);
00543 librdf_uri *type_uri = stringToUri(dtu);
00544 node = librdf_new_node_from_typed_literal
00545 (m_w.getWorld(), literal, 0, type_uri);
00546 if (!node) throw RDFException
00547 ("Failed to construct node from typed literal");
00548 } else {
00549 node = librdf_new_node_from_literal
00550 (m_w.getWorld(), literal, 0, 0);
00551 if (!node) throw RDFException
00552 ("Failed to construct node from literal");
00553 }
00554 }
00555 break;
00556 }
00557 return node;
00558 }
00559
00560 Node lrdfNodeToNode(librdf_node *node) const {
00561
00562 Node v;
00563 if (!node) return v;
00564
00565 v.type = Node::Literal;
00566 QString text;
00567
00568 if (librdf_node_is_resource(node)) {
00569
00570 v.type = Node::URI;
00571 librdf_uri *uri = librdf_node_get_uri(node);
00572 v.value = uriToString(uri);
00573
00574 } else if (librdf_node_is_literal(node)) {
00575
00576 v.type = Node::Literal;
00577 const char *s = (const char *)librdf_node_get_literal_value(node);
00578 if (s) v.value = s;
00579 librdf_uri *type_uri = librdf_node_get_literal_value_datatype_uri(node);
00580 if (type_uri) v.datatype = uriToString(type_uri);
00581
00582 } else if (librdf_node_is_blank(node)) {
00583
00584 v.type = Node::Blank;
00585 const char *s = (const char *)librdf_node_get_literal_value(node);
00586 if (s) v.value = s;
00587 }
00588
00589 return v;
00590 }
00591
00592 librdf_statement *tripleToStatement(Triple t) const {
00593 librdf_node *na = nodeToLrdfNode(t.a);
00594 librdf_node *nb = nodeToLrdfNode(t.b);
00595 librdf_node *nc = nodeToLrdfNode(t.c);
00596 librdf_statement *statement =
00597 librdf_new_statement_from_nodes(m_w.getWorld(), na, nb, nc);
00598 if (!statement) throw RDFException("Failed to construct statement");
00599 return statement;
00600 }
00601
00602 Triple statementToTriple(librdf_statement *statement) const {
00603 librdf_node *subject = librdf_statement_get_subject(statement);
00604 librdf_node *predicate = librdf_statement_get_predicate(statement);
00605 librdf_node *object = librdf_statement_get_object(statement);
00606 Triple triple(lrdfNodeToNode(subject),
00607 lrdfNodeToNode(predicate),
00608 lrdfNodeToNode(object));
00609 return triple;
00610 }
00611
00612 bool checkComplete(librdf_statement *statement) const {
00613 if (librdf_statement_is_complete(statement)) return true;
00614 else {
00615 unsigned char *text = librdf_statement_to_string(statement);
00616 QString str = QString::fromUtf8((char *)text);
00617 std::cerr << "BasicStore::checkComplete: WARNING: RDF statement is incomplete: " << str.toStdString() << std::endl;
00618 free(text);
00619 return false;
00620 }
00621 }
00622
00623 Triples doMatch(Triple t, bool single = false) const {
00624
00625
00626 Triples results;
00627 librdf_statement *templ = tripleToStatement(t);
00628 librdf_stream *stream = librdf_model_find_statements(m_model, templ);
00629 librdf_free_statement(templ);
00630 if (!stream) throw RDFException("Failed to match RDF triples");
00631 while (!librdf_stream_end(stream)) {
00632 librdf_statement *current = librdf_stream_get_object(stream);
00633 if (current) results.push_back(statementToTriple(current));
00634 if (single) break;
00635 librdf_stream_next(stream);
00636 }
00637 librdf_free_stream(stream);
00638 return results;
00639 }
00640
00641 ResultSet runQuery(QString rawQuery) const {
00642
00643 if (m_baseUri == "#") {
00644 std::cerr << "BasicStore::runQuery: WARNING: Query requested on RDF store with default '#' base URI: results may be not as expected" << std::endl;
00645 }
00646
00647 QString sparql;
00648 for (PrefixMap::const_iterator i = m_prefixes.begin();
00649 i != m_prefixes.end(); ++i) {
00650 sparql += QString(" PREFIX %1: <%2> ").arg(i.key()).arg(i.value());
00651 }
00652 sparql += rawQuery;
00653
00654 ResultSet returned;
00655 librdf_query *query =
00656 librdf_new_query(m_w.getWorld(), "sparql", 0,
00657 (const unsigned char *)sparql.toUtf8().data(), 0);
00658 if (!query) return returned;
00659
00660 librdf_query_results *results = librdf_query_execute(query, m_model);
00661 if (!results) {
00662 librdf_free_query(query);
00663 return returned;
00664 }
00665 if (!librdf_query_results_is_bindings(results)) {
00666 librdf_free_query_results(results);
00667 librdf_free_query(query);
00668 return returned;
00669 }
00670
00671 while (!librdf_query_results_finished(results)) {
00672 int count = librdf_query_results_get_bindings_count(results);
00673 Dictionary dict;
00674 for (int i = 0; i < count; ++i) {
00675
00676 const char *name =
00677 librdf_query_results_get_binding_name(results, i);
00678 if (!name) continue;
00679 QString key = (const char *)name;
00680
00681 librdf_node *node =
00682 librdf_query_results_get_binding_value(results, i);
00683
00684 dict[key] = lrdfNodeToNode(node);
00685 }
00686
00687 returned.push_back(dict);
00688 librdf_query_results_next(results);
00689 }
00690
00691 librdf_free_query_results(results);
00692 librdf_free_query(query);
00693
00694
00695
00696 return returned;
00697 }
00698 };
00699
00700 QMutex
00701 BasicStore::D::m_mutex;
00702
00703 QMutex
00704 BasicStore::D::World::m_mutex;
00705
00706 librdf_world *
00707 BasicStore::D::World::m_world = 0;
00708
00709 int
00710 BasicStore::D::World::m_refcount = 0;
00711
00712 BasicStore::BasicStore() :
00713 m_d(new D())
00714 {
00715 }
00716
00717 BasicStore::~BasicStore()
00718 {
00719 delete m_d;
00720 }
00721
00722 void
00723 BasicStore::setBaseUri(QString uri)
00724 {
00725 m_d->setBaseUri(uri);
00726 }
00727
00728 QString
00729 BasicStore::getBaseUri() const
00730 {
00731 return m_d->getBaseUri();
00732 }
00733
00734 void
00735 BasicStore::clear()
00736 {
00737 m_d->clear();
00738 }
00739
00740 bool
00741 BasicStore::add(Triple t)
00742 {
00743 return m_d->add(t);
00744 }
00745
00746 bool
00747 BasicStore::remove(Triple t)
00748 {
00749 return m_d->remove(t);
00750 }
00751
00752 void
00753 BasicStore::change(ChangeSet t)
00754 {
00755 m_d->change(t);
00756 }
00757
00758 void
00759 BasicStore::revert(ChangeSet t)
00760 {
00761 m_d->revert(t);
00762 }
00763
00764 bool
00765 BasicStore::contains(Triple t) const
00766 {
00767 return m_d->contains(t);
00768 }
00769
00770 Triples
00771 BasicStore::match(Triple t) const
00772 {
00773 return m_d->match(t);
00774 }
00775
00776 void
00777 BasicStore::addPrefix(QString prefix, QString uri)
00778 {
00779 m_d->addPrefix(prefix, uri);
00780 }
00781
00782 ResultSet
00783 BasicStore::query(QString sparql) const
00784 {
00785 return m_d->query(sparql);
00786 }
00787
00788 Triple
00789 BasicStore::matchFirst(Triple t) const
00790 {
00791 return m_d->matchFirst(t);
00792 }
00793
00794 Node
00795 BasicStore::queryFirst(QString sparql, QString bindingName) const
00796 {
00797 return m_d->queryFirst(sparql, bindingName);
00798 }
00799
00800 QUrl
00801 BasicStore::getUniqueUri(QString prefix) const
00802 {
00803 return m_d->getUniqueUri(prefix);
00804 }
00805
00806 QUrl
00807 BasicStore::expand(QString uri) const
00808 {
00809 return m_d->expand(uri);
00810 }
00811
00812 void
00813 BasicStore::save(QString filename) const
00814 {
00815 m_d->save(filename);
00816 }
00817
00818 void
00819 BasicStore::import(QString url, ImportDuplicatesMode idm)
00820 {
00821 m_d->import(url, idm);
00822 }
00823
00824 BasicStore *
00825 BasicStore::load(QString url)
00826 {
00827 BasicStore *s = new BasicStore();
00828
00829 s->import(url, ImportIgnoreDuplicates);
00830 return s;
00831 }
00832
00833 }
00834
00835
00836
00837