changeset 47:273bd328b215

* Add (currently unused) ComposerFileIndex akin to FeatureFileIndex:
author Chris Cannam
date Fri, 28 May 2010 16:22:37 +0100
parents c8b777862198
children 5f23d5b29aaf
files common/ComposerFileIndex.cpp common/ComposerFileIndex.h
diffstat 2 files changed, 230 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/ComposerFileIndex.cpp	Fri May 28 16:22:37 2010 +0100
@@ -0,0 +1,182 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+#include "ComposerFileIndex.h"
+#include "TypeRegistrar.h"
+
+#include <QMutexLocker>
+#include <QDir>
+
+#include "base/TempDirectory.h"
+#include "base/Exceptions.h"
+
+using namespace Dataquay;
+
+
+namespace ClassicalData {
+
+ComposerFileIndex *
+ComposerFileIndex::getInstance()
+{
+    static ComposerFileIndex instance;
+    return &instance;
+}
+
+ComposerFileIndex::ComposerFileIndex() :
+    m_bs(0),
+    m_index(0)
+{
+    try {
+	m_indexFileName = getIndexFileName();
+    } catch (DirectoryCreationFailed f) {
+        std::cerr << "ComposerFileIndex: ERROR: Failed to find or create index directory: " << f.what() << std::endl;
+        return;
+    }
+
+    m_bs = new BasicStore;
+    m_index = new TransactionalStore(m_bs);
+
+    TypeRegistrar::addMappings(m_bs, 0);
+
+    if (QFile(m_indexFileName).exists()) {
+	m_bs->import(QUrl::fromLocalFile(m_indexFileName),
+                     BasicStore::ImportIgnoreDuplicates);
+	//!!! catch
+    }
+}
+
+ComposerFileIndex::~ComposerFileIndex()
+{
+    delete m_index;
+    delete m_bs;
+}
+
+QString
+ComposerFileIndex::getIndexFileName()
+{
+    QDir d = TempDirectory::getInstance()->getContainingPath();
+    QString n("index");
+    QFileInfo fi(d.filePath(n));
+
+    if ((fi.exists() && !fi.isDir()) ||
+        (!fi.exists() && !d.mkdir(n))) {
+        throw DirectoryCreationFailed(fi.filePath());
+    }
+
+    return QDir(fi.filePath()).filePath("composer-details.ttl");
+}
+
+QString
+ComposerFileIndex::getComposerDirectoryName()
+{
+    QDir d = TempDirectory::getInstance()->getContainingPath();
+    QString n("composers");
+    QFileInfo fi(d.filePath(n));
+
+    if ((fi.exists() && !fi.isDir()) ||
+        (!fi.exists() && !d.mkdir(n))) {
+        throw DirectoryCreationFailed(fi.filePath());
+    }
+
+    return fi.filePath();
+}
+
+void
+ComposerFileIndex::loadFor(Uri composerUri, Store *store)
+{
+    if (!m_index) {
+	std::cerr << "ComposerFileIndex::loadFor: No index!" << std::endl;
+	return;
+    }
+    updateIndex();
+
+    Triple pattern(Node(), "foaf:primaryTopic", composerUri);
+    Triples results = m_index->match(pattern);
+    std::cerr << "ComposerFileIndex::loadFor: " << results.size() << " file(s) for composer " << composerUri << std::endl;
+
+    bool loadedSomething = false;
+
+    foreach (Triple t, results) {
+        try {
+            BasicStore *b = BasicStore::load(QUrl(t.a.value));
+            //!!! This is hardly the most efficient!
+            Triples all = b->match(Triple());
+            //!!! There is no Store::add(Triples)
+            foreach (Triple t, all) {
+                store->add(t);
+            }
+        } catch (...) { } //!!!???
+    }
+
+    return loadedSomething;
+}
+
+void
+ComposerFileIndex::composerFileAdded(QString filepath)
+{
+    index(QUrl::fromLocalFile(filepath));
+}    
+
+void
+ComposerFileIndex::updateIndex()
+{
+    QMutexLocker locker(&m_mutex);
+    if (!m_index) return;
+
+    std::cerr << "Generating index..." << std::endl;
+
+    QDir composerDir;
+    try {
+	QString s = getComposerDirectoryName();
+        composerDir = QDir(s);
+    } catch (DirectoryCreationFailed f) {
+        std::cerr << "ComposerFileIndex::updateIndex: ERROR: Failed to find or create composer directory: " << f.what() << std::endl;
+        return;
+    }
+
+    composerDir.setFilter(QDir::Files);
+
+    for (unsigned int i = 0; i < composerDir.count(); ++i) {
+        QFileInfo fi(composerDir.filePath(composerDir[i]));
+        if (fi.isFile() && fi.isReadable()) {
+            index(QUrl::fromLocalFile(fi.filePath()));
+        }
+    }
+
+    //!!! remove triples from index that refer to nonexistent files?
+
+    std::cerr << "Saving index to " << m_indexFileName.toStdString() << std::endl;
+    m_bs->save(m_indexFileName);
+
+    std::cerr << "Done" << std::endl;
+}
+
+void
+ComposerFileIndex::index(QUrl fileUrl)
+{
+    Triple typeTriple(Uri(fileUrl), "a", m_index->expand("foaf:Document"));
+
+    if (m_index->contains(typeTriple)) {
+        return;
+    }
+
+    Transaction *tx = m_index->startTransaction();
+    tx->add(typeTriple);
+
+    try {
+        BasicStore *b = BasicStore::load(fileUrl);
+        Triples ts = b->match
+            (Triple(Node(), "a", m_index->expand("classical:Composer")));
+        foreach (Triple t, ts) {
+            tx->add(Triple(Uri(fileUrl), "foaf:primaryTopic", t.a));;
+        }
+    } catch (std::exception &e) {
+        std::cerr << "Caught exception: \"" << e.what() << "\" while indexing "
+                  << Uri(fileUrl) << ", skipping" << std::endl;
+    }
+
+    delete tx;
+}
+
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/ComposerFileIndex.h	Fri May 28 16:22:37 2010 +0100
@@ -0,0 +1,48 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+#ifndef _CLASSICAL_DATA_COMPOSER_FILE_INDEX_H_
+#define _CLASSICAL_DATA_COMPOSER_FILE_INDEX_H_
+
+#include "Objects.h"
+
+#include <dataquay/BasicStore.h>
+#include <dataquay/TransactionalStore.h>
+
+#include <QMutex>
+
+namespace ClassicalData {
+
+class ComposerFileIndex : public QObject
+{
+    Q_OBJECT
+
+public:
+    static ComposerFileIndex *getInstance();
+    
+    ComposerFileIndex();
+    ~ComposerFileIndex();
+
+    void loadFor(AudioFile *, Dataquay::Store *);
+
+public slots:
+    void composerFileAdded(QString filepath);
+
+private:
+    QMutex m_mutex;
+    QString m_indexFileName;
+    Dataquay::BasicStore *m_bs;
+    Dataquay::TransactionalStore *m_index;
+    QString getIndexFileName();
+    QString getComposerDirectoryName();
+    bool loadFor(Dataquay::Uri canonicalUri, Dataquay::Uri actingUri,
+                 QString hash, Dataquay::Store *);
+    void updateIndex();
+    void index(QUrl);
+};
+
+}
+
+#endif
+
+
+