Mercurial > hg > classical
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 + + +