##// END OF EJS Templates
Rebase fix CatalogueCatalogue
perrinel -
r1355:ce843f4ddfb0
parent child
Show More
@@ -1,500 +1,492
1 1 #include <Catalogue/CatalogueController.h>
2 2
3 3 #include <Variable/Variable.h>
4 4
5 5 #include <CatalogueDao.h>
6 6
7 7 #include <ComparaisonPredicate.h>
8 8 #include <CompoundPredicate.h>
9 9 #include <DBCatalogue.h>
10 10 #include <DBEvent.h>
11 11 #include <DBEventProduct.h>
12 12 #include <DBTag.h>
13 13 #include <IRequestPredicate.h>
14 14
15 15 #include <QDataStream>
16 16 #include <QMutex>
17 17 #include <QThread>
18 18
19 19 #include <QDir>
20 20 #include <QStandardPaths>
21 21
22 22 Q_LOGGING_CATEGORY(LOG_CatalogueController, "CatalogueController")
23 23
24 24 namespace {
25 25
26 26 static QString REPOSITORY_WORK_SUFFIX = QString{"_work"};
27 27 static QString REPOSITORY_TRASH_SUFFIX = QString{"_trash"};
28 28 }
29 29
30 30 /**
31 31 * Possible types of an repository
32 32 */
33 33 enum class DBType { SYNC, WORK, TRASH};
34 34 class CatalogueController::CatalogueControllerPrivate {
35 35
36 36 public:
37 37 explicit CatalogueControllerPrivate(CatalogueController *parent) : m_Q{parent} {}
38 38
39 39 CatalogueDao m_CatalogueDao;
40 40
41 41 QStringList m_RepositoryList;
42 42 CatalogueController *m_Q;
43 43
44 44 QSet<QString> m_EventKeysWithChanges;
45 45
46 46 QString eventUniqueKey(const std::shared_ptr<DBEvent> &event) const;
47 47
48 48 void copyDBtoDB(const QString &dbFrom, const QString &dbTo);
49 49 QString toWorkRepository(QString repository);
50 50 QString toSyncRepository(QString repository);
51 51 void savAllDB();
52 52
53 53 void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true);
54 54 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist = true);
55 55
56 56 std::shared_ptr<IRequestPredicate> createFinder(const QUuid& uniqId, const QString & repository, DBType type);
57 57 };
58 58
59 59 CatalogueController::CatalogueController(QObject *parent)
60 60 : impl{spimpl::make_unique_impl<CatalogueControllerPrivate>(this)}
61 61 {
62 62 qCDebug(LOG_CatalogueController()) << tr("CatalogueController construction")
63 63 << QThread::currentThread();
64 64 }
65 65
66 66 CatalogueController::~CatalogueController()
67 67 {
68 68 qCDebug(LOG_CatalogueController()) << tr("CatalogueController destruction")
69 69 << QThread::currentThread();
70 70 }
71 71
72 72 QStringList CatalogueController::getRepositories() const
73 73 {
74 74 return impl->m_RepositoryList;
75 75 }
76 76
77 77 void CatalogueController::addDB(const QString &dbPath)
78 78 {
79 79 QDir dbDir(dbPath);
80 80 if (dbDir.exists()) {
81 81 auto dirName = dbDir.dirName();
82 82
83 83 if (std::find(impl->m_RepositoryList.cbegin(), impl->m_RepositoryList.cend(), dirName)
84 84 != impl->m_RepositoryList.cend()) {
85 85 qCCritical(LOG_CatalogueController())
86 86 << tr("Impossible to addDB that is already loaded");
87 87 }
88 88
89 89 if (!impl->m_CatalogueDao.addDB(dbPath, dirName)) {
90 90 qCCritical(LOG_CatalogueController())
91 91 << tr("Impossible to addDB %1 from %2 ").arg(dirName, dbPath);
92 92 }
93 93 else {
94 94 impl->m_RepositoryList << dirName;
95 95 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
96 96 }
97 97 }
98 98 else {
99 99 qCCritical(LOG_CatalogueController()) << tr("Impossible to addDB that not exists: ")
100 100 << dbPath;
101 101 }
102 102 }
103 103
104 104 void CatalogueController::saveDB(const QString &destinationPath, const QString &repository)
105 105 {
106 106 if (!impl->m_CatalogueDao.saveDB(destinationPath, repository)) {
107 107 qCCritical(LOG_CatalogueController())
108 108 << tr("Impossible to saveDB %1 from %2 ").arg(repository, destinationPath);
109 109 }
110 110 }
111 111
112 112 std::list<std::shared_ptr<DBEvent> >
113 113 CatalogueController::retrieveEvents(const QString &repository) const
114 114 {
115 115 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
116 116
117 117 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
118 118 auto events = impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName));
119 119 for (auto event : events) {
120 120 eventsShared.push_back(std::make_shared<DBEvent>(event));
121 121 }
122 122 return eventsShared;
123 123 }
124 124
125 125 std::list<std::shared_ptr<DBEvent> > CatalogueController::retrieveAllEvents() const
126 126 {
127 127 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
128 128 for (auto repository : impl->m_RepositoryList) {
129 129 eventsShared.splice(eventsShared.end(), retrieveEvents(repository));
130 130 }
131 131
132 132 return eventsShared;
133 133 }
134 134
135 135 std::list<std::shared_ptr<DBEvent> >
136 136 CatalogueController::retrieveEventsFromCatalogue(std::shared_ptr<DBCatalogue> catalogue) const
137 137 {
138 138 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
139 139 auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue);
140 140 for (auto event : events) {
141 141 eventsShared.push_back(std::make_shared<DBEvent>(event));
142 142 }
143 143 return eventsShared;
144 144 }
145 145
146 146 void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event)
147 147 {
148 148 event->setRepository(impl->toWorkRepository(event->getRepository()));
149 149
150 150 auto uniqueId = impl->eventUniqueKey(event);
151 151 impl->m_EventKeysWithChanges.insert(uniqueId);
152 152
153 153 impl->m_CatalogueDao.updateEvent(*event);
154 154 }
155 155
156 156 void CatalogueController::updateEventProduct(std::shared_ptr<DBEventProduct> eventProduct)
157 157 {
158 158 impl->m_CatalogueDao.updateEventProduct(*eventProduct);
159 159 }
160 160
161 161 void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
162 162 {
163 163 // Remove it from both repository and repository_work
164 164 event->setRepository(impl->toWorkRepository(event->getRepository()));
165 165 impl->m_CatalogueDao.removeEvent(*event);
166 166 event->setRepository(impl->toSyncRepository(event->getRepository()));
167 167 impl->m_CatalogueDao.removeEvent(*event);
168 168 impl->savAllDB();
169 169 }
170 170
171 171 void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
172 172 {
173 173 event->setRepository(impl->toWorkRepository(event->getRepository()));
174 174
175 175 auto eventTemp = *event;
176 176 impl->m_CatalogueDao.addEvent(eventTemp);
177 177
178 178 // Call update is necessary at the creation of add Event if it has some tags or some event
179 179 // products
180 180 if (!event->getEventProducts().empty() || !event->getTags().empty()) {
181 181
182 182 auto eventProductsTemp = eventTemp.getEventProducts();
183 183 auto eventProductTempUpdated = std::list<DBEventProduct>{};
184 184 for (auto eventProductTemp : eventProductsTemp) {
185 185 eventProductTemp.setEvent(eventTemp);
186 186 eventProductTempUpdated.push_back(eventProductTemp);
187 187 }
188 188 eventTemp.setEventProducts(eventProductTempUpdated);
189 189
190 190 impl->m_CatalogueDao.updateEvent(eventTemp);
191 191 }
192 192
193
194 // update event parameter
195 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
196 QString{"uniqId"}, event->getUniqId(), ComparaisonOperation::EQUALEQUAL);
197
198 auto workRepositoryPredicate = std::make_shared<ComparaisonPredicate>(
199 QString{"repository"}, impl->toWorkRepository(event->getRepository()),
200 ComparaisonOperation::EQUALEQUAL);
201
202 auto workPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
203 workPred->AddRequestPredicate(uniqIdPredicate);
204 workPred->AddRequestPredicate(workRepositoryPredicate);
205
193 auto workPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::WORK);
206 194
207 195 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
208 196 *event = workEvent;
197
198
199 auto uniqueId = impl->eventUniqueKey(event);
200 impl->m_EventKeysWithChanges.insert(uniqueId);
209 201 }
210 202
211 203 void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
212 204 {
213 205 impl->saveEvent(event, true);
214 206 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
215 207 }
216 208
217 209 void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool &removed)
218 210 {
219 211 auto syncPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::SYNC);
220 212 auto workPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::WORK);
221 213
222 214 auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
223 215 if (!syncEvent.getUniqId().isNull()) {
224 216 removed = false;
225 217 impl->m_CatalogueDao.copyEvent(syncEvent, impl->toWorkRepository(event->getRepository()),
226 218 true);
227 219
228 220 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
229 221 *event = workEvent;
230 222 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
231 223 }
232 224 else {
233 225 removed = true;
234 226 // Since the element wasn't in sync repository. Discard it means remove it
235 227 event->setRepository(impl->toWorkRepository(event->getRepository()));
236 228 impl->m_CatalogueDao.removeEvent(*event);
237 229 }
238 230 }
239 231
240 232 bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event) const
241 233 {
242 234 return impl->m_EventKeysWithChanges.contains(impl->eventUniqueKey(event));
243 235 }
244 236
245 237 std::list<std::shared_ptr<DBCatalogue> >
246 238 CatalogueController::retrieveCatalogues(const QString &repository) const
247 239 {
248 240 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
249 241
250 242 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
251 243 auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
252 244 for (auto catalogue : catalogues) {
253 245 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
254 246 }
255 247 return cataloguesShared;
256 248 }
257 249
258 250 void CatalogueController::addCatalogue(std::shared_ptr<DBCatalogue> catalogue)
259 251 {
260 252 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
261 253
262 254 auto catalogueTemp = *catalogue;
263 255 impl->m_CatalogueDao.addCatalogue(catalogueTemp);
264 256
265 257 auto workPred = impl->createFinder(catalogue->getUniqId(), catalogue->getRepository(), DBType::WORK);
266 258
267 259 auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
268 260 *catalogue = workCatalogue;
269 261
270 262 // auto uniqueId = impl->eventUniqueKey(catalogue);
271 263 // impl->m_EventKeysWithChanges.insert(uniqueId);
272 264 }
273 265
274 266 void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue)
275 267 {
276 268 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
277 269
278 270 // auto uniqueId = impl->eventUniqueKey(event);
279 271 // impl->m_EventKeysWithChanges.insert(uniqueId);
280 272
281 273 impl->m_CatalogueDao.updateCatalogue(*catalogue);
282 274 }
283 275
284 276 void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue)
285 277 {
286 278 // Remove it from both repository and repository_work
287 279 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
288 280 impl->m_CatalogueDao.removeCatalogue(*catalogue);
289 281 catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
290 282 impl->m_CatalogueDao.removeCatalogue(*catalogue);
291 283 impl->savAllDB();
292 284 }
293 285
294 286 void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue)
295 287 {
296 288 impl->saveCatalogue(catalogue, true);
297 289 // impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
298 290 }
299 291
300 292 void CatalogueController::saveAll()
301 293 {
302 294 for (auto repository : impl->m_RepositoryList) {
303 295 // Save Event
304 296 auto events = this->retrieveEvents(repository);
305 297 for (auto event : events) {
306 298 impl->saveEvent(event, false);
307 299 }
308 300
309 301 // Save Catalogue
310 302 auto catalogues = this->retrieveCatalogues(repository);
311 303 for (auto catalogue : catalogues) {
312 304 impl->saveCatalogue(catalogue, false);
313 305 }
314 306 }
315 307
316 308 impl->savAllDB();
317 309 impl->m_EventKeysWithChanges.clear();
318 310 }
319 311
320 312 bool CatalogueController::hasChanges() const
321 313 {
322 314 return !impl->m_EventKeysWithChanges.isEmpty(); // TODO: catalogues
323 315 }
324 316
325 317 QByteArray
326 318 CatalogueController::mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const
327 319 {
328 320 auto encodedData = QByteArray{};
329 321
330 322 QMap<QString, QVariantList> idsPerRepository;
331 323 for (auto event : events) {
332 324 idsPerRepository[event->getRepository()] << event->getUniqId();
333 325 }
334 326
335 327 QDataStream stream{&encodedData, QIODevice::WriteOnly};
336 328 stream << idsPerRepository;
337 329
338 330 return encodedData;
339 331 }
340 332
341 333 QVector<std::shared_ptr<DBEvent> >
342 334 CatalogueController::eventsForMimeData(const QByteArray &mimeData) const
343 335 {
344 336 auto events = QVector<std::shared_ptr<DBEvent> >{};
345 337 QDataStream stream{mimeData};
346 338
347 339 QMap<QString, QVariantList> idsPerRepository;
348 340 stream >> idsPerRepository;
349 341
350 342 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
351 343 auto repository = it.key();
352 344 auto allRepositoryEvent = retrieveEvents(repository);
353 345 for (auto uuid : it.value()) {
354 346 for (auto repositoryEvent : allRepositoryEvent) {
355 347 if (uuid.toUuid() == repositoryEvent->getUniqId()) {
356 348 events << repositoryEvent;
357 349 }
358 350 }
359 351 }
360 352 }
361 353
362 354 return events;
363 355 }
364 356
365 357 void CatalogueController::initialize()
366 358 {
367 359 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init")
368 360 << QThread::currentThread();
369 361
370 362 impl->m_CatalogueDao.initialize();
371 363 auto defaultRepositoryLocation
372 364 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
373 365
374 366 QDir defaultRepositoryLocationDir;
375 367 if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) {
376 368 defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
377 369 auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
378 370
379 371 qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ")
380 372 << defaultRepository;
381 373
382 374 QDir dbDir(defaultRepository);
383 375 impl->m_RepositoryList << REPOSITORY_DEFAULT;
384 376 if (dbDir.exists()) {
385 377 auto dirName = dbDir.dirName();
386 378
387 379 if (impl->m_CatalogueDao.addDB(defaultRepository, dirName)) {
388 380 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
389 381 }
390 382 }
391 383 else {
392 384 qCInfo(LOG_CatalogueController()) << tr("Initialisation of Default repository detected")
393 385 << defaultRepository;
394 386 }
395 387 }
396 388 else {
397 389 qCWarning(LOG_CatalogueController())
398 390 << tr("Cannot load the persistent default repository from ")
399 391 << defaultRepositoryLocation;
400 392 }
401 393
402 394 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
403 395 }
404 396
405 397 QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
406 398 const std::shared_ptr<DBEvent> &event) const
407 399 {
408 400 return event->getUniqId().toString().append(event->getRepository());
409 401 }
410 402
411 403 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
412 404 const QString &dbTo)
413 405 {
414 406 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
415 407 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
416 408 auto events = m_CatalogueDao.getEvents(dbFrom);
417 409 for (auto catalogue : catalogues) {
418 410 m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
419 411 }
420 412
421 413 for (auto event : events) {
422 414 m_CatalogueDao.copyEvent(event, dbTo, true);
423 415 }
424 416 }
425 417
426 418 QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository)
427 419 {
428 420 auto syncRepository = toSyncRepository(repository);
429 421
430 422 return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
431 423 }
432 424
433 425 QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository)
434 426 {
435 427 auto syncRepository = repository;
436 428 if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) {
437 429 syncRepository.remove(REPOSITORY_WORK_SUFFIX);
438 430 }
439 431 else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) {
440 432 syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
441 433 }
442 434 return syncRepository;
443 435 }
444 436
445 437 void CatalogueController::CatalogueControllerPrivate::savAllDB()
446 438 {
447 439 for (auto repository : m_RepositoryList) {
448 440 auto defaultRepositoryLocation
449 441 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
450 442 m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
451 443 }
452 444 }
453 445
454 446 void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event,
455 447 bool persist)
456 448 {
457 449 m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true);
458 450 if (persist) {
459 451 savAllDB();
460 452 }
461 453 }
462 454
463 455 void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
464 456 std::shared_ptr<DBCatalogue> catalogue, bool persist)
465 457 {
466 458 m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true);
467 459 if (persist) {
468 460 savAllDB();
469 461 }
470 462 }
471 463
472 464 std::shared_ptr<IRequestPredicate> CatalogueController::CatalogueControllerPrivate::createFinder(const QUuid &uniqId, const QString &repository, DBType type)
473 465 {
474 466 // update catalogue parameter
475 467 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
476 468 QString{"uniqId"}, uniqId, ComparaisonOperation::EQUALEQUAL);
477 469
478 470 auto repositoryType = repository;
479 471 switch (type) {
480 472 case DBType::SYNC:
481 473 repositoryType = toSyncRepository(repositoryType);
482 474 break;
483 475 case DBType::WORK:
484 476 repositoryType =toWorkRepository(repositoryType);
485 477 break;
486 478 case DBType::TRASH:
487 479 default:
488 480 break;
489 481 }
490 482
491 483 auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
492 484 QString{"repository"}, repositoryType,
493 485 ComparaisonOperation::EQUALEQUAL);
494 486
495 487 auto finderPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
496 488 finderPred->AddRequestPredicate(uniqIdPredicate);
497 489 finderPred->AddRequestPredicate(repositoryPredicate);
498 490
499 491 return finderPred;
500 492 }
General Comments 0
You need to be logged in to leave comments. Login now