diff options
author | Minijackson <minijackson@riseup.net> | 2018-08-22 10:36:29 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2018-08-22 10:36:29 +0200 |
commit | 3559ec6e6e698f20e600dfbbdff0d56d66576c0d (patch) | |
tree | 0e44c41f0436520aac2f78c8a20b05ddb0b3beab | |
parent | fc00461a517db33ca641e09a6987ed2d855729b3 (diff) | |
download | sink-3559ec6e6e698f20e600dfbbdff0d56d66576c0d.tar.gz sink-3559ec6e6e698f20e600dfbbdff0d56d66576c0d.zip |
Re-do fullScan function and test it
-rw-r--r-- | common/storage/entitystore.cpp | 26 | ||||
-rw-r--r-- | tests/entitystoretest.cpp | 48 |
2 files changed, 52 insertions, 22 deletions
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 7776bfc..250f01d 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp | |||
@@ -440,30 +440,12 @@ QVector<Identifier> EntityStore::fullScan(const QByteArray &type) | |||
440 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; | 440 | SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; |
441 | return {}; | 441 | return {}; |
442 | } | 442 | } |
443 | //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. | ||
444 | QSet<Identifier> keys; | ||
445 | DataStore::mainDatabase(d->getTransaction(), type) | ||
446 | .scan(QByteArray(), | ||
447 | [&](const QByteArray &key, const QByteArray &data) -> bool { | ||
448 | EntityBuffer buffer(const_cast<const char *>(data.data()), data.size()); | ||
449 | if (!buffer.isValid()) { | ||
450 | SinkWarningCtx(d->logCtx) << "Read invalid buffer from disk"; | ||
451 | return true; | ||
452 | } | ||
453 | 443 | ||
454 | size_t revision = byteArrayToSizeT(key); | 444 | QSet<Identifier> keys; |
455 | 445 | ||
456 | const auto metadata = flatbuffers::GetRoot<Metadata>(buffer.metadataBuffer()); | 446 | DataStore::getUids(type, d->getTransaction(), [&keys] (const QByteArray &uid) { |
457 | const QByteArray uid = DataStore::getUidFromRevision(d->getTransaction(), revision); | 447 | keys << Identifier::fromDisplayByteArray(uid); |
458 | const auto identifier = Sink::Storage::Identifier::fromDisplayByteArray(uid); | 448 | }); |
459 | if (keys.contains(identifier)) { | ||
460 | //Not something that should persist if the replay works, so we keep a message for now. | ||
461 | SinkTraceCtx(d->logCtx) << "Multiple revisions for uid: " << Sink::Storage::Key::fromInternalByteArray(key) << ". This is normal if changereplay has not completed yet."; | ||
462 | } | ||
463 | keys << identifier; | ||
464 | return true; | ||
465 | }, | ||
466 | [&](const DataStore::Error &error) { SinkWarningCtx(d->logCtx) << "Error during fullScan query: " << error.message; }); | ||
467 | 449 | ||
468 | SinkTraceCtx(d->logCtx) << "Full scan retrieved " << keys.size() << " results."; | 450 | SinkTraceCtx(d->logCtx) << "Full scan retrieved " << keys.size() << " results."; |
469 | return keys.toList().toVector(); | 451 | return keys.toList().toVector(); |
diff --git a/tests/entitystoretest.cpp b/tests/entitystoretest.cpp index 03b940b..aab5b3b 100644 --- a/tests/entitystoretest.cpp +++ b/tests/entitystoretest.cpp | |||
@@ -29,6 +29,54 @@ private slots: | |||
29 | { | 29 | { |
30 | } | 30 | } |
31 | 31 | ||
32 | void testFullScan() | ||
33 | { | ||
34 | using namespace Sink; | ||
35 | ResourceContext resourceContext{resourceInstanceIdentifier.toUtf8(), "dummy", AdaptorFactoryRegistry::instance().getFactories("test")}; | ||
36 | Storage::EntityStore store(resourceContext, {}); | ||
37 | |||
38 | auto mail = ApplicationDomain::ApplicationDomainType::createEntity<ApplicationDomain::Mail>("res1"); | ||
39 | mail.setExtractedMessageId("messageid"); | ||
40 | mail.setExtractedSubject("boo"); | ||
41 | |||
42 | auto mail2 = ApplicationDomain::ApplicationDomainType::createEntity<ApplicationDomain::Mail>("res1"); | ||
43 | mail2.setExtractedMessageId("messageid2"); | ||
44 | mail2.setExtractedSubject("foo"); | ||
45 | |||
46 | auto mail3 = ApplicationDomain::ApplicationDomainType::createEntity<ApplicationDomain::Mail>("res1"); | ||
47 | mail3.setExtractedMessageId("messageid2"); | ||
48 | mail3.setExtractedSubject("foo"); | ||
49 | |||
50 | store.startTransaction(Storage::DataStore::ReadWrite); | ||
51 | store.add("mail", mail, false); | ||
52 | store.add("mail", mail2, false); | ||
53 | store.add("mail", mail3, false); | ||
54 | |||
55 | mail.setExtractedSubject("foo"); | ||
56 | |||
57 | store.modify("mail", mail, QByteArrayList{}, false); | ||
58 | |||
59 | { | ||
60 | const auto ids = store.fullScan("mail"); | ||
61 | |||
62 | QCOMPARE(ids.size(), 3); | ||
63 | QVERIFY(ids.contains(Sink::Storage::Identifier::fromDisplayByteArray(mail.identifier()))); | ||
64 | QVERIFY(ids.contains(Sink::Storage::Identifier::fromDisplayByteArray(mail2.identifier()))); | ||
65 | QVERIFY(ids.contains(Sink::Storage::Identifier::fromDisplayByteArray(mail3.identifier()))); | ||
66 | } | ||
67 | |||
68 | store.remove("mail", mail3, false); | ||
69 | store.commitTransaction(); | ||
70 | |||
71 | { | ||
72 | const auto ids = store.fullScan("mail"); | ||
73 | |||
74 | QCOMPARE(ids.size(), 2); | ||
75 | QVERIFY(ids.contains(Sink::Storage::Identifier::fromDisplayByteArray(mail.identifier()))); | ||
76 | QVERIFY(ids.contains(Sink::Storage::Identifier::fromDisplayByteArray(mail2.identifier()))); | ||
77 | } | ||
78 | } | ||
79 | |||
32 | void readAll() | 80 | void readAll() |
33 | { | 81 | { |
34 | using namespace Sink; | 82 | using namespace Sink; |