# HG changeset patch # User Chris Cannam # Date 1227290594 0 # Node ID c3fb8258e34d9ce74551b0dc6d56b0781a2d7da6 # Parent 82ab61fa9223799dee1aff76962d7d5304426519 * Make it possible to import an entire session from an RDF document. However, at the moment the timings of events appear to be constrained by how far the audio decoder has got through its audio file at the time the event is queried -- need to investigate. diff -r 82ab61fa9223 -r c3fb8258e34d rdf/RDFImporter.cpp --- a/rdf/RDFImporter.cpp Fri Nov 21 16:12:29 2008 +0000 +++ b/rdf/RDFImporter.cpp Fri Nov 21 18:03:14 2008 +0000 @@ -40,15 +40,20 @@ public: RDFImporterImpl(QString url, int sampleRate); virtual ~RDFImporterImpl(); + + void setSampleRate(int sampleRate) { m_sampleRate = sampleRate; } bool isOK(); QString getErrorString() const; + QString getAudioAvailableUrl() const { return m_audioAvailableAt; } + std::vector getDataModels(ProgressReporter *); protected: QString m_uristring; QString m_errorString; + QString m_audioAvailableAt; int m_sampleRate; void getDataModelsSparse(std::vector &, ProgressReporter *); @@ -79,6 +84,12 @@ delete m_d; } +void +RDFImporter::setSampleRate(int sampleRate) +{ + m_d->setSampleRate(sampleRate); +} + bool RDFImporter::isOK() { @@ -91,6 +102,12 @@ return m_d->getErrorString(); } +QString +RDFImporter::getAudioAvailableUrl() const +{ + return m_d->getAudioAvailableUrl(); +} + std::vector RDFImporter::getDataModels(ProgressReporter *r) { @@ -101,6 +118,19 @@ m_uristring(uri), m_sampleRate(sampleRate) { + SimpleSPARQLQuery::Value value = + SimpleSPARQLQuery::singleResultQuery + (SimpleSPARQLQuery::QueryFromSingleSource, + QString + (" PREFIX mo: " + " SELECT ?url FROM <%1> " + " WHERE { ?signal a mo:Signal ; mo:available_as ?url } " + ).arg(uri), + "url"); + + if (value.type == SimpleSPARQLQuery::URIValue) { + m_audioAvailableAt = value.value; + } } RDFImporterImpl::~RDFImporterImpl() @@ -124,6 +154,11 @@ { std::vector models; + if (m_sampleRate == 0) { + std::cerr << "RDFImporter::getDataModels: invalid sample rate" << std::endl; + return models; + } + getDataModelsDense(models, reporter); QString error; @@ -703,4 +738,70 @@ return; } +RDFImporter::RDFDocumentType +RDFImporter::identifyDocumentType(QString url) +{ + bool haveAudio = false; + bool haveAnnotations = false; + SimpleSPARQLQuery::Value value = + SimpleSPARQLQuery::singleResultQuery + (SimpleSPARQLQuery::QueryFromSingleSource, + QString + (" PREFIX mo: " + " SELECT ?url FROM <%1> " + " WHERE { ?signal a mo:Signal ; mo:available_as ?url } " + ).arg(url), + "url"); + + if (value.type == SimpleSPARQLQuery::URIValue) { + haveAudio = true; + } + + value = + SimpleSPARQLQuery::singleResultQuery + (SimpleSPARQLQuery::QueryFromSingleSource, + QString + (" PREFIX event: " + " SELECT ?thing FROM <%1> " + " WHERE { ?thing event:time ?time } " + ).arg(url), + "thing"); + + if (value.type == SimpleSPARQLQuery::URIValue) { + haveAnnotations = true; + } + + if (!haveAnnotations) { + + value = + SimpleSPARQLQuery::singleResultQuery + (SimpleSPARQLQuery::QueryFromSingleSource, + QString + (" PREFIX af: " + " SELECT ?thing FROM <%1> " + " WHERE { ?signal af:signal_feature ?thing } " + ).arg(url), + "thing"); + + if (value.type == SimpleSPARQLQuery::URIValue) { + haveAnnotations = true; + } + } + + if (haveAudio) { + if (haveAnnotations) { + return AudioRefAndAnnotations; + } else { + return AudioRef; + } + } else { + if (haveAnnotations) { + return Annotations; + } else { + return OtherDocument; + } + } +} + + diff -r 82ab61fa9223 -r c3fb8258e34d rdf/RDFImporter.h --- a/rdf/RDFImporter.h Fri Nov 21 16:12:29 2008 +0000 +++ b/rdf/RDFImporter.h Fri Nov 21 18:03:14 2008 +0000 @@ -37,14 +37,27 @@ */ static QString getKnownExtensions(); - RDFImporter(QString url, int sampleRate); + RDFImporter(QString url, int sampleRate = 0); virtual ~RDFImporter(); + void setSampleRate(int sampleRate); + bool isOK(); QString getErrorString() const; + QString getAudioAvailableUrl() const; + std::vector getDataModels(ProgressReporter *reporter); + enum RDFDocumentType { + AudioRefAndAnnotations, + Annotations, + AudioRef, + OtherDocument + }; + + static RDFDocumentType identifyDocumentType(QString url); + protected: RDFImporterImpl *m_d; }; diff -r 82ab61fa9223 -r c3fb8258e34d rdf/SimpleSPARQLQuery.cpp --- a/rdf/SimpleSPARQLQuery.cpp Fri Nov 21 16:12:29 2008 +0000 +++ b/rdf/SimpleSPARQLQuery.cpp Fri Nov 21 18:03:14 2008 +0000 @@ -31,7 +31,7 @@ #include -//#define DEBUG_SIMPLE_SPARQL_QUERY 1 +#define DEBUG_SIMPLE_SPARQL_QUERY 1 #include @@ -115,8 +115,6 @@ librdf_uri *getUri(QString uriString, QString &errorString) { - QMutexLocker locker(&m_mutex); - if (m_parsedUris.find(uriString) != m_parsedUris.end()) { return m_parsedUris[uriString]; } @@ -143,7 +141,7 @@ errorString = QString("Failed to parse RDF from URI \"%1\"") .arg(uriString); librdf_free_parser(parser); - librdf_free_uri(uri); +// librdf_free_uri(uri); return 0; } else { @@ -315,7 +313,7 @@ { ResultList list; - m_mutex.lock(); + QMutexLocker locker(&m_mutex); if (m_type == QueryFromModel) { if (!m_redland) { @@ -323,7 +321,6 @@ // added to the model yet (m_redland is only created when // addSourceToModel is called) cerr << "SimpleSPARQLQuery::execute: NOTE: No sources have been added to data model yet, so no results are possible" << endl; - m_mutex.unlock(); return list; } } @@ -336,7 +333,6 @@ cerr << "ERROR: SimpleSPARQLQuery::execute: Failed to initialise Rasqal query engine" << endl; delete m_rasqal; m_rasqal = 0; - m_mutex.unlock(); return list; } } @@ -348,8 +344,6 @@ #endif } - m_mutex.unlock(); - if (m_type == QueryFromSingleSource) { return executeDirectParser(); } else { @@ -426,6 +420,11 @@ const unsigned char *name = rasqal_query_results_get_binding_name(results, i); + if (!name) { + std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl; + continue; + } + rasqal_literal *literal = rasqal_query_results_get_binding_value(results, i); @@ -437,10 +436,16 @@ } ValueType type = LiteralValue; - if (literal->type == RASQAL_LITERAL_URI) type = URIValue; - else if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue; + if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue; + else if (literal->type == RASQAL_LITERAL_URI) type = URIValue; - QString text = (const char *)rasqal_literal_as_string(literal); + QString text; + const char *lit = (const char *)rasqal_literal_as_string(literal); + if (!lit) { + std::cerr << "WARNING: Result " << i << " of query has null value" << std::endl; + } else { + text = lit; + } #ifdef DEBUG_SIMPLE_SPARQL_QUERY std::cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << std::endl; @@ -539,6 +544,11 @@ const char *name = librdf_query_results_get_binding_name(results, i); + if (!name) { + std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl; + continue; + } + librdf_node *node = librdf_query_results_get_binding_value(results, i); @@ -556,12 +566,24 @@ type = URIValue; librdf_uri *uri = librdf_node_get_uri(node); - text = (const char *)librdf_uri_as_string(uri); + const char *us = (const char *)librdf_uri_as_string(uri); + + if (!us) { + std::cerr << "WARNING: Result " << i << " of query claims URI type, but has null URI" << std::endl; + } else { + text = us; + } } else if (librdf_node_is_literal(node)) { type = LiteralValue; - text = (const char *)librdf_node_get_literal_value(node); + + const char *lit = (const char *)librdf_node_get_literal_value(node); + if (!lit) { + std::cerr << "WARNING: Result " << i << " of query claims literal type, but has no literal" << std::endl; + } else { + text = lit; + } } else if (librdf_node_is_blank(node)) { @@ -617,7 +639,7 @@ { QString err; - m_mutex.lock(); + QMutexLocker locker(&m_mutex); if (!m_redland) { m_redland = new WredlandWorldWrapper(); @@ -625,13 +647,10 @@ cerr << "ERROR: SimpleSPARQLQuery::addSourceToModel: Failed to initialise Redland datastore" << endl; delete m_redland; m_redland = 0; - m_mutex.unlock(); return false; } } - m_mutex.unlock(); - librdf_uri *uri = m_redland->getUri(sourceUri, err); if (!uri) {