Chris@44
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@44
|
2
|
Chris@47
|
3 #include "ComposerFileIndex.h"
|
Chris@44
|
4 #include "TypeRegistrar.h"
|
Chris@44
|
5
|
Chris@44
|
6 #include <QMutexLocker>
|
Chris@44
|
7 #include <QDir>
|
Chris@44
|
8
|
Chris@44
|
9 #include "base/TempDirectory.h"
|
Chris@44
|
10 #include "base/Exceptions.h"
|
Chris@44
|
11
|
Chris@44
|
12 using namespace Dataquay;
|
Chris@44
|
13
|
Chris@44
|
14
|
Chris@44
|
15 namespace ClassicalData {
|
Chris@44
|
16
|
Chris@47
|
17 ComposerFileIndex *
|
Chris@47
|
18 ComposerFileIndex::getInstance()
|
Chris@44
|
19 {
|
Chris@47
|
20 static ComposerFileIndex instance;
|
Chris@44
|
21 return &instance;
|
Chris@44
|
22 }
|
Chris@44
|
23
|
Chris@47
|
24 ComposerFileIndex::ComposerFileIndex() :
|
Chris@45
|
25 m_bs(0),
|
Chris@44
|
26 m_index(0)
|
Chris@44
|
27 {
|
Chris@44
|
28 try {
|
Chris@44
|
29 m_indexFileName = getIndexFileName();
|
Chris@44
|
30 } catch (DirectoryCreationFailed f) {
|
Chris@47
|
31 std::cerr << "ComposerFileIndex: ERROR: Failed to find or create index directory: " << f.what() << std::endl;
|
Chris@44
|
32 return;
|
Chris@44
|
33 }
|
Chris@44
|
34
|
Chris@45
|
35 m_bs = new BasicStore;
|
Chris@45
|
36 m_index = new TransactionalStore(m_bs);
|
Chris@44
|
37
|
Chris@45
|
38 TypeRegistrar::addMappings(m_bs, 0);
|
Chris@44
|
39
|
Chris@44
|
40 if (QFile(m_indexFileName).exists()) {
|
Chris@45
|
41 m_bs->import(QUrl::fromLocalFile(m_indexFileName),
|
Chris@45
|
42 BasicStore::ImportIgnoreDuplicates);
|
Chris@44
|
43 //!!! catch
|
Chris@44
|
44 }
|
Chris@44
|
45 }
|
Chris@44
|
46
|
Chris@47
|
47 ComposerFileIndex::~ComposerFileIndex()
|
Chris@44
|
48 {
|
Chris@45
|
49 delete m_index;
|
Chris@45
|
50 delete m_bs;
|
Chris@44
|
51 }
|
Chris@44
|
52
|
Chris@44
|
53 QString
|
Chris@47
|
54 ComposerFileIndex::getIndexFileName()
|
Chris@44
|
55 {
|
Chris@44
|
56 QDir d = TempDirectory::getInstance()->getContainingPath();
|
Chris@44
|
57 QString n("index");
|
Chris@44
|
58 QFileInfo fi(d.filePath(n));
|
Chris@44
|
59
|
Chris@44
|
60 if ((fi.exists() && !fi.isDir()) ||
|
Chris@44
|
61 (!fi.exists() && !d.mkdir(n))) {
|
Chris@44
|
62 throw DirectoryCreationFailed(fi.filePath());
|
Chris@44
|
63 }
|
Chris@44
|
64
|
Chris@47
|
65 return QDir(fi.filePath()).filePath("composer-details.ttl");
|
Chris@44
|
66 }
|
Chris@44
|
67
|
Chris@44
|
68 QString
|
Chris@47
|
69 ComposerFileIndex::getComposerDirectoryName()
|
Chris@44
|
70 {
|
Chris@44
|
71 QDir d = TempDirectory::getInstance()->getContainingPath();
|
Chris@47
|
72 QString n("composers");
|
Chris@44
|
73 QFileInfo fi(d.filePath(n));
|
Chris@44
|
74
|
Chris@44
|
75 if ((fi.exists() && !fi.isDir()) ||
|
Chris@44
|
76 (!fi.exists() && !d.mkdir(n))) {
|
Chris@44
|
77 throw DirectoryCreationFailed(fi.filePath());
|
Chris@44
|
78 }
|
Chris@44
|
79
|
Chris@44
|
80 return fi.filePath();
|
Chris@44
|
81 }
|
Chris@44
|
82
|
Chris@44
|
83 void
|
Chris@47
|
84 ComposerFileIndex::loadFor(Uri composerUri, Store *store)
|
Chris@44
|
85 {
|
Chris@44
|
86 if (!m_index) {
|
Chris@47
|
87 std::cerr << "ComposerFileIndex::loadFor: No index!" << std::endl;
|
Chris@44
|
88 return;
|
Chris@44
|
89 }
|
Chris@44
|
90 updateIndex();
|
Chris@44
|
91
|
Chris@47
|
92 Triple pattern(Node(), "foaf:primaryTopic", composerUri);
|
Chris@46
|
93 Triples results = m_index->match(pattern);
|
Chris@47
|
94 std::cerr << "ComposerFileIndex::loadFor: " << results.size() << " file(s) for composer " << composerUri << std::endl;
|
Chris@45
|
95
|
Chris@46
|
96 bool loadedSomething = false;
|
Chris@45
|
97
|
Chris@46
|
98 foreach (Triple t, results) {
|
Chris@46
|
99 try {
|
Chris@46
|
100 BasicStore *b = BasicStore::load(QUrl(t.a.value));
|
Chris@47
|
101 //!!! This is hardly the most efficient!
|
Chris@47
|
102 Triples all = b->match(Triple());
|
Chris@47
|
103 //!!! There is no Store::add(Triples)
|
Chris@47
|
104 foreach (Triple t, all) {
|
Chris@47
|
105 store->add(t);
|
Chris@46
|
106 }
|
Chris@47
|
107 } catch (...) { } //!!!???
|
Chris@45
|
108 }
|
Chris@45
|
109
|
Chris@46
|
110 return loadedSomething;
|
Chris@44
|
111 }
|
Chris@44
|
112
|
Chris@44
|
113 void
|
Chris@47
|
114 ComposerFileIndex::composerFileAdded(QString filepath)
|
Chris@45
|
115 {
|
Chris@45
|
116 index(QUrl::fromLocalFile(filepath));
|
Chris@45
|
117 }
|
Chris@45
|
118
|
Chris@45
|
119 void
|
Chris@47
|
120 ComposerFileIndex::updateIndex()
|
Chris@44
|
121 {
|
Chris@44
|
122 QMutexLocker locker(&m_mutex);
|
Chris@44
|
123 if (!m_index) return;
|
Chris@44
|
124
|
Chris@46
|
125 std::cerr << "Generating index..." << std::endl;
|
Chris@46
|
126
|
Chris@47
|
127 QDir composerDir;
|
Chris@44
|
128 try {
|
Chris@47
|
129 QString s = getComposerDirectoryName();
|
Chris@47
|
130 composerDir = QDir(s);
|
Chris@44
|
131 } catch (DirectoryCreationFailed f) {
|
Chris@47
|
132 std::cerr << "ComposerFileIndex::updateIndex: ERROR: Failed to find or create composer directory: " << f.what() << std::endl;
|
Chris@44
|
133 return;
|
Chris@44
|
134 }
|
Chris@44
|
135
|
Chris@47
|
136 composerDir.setFilter(QDir::Files);
|
Chris@44
|
137
|
Chris@47
|
138 for (unsigned int i = 0; i < composerDir.count(); ++i) {
|
Chris@47
|
139 QFileInfo fi(composerDir.filePath(composerDir[i]));
|
Chris@44
|
140 if (fi.isFile() && fi.isReadable()) {
|
Chris@45
|
141 index(QUrl::fromLocalFile(fi.filePath()));
|
Chris@44
|
142 }
|
Chris@44
|
143 }
|
Chris@44
|
144
|
Chris@44
|
145 //!!! remove triples from index that refer to nonexistent files?
|
Chris@44
|
146
|
Chris@44
|
147 std::cerr << "Saving index to " << m_indexFileName.toStdString() << std::endl;
|
Chris@45
|
148 m_bs->save(m_indexFileName);
|
Chris@46
|
149
|
Chris@46
|
150 std::cerr << "Done" << std::endl;
|
Chris@45
|
151 }
|
Chris@45
|
152
|
Chris@45
|
153 void
|
Chris@47
|
154 ComposerFileIndex::index(QUrl fileUrl)
|
Chris@45
|
155 {
|
Chris@45
|
156 Triple typeTriple(Uri(fileUrl), "a", m_index->expand("foaf:Document"));
|
Chris@45
|
157
|
Chris@45
|
158 if (m_index->contains(typeTriple)) {
|
Chris@45
|
159 return;
|
Chris@45
|
160 }
|
Chris@45
|
161
|
Chris@45
|
162 Transaction *tx = m_index->startTransaction();
|
Chris@45
|
163 tx->add(typeTriple);
|
Chris@45
|
164
|
Chris@45
|
165 try {
|
Chris@45
|
166 BasicStore *b = BasicStore::load(fileUrl);
|
Chris@45
|
167 Triples ts = b->match
|
Chris@47
|
168 (Triple(Node(), "a", m_index->expand("classical:Composer")));
|
Chris@45
|
169 foreach (Triple t, ts) {
|
Chris@45
|
170 tx->add(Triple(Uri(fileUrl), "foaf:primaryTopic", t.a));;
|
Chris@45
|
171 }
|
Chris@46
|
172 } catch (std::exception &e) {
|
Chris@46
|
173 std::cerr << "Caught exception: \"" << e.what() << "\" while indexing "
|
Chris@46
|
174 << Uri(fileUrl) << ", skipping" << std::endl;
|
Chris@46
|
175 }
|
Chris@48
|
176
|
Chris@48
|
177 tx->commit();
|
Chris@45
|
178 delete tx;
|
Chris@44
|
179 }
|
Chris@44
|
180
|
Chris@44
|
181
|
Chris@44
|
182 }
|
Chris@44
|
183
|