##// END OF EJS Templates
Discard an added event remove it now.
perrinel -
r1354:2fbafc860af0
parent child
Show More
@@ -1,501 +1,500
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
193 194 // update event parameter
194 195 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
195 196 QString{"uniqId"}, event->getUniqId(), ComparaisonOperation::EQUALEQUAL);
196 197
197 198 auto workRepositoryPredicate = std::make_shared<ComparaisonPredicate>(
198 199 QString{"repository"}, impl->toWorkRepository(event->getRepository()),
199 200 ComparaisonOperation::EQUALEQUAL);
200 201
201 202 auto workPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
202 203 workPred->AddRequestPredicate(uniqIdPredicate);
203 204 workPred->AddRequestPredicate(workRepositoryPredicate);
204 205
206
205 207 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
206 208 *event = workEvent;
207
208 auto uniqueId = impl->eventUniqueKey(event);
209 impl->m_EventKeysWithChanges.insert(uniqueId);
210 209 }
211 210
212 211 void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
213 212 {
214 213 impl->saveEvent(event, true);
215 214 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
216 215 }
217 216
218 217 void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool &removed)
219 218 {
220 219 auto syncPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::SYNC);
221 220 auto workPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::WORK);
222 221
223 222 auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
224 223 if (!syncEvent.getUniqId().isNull()) {
225 224 removed = false;
226 225 impl->m_CatalogueDao.copyEvent(syncEvent, impl->toWorkRepository(event->getRepository()),
227 226 true);
228 227
229 228 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
230 229 *event = workEvent;
231 230 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
232 231 }
233 232 else {
234 233 removed = true;
235 234 // Since the element wasn't in sync repository. Discard it means remove it
236 235 event->setRepository(impl->toWorkRepository(event->getRepository()));
237 236 impl->m_CatalogueDao.removeEvent(*event);
238 237 }
239 238 }
240 239
241 240 bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event) const
242 241 {
243 242 return impl->m_EventKeysWithChanges.contains(impl->eventUniqueKey(event));
244 243 }
245 244
246 245 std::list<std::shared_ptr<DBCatalogue> >
247 246 CatalogueController::retrieveCatalogues(const QString &repository) const
248 247 {
249 248 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
250 249
251 250 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
252 251 auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
253 252 for (auto catalogue : catalogues) {
254 253 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
255 254 }
256 255 return cataloguesShared;
257 256 }
258 257
259 258 void CatalogueController::addCatalogue(std::shared_ptr<DBCatalogue> catalogue)
260 259 {
261 260 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
262 261
263 262 auto catalogueTemp = *catalogue;
264 263 impl->m_CatalogueDao.addCatalogue(catalogueTemp);
265 264
266 265 auto workPred = impl->createFinder(catalogue->getUniqId(), catalogue->getRepository(), DBType::WORK);
267 266
268 267 auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
269 268 *catalogue = workCatalogue;
270 269
271 270 // auto uniqueId = impl->eventUniqueKey(catalogue);
272 271 // impl->m_EventKeysWithChanges.insert(uniqueId);
273 272 }
274 273
275 274 void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue)
276 275 {
277 276 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
278 277
279 278 // auto uniqueId = impl->eventUniqueKey(event);
280 279 // impl->m_EventKeysWithChanges.insert(uniqueId);
281 280
282 281 impl->m_CatalogueDao.updateCatalogue(*catalogue);
283 282 }
284 283
285 284 void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue)
286 285 {
287 286 // Remove it from both repository and repository_work
288 287 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
289 288 impl->m_CatalogueDao.removeCatalogue(*catalogue);
290 289 catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
291 290 impl->m_CatalogueDao.removeCatalogue(*catalogue);
292 291 impl->savAllDB();
293 292 }
294 293
295 294 void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue)
296 295 {
297 296 impl->saveCatalogue(catalogue, true);
298 297 // impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
299 298 }
300 299
301 300 void CatalogueController::saveAll()
302 301 {
303 302 for (auto repository : impl->m_RepositoryList) {
304 303 // Save Event
305 304 auto events = this->retrieveEvents(repository);
306 305 for (auto event : events) {
307 306 impl->saveEvent(event, false);
308 307 }
309 308
310 309 // Save Catalogue
311 310 auto catalogues = this->retrieveCatalogues(repository);
312 311 for (auto catalogue : catalogues) {
313 312 impl->saveCatalogue(catalogue, false);
314 313 }
315 314 }
316 315
317 316 impl->savAllDB();
318 317 impl->m_EventKeysWithChanges.clear();
319 318 }
320 319
321 320 bool CatalogueController::hasChanges() const
322 321 {
323 322 return !impl->m_EventKeysWithChanges.isEmpty(); // TODO: catalogues
324 323 }
325 324
326 325 QByteArray
327 326 CatalogueController::mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const
328 327 {
329 328 auto encodedData = QByteArray{};
330 329
331 330 QMap<QString, QVariantList> idsPerRepository;
332 331 for (auto event : events) {
333 332 idsPerRepository[event->getRepository()] << event->getUniqId();
334 333 }
335 334
336 335 QDataStream stream{&encodedData, QIODevice::WriteOnly};
337 336 stream << idsPerRepository;
338 337
339 338 return encodedData;
340 339 }
341 340
342 341 QVector<std::shared_ptr<DBEvent> >
343 342 CatalogueController::eventsForMimeData(const QByteArray &mimeData) const
344 343 {
345 344 auto events = QVector<std::shared_ptr<DBEvent> >{};
346 345 QDataStream stream{mimeData};
347 346
348 347 QMap<QString, QVariantList> idsPerRepository;
349 348 stream >> idsPerRepository;
350 349
351 350 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
352 351 auto repository = it.key();
353 352 auto allRepositoryEvent = retrieveEvents(repository);
354 353 for (auto uuid : it.value()) {
355 354 for (auto repositoryEvent : allRepositoryEvent) {
356 355 if (uuid.toUuid() == repositoryEvent->getUniqId()) {
357 356 events << repositoryEvent;
358 357 }
359 358 }
360 359 }
361 360 }
362 361
363 362 return events;
364 363 }
365 364
366 365 void CatalogueController::initialize()
367 366 {
368 367 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init")
369 368 << QThread::currentThread();
370 369
371 370 impl->m_CatalogueDao.initialize();
372 371 auto defaultRepositoryLocation
373 372 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
374 373
375 374 QDir defaultRepositoryLocationDir;
376 375 if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) {
377 376 defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
378 377 auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
379 378
380 379 qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ")
381 380 << defaultRepository;
382 381
383 382 QDir dbDir(defaultRepository);
384 383 impl->m_RepositoryList << REPOSITORY_DEFAULT;
385 384 if (dbDir.exists()) {
386 385 auto dirName = dbDir.dirName();
387 386
388 387 if (impl->m_CatalogueDao.addDB(defaultRepository, dirName)) {
389 388 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
390 389 }
391 390 }
392 391 else {
393 392 qCInfo(LOG_CatalogueController()) << tr("Initialisation of Default repository detected")
394 393 << defaultRepository;
395 394 }
396 395 }
397 396 else {
398 397 qCWarning(LOG_CatalogueController())
399 398 << tr("Cannot load the persistent default repository from ")
400 399 << defaultRepositoryLocation;
401 400 }
402 401
403 402 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
404 403 }
405 404
406 405 QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
407 406 const std::shared_ptr<DBEvent> &event) const
408 407 {
409 408 return event->getUniqId().toString().append(event->getRepository());
410 409 }
411 410
412 411 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
413 412 const QString &dbTo)
414 413 {
415 414 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
416 415 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
417 416 auto events = m_CatalogueDao.getEvents(dbFrom);
418 417 for (auto catalogue : catalogues) {
419 418 m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
420 419 }
421 420
422 421 for (auto event : events) {
423 422 m_CatalogueDao.copyEvent(event, dbTo, true);
424 423 }
425 424 }
426 425
427 426 QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository)
428 427 {
429 428 auto syncRepository = toSyncRepository(repository);
430 429
431 430 return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
432 431 }
433 432
434 433 QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository)
435 434 {
436 435 auto syncRepository = repository;
437 436 if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) {
438 437 syncRepository.remove(REPOSITORY_WORK_SUFFIX);
439 438 }
440 439 else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) {
441 440 syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
442 441 }
443 442 return syncRepository;
444 443 }
445 444
446 445 void CatalogueController::CatalogueControllerPrivate::savAllDB()
447 446 {
448 447 for (auto repository : m_RepositoryList) {
449 448 auto defaultRepositoryLocation
450 449 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
451 450 m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
452 451 }
453 452 }
454 453
455 454 void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event,
456 455 bool persist)
457 456 {
458 457 m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true);
459 458 if (persist) {
460 459 savAllDB();
461 460 }
462 461 }
463 462
464 463 void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
465 464 std::shared_ptr<DBCatalogue> catalogue, bool persist)
466 465 {
467 466 m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true);
468 467 if (persist) {
469 468 savAllDB();
470 469 }
471 470 }
472 471
473 472 std::shared_ptr<IRequestPredicate> CatalogueController::CatalogueControllerPrivate::createFinder(const QUuid &uniqId, const QString &repository, DBType type)
474 473 {
475 474 // update catalogue parameter
476 475 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
477 476 QString{"uniqId"}, uniqId, ComparaisonOperation::EQUALEQUAL);
478 477
479 478 auto repositoryType = repository;
480 479 switch (type) {
481 480 case DBType::SYNC:
482 481 repositoryType = toSyncRepository(repositoryType);
483 482 break;
484 483 case DBType::WORK:
485 484 repositoryType =toWorkRepository(repositoryType);
486 485 break;
487 486 case DBType::TRASH:
488 487 default:
489 488 break;
490 489 }
491 490
492 491 auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
493 492 QString{"repository"}, repositoryType,
494 493 ComparaisonOperation::EQUALEQUAL);
495 494
496 495 auto finderPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
497 496 finderPred->AddRequestPredicate(uniqIdPredicate);
498 497 finderPred->AddRequestPredicate(repositoryPredicate);
499 498
500 499 return finderPred;
501 500 }
General Comments 0
You need to be logged in to leave comments. Login now