Chris@44: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@44: Chris@47: #include "ComposerFileIndex.h" Chris@44: #include "TypeRegistrar.h" Chris@44: Chris@44: #include Chris@44: #include Chris@44: Chris@44: #include "base/TempDirectory.h" Chris@44: #include "base/Exceptions.h" Chris@44: Chris@44: using namespace Dataquay; Chris@44: Chris@44: Chris@44: namespace ClassicalData { Chris@44: Chris@47: ComposerFileIndex * Chris@47: ComposerFileIndex::getInstance() Chris@44: { Chris@47: static ComposerFileIndex instance; Chris@44: return &instance; Chris@44: } Chris@44: Chris@47: ComposerFileIndex::ComposerFileIndex() : Chris@45: m_bs(0), Chris@44: m_index(0) Chris@44: { Chris@44: try { Chris@44: m_indexFileName = getIndexFileName(); Chris@44: } catch (DirectoryCreationFailed f) { Chris@47: std::cerr << "ComposerFileIndex: ERROR: Failed to find or create index directory: " << f.what() << std::endl; Chris@44: return; Chris@44: } Chris@44: Chris@45: m_bs = new BasicStore; Chris@45: m_index = new TransactionalStore(m_bs); Chris@44: Chris@45: TypeRegistrar::addMappings(m_bs, 0); Chris@44: Chris@44: if (QFile(m_indexFileName).exists()) { Chris@45: m_bs->import(QUrl::fromLocalFile(m_indexFileName), Chris@45: BasicStore::ImportIgnoreDuplicates); Chris@44: //!!! catch Chris@44: } Chris@44: } Chris@44: Chris@47: ComposerFileIndex::~ComposerFileIndex() Chris@44: { Chris@45: delete m_index; Chris@45: delete m_bs; Chris@44: } Chris@44: Chris@44: QString Chris@47: ComposerFileIndex::getIndexFileName() Chris@44: { Chris@44: QDir d = TempDirectory::getInstance()->getContainingPath(); Chris@44: QString n("index"); Chris@44: QFileInfo fi(d.filePath(n)); Chris@44: Chris@44: if ((fi.exists() && !fi.isDir()) || Chris@44: (!fi.exists() && !d.mkdir(n))) { Chris@44: throw DirectoryCreationFailed(fi.filePath()); Chris@44: } Chris@44: Chris@47: return QDir(fi.filePath()).filePath("composer-details.ttl"); Chris@44: } Chris@44: Chris@44: QString Chris@47: ComposerFileIndex::getComposerDirectoryName() Chris@44: { Chris@44: QDir d = TempDirectory::getInstance()->getContainingPath(); Chris@47: QString n("composers"); Chris@44: QFileInfo fi(d.filePath(n)); Chris@44: Chris@44: if ((fi.exists() && !fi.isDir()) || Chris@44: (!fi.exists() && !d.mkdir(n))) { Chris@44: throw DirectoryCreationFailed(fi.filePath()); Chris@44: } Chris@44: Chris@44: return fi.filePath(); Chris@44: } Chris@44: Chris@44: void Chris@47: ComposerFileIndex::loadFor(Uri composerUri, Store *store) Chris@44: { Chris@44: if (!m_index) { Chris@47: std::cerr << "ComposerFileIndex::loadFor: No index!" << std::endl; Chris@44: return; Chris@44: } Chris@44: updateIndex(); Chris@44: Chris@47: Triple pattern(Node(), "foaf:primaryTopic", composerUri); Chris@46: Triples results = m_index->match(pattern); Chris@47: std::cerr << "ComposerFileIndex::loadFor: " << results.size() << " file(s) for composer " << composerUri << std::endl; Chris@45: Chris@46: bool loadedSomething = false; Chris@45: Chris@46: foreach (Triple t, results) { Chris@46: try { Chris@46: BasicStore *b = BasicStore::load(QUrl(t.a.value)); Chris@47: //!!! This is hardly the most efficient! Chris@47: Triples all = b->match(Triple()); Chris@47: //!!! There is no Store::add(Triples) Chris@47: foreach (Triple t, all) { Chris@47: store->add(t); Chris@46: } Chris@47: } catch (...) { } //!!!??? Chris@45: } Chris@45: Chris@46: return loadedSomething; Chris@44: } Chris@44: Chris@44: void Chris@47: ComposerFileIndex::composerFileAdded(QString filepath) Chris@45: { Chris@45: index(QUrl::fromLocalFile(filepath)); Chris@45: } Chris@45: Chris@45: void Chris@47: ComposerFileIndex::updateIndex() Chris@44: { Chris@44: QMutexLocker locker(&m_mutex); Chris@44: if (!m_index) return; Chris@44: Chris@46: std::cerr << "Generating index..." << std::endl; Chris@46: Chris@47: QDir composerDir; Chris@44: try { Chris@47: QString s = getComposerDirectoryName(); Chris@47: composerDir = QDir(s); Chris@44: } catch (DirectoryCreationFailed f) { Chris@47: std::cerr << "ComposerFileIndex::updateIndex: ERROR: Failed to find or create composer directory: " << f.what() << std::endl; Chris@44: return; Chris@44: } Chris@44: Chris@47: composerDir.setFilter(QDir::Files); Chris@44: Chris@47: for (unsigned int i = 0; i < composerDir.count(); ++i) { Chris@47: QFileInfo fi(composerDir.filePath(composerDir[i])); Chris@44: if (fi.isFile() && fi.isReadable()) { Chris@45: index(QUrl::fromLocalFile(fi.filePath())); Chris@44: } Chris@44: } Chris@44: Chris@44: //!!! remove triples from index that refer to nonexistent files? Chris@44: Chris@44: std::cerr << "Saving index to " << m_indexFileName.toStdString() << std::endl; Chris@45: m_bs->save(m_indexFileName); Chris@46: Chris@46: std::cerr << "Done" << std::endl; Chris@45: } Chris@45: Chris@45: void Chris@47: ComposerFileIndex::index(QUrl fileUrl) Chris@45: { Chris@45: Triple typeTriple(Uri(fileUrl), "a", m_index->expand("foaf:Document")); Chris@45: Chris@45: if (m_index->contains(typeTriple)) { Chris@45: return; Chris@45: } Chris@45: Chris@45: Transaction *tx = m_index->startTransaction(); Chris@45: tx->add(typeTriple); Chris@45: Chris@45: try { Chris@45: BasicStore *b = BasicStore::load(fileUrl); Chris@45: Triples ts = b->match Chris@47: (Triple(Node(), "a", m_index->expand("classical:Composer"))); Chris@45: foreach (Triple t, ts) { Chris@45: tx->add(Triple(Uri(fileUrl), "foaf:primaryTopic", t.a));; Chris@45: } Chris@46: } catch (std::exception &e) { Chris@46: std::cerr << "Caught exception: \"" << e.what() << "\" while indexing " Chris@46: << Uri(fileUrl) << ", skipping" << std::endl; Chris@46: } Chris@48: Chris@48: tx->commit(); Chris@45: delete tx; Chris@44: } Chris@44: Chris@44: Chris@44: } Chris@44: