From cdf9351a39136b72fd76d3ad5e40821a92aab24c Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Wed, 14 Oct 2020 11:44:46 +0530 Subject: [PATCH 01/13] work in progress --- nitrite-android-example/build.gradle | 9 +- .../no2/test/RepositoryModificationTest.java | 8 +- .../java/org/dizitart/no2/mapdb/MapDBMap.java | 77 +-- .../org/dizitart/no2/mapdb/MapDBStore.java | 6 +- .../no2/mapdb/NitriteBuilderTest.java | 6 +- .../mapdb/collection/CollectionIndexTest.java | 22 +- .../repository/RepositoryFactoryTest.java | 4 +- .../RepositoryModificationTest.java | 8 +- .../dizitart/no2/mvstore/NitriteMVMap.java | 5 + .../dizitart/no2/mvstore/ReverseIterator.java | 42 ++ .../no2/mvstore/compat/v3/MigrationUtil.java | 10 +- .../org/dizitart/no2/NitriteBuilderTest.java | 6 +- .../no2/collection/CollectionIndexTest.java | 22 +- .../no2/repository/RepositoryFactoryTest.java | 4 +- .../RepositoryModificationTest.java | 8 +- .../no2/sync/ReplicationTemplate.java | 4 +- .../org/dizitart/no2/rocksdb/EntrySet.java | 17 +- .../org/dizitart/no2/rocksdb/RocksDBMap.java | 8 +- .../rocksdb/formatter/NitriteSerializers.java | 20 +- .../no2/rocksdb/NitriteBuilderTest.java | 6 +- .../collection/CollectionIndexTest.java | 22 +- .../repository/RepositoryFactoryTest.java | 4 +- .../RepositoryModificationTest.java | 8 +- .../no2/spatial/IntersectsFilter.java | 4 +- .../dizitart/no2/spatial/SpatialIndexer.java | 4 +- .../dizitart/no2/spatial/WithinFilter.java | 4 +- .../no2/support/NitriteJsonExporter.java | 12 +- .../no2/support/NitriteJsonImporter.java | 10 +- .../support/ExporterImporterOptionTest.java | 4 +- .../java/org/dizitart/no2/NitriteConfig.java | 21 +- .../collection/DefaultNitriteCollection.java | 59 +-- .../no2/collection/DocumentCursor.java | 24 +- .../no2/collection/NitriteCollection.java | 92 ++-- .../operation/BoundedDocumentStream.java | 4 +- .../operation/CollectionOperations.java | 42 +- .../operation/DocumentCursorImpl.java | 8 +- .../operation/DocumentIndexWriter.java | 158 ++++++ .../no2/collection/operation/FindOptions.java | 21 + .../collection/operation/IndexOperations.java | 279 ++++------ .../collection/operation/ReadOperations.java | 44 +- .../operation/SortedDocumentCursor.java | 4 +- .../collection/operation/StreamGenerator.java | 11 + .../collection/operation/WriteOperations.java | 53 +- .../common/{NullEntry.java => DBNull.java} | 10 +- .../org/dizitart/no2/common/FieldValues.java | 46 ++ .../java/org/dizitart/no2/common/Fields.java | 127 +++++ .../no2/common/PersistentCollection.java | 226 +++++--- .../common/concurrent/ThreadPoolManager.java | 5 +- .../no2/common/util/DocumentUtils.java | 17 + .../dizitart/no2/common/util/Iterables.java | 19 + .../dizitart/no2/common/util/StringUtils.java | 5 + .../no2/common/util/ValidationUtils.java | 7 + .../dizitart/no2/filters/EqualsFilter.java | 8 +- .../no2/filters/GreaterEqualFilter.java | 4 +- .../no2/filters/GreaterThanFilter.java | 4 +- .../org/dizitart/no2/filters/InFilter.java | 4 +- .../no2/filters/IndexAwareFilter.java | 4 +- .../no2/filters/IndexedQuerySupport.java | 28 + .../no2/filters/LesserEqualFilter.java | 4 +- .../no2/filters/LesserThanFilter.java | 4 +- .../dizitart/no2/filters/NotEqualsFilter.java | 8 +- .../org/dizitart/no2/filters/NotInFilter.java | 4 +- .../dizitart/no2/filters/QueryOptimizer.java | 61 +++ .../org/dizitart/no2/filters/TextFilter.java | 4 +- .../no2/index/BaseNitriteIndexer.java | 62 +++ .../dizitart/no2/index/ComparableIndexer.java | 499 +++++++++++------- .../{IndexEntry.java => IndexDescriptor.java} | 30 +- .../org/dizitart/no2/index/IndexMeta.java | 6 +- .../java/org/dizitart/no2/index/Indexer.java | 52 -- .../dizitart/no2/index/NitriteIndexer.java | 39 ++ .../no2/index/NitriteTextIndexer.java | 5 +- .../org/dizitart/no2/index/TextIndexer.java | 2 +- .../no2/migration/commands/AddField.java | 8 +- .../migration/commands/ChangeDataType.java | 8 +- .../no2/migration/commands/DeleteField.java | 6 +- .../no2/migration/commands/Rename.java | 10 +- .../no2/migration/commands/RenameField.java | 8 +- .../dizitart/no2/module/PluginManager.java | 16 +- .../repository/DefaultObjectRepository.java | 25 +- .../no2/repository/ObjectRepository.java | 137 +++-- .../org/dizitart/no2/store/IndexCatalog.java | 73 +-- .../org/dizitart/no2/store/NitriteMap.java | 3 + .../no2/store/memory/InMemoryMap.java | 72 +-- .../DefaultTransactionalCollection.java | 89 ++-- .../DefaultTransactionalRepository.java | 26 +- .../no2/transaction/TransactionalConfig.java | 16 +- .../no2/transaction/TransactionalMap.java | 94 ++-- ...ntryTest.java => IndexDescriptorTest.java} | 12 +- .../org/dizitart/no2/NitriteBuilderTest.java | 6 +- .../no2/collection/CollectionIndexTest.java | 22 +- .../no2/filters/EqualsFilterTest.java | 8 +- .../no2/filters/NotEqualsFilterTest.java | 10 +- .../dizitart/no2/filters/TextFilterTest.java | 2 +- .../no2/index/IndexDescriptorTest.java | 28 + .../dizitart/no2/index/IndexEntryTest.java | 28 - .../no2/repository/RepositoryFactoryTest.java | 4 +- .../RepositoryModificationTest.java | 8 +- .../org/dizitart/no2/rx/FlowableCursor.java | 12 +- .../no2/rx/FlowableDocumentCursor.java | 10 +- ...eStream.java => FlowableRecordStream.java} | 8 +- .../no2/rx/RxNitriteCollectionImpl.java | 4 +- .../no2/rx/RxObjectRepositoryImpl.java | 4 +- .../no2/rx/RxPersistentCollection.java | 4 +- 103 files changed, 2014 insertions(+), 1225 deletions(-) create mode 100644 nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/ReverseIterator.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java rename nitrite/src/main/java/org/dizitart/no2/common/{NullEntry.java => DBNull.java} (54%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/Fields.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java rename nitrite/src/main/java/org/dizitart/no2/index/{IndexEntry.java => IndexDescriptor.java} (75%) delete mode 100644 nitrite/src/main/java/org/dizitart/no2/index/Indexer.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java rename nitrite/src/test/java/org/dizitart/no2/{IndexEntryTest.java => IndexDescriptorTest.java} (72%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/index/IndexEntryTest.java rename rx-nitrite/src/main/java/org/dizitart/no2/rx/{FlowableReadableStream.java => FlowableRecordStream.java} (81%) diff --git a/nitrite-android-example/build.gradle b/nitrite-android-example/build.gradle index f7a99d5ff..63ceba59d 100644 --- a/nitrite-android-example/build.gradle +++ b/nitrite-android-example/build.gradle @@ -46,8 +46,7 @@ android { exclude 'META-INF/LGPL2.1' } - compileSdkVersion 28 - + compileSdkVersion 29 defaultConfig { applicationId "org.dizitart.no2.example.android" @@ -56,8 +55,9 @@ android { versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" +// multiDexEnabled true + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -72,6 +72,7 @@ android { } compileOptions { +// coreLibraryDesugaringEnabled true sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } @@ -92,6 +93,8 @@ dependencies { implementation 'com.android.support:design:28.0.0' annotationProcessor "org.projectlombok:lombok:1.18.12" +// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9' + testImplementation 'junit:junit:4.13' testAnnotationProcessor "org.projectlombok:lombok:1.18.12" androidTestImplementation 'com.android.support.test:runner:1.0.2' diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java index d9f8b9668..b607e7f5b 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java @@ -21,7 +21,7 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.Cursor; @@ -69,7 +69,7 @@ public void testRebuildIndex() { @Test public void testListIndexes() { - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); @@ -81,7 +81,7 @@ public void testListIndexes() { public void testDropIndex() { testListIndexes(); companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); } @@ -89,7 +89,7 @@ public void testDropIndex() { public void testDropAllIndex() { testListIndexes(); companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 0); } diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java index 7eabe6740..27635a93a 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java @@ -3,7 +3,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.NullEntry; +import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.NitriteIOException; @@ -14,6 +14,7 @@ import java.util.Iterator; import java.util.Map; +import java.util.NavigableMap; import static org.dizitart.no2.common.util.ValidationUtils.notNull; @@ -26,14 +27,14 @@ public class MapDBMap implements NitriteMap { private final BTreeMap bTreeMap; @Getter(AccessLevel.PACKAGE) - private final BTreeMap nullEntryMap; + private final BTreeMap nullEntryMap; private final NitriteStore nitriteStore; private final String mapName; public MapDBMap(String mapName, BTreeMap bTreeMap, - BTreeMap nullEntryMap, NitriteStore nitriteStore) { + BTreeMap nullEntryMap, NitriteStore nitriteStore) { this.bTreeMap = bTreeMap; this.mapName = mapName; this.nitriteStore = nitriteStore; @@ -43,7 +44,7 @@ public MapDBMap(String mapName, BTreeMap bTreeMap, @Override public boolean containsKey(K k) { if (k == null) { - return nullEntryMap.containsKey(NullEntry.getInstance()); + return nullEntryMap.containsKey(DBNull.getInstance()); } return bTreeMap.containsKey(k); } @@ -51,7 +52,7 @@ public boolean containsKey(K k) { @Override public V get(K k) { if (k == null) { - return nullEntryMap.get(NullEntry.getInstance()); + return nullEntryMap.get(DBNull.getInstance()); } Map.Entry firstEntry = bTreeMap.firstEntry(); @@ -90,7 +91,7 @@ public RecordStream values() { public V remove(K k) { V value; if (k == null) { - value = nullEntryMap.remove(NullEntry.getInstance()); + value = nullEntryMap.remove(DBNull.getInstance()); } else { value = bTreeMap.remove(k); } @@ -102,7 +103,7 @@ public V remove(K k) { public RecordStream keySet() { return RecordStream.fromIterable(() -> new Iterator() { final Iterator keyIterator = bTreeMap.keyIterator(); - final Iterator nullEntryIterator = nullEntryMap.keyIterator(); + final Iterator nullEntryIterator = nullEntryMap.keyIterator(); @Override public boolean hasNext() { @@ -129,7 +130,7 @@ public void put(K k, V v) { notNull(v, "value cannot be null"); try { if (k == null) { - nullEntryMap.put(NullEntry.getInstance(), v); + nullEntryMap.put(DBNull.getInstance(), v); } else { Map.Entry firstEntry = bTreeMap.firstEntry(); if (firstEntry != null) { @@ -157,7 +158,7 @@ public V putIfAbsent(K k, V v) { V value; if (k == null) { - value = nullEntryMap.putIfAbsent(NullEntry.getInstance(), v); + value = nullEntryMap.putIfAbsent(DBNull.getInstance(), v); } else { value = bTreeMap.putIfAbsent(k, v); } @@ -167,30 +168,12 @@ public V putIfAbsent(K k, V v) { @Override public RecordStream> entries() { - return () -> new Iterator>() { - final Iterator> entryIterator = bTreeMap.entrySet().iterator(); - final Iterator> nullEntryIterator = nullEntryMap.entrySet().iterator(); - - @Override - public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return entryIterator.hasNext(); - } - return true; - } + return getStream(bTreeMap, nullEntryMap); + } - @Override - public Pair next() { - if (nullEntryIterator.hasNext()) { - Map.Entry entry = nullEntryIterator.next(); - return new Pair<>(null, entry.getValue()); - } else { - Map.Entry entry = entryIterator.next(); - return new Pair<>(entry.getKey(), entry.getValue()); - } - } - }; + @Override + public RecordStream> reversedEntries() { + return getStream(bTreeMap.descendingMap(), nullEntryMap.descendingMap()); } @Override @@ -240,4 +223,34 @@ public void close() { bTreeMap.close(); nullEntryMap.close(); } + + private RecordStream> getStream(NavigableMap primaryMap, + NavigableMap nullEntryMap) { + return RecordStream.fromIterable(() -> new Iterator>() { + private final Iterator> entryIterator = + primaryMap.entrySet().iterator(); + private final Iterator> nullEntryIterator = + nullEntryMap.entrySet().iterator(); + + @Override + public boolean hasNext() { + boolean result = nullEntryIterator.hasNext(); + if (!result) { + return entryIterator.hasNext(); + } + return true; + } + + @Override + public Pair next() { + if (nullEntryIterator.hasNext()) { + Map.Entry entry = nullEntryIterator.next(); + return new Pair<>(null, entry.getValue()); + } else { + Map.Entry entry = entryIterator.next(); + return new Pair<>(entry.getKey(), entry.getValue()); + } + } + }); + } } diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java index 22ba080d2..85c579539 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java @@ -1,7 +1,7 @@ package org.dizitart.no2.mapdb; import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.NullEntry; +import org.dizitart.no2.common.DBNull; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.index.BoundingBox; import org.dizitart.no2.mapdb.serializers.Serializers; @@ -94,7 +94,7 @@ public NitriteMap openMap(String mapName, Class keyT BTreeMap bTreeMap = treeMapMaker.createOrOpen(); // mapdb btreemap does not support null key, so all null key entries are maintained in a separate map - DB.TreeMapMaker nullMapMaker = (DB.TreeMapMaker) db + DB.TreeMapMaker nullMapMaker = (DB.TreeMapMaker) db .treeMap(mapName + "null-map") .counterEnable() .valuesOutsideNodesEnable(); @@ -103,7 +103,7 @@ public NitriteMap openMap(String mapName, Class keyT nullMapMaker.valueSerializer(valueSerializer); } - BTreeMap nullMap = nullMapMaker.createOrOpen(); + BTreeMap nullMap = nullMapMaker.createOrOpen(); MapDBMap mapDBMap = new MapDBMap<>(mapName, bTreeMap, nullMap, this); nitriteMapRegistry.put(mapName, mapDBMap); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java index 26d80df47..dbc63bd74 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java @@ -25,7 +25,7 @@ import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; @@ -307,7 +307,7 @@ public void testInvalidPath() { assertNull(db); } - private static class CustomIndexer implements Indexer { + private static class CustomIndexer implements NitriteIndexer { @Override public String getIndexType() { @@ -335,7 +335,7 @@ public void dropIndex(NitriteMap collection, String field) } @Override - public Indexer clone() throws CloneNotSupportedException { + public NitriteIndexer clone() throws CloneNotSupportedException { return null; } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java index 4a56c3cff..8727f6c85 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java @@ -23,7 +23,7 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; @@ -140,9 +140,9 @@ public void testCreateIndexAsync() { public void testRebuildIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); insert(); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), false); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), false); } } @@ -152,9 +152,9 @@ public void testRebuildIndexAsync() { insert(); await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), true); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), true); await().until(bodyIndexingCompleted()); } } @@ -162,14 +162,14 @@ public void testRebuildIndexAsync() { @Test public void testRebuildIndexOnRunningIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexEntry idx = indices.iterator().next(); + Collection indices = collection.listIndices(); + IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java index 859a822d6..25e4821dc 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java @@ -24,7 +24,7 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapdb.Retry; import org.dizitart.no2.mapdb.TestUtil; @@ -123,7 +123,7 @@ public void rebuildIndex(String field, boolean isAsync) { } @Override - public Collection listIndices() { + public Collection listIndices() { return null; } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java index 0cd95fba9..023f1269b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.mapdb.repository.data.*; @@ -70,7 +70,7 @@ public void testRebuildIndex() { @Test public void testListIndexes() { - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); @@ -82,7 +82,7 @@ public void testListIndexes() { public void testDropIndex() { testListIndexes(); companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); } @@ -90,7 +90,7 @@ public void testDropIndex() { public void testDropAllIndex() { testListIndexes(); companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 0); } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java index 6e56eb5aa..5dc1dac1c 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java @@ -121,6 +121,11 @@ public Pair next() { }; } + @Override + public RecordStream> reversedEntries() { + return () -> new ReverseIterator<>(mvMap); + } + @Override public Key higherKey(Key key) { return mvMap.higherKey(key); diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/ReverseIterator.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/ReverseIterator.java new file mode 100644 index 000000000..f98c0fae0 --- /dev/null +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/ReverseIterator.java @@ -0,0 +1,42 @@ +package org.dizitart.no2.mvstore; + +import org.dizitart.no2.common.tuples.Pair; +import org.h2.mvstore.MVMap; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author Anindya Chatterjee + */ +public class ReverseIterator implements Iterator> { + private final MVMap mvMap; + private Key anchor; + private boolean started; + + public ReverseIterator(MVMap mvMap) { + long version = mvMap.getVersion(); + this.mvMap = mvMap.openVersion(version); + this.anchor = this.mvMap.lastKey(); + this.started = false; + } + + @Override + public boolean hasNext() { + Key key = started ? mvMap.lowerKey(this.anchor) : mvMap.floorKey(this.anchor); + return key != null; + } + + @Override + public Pair next() { + Key key = started ? mvMap.lowerKey(this.anchor) : mvMap.floorKey(this.anchor); + this.started = true; + if (key == null) { + throw new NoSuchElementException(); + } + + Value value = mvMap.get(key); + this.anchor = key; + return new Pair<>(key, value); + } +} diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java index 138c8888c..240785237 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java @@ -21,7 +21,7 @@ import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; import org.dizitart.no2.store.UserCredential; import org.h2.mvstore.MVMap; @@ -175,19 +175,19 @@ private static Document document(Compat.Document value) { private static IndexMeta indexMeta(Compat.IndexMeta value) { Compat.Index index = value.getIndex(); - IndexEntry indexEntry = indexEntry(index); + IndexDescriptor indexDescriptor = indexEntry(index); IndexMeta indexMeta = new IndexMeta(); - indexMeta.setIndexEntry(indexEntry); + indexMeta.setIndexDescriptor(indexDescriptor); indexMeta.setIndexMap(value.getIndexMap()); indexMeta.setIsDirty(value.getIsDirty()); return indexMeta; } - private static IndexEntry indexEntry(Compat.Index value) { + private static IndexDescriptor indexEntry(Compat.Index value) { String indexType = value.getIndexType().name(); - return new IndexEntry(indexType, value.getField(), value.getCollectionName()); + return new IndexDescriptor(indexType, value.getField(), value.getCollectionName()); } private static NitriteId nitriteId(Compat.NitriteId value) { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index eabd8d511..a27e3dbb8 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreConfig; @@ -315,7 +315,7 @@ public void testInvalidPath() { assertNull(db); } - private static class CustomIndexer implements Indexer { + private static class CustomIndexer implements NitriteIndexer { @Override public String getIndexType() { @@ -343,7 +343,7 @@ public void dropIndex(NitriteMap collection, String field) } @Override - public Indexer clone() throws CloneNotSupportedException { + public NitriteIndexer clone() throws CloneNotSupportedException { return null; } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java index 161e52626..1a9bdb9ab 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java @@ -19,7 +19,7 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; import org.junit.Test; @@ -136,9 +136,9 @@ public void testCreateIndexAsync() { public void testRebuildIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); insert(); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), false); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), false); } } @@ -148,9 +148,9 @@ public void testRebuildIndexAsync() { insert(); await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), true); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), true); await().until(bodyIndexingCompleted()); } } @@ -158,14 +158,14 @@ public void testRebuildIndexAsync() { @Test public void testRebuildIndexOnRunningIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexEntry idx = indices.iterator().next(); + Collection indices = collection.listIndices(); + IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java index e012507f7..7612946b0 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java @@ -26,7 +26,7 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.store.NitriteStore; import org.junit.After; @@ -122,7 +122,7 @@ public void rebuildIndex(String field, boolean isAsync) { } @Override - public Collection listIndices() { + public Collection listIndices() { return null; } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java index 7c0813651..3c259a8a8 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.data.*; @@ -68,7 +68,7 @@ public void testRebuildIndex() { @Test public void testListIndexes() { - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); @@ -80,7 +80,7 @@ public void testListIndexes() { public void testDropIndex() { testListIndexes(); companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); } @@ -88,7 +88,7 @@ public void testDropIndex() { public void testDropAllIndex() { testListIndexes(); companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 0); } diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java index 53ecd7f00..1338f1e4b 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java @@ -76,7 +76,7 @@ public class ReplicationTemplate implements ReplicationOperation { public ReplicationTemplate(Config config) { this.config = config; - init(); + initialize(); } public void connect() { @@ -186,7 +186,7 @@ public void collectGarbage(Long ttl) { } } - private void init() { + private void initialize() { this.messageFactory = new MessageFactory(); this.connected = new AtomicBoolean(false); this.exchangeFlag = new AtomicBoolean(false); diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java index 68fe5abb1..43ce9f1e5 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java @@ -12,14 +12,17 @@ class EntrySet implements Iterable> { private final ColumnFamilyHandle columnFamilyHandle; private final Class keyType; private final Class valueType; + private final boolean reverse; public EntrySet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, - ObjectFormatter objectFormatter, Class keyType, Class valueType) { + ObjectFormatter objectFormatter, Class keyType, + Class valueType, boolean reverse) { this.rocksDB = rocksDB; this.columnFamilyHandle = columnFamilyHandle; this.objectFormatter = objectFormatter; this.keyType = keyType; this.valueType = valueType; + this.reverse = reverse; } @Override @@ -33,7 +36,11 @@ private class EntryIterator implements Iterator> { public EntryIterator() { rawEntryIterator = rocksDB.newIterator(columnFamilyHandle); - rawEntryIterator.seekToFirst(); + if (reverse) { + rawEntryIterator.seekToLast(); + } else { + rawEntryIterator.seekToFirst(); + } } @Override @@ -55,7 +62,11 @@ public Pair next() { K key = (K) objectFormatter.decodeKey(rawEntryIterator.key(), keyType); try { V value = (V) objectFormatter.decode(rawEntryIterator.value(), valueType); - rawEntryIterator.next(); + if (reverse) { + rawEntryIterator.prev(); + } else { + rawEntryIterator.next(); + } return new Pair<>(key, value); } catch (Exception e) { System.out.println(new String(rawEntryIterator.value())); diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java index 37870e88d..da4fc9675 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java @@ -208,7 +208,13 @@ public V putIfAbsent(K k, V v) { @Override public RecordStream> entries() { return RecordStream.fromIterable(new EntrySet<>(rocksDB, columnFamilyHandle, - objectFormatter, getKeyType(), getValueType())); + objectFormatter, getKeyType(), getValueType(), false)); + } + + @Override + public RecordStream> reversedEntries() { + return RecordStream.fromIterable(new EntrySet<>(rocksDB, columnFamilyHandle, + objectFormatter, getKeyType(), getValueType(), true)); } @Override diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java index 98146e61c..226d3d396 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java @@ -9,7 +9,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; import org.dizitart.no2.store.UserCredential; @@ -87,39 +87,39 @@ private static class IndexMetaSerializer extends Serializer { @Override public void write(Kryo kryo, Output output, IndexMeta object) { - kryo.writeObject(output, object.getIndexEntry()); + kryo.writeObject(output, object.getIndexDescriptor()); output.writeString(object.getIndexMap()); output.writeBoolean(object.getIsDirty().get()); } @Override public IndexMeta read(Kryo kryo, Input input, Class type) { - IndexEntry indexEntry = kryo.readObject(input, IndexEntry.class); + IndexDescriptor indexDescriptor = kryo.readObject(input, IndexDescriptor.class); String indexMap = input.readString(); boolean isDirty = input.readBoolean(); IndexMeta indexMeta = new IndexMeta(); - indexMeta.setIndexEntry(indexEntry); + indexMeta.setIndexDescriptor(indexDescriptor); indexMeta.setIndexMap(indexMap); indexMeta.setIsDirty(new AtomicBoolean(isDirty)); return indexMeta; } } - private static class IndexEntrySerializer extends Serializer { + private static class IndexEntrySerializer extends Serializer { @Override - public void write(Kryo kryo, Output output, IndexEntry object) { + public void write(Kryo kryo, Output output, IndexDescriptor object) { output.writeString(object.getCollectionName()); - output.writeString(object.getField()); + output.writeString(object.getFields()); output.writeString(object.getIndexType()); } @Override - public IndexEntry read(Kryo kryo, Input input, Class type) { + public IndexDescriptor read(Kryo kryo, Input input, Class type) { String collectionName = input.readString(); String field = input.readString(); String indexType = input.readString(); - return new IndexEntry(indexType, field, collectionName); + return new IndexDescriptor(indexType, field, collectionName); } } @@ -171,7 +171,7 @@ public static void registerAll(KryoObjectFormatter kryoObjectFormatter) { kryoObjectFormatter.registerSerializer(Pair.class, new PairSerializer()); kryoObjectFormatter.registerSerializer(Document.class, new DocumentSerializer()); kryoObjectFormatter.registerSerializer(IndexMeta.class, new IndexMetaSerializer()); - kryoObjectFormatter.registerSerializer(IndexEntry.class, new IndexEntrySerializer()); + kryoObjectFormatter.registerSerializer(IndexDescriptor.class, new IndexEntrySerializer()); kryoObjectFormatter.registerSerializer(UserCredential.class, new UserCredentialSerializer()); kryoObjectFormatter.registerSerializer(Attributes.class, new AttributesSerializer()); } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java index 895048181..f2f29da6c 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java @@ -26,7 +26,7 @@ import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; @@ -256,7 +256,7 @@ public void testFieldSeparator() { assertEquals(document.get("colorCodes::1::color"), "Green"); } - private static class CustomIndexer implements Indexer { + private static class CustomIndexer implements NitriteIndexer { @Override public String getIndexType() { @@ -284,7 +284,7 @@ public void dropIndex(NitriteMap collection, String field) } @Override - public Indexer clone() throws CloneNotSupportedException { + public NitriteIndexer clone() throws CloneNotSupportedException { return null; } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java index 59c46cfeb..d56218dea 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java @@ -23,7 +23,7 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; @@ -140,9 +140,9 @@ public void testCreateIndexAsync() { public void testRebuildIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); insert(); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), false); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), false); } } @@ -152,9 +152,9 @@ public void testRebuildIndexAsync() { insert(); await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), true); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), true); await().until(bodyIndexingCompleted()); } } @@ -162,14 +162,14 @@ public void testRebuildIndexAsync() { @Test public void testRebuildIndexOnRunningIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexEntry idx = indices.iterator().next(); + Collection indices = collection.listIndices(); + IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java index 693884346..64540be80 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java @@ -24,7 +24,7 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.repository.RepositoryFactory; import org.dizitart.no2.rocksdb.DbTestOperations; @@ -127,7 +127,7 @@ public void rebuildIndex(String field, boolean isAsync) { } @Override - public Collection listIndices() { + public Collection listIndices() { return null; } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java index 53b047a44..723d6f0ef 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.rocksdb.repository.data.*; @@ -70,7 +70,7 @@ public void testRebuildIndex() { @Test public void testListIndexes() { - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); @@ -82,7 +82,7 @@ public void testListIndexes() { public void testDropIndex() { testListIndexes(); companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); } @@ -90,7 +90,7 @@ public void testDropIndex() { public void testDropAllIndex() { testListIndexes(); companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 0); } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java index d20f7b6a0..2b5ab8574 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java @@ -35,8 +35,8 @@ protected IntersectsFilter(String field, Geometry geometry) { @Override protected Set findIndexedIdSet() { if (getIsFieldIndexed()) { - if (getIndexer() instanceof SpatialIndexer && getValue() != null) { - SpatialIndexer spatialIndexer = (SpatialIndexer) getIndexer(); + if (getNitriteIndexer() instanceof SpatialIndexer && getValue() != null) { + SpatialIndexer spatialIndexer = (SpatialIndexer) getNitriteIndexer(); RecordStream idSet = spatialIndexer.findIntersects(getCollectionName(), getField(), getValue()); return idSet.toSet(); } else { diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java index fe26b59eb..5cf5641c7 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java @@ -22,7 +22,7 @@ import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.BoundingBox; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteRTree; @@ -33,7 +33,7 @@ * @author Anindya Chatterjee * @since 4.0.0 */ -public class SpatialIndexer implements Indexer { +public class SpatialIndexer implements NitriteIndexer { public static final String SpatialIndex = "Spatial"; private NitriteMapper nitriteMapper; diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java index 842043496..7afe310f7 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java @@ -35,8 +35,8 @@ protected WithinFilter(String field, Geometry geometry) { @Override protected Set findIndexedIdSet() { if (getIsFieldIndexed()) { - if (getIndexer() instanceof SpatialIndexer && getValue() != null) { - SpatialIndexer spatialIndexer = (SpatialIndexer) getIndexer(); + if (getNitriteIndexer() instanceof SpatialIndexer && getValue() != null) { + SpatialIndexer spatialIndexer = (SpatialIndexer) getNitriteIndexer(); RecordStream idSet = spatialIndexer.findWithin(getCollectionName(), getField(), getValue()); return idSet.toSet(); } else { diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonExporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonExporter.java index 67dec708e..cb2fcff73 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonExporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonExporter.java @@ -24,7 +24,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.PersistentCollection; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.repository.ObjectRepository; import java.io.ByteArrayOutputStream; @@ -139,7 +139,7 @@ private void writeRepository(ObjectRepository repository) throws IOException generator.writeFieldName(TAG_TYPE); generator.writeString(repository.getType().getName()); - Collection indices = repository.listIndices(); + Collection indices = repository.listIndices(); writeIndices(indices); DocumentCursor cursor = repository.getDocumentCollection().find(); @@ -156,7 +156,7 @@ private void writeKeyedRepository(String key, ObjectRepository repository) th generator.writeFieldName(TAG_TYPE); generator.writeString(repository.getType().getName()); - Collection indices = repository.listIndices(); + Collection indices = repository.listIndices(); writeIndices(indices); DocumentCursor cursor = repository.getDocumentCollection().find(); @@ -169,7 +169,7 @@ private void writeCollection(NitriteCollection nitriteCollection) throws IOExcep generator.writeFieldName(TAG_NAME); generator.writeString(nitriteCollection.getName()); - Collection indices = nitriteCollection.listIndices(); + Collection indices = nitriteCollection.listIndices(); writeIndices(indices); DocumentCursor cursor = nitriteCollection.find(); @@ -177,11 +177,11 @@ private void writeCollection(NitriteCollection nitriteCollection) throws IOExcep generator.writeEndObject(); } - private void writeIndices(Collection indices) throws IOException { + private void writeIndices(Collection indices) throws IOException { generator.writeFieldName(TAG_INDICES); generator.writeStartArray(); if (options.isExportIndices()) { - for (IndexEntry index : indices) { + for (IndexDescriptor index : indices) { generator.writeStartObject(); generator.writeFieldName(TAG_INDEX); generator.writeObject(writeEncodedObject(index)); diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java index 2c72576f0..76882c677 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java @@ -24,7 +24,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.PersistentCollection; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.repository.ObjectRepository; @@ -179,11 +179,11 @@ private void readIndices(PersistentCollection collection) throws IOException if (TAG_INDEX.equals(fieldName)) { parser.nextToken(); String data = parser.readValueAs(String.class); - IndexEntry index = (IndexEntry) readEncodedObject(data); + IndexDescriptor index = (IndexDescriptor) readEncodedObject(data); if (collection != null && index != null - && index.getField() != null - && !collection.hasIndex(index.getField())) { - collection.createIndex(index.getField(), + && index.getFields() != null + && !collection.hasIndex(index.getFields())) { + collection.createIndex(index.getFields(), IndexOptions.indexOptions(index.getIndexType())); } } diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/ExporterImporterOptionTest.java b/nitrite-support/src/test/java/org/dizitart/no2/support/ExporterImporterOptionTest.java index f7b868910..1523eff59 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/ExporterImporterOptionTest.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/ExporterImporterOptionTest.java @@ -19,7 +19,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.PersistentCollection; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; @@ -87,6 +87,6 @@ public void testImportExportSingle() { new ArrayList()); assertEquals(destCompRepo.listIndices(), sourceCompRepo.listIndices()); - assertEquals(destSecondColl.listIndices(), new LinkedHashSet()); + assertEquals(destSecondColl.listIndices(), new LinkedHashSet()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java index 225470598..4ee8d82d7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java @@ -21,8 +21,9 @@ import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.common.Constants; +import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.module.NitriteModule; @@ -144,15 +145,19 @@ public void autoConfigure() { } /** - * Finds an {@link Indexer} by indexType. + * Finds an {@link NitriteIndexer} by indexType. * - * @param indexType the type of {@link Indexer} to find. - * @return the {@link Indexer} + * @param indexType the type of {@link NitriteIndexer} to find. + * @return the {@link NitriteIndexer} */ - public Indexer findIndexer(String indexType) { - Indexer indexer = pluginManager.getIndexerMap().get(indexType); - indexer.initialize(this); - return indexer; + public NitriteIndexer findIndexer(String indexType) { + NitriteIndexer nitriteIndexer = pluginManager.getIndexerMap().get(indexType); + if (nitriteIndexer != null) { + nitriteIndexer.initialize(this); + return nitriteIndexer; + } else { + throw new IndexingException("no indexer found for index type " + indexType); + } } /** diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 9ffa2944f..5392c5ab0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -22,6 +22,7 @@ import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.collection.operation.CollectionOperations; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.common.event.EventBus; @@ -31,7 +32,7 @@ import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.store.NitriteMap; @@ -42,8 +43,7 @@ import static org.dizitart.no2.collection.UpdateOptions.updateOptions; import static org.dizitart.no2.common.util.DocumentUtils.createUniqueFilter; -import static org.dizitart.no2.common.util.ValidationUtils.containsNull; -import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import static org.dizitart.no2.common.util.ValidationUtils.*; /** * @author Anindya Chatterjee. @@ -167,7 +167,6 @@ public DocumentCursor find() { public DocumentCursor find(Filter filter) { checkOpened(); - try { readLock.lock(); return collectionOperations.find(filter); @@ -176,17 +175,17 @@ public DocumentCursor find(Filter filter) { } } - public void createIndex(String field, IndexOptions indexOptions) { + public void createIndex(Fields fields, IndexOptions indexOptions) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); // by default async is false while creating index try { writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(field, IndexType.Unique, false); + collectionOperations.createIndex(fields, IndexType.Unique, false); } else { - collectionOperations.createIndex(field, indexOptions.getIndexType(), + collectionOperations.createIndex(fields, indexOptions.getIndexType(), indexOptions.isAsync()); } } finally { @@ -194,33 +193,33 @@ public void createIndex(String field, IndexOptions indexOptions) { } } - public void rebuildIndex(String field, boolean isAsync) { + public void rebuildIndex(Fields fields, boolean isAsync) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); - IndexEntry indexEntry; + IndexDescriptor indexDescriptor; try { readLock.lock(); - indexEntry = collectionOperations.findIndex(field); + indexDescriptor = collectionOperations.findIndex(fields); } finally { readLock.unlock(); } - if (indexEntry != null) { - validateRebuildIndex(indexEntry); + if (indexDescriptor != null) { + validateRebuildIndex(indexDescriptor); try { writeLock.lock(); - collectionOperations.rebuildIndex(indexEntry, isAsync); + collectionOperations.rebuildIndex(indexDescriptor, isAsync); } finally { writeLock.unlock(); } } else { - throw new IndexingException(field + " is not indexed"); + throw new IndexingException(fields + " is not indexed"); } } - public Collection listIndices() { + public Collection listIndices() { checkOpened(); try { @@ -231,37 +230,37 @@ public Collection listIndices() { } } - public boolean hasIndex(String field) { + public boolean hasIndex(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); try { readLock.lock(); - return collectionOperations.hasIndex(field); + return collectionOperations.hasIndex(fields); } finally { readLock.unlock(); } } - public boolean isIndexing(String field) { + public boolean isIndexing(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "field cannot be null"); try { readLock.lock(); - return collectionOperations.isIndexing(field); + return collectionOperations.isIndexing(fields); } finally { readLock.unlock(); } } - public void dropIndex(String field) { + public void dropIndex(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); try { writeLock.lock(); - collectionOperations.dropIndex(field); + collectionOperations.dropIndex(fields); } finally { writeLock.unlock(); } @@ -407,11 +406,11 @@ private void checkOpened() { } } - private void validateRebuildIndex(IndexEntry indexEntry) { - notNull(indexEntry, "index cannot be null"); + private void validateRebuildIndex(IndexDescriptor indexDescriptor) { + notNull(indexDescriptor, "index cannot be null"); - if (isIndexing(indexEntry.getField())) { - throw new IndexingException("indexing on value " + indexEntry.getField() + " is currently running"); + if (isIndexing(indexDescriptor.getFields())) { + throw new IndexingException("indexing on value " + indexDescriptor.getFields() + " is currently running"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java b/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java index ca4fcbf10..a3ef2e4c2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java @@ -16,13 +16,13 @@ package org.dizitart.no2.collection; -import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.*; +import org.dizitart.no2.common.tuples.Pair; import java.text.Collator; +import static org.dizitart.no2.common.Fields.multiple; + /** * An interface to iterate over database {@code find()} results. It provides a * mechanism to iterate over all {@link NitriteId}s of the result. @@ -52,7 +52,7 @@ */ public interface DocumentCursor extends RecordStream { - DocumentCursor sort(String field, SortOrder sortOrder, Collator collator, NullOrder nullOrder); + DocumentCursor sort(Fields fields, Collator collator, NullOrder nullOrder); DocumentCursor skipLimit(long skip, long size); @@ -91,14 +91,18 @@ default DocumentCursor sort(String field) { } default DocumentCursor sort(String field, SortOrder sortOrder) { - return sort(field, sortOrder, NullOrder.Default); + return sort(multiple(new Pair<>(field, sortOrder)), NullOrder.Default); + } + + default DocumentCursor sort(Fields fields) { + return sort(fields, null, NullOrder.Default); } - default DocumentCursor sort(String field, SortOrder sortOrder, Collator collator) { - return sort(field, sortOrder, collator, NullOrder.Default); + default DocumentCursor sort(Fields fields, Collator collator) { + return sort(fields, collator, NullOrder.Default); } - default DocumentCursor sort(String field, SortOrder sortOrder, NullOrder nullOrder) { - return sort(field, sortOrder, null, nullOrder); + default DocumentCursor sort(Fields fields, NullOrder nullOrder) { + return sort(fields, null, nullOrder); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java index 57da139de..fca4c3ee8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java @@ -19,6 +19,7 @@ import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.events.EventAware; import org.dizitart.no2.collection.events.EventType; +import org.dizitart.no2.collection.operation.FindOptions; import org.dizitart.no2.common.PersistentCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; @@ -42,17 +43,18 @@ * A nitrite collection supports indexing. Every nitrite collection is also * observable. *

- * [[app-listing]] - * [source,java] - * .Create a collection - * -- - * // create/open a database + *

Create a collection

+ *
+ * {@code
  * Nitrite db = Nitrite.builder()
- * .openOrCreate("user", "password");
- * 

- * include::/src/docs/asciidoc/examples/collection.adoc[] - *

- * -- + * .loadModule(MVStoreModule("/tmp/tmp.db")) + * .openOrCreate("user", "password"); + * + * NitriteCollection collection = db.getCollection("products"); + * } + *

+ * + *

* * @author Anindya Chatterjee * @see EventAware @@ -64,29 +66,29 @@ */ public interface NitriteCollection extends PersistentCollection { /** - * Insert documents into a collection. If the document contains a '_id' value, then + * Insert documents into a collection. If the document contains a {@code _id} value, then * the value will be used as a unique key to identify the document in the collection. - * If the document does not contain any '_id' value, then nitrite will generate a new + * If the document does not contain any {@code _id} value, then nitrite will generate a new * {@link NitriteId} and will add it to the document. *

* If any of the value is already indexed in the collection, then after insertion the * index will also be updated. *

- * [icon="{@docRoot}/note.png"] * NOTE: These operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Insert}. - * + *

+ * * @param document the document to insert * @param documents other documents to insert in a batch. * @return the result of write operation. - * @throws ValidationException if `document` is `null`. - * @throws InvalidIdException if the '_id' value contains `null` value. - * @throws InvalidIdException if the '_id' value contains non comparable type, i.e. + * @throws ValidationException if {@code document} is {@code null}. + * @throws InvalidIdException if the {@code _id} value contains {@code null} value. + * @throws InvalidIdException if the {@code _id} value contains non comparable type, i.e. * type that does not implement {@link Comparable}. - * @throws InvalidIdException if the '_id' contains value, which is not of the same java - * type as of other documents' '_id' in the collection. - * @throws UniqueConstraintException if the value of '_id' value clashes with the id + * @throws InvalidIdException if the {@code _id} contains value, which is not of the same java + * type as of other documents' {@code _id} in the collection. + * @throws UniqueConstraintException if the value of {@code _id} value clashes with the id * of another document in the collection. * @throws UniqueConstraintException if a value of the document is indexed and it * violates the unique constraint in the collection(if any). @@ -112,17 +114,17 @@ default WriteResult insert(Document document, Document... documents) { /** * Update documents in the collection. *

- * If the `filter` is `null`, it will update all documents in the collection. + * If the {@code filter} is {@code null}, it will update all documents in the collection. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update}. + *

* * @param filter the filter to apply to select documents from the collection. * @param update the modifications to apply. * @return the result of the update operation. - * @throws ValidationException if the `update` document is `null`. + * @throws ValidationException if the {@code update} document is {@code null}. */ default WriteResult update(Filter filter, Document update) { return update(filter, update, new UpdateOptions()); @@ -130,22 +132,22 @@ default WriteResult update(Filter filter, Document update) { /** * Updates document in the collection. Update operation can be customized - * with the help of `updateOptions`. + * with the help of {@code updateOptions}. *

- * If the `filter` is `null`, it will update all documents in the collection unless - * `justOnce` is set to `true` in `updateOptions`. + * If the {@code filter} is {@code null}, it will update all documents in the collection unless + * {@code justOnce} is set to {@code true} in {@code updateOptions}. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update} or {@link EventType#Insert}. + *

* * @param filter the filter to apply to select documents from the collection. * @param update the modifications to apply. * @param updateOptions the update options to customize the operation. * @return the result of the update operation. - * @throws ValidationException if the `update` document is `null`. - * @throws ValidationException if `updateOptions` is `null`. + * @throws ValidationException if the {@code update} document is {@code null}. + * @throws ValidationException if {@code updateOptions} is {@code null}. * @see UpdateOptions */ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions); @@ -153,12 +155,12 @@ default WriteResult update(Filter filter, Document update) { /** * Removes matching elements from the collection. *

- * If the `filter` is `null`, it will remove all objects from the collection. + * If the {@code filter} is {@code null}, it will remove all objects from the collection. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Remove}. + *

* * @param filter the filter to apply to select elements from collection. * @return the result of the remove operation. @@ -169,15 +171,15 @@ default WriteResult remove(Filter filter) { /** * Removes document from a collection. Remove operation can be customized by - * `removeOptions`. + * {@code removeOptions}. *

- * If the `filter` is `null`, it will remove all documents in the collection unless - * `justOnce` is set to `true` in `removeOptions`. + * If the {@code filter} is {@code null}, it will remove all documents in the collection unless + * {@code justOnce} is set to {@code true} in {@code removeOptions}. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Remove}. + *

* * @param filter the filter to apply to select documents from collection. * @param justOne indicates if only one element will be removed or all of them. @@ -190,7 +192,11 @@ default WriteResult remove(Filter filter) { * * @return a cursor to all documents in the collection. */ - DocumentCursor find(); + default DocumentCursor find() { + return find(new FindOptions()); + } + + DocumentCursor find(FindOptions findOptions); /** * Applies a filter on the collection and returns a cursor to the @@ -198,25 +204,29 @@ default WriteResult remove(Filter filter) { *

* See {@link Filter} for all available filters. *

- * [icon="{@docRoot}/note.png"] * NOTE: If there is an index on the value specified in the filter, this operation * will take advantage of the index. + *

* * @param filter the filter to apply to select documents from collection. * @return a cursor to all selected documents. - * @throws ValidationException if `filter` is null. + * @throws ValidationException if {@code filter} is null. * @see Filter * @see DocumentCursor#project(Document) */ - DocumentCursor find(Filter filter); + default DocumentCursor find(Filter filter) { + return find(filter, new FindOptions()); + } + + DocumentCursor find(Filter filter, FindOptions findOptions); /** * Gets a single element from the collection by its id. If no element - * is found, it will return `null`. + * is found, it will return {@code null}. * * @param nitriteId the nitrite id * @return the unique document associated with the nitrite id. - * @throws ValidationException if `nitriteId` is `null`. + * @throws ValidationException if `nitriteId` is {@code null}. */ Document getById(NitriteId nitriteId); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java index d7091542c..35bc2bc19 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java @@ -75,10 +75,10 @@ public BoundedIterator(final Iterator iterator, final long offset, this.offset = offset; this.size = size; pos = 0; - init(); + initialize(); } - private void init() { + private void initialize() { while (pos < offset && iterator.hasNext()) { iterator.next(); pos++; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java index a083c318f..94db9e238 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java @@ -24,11 +24,12 @@ import org.dizitart.no2.collection.events.CollectionEventInfo; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.NitriteMap; import java.util.Collection; @@ -57,35 +58,35 @@ public CollectionOperations(String collectionName, this.nitriteMap = nitriteMap; this.nitriteConfig = nitriteConfig; this.eventBus = eventBus; - init(); + initialize(); } - public void createIndex(String field, String indexType, boolean async) { - indexOperations.ensureIndex(field, indexType, async); + public void createIndex(Fields fields, String indexType, boolean async) { + indexOperations.createIndex(fields, indexType, async); } - public IndexEntry findIndex(String field) { - return indexOperations.findIndexEntry(field); + public IndexDescriptor findIndex(Fields fields) { + return indexOperations.findIndexDescriptor(fields); } - public void rebuildIndex(IndexEntry indexEntry, boolean async) { - indexOperations.rebuildIndex(indexEntry, async); + public void rebuildIndex(IndexDescriptor indexDescriptor, boolean async) { + indexOperations.buildIndex(indexDescriptor, async, true); } - public Collection listIndexes() { + public Collection listIndexes() { return indexOperations.listIndexes(); } - public boolean hasIndex(String field) { - return indexOperations.hasIndexEntry(field); + public boolean hasIndex(Fields fields) { + return indexOperations.hasIndexEntry(fields); } - public boolean isIndexing(String field) { - return indexOperations.isIndexing(field); + public boolean isIndexing(Fields fields) { + return indexOperations.isIndexing(fields); } - public void dropIndex(String field) { - indexOperations.dropIndex(field); + public void dropIndex(Fields fields) { + indexOperations.dropIndex(fields); } public void dropAllIndices() { @@ -143,15 +144,16 @@ public void close() { } } - private void init() { + private void initialize() { this.indexOperations = new IndexOperations(nitriteConfig, nitriteMap, eventBus); - this.readOperations = new ReadOperations(collectionName, nitriteConfig, nitriteMap, indexOperations); - this.writeOperations = new WriteOperations(indexOperations, readOperations, - nitriteMap, eventBus); + DocumentIndexWriter indexWriter = new DocumentIndexWriter(nitriteConfig, nitriteMap, indexOperations); + this.readOperations = new ReadOperations(collectionName, nitriteConfig, nitriteMap, indexWriter); + this.writeOperations = new WriteOperations(indexWriter, readOperations, nitriteMap, eventBus); } private void dropNitriteMap() { - NitriteMap catalogueMap = nitriteMap.getStore().openMap(COLLECTION_CATALOG, String.class, Document.class); + NitriteMap catalogueMap = nitriteMap.getStore().openMap(COLLECTION_CATALOG, + String.class, Document.class); for (Pair entry : catalogueMap.entries()) { String catalogue = entry.getFirst(); Document document = entry.getSecond(); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java index f6ca0a4de..71f96fad1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java @@ -33,13 +33,19 @@ */ class DocumentCursorImpl implements DocumentCursor { private final RecordStream> recordStream; + private FindOptions findOptions; DocumentCursorImpl(RecordStream> recordStream) { this.recordStream = recordStream; } @Override - public DocumentCursor sort(String field, SortOrder sortOrder, Collator collator, NullOrder nullOrder) { + public DocumentCursor sort(Fields fields, Collator collator, NullOrder nullOrder) { + findOptions = new FindOptions(); + findOptions.collator(collator); + findOptions.nullOrder(nullOrder); + findOptions.sortBy(fields); + return new DocumentCursorImpl(new SortedDocumentCursor(field, sortOrder, collator, nullOrder, recordStream)); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java new file mode 100644 index 000000000..434345d56 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2017-2020. Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.util.DocumentUtils; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndexer; +import org.dizitart.no2.store.IndexCatalog; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.Collection; + +/** + * @author Anindya Chatterjee + */ +class DocumentIndexWriter { + private final NitriteConfig nitriteConfig; + private final NitriteMap nitriteMap; + private final IndexOperations indexOperations; + private String collectionName; + private IndexCatalog indexCatalog; + + DocumentIndexWriter(NitriteConfig nitriteConfig, + NitriteMap nitriteMap, + IndexOperations indexOperations) { + this.nitriteConfig = nitriteConfig; + this.nitriteMap = nitriteMap; + this.indexOperations = indexOperations; + initialize(); + } + + void writeIndexEntry(Document document) { + Collection indexEntries = indexOperations.listIndexes(); + if (indexEntries != null) { + for (IndexDescriptor indexDescriptor : indexEntries) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + + writeIndexEntryInternal(indexDescriptor, document, nitriteIndexer); + } + } + } + + void removeIndexEntry(Document document) { + Collection indexEntries = indexOperations.listIndexes(); + if (indexEntries != null) { + for (IndexDescriptor indexDescriptor : indexEntries) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + + removeIndexEntryInternal(indexDescriptor, document, nitriteIndexer); + } + } + } + + void updateIndexEntry(Document oldDocument, Document newDocument) { + Collection indexEntries = indexOperations.listIndexes(); + if (indexEntries != null) { + for (IndexDescriptor indexDescriptor : indexEntries) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + +// Fields fields = indexDescriptor.getFields(); +// Object newValue = newDocument.get(field); +// Object oldValue = oldDocument.get(field); +// +// if (newValue == null) continue; +// if (newValue instanceof Comparable && oldValue instanceof Comparable) { +// if (((Comparable) newValue).compareTo(oldValue) == 0) continue; +// } +// +// validateDocumentIndexField(newValue, fields); +// +// if (indexCatalog.isDirtyIndex(collectionName, fields) +// && !getBuildFlag(field).get()) { +// // rebuild will also take care of the current document +// rebuildIndex(indexDescriptor, true); +// } else { +// String indexType = indexDescriptor.getIndexType(); +// NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); +// nitriteIndexer.updateIndex(nitriteMap, nitriteId, field, newValue, oldValue); +// } + + removeIndexEntryInternal(indexDescriptor, oldDocument, nitriteIndexer); + writeIndexEntryInternal(indexDescriptor, newDocument, nitriteIndexer); + } + } + } + + private void initialize() { + NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); + this.indexCatalog = nitriteStore.getIndexCatalog(); + this.collectionName = nitriteMap.getName(); + } + + private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, + NitriteIndexer nitriteIndexer) { + if (indexDescriptor != null) { + Fields fields = indexDescriptor.getFields(); + FieldValues fieldValues = DocumentUtils.getValues(document, fields); + +// Object fieldValue = document.get(field); +// validateDocumentIndexField(fieldValue, field); + + // if dirty index and currently indexing is not running, rebuild + if (indexCatalog.isDirtyIndex(collectionName, fields) + && !indexOperations.getBuildFlag(fields).get()) { + // rebuild will also take care of the current document + indexOperations.buildIndex(indexDescriptor, true); + } else if (nitriteIndexer != null) { + nitriteIndexer.writeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } + } + } + + private void removeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, + NitriteIndexer nitriteIndexer) { + if (indexDescriptor != null) { + Fields fields = indexDescriptor.getFields(); + FieldValues fieldValues = DocumentUtils.getValues(document, fields); + +// Object fieldValue = document.get(field); +// if (fieldValue == null) return; +// +// validateDocumentIndexField(fieldValue, field); + + // if dirty index and currently indexing is not running, rebuild + if (indexCatalog.isDirtyIndex(collectionName, fields) + && !indexOperations.getBuildFlag(fields).get()) { + // rebuild will also take care of the current document + indexOperations.buildIndex(indexDescriptor, true); + } else if (nitriteIndexer != null) { + nitriteIndexer.removeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } + } + } + +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java new file mode 100644 index 000000000..85da006a7 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java @@ -0,0 +1,21 @@ +package org.dizitart.no2.collection.operation; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.NullOrder; + +import java.text.Collator; + +/** + * @author Anindya Chatterjee + */ +@Data +@Accessors(fluent = true, chain = true) +public class FindOptions { + private Fields sortBy; + private Collator collator; + private NullOrder nullOrder; + private long skip; + private long limit; +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index aa51a8355..3f223eeaf 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.dizitart.no2.collection.operation; import org.dizitart.no2.NitriteConfig; @@ -22,23 +6,30 @@ import org.dizitart.no2.collection.events.CollectionEventInfo; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.events.EventType; -import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.concurrent.ThreadPoolManager; import org.dizitart.no2.common.event.EventBus; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.util.DocumentUtils; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.index.IndexEntry; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -import static org.dizitart.no2.common.util.ValidationUtils.validateDocumentIndexField; +import static org.dizitart.no2.common.concurrent.ThreadPoolManager.runAsync; /** * @author Anindya Chatterjee @@ -47,17 +38,19 @@ class IndexOperations implements AutoCloseable { private final NitriteConfig nitriteConfig; private final NitriteMap nitriteMap; private final EventBus, CollectionEventListener> eventBus; + private String collectionName; private IndexCatalog indexCatalog; - private Map indexBuildRegistry; + private Map indexBuildRegistry; private ExecutorService rebuildExecutor; + private Collection indexDescriptorCache; IndexOperations(NitriteConfig nitriteConfig, NitriteMap nitriteMap, EventBus, CollectionEventListener> eventBus) { this.nitriteConfig = nitriteConfig; this.nitriteMap = nitriteMap; this.eventBus = eventBus; - init(); + initialize(); } @Override @@ -67,230 +60,156 @@ public void close() { } } - void ensureIndex(String field, String indexType, boolean isAsync) { - IndexEntry indexEntry; - if (!hasIndexEntry(field)) { + void createIndex(Fields fields, String indexType, boolean isAsync) { + IndexDescriptor indexDescriptor; + if (!hasIndexEntry(fields)) { // if no index create index - indexEntry = indexCatalog.createIndexEntry(collectionName, field, indexType); + indexDescriptor = indexCatalog.createIndexDescriptor(collectionName, fields, indexType); } else { // if index already there throw - throw new IndexingException("index already exists on " + field); - } - - rebuildIndex(indexEntry, isAsync); - } - - void writeIndex(Document document, NitriteId nitriteId) { - Collection indexEntries = listIndexes(); - if (indexEntries != null) { - for (IndexEntry indexEntry : indexEntries) { - String field = indexEntry.getField(); - String indexType = indexEntry.getIndexType(); - Indexer indexer = findIndexer(indexType); - - writeIndexEntry(field, document, nitriteId, indexer, indexEntry); - } + throw new IndexingException("index already exists on " + fields); } - } - void removeIndex(Document document, NitriteId nitriteId) { - Collection indexEntries = listIndexes(); - if (indexEntries != null) { - for (IndexEntry indexEntry : indexEntries) { - String field = indexEntry.getField(); - String indexType = indexEntry.getIndexType(); - Indexer indexer = findIndexer(indexType); + buildIndex(indexDescriptor, isAsync, false); - removeIndexEntry(field, document, nitriteId, indexer, indexEntry); - } - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - void updateIndex(Document oldDocument, Document newDocument, NitriteId nitriteId) { - Collection indexEntries = listIndexes(); - if (indexEntries != null) { - for (IndexEntry indexEntry : indexEntries) { - String field = indexEntry.getField(); - Object newValue = newDocument.get(field); - Object oldValue = oldDocument.get(field); - - if (newValue == null) continue; - if (newValue instanceof Comparable && oldValue instanceof Comparable) { - if (((Comparable) newValue).compareTo(oldValue) == 0) continue; - } - - validateDocumentIndexField(newValue, field); - - if (indexCatalog.isDirtyIndex(collectionName, field) - && !getBuildFlag(field).get()) { - // rebuild will also take care of the current document - rebuildIndex(indexEntry, true); - } else { - String indexType = indexEntry.getIndexType(); - Indexer indexer = findIndexer(indexType); - indexer.updateIndex(nitriteMap, nitriteId, field, newValue, oldValue); - } - } - } + // update descriptor cache + updateIndexDescriptorCache(); } // call to this method is already synchronized, only one thread per field // can access it only if rebuild is already not running for that field - void rebuildIndex(IndexEntry indexEntry, boolean isAsync) { - final String field = indexEntry.getField(); - if (getBuildFlag(field).compareAndSet(false, true)) { + void buildIndex(IndexDescriptor indexDescriptor, boolean isAsync, boolean rebuild) { + final Fields fields = indexDescriptor.getFields(); + if (getBuildFlag(fields).compareAndSet(false, true)) { if (isAsync) { - rebuildExecutor.submit(() -> buildIndexInternal(field, indexEntry)); + rebuildExecutor.submit(() -> buildIndexInternal(indexDescriptor, rebuild)); } else { - buildIndexInternal(field, indexEntry); + buildIndexInternal(indexDescriptor, rebuild); } return; } - throw new IndexingException("indexing is already running on " + indexEntry.getField()); + throw new IndexingException("indexing is already running on " + indexDescriptor.getFields()); } - void dropIndex(String field) { - if (getBuildFlag(field).get()) { - throw new IndexingException("cannot drop index as indexing is running on " + field); + void dropIndex(Fields fields) { + if (getBuildFlag(fields).get()) { + throw new IndexingException("cannot drop index as indexing is running on " + fields); } - IndexEntry indexEntry = findIndexEntry(field); - if (indexEntry != null) { - String indexType = indexEntry.getIndexType(); - Indexer indexer = findIndexer(indexType); - indexer.dropIndex(nitriteMap, field); - indexCatalog.dropIndexEntry(collectionName, field); - indexBuildRegistry.remove(field); + IndexDescriptor indexDescriptor = findIndexDescriptor(fields); + if (indexDescriptor != null) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + nitriteIndexer.dropIndex(indexDescriptor, nitriteConfig); + + indexCatalog.dropIndexDescriptor(collectionName, fields); + indexBuildRegistry.remove(fields); + + // update descriptor cache + updateIndexDescriptorCache(); } else { - throw new IndexingException(field + " is not indexed"); + throw new IndexingException(fields + " is not indexed"); } } void dropAllIndices() { - for (Map.Entry entry : indexBuildRegistry.entrySet()) { + for (Map.Entry entry : indexBuildRegistry.entrySet()) { if (entry.getValue() != null && entry.getValue().get()) { throw new IndexingException("cannot drop index as indexing is running on " + entry.getKey()); } } - for (IndexEntry index : listIndexes()) { - dropIndex(index.getField()); + List> futures = new ArrayList<>(); + for (IndexDescriptor index : listIndexes()) { + futures.add(runAsync(() -> dropIndex(index.getFields()))); } + + for (Future future : futures) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new IndexingException("failed to drop all indices", e); + } + } + indexBuildRegistry.clear(); + + // update descriptor cache + updateIndexDescriptorCache(); } - boolean isIndexing(String field) { + boolean isIndexing(Fields field) { // has an index will only return true, if there is an index on // the value and indexing is not running on it - return indexCatalog.hasIndexEntry(collectionName, field) + return indexCatalog.hasIndexDescriptor(collectionName, field) && getBuildFlag(field).get(); } - boolean hasIndexEntry(String field) { - return indexCatalog.hasIndexEntry(collectionName, field); + boolean hasIndexEntry(Fields field) { + return indexCatalog.hasIndexDescriptor(collectionName, field); } - Collection listIndexes() { - return indexCatalog.listIndexEntries(collectionName); + Collection listIndexes() { + return indexDescriptorCache; } - IndexEntry findIndexEntry(String field) { - return indexCatalog.findIndexEntry(collectionName, field); + IndexDescriptor findIndexDescriptor(Fields field) { + return indexCatalog.findIndexDescriptor(collectionName, field); } - Indexer findIndexer(String indexType) { - Indexer indexer = nitriteConfig.findIndexer(indexType); - if (indexer != null) { - return indexer; - } - throw new IndexingException("no indexer found for index type " + indexType); + AtomicBoolean getBuildFlag(Fields field) { + AtomicBoolean flag = indexBuildRegistry.get(field); + if (flag != null) return flag; + + flag = new AtomicBoolean(false); + indexBuildRegistry.put(field, flag); + return flag; } - private void init() { + private void initialize() { NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); this.indexCatalog = nitriteStore.getIndexCatalog(); this.collectionName = nitriteMap.getName(); this.indexBuildRegistry = new ConcurrentHashMap<>(); this.rebuildExecutor = ThreadPoolManager.workerPool(); + updateIndexDescriptorCache(); + } + + private void updateIndexDescriptorCache() { + indexDescriptorCache = indexCatalog.listIndexDescriptors(collectionName); } - private void buildIndexInternal(final String field, final IndexEntry indexEntry) { + private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild) { + Fields fields = indexDescriptor.getFields(); try { - alert(EventType.IndexStart, field); + alert(EventType.IndexStart, fields); // first put dirty marker - indexCatalog.beginIndexing(collectionName, field); + indexCatalog.beginIndexing(collectionName, fields); - String indexType = indexEntry.getIndexType(); - Indexer indexer = findIndexer(indexType); + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + + // if rebuild drop existing index + if (rebuild) { + nitriteIndexer.dropIndex(indexDescriptor, nitriteConfig); + } - // re-create the index for the values of the field from document for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); - if (document.getFields().contains(field)) { - // remove old values if exists - removeIndexEntry(field, entry.getSecond(), entry.getFirst(), indexer, indexEntry); - - // re-create new entry - writeIndexEntry(field, entry.getSecond(), entry.getFirst(), indexer, indexEntry); - } + FieldValues fieldValues = DocumentUtils.getValues(document, indexDescriptor.getFields()); + nitriteIndexer.writeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); } } finally { // remove dirty marker to denote indexing completed successfully // if dirty marker is found in any index, it needs to be rebuild - indexCatalog.endIndexing(collectionName, field); - getBuildFlag(field).set(false); - alert(EventType.IndexEnd, field); - } - } - - private void writeIndexEntry(String field, Document document, NitriteId nitriteId, - Indexer indexer, IndexEntry indexEntry) { - if (indexEntry != null) { - Object fieldValue = document.get(field); - validateDocumentIndexField(fieldValue, field); - - // if dirty index and currently indexing is not running, rebuild - if (indexCatalog.isDirtyIndex(collectionName, field) - && !getBuildFlag(field).get()) { - // rebuild will also take care of the current document - rebuildIndex(indexEntry, true); - } else if (indexer != null) { - indexer.writeIndex(nitriteMap, nitriteId, field, fieldValue); - } + indexCatalog.endIndexing(collectionName, fields); + getBuildFlag(fields).set(false); + alert(EventType.IndexEnd, fields); } } - private void removeIndexEntry(String field, Document document, NitriteId nitriteId, - Indexer indexer, IndexEntry indexEntry) { - if (indexEntry != null) { - Object fieldValue = document.get(field); - if (fieldValue == null) return; - - validateDocumentIndexField(fieldValue, field); - - // if dirty index and currently indexing is not running, rebuild - if (indexCatalog.isDirtyIndex(collectionName, field) - && !getBuildFlag(field).get()) { - // rebuild will also take care of the current document - rebuildIndex(indexEntry, true); - } else if (indexer != null) { - indexer.removeIndex(nitriteMap, nitriteId, field, fieldValue); - } - } - } - - private AtomicBoolean getBuildFlag(String field) { - AtomicBoolean flag = indexBuildRegistry.get(field); - if (flag != null) return flag; - - flag = new AtomicBoolean(false); - indexBuildRegistry.put(field, flag); - return flag; - } - - private void alert(EventType eventType, String field) { - CollectionEventInfo eventInfo = new CollectionEventInfo<>(); + private void alert(EventType eventType, Fields field) { + CollectionEventInfo eventInfo = new CollectionEventInfo<>(); eventInfo.setItem(field); eventInfo.setTimestamp(System.currentTimeMillis()); eventInfo.setEventType(eventType); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java index e7eebbf65..9fc37b8ec 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java @@ -23,8 +23,8 @@ import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.filters.*; -import org.dizitart.no2.index.IndexEntry; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.store.NitriteMap; import java.util.*; @@ -38,31 +38,37 @@ class ReadOperations { private final String collectionName; private final NitriteConfig nitriteConfig; private final NitriteMap nitriteMap; - private final IndexOperations indexOperations; + private final DocumentIndexWriter documentIndexWriter; ReadOperations(String collectionName, NitriteConfig nitriteConfig, NitriteMap nitriteMap, - IndexOperations indexOperations) { + DocumentIndexWriter documentIndexWriter) { this.nitriteMap = nitriteMap; this.nitriteConfig = nitriteConfig; this.collectionName = collectionName; - this.indexOperations = indexOperations; + this.documentIndexWriter = documentIndexWriter; } - public DocumentCursor find() { - RecordStream> recordStream = nitriteMap.entries(); + public DocumentCursor find(FindOptions findOptions) { + RecordStream> recordStream = findSuitableStream(null, findOptions); return new DocumentCursorImpl(recordStream); } - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { if (filter == null || filter == Filter.ALL) { - return find(); + return find(findOptions); } + // get all indices for this collection + // find the suitable index (prefix included) + // find the index map + // supply indexmap, collectionmap to filter + + prepareFilter(filter); - RecordStream> recordStream = findSuitableStream(filter); + RecordStream> recordStream = findSuitableStream(filter, findOptions); return new DocumentCursorImpl(recordStream); } @@ -106,12 +112,12 @@ private void prepareLogicalFilter(LogicalFilter logicalFilter) { private void prepareIndexedFilter(IndexAwareFilter indexAwareFilter) { String field = indexAwareFilter.getField(); - IndexEntry indexEntry = indexOperations.findIndexEntry(field); - if (indexEntry != null) { - String indexType = indexEntry.getIndexType(); - Indexer indexer = indexOperations.findIndexer(indexType); - if (indexer != null) { - indexAwareFilter.setIndexer(indexer); + IndexDescriptor indexDescriptor = documentIndexWriter.findIndexDescriptor(field); + if (indexDescriptor != null) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = documentIndexWriter.findIndexer(indexType); + if (nitriteIndexer != null) { + indexAwareFilter.setNitriteIndexer(nitriteIndexer); indexAwareFilter.setIsFieldIndexed(true); } } else { @@ -122,12 +128,14 @@ private void prepareIndexedFilter(IndexAwareFilter indexAwareFilter) { } } - private RecordStream> findSuitableStream(Filter filter) { + private RecordStream> findSuitableStream(Filter filter, FindOptions findOptions) { if (filter instanceof AndFilter) { AndFilter andFilter = (AndFilter) filter; Filter lhs = andFilter.getLhs(); Filter rhs = andFilter.getRhs(); + // TODO: check if compound index is supported + if (lhs instanceof IndexAwareFilter && ((IndexAwareFilter) lhs).getIsFieldIndexed()) { // Indexed AND Filter => IndexScan (LHS) -> Filter (RHS) @@ -195,6 +203,8 @@ private RecordStream> getUnionStream( } private RecordStream> getIndexedStream(IndexAwareFilter indexAwareFilter) { + // TODO: check if prefix of compound index is possible + return new IndexedStream(indexAwareFilter, nitriteMap); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java index 3f3acf7f9..04bec304d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java @@ -74,7 +74,7 @@ public SortedDocumentIterator(String field, this.collator = collator; this.nullOrder = nullOrder; this.iterator = iterator; - init(); + initialize(); } @Override @@ -87,7 +87,7 @@ public Pair next() { return sortedIterator.next(); } - private void init() { + private void initialize() { NavigableMap>> sortedMap; if (collator != null) { sortedMap = new TreeMap<>(collator); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java new file mode 100644 index 000000000..26e3f4127 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java @@ -0,0 +1,11 @@ +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.common.RecordStream; + +/** + * + * @author Anindya Chatterjee + */ +public interface StreamGenerator { + RecordStream generate(FindOptions options); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java index b03b3dd01..866fa689b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java @@ -26,6 +26,7 @@ import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; +import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.store.NitriteMap; @@ -40,16 +41,16 @@ */ @Slf4j class WriteOperations { - private final IndexOperations indexOperations; + private final DocumentIndexWriter documentIndexWriter; private final ReadOperations readOperations; private final EventBus, CollectionEventListener> eventBus; private final NitriteMap nitriteMap; - WriteOperations(IndexOperations indexOperations, + WriteOperations(DocumentIndexWriter documentIndexWriter, ReadOperations readOperations, NitriteMap nitriteMap, EventBus, CollectionEventListener> eventBus) { - this.indexOperations = indexOperations; + this.documentIndexWriter = documentIndexWriter; this.readOperations = readOperations; this.eventBus = eventBus; this.nitriteMap = nitriteMap; @@ -60,25 +61,25 @@ WriteResult insert(Document... documents) { log.debug("Total {} document(s) to be inserted in {}", documents.length, nitriteMap.getName()); for (Document document : documents) { - Document item = document.clone(); - NitriteId nitriteId = item.getId(); - String source = item.getSource(); + Document newDoc = document.clone(); + NitriteId nitriteId = newDoc.getId(); + String source = newDoc.getSource(); long time = System.currentTimeMillis(); - if (!REPLICATOR.contentEquals(item.getSource())) { + if (!REPLICATOR.contentEquals(newDoc.getSource())) { // if replicator is not inserting the document that means // it is being inserted by user, so update metadata - item.remove(DOC_SOURCE); - item.put(DOC_REVISION, 1); - item.put(DOC_MODIFIED, time); + newDoc.remove(DOC_SOURCE); + newDoc.put(DOC_REVISION, 1); + newDoc.put(DOC_MODIFIED, time); } else { // if replicator is inserting the document, remove the source // but keep the revision intact - item.remove(DOC_SOURCE); + newDoc.remove(DOC_SOURCE); } - log.debug("Inserting document {} in {}", item, nitriteMap.getName()); - Document already = nitriteMap.putIfAbsent(nitriteId, item); + log.debug("Inserting document {} in {}", newDoc, nitriteMap.getName()); + Document already = nitriteMap.putIfAbsent(nitriteId, newDoc); if (already != null) { log.warn("Another document {} already exists with same id {}", already, nitriteId); @@ -87,18 +88,18 @@ WriteResult insert(Document... documents) { "entry with same id already exists in " + nitriteMap.getName()); } else { try { - indexOperations.writeIndex(item, nitriteId); - } catch (UniqueConstraintException uce) { - log.error("Unique constraint violated for the document " - + document + " in " + nitriteMap.getName(), uce); + documentIndexWriter.writeIndexEntry(newDoc); + } catch (UniqueConstraintException | IndexingException e) { + log.error("Index operation has failed during insertion for the document " + + document + " in " + nitriteMap.getName(), e); nitriteMap.remove(nitriteId); - throw uce; + throw e; } } nitriteIds.add(nitriteId); - Document eventDoc = item.clone(); + Document eventDoc = newDoc.clone(); CollectionEventInfo eventInfo = new CollectionEventInfo<>(); eventInfo.setItem(eventDoc); eventInfo.setTimestamp(time); @@ -171,7 +172,15 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) writeResult.addToList(nitriteId); } - indexOperations.updateIndex(oldDocument, item, nitriteId); + try { + documentIndexWriter.updateIndexEntry(oldDocument, item); + } catch (UniqueConstraintException | IndexingException e) { + log.error("Index operation failed during update, reverting changes for the document " + + oldDocument + " in " + nitriteMap.getName(), e); + nitriteMap.put(nitriteId, oldDocument); + documentIndexWriter.updateIndexEntry(item, oldDocument); + throw e; + } CollectionEventInfo eventInfo = new CollectionEventInfo<>(); Document eventDoc = item.clone(); @@ -238,7 +247,7 @@ WriteResult remove(Filter filter, boolean justOnce) { return result; } - public WriteResult remove(Document document) { + WriteResult remove(Document document) { WriteResultImpl result = new WriteResultImpl(); CollectionEventInfo eventInfo = removeAndCreateEvent(document, result); if (eventInfo != null) { @@ -253,7 +262,7 @@ private CollectionEventInfo removeAndCreateEvent(Document document, Wr document = nitriteMap.remove(nitriteId); if (document != null) { long time = System.currentTimeMillis(); - indexOperations.removeIndex(document, nitriteId); + documentIndexWriter.removeIndexEntry(document); writeResult.addToList(nitriteId); int rev = document.getRevision(); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/NullEntry.java b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java similarity index 54% rename from nitrite/src/main/java/org/dizitart/no2/common/NullEntry.java rename to nitrite/src/main/java/org/dizitart/no2/common/DBNull.java index ac56c9079..1e2d95b7a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/NullEntry.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java @@ -7,19 +7,19 @@ * * @author Anindya Chatterjee */ -public class NullEntry implements Comparable, Serializable { +public class DBNull implements Comparable, Serializable { private static final long serialVersionUID = 1598819770L; - private static final NullEntry instance = new NullEntry(); + private static final DBNull instance = new DBNull(); - private NullEntry() { + private DBNull() { } @Override - public int compareTo(NullEntry o) { + public int compareTo(DBNull o) { return 0; } - public static NullEntry getInstance() { + public static DBNull getInstance() { return instance; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java new file mode 100644 index 000000000..0c6598041 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -0,0 +1,46 @@ +package org.dizitart.no2.common; + +import lombok.Data; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.ValidationException; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Anindya Chatterjee + */ +@Data +public class FieldValues { + private NitriteId nitriteId; + private Fields fields; + private List> values; + + public FieldValues() { + values = new ArrayList<>(); + } + + public Object get(String field) { + if (fields.getFieldNames().contains(field)) { + for (Pair value : values) { + if (value.getFirst().equals(field)) { + return value.getSecond(); + } + } + } + return null; + } + + public Object getFirstValue() { + return getValueAt(0); + } + + public Object getValueAt(int index) { + if (index > values.size() - 1) { + throw new ValidationException("invalid index provided"); + } + + return values.get(index).getSecond(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java new file mode 100644 index 000000000..f472ef254 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -0,0 +1,127 @@ +package org.dizitart.no2.common; + +import lombok.Data; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.util.StringUtils; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; +import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; + +/** + * @author Anindya Chatterjee + */ +@Data +public class Fields implements Comparable, Serializable { + private static final long serialVersionUID = 1601646404L; + + // order of the given fields matter + private List> fieldList; + private transient List fieldNames; + + private Fields() { + fieldList = new ArrayList<>(); + } + + public static Fields single(String field) { + Fields fields = new Fields(); + fields.fieldList.add(new Pair<>(field, SortOrder.Ascending)); + return fields; + } + + @SafeVarargs + public static Fields multiple(Pair... fields) { + notNull(fields, "fields cannot be null"); + notEmpty(fields, "fields cannot be empty"); + + Fields f = new Fields(); + f.fieldList.addAll(Arrays.asList(fields)); + return f; + } + + public List getFieldNames() { + if (fieldNames != null) { + return fieldNames; + } + + fieldNames = new ArrayList<>(); + for (Pair pair : fieldList) { + fieldNames.add(pair.getFirst()); + } + return fieldNames; + } + + public Pair getFirstKey() { + return fieldList.get(0); + } + + public SortOrder getSortOrder(String fieldName) { + for (Pair pair : fieldList) { + if (pair.getFirst().equals(fieldName)) { + return pair.getSecond(); + } + } + return null; + } + + public String getEncodedName() { + return StringUtils.join(INTERNAL_NAME_SEPARATOR, getFieldNames()); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("["); + int count = 0; + for (Pair field : fieldList) { + count++; + stringBuilder.append("{") + .append(field.getFirst()) + .append(": ") + .append(field.getSecond()) + .append("}"); + + if (count != fieldList.size()) { + stringBuilder.append(", "); + } + } + stringBuilder.append("]"); + return stringBuilder.toString(); + } + + @Override + public int compareTo(Fields other) { + if (other == null) return 1; + int fieldsSize = getFieldNames().size(); + int otherFieldsSize = other.getFieldNames().size(); + int result = Integer.compare(fieldsSize, otherFieldsSize); + if (result == 0) { + String[] keys = getFieldNames().toArray(new String[0]); + String[] otherKeys = other.getFieldNames().toArray(new String[0]); + for (int i = 0; i < keys.length; i++) { + int cmp = keys[i].compareTo(otherKeys[i]); + if (cmp != 0) { + return cmp; + } + } + } + + return result; + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + stream.writeObject(fieldList); + } + + @SuppressWarnings("unchecked") + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + fieldList = (List>) stream.readObject(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java index 205d4d52b..f0413719e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java @@ -22,7 +22,7 @@ import org.dizitart.no2.collection.events.EventAware; import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.collection.meta.MetadataAware; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.ObjectRepository; @@ -31,6 +31,9 @@ import java.io.Closeable; import java.util.Collection; +import static org.dizitart.no2.common.Fields.multiple; +import static org.dizitart.no2.common.Fields.single; + /** * The interface Persistent collection. * @@ -42,73 +45,146 @@ */ public interface PersistentCollection extends EventAware, MetadataAware, Closeable { /** - * Creates an index on `value`, if not already exists. - * If `indexOptions` is `null`, it will use default options. + * Creates an index on the {@code field}, if not already exists. + * If {@code indexOptions} is {@code null}, it will use default options. *

- * The default indexing option is - *

- * - `indexOptions.setAsync(false);` - * - `indexOptions.setIndexType(IndexType.Unique);` + * The default indexing option is - + * + *

    + *
  • {@code indexOptions.setAsync(false);}
  • + *
  • {@code indexOptions.setIndexType(IndexType.Unique);}
  • + *
+ * *

- * [icon="{@docRoot}/note.png"] - * [NOTE] - * ==== - * - '_id' value of the document is always indexed. But full text - * indexing is not supported on '_id' value. - * - Compound index is not supported. - * - Indexing on arrays or collection is not supported - * - Indexing on non-comparable value is not supported - * ==== - * - * @param field the value to be indexed. + * NOTE: + *

    + *
  • _id value of the document is always indexed. But full-text indexing is not supported on _id value.
  • + *
  • Indexing on non-comparable value is not supported.
  • + *
+ *

+ * + * @param field the field to be indexed. * @param indexOptions index options. - * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on `value`. + * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on the field. * @see org.dizitart.no2.index.IndexOptions * @see IndexType */ - void createIndex(String field, IndexOptions indexOptions); + default void createIndex(String field, IndexOptions indexOptions) { + createIndex(single(field), indexOptions); + } /** - * Rebuilds index on `field` if it exists. + * Creates an index on {@code fields}, if not already exists. + * If {@code indexOptions} is {@code null}, it will use default options. + *

+ *

+ * The default indexing option is - * - * @param field the value to be indexed. - * @param isAsync if set to `true`, the indexing will run in background; otherwise, in foreground. - * @throws org.dizitart.no2.exceptions.IndexingException if the `field` is not indexed. + *

    + *
  • {@code indexOptions.setAsync(false);}
  • + *
  • {@code indexOptions.setIndexType(IndexType.Unique);}
  • + *
+ * + *

+ * NOTE: + *

    + *
  • _id value of the document is always indexed. But full-text indexing is not supported on _id value.
  • + *
  • Indexing on non-comparable value is not supported.
  • + *
+ *

+ * + * @param fields the fields + * @param indexOptions the index options + * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on the fields. + * @see org.dizitart.no2.index.IndexOptions + * @see IndexType */ - void rebuildIndex(String field, boolean isAsync); + void createIndex(Fields fields, IndexOptions indexOptions); + + /** + * Rebuilds index on the {@code field} if it exists. + * + * @param field the field to be indexed. + * @param isAsync if set to {@code true}, the indexing will run in background; otherwise, in foreground. + * @throws org.dizitart.no2.exceptions.IndexingException if the {@code field} is not indexed. + */ + default void rebuildIndex(String field, boolean isAsync) { + rebuildIndex(single(field), isAsync); + } + + /** + * Rebuilds index on {@code fields} if it exists. + * + * @param fields the fields to be indexed. + * @param isAsync if set to {@code true}, the indexing will run in background; otherwise, in foreground. + * @throws org.dizitart.no2.exceptions.IndexingException if the {@code fields} is not indexed. + */ + void rebuildIndex(Fields fields, boolean isAsync); /** * Gets a set of all indices in the collection. * * @return a set of all indices. - * @see IndexEntry + * @see IndexDescriptor */ - Collection listIndices(); + Collection listIndices(); /** - * Checks if a value is already indexed or not. + * Checks if the {@code field} is already indexed or not. * - * @param field the value to check. - * @return `true` if the `value` is indexed; otherwise, `false`. + * @param field the field to check. + * @return {@code true} if the {@code field} is indexed; otherwise, {@code false}. */ - boolean hasIndex(String field); + default boolean hasIndex(String field) { + return hasIndex(single(field)); + } /** - * Checks if indexing operation is currently ongoing for a `field`. + * Checks if the fields are already indexed or not. * - * @param field the value to check. - * @return `true` if indexing is currently running; otherwise, `false`. + * @param fields the fields to check + * @return {@code true} if the {@code fields} are indexed; otherwise, {@code false}. */ - boolean isIndexing(String field); + boolean hasIndex(Fields fields); /** - * Drops the index on a `field`. + * Checks if indexing operation is currently ongoing for the {@code field}. * - * @param field the index of the `field` to drop. - * @throws org.dizitart.no2.exceptions.IndexingException if indexing is currently running on the `field`. - * @throws org.dizitart.no2.exceptions.IndexingException if the `field` is not indexed. + * @param field the field to check. + * @return {@code true} if indexing is currently running; otherwise, {@code false}. */ - void dropIndex(String field); + default boolean isIndexing(String field) { + return isIndexing(single(field)); + } + + /** + * Checks if indexing operation is currently ongoing for the {@code fields}. + * + * @param fields the fields to check. + * @return {@code true} if indexing is currently running; otherwise, {@code false}. + */ + boolean isIndexing(Fields fields); + + /** + * Drops the index on the {@code field}. + * + * @param field the index of the {@code field} to drop. + * @throws org.dizitart.no2.exceptions.IndexingException if indexing is currently running on the {@code field}. + * @throws org.dizitart.no2.exceptions.IndexingException if the {@code field} is not indexed. + */ + default void dropIndex(String field) { + dropIndex(multiple(field)); + } + + /** + * Drops the index on the {@code fields}. + * + * @param fields the index of the {@code fields} to drop. + * @throws org.dizitart.no2.exceptions.IndexingException if indexing is currently running on the {@code fields}. + * @throws org.dizitart.no2.exceptions.IndexingException if the {@code fields} is not indexed. + */ + void dropIndex(Fields fields); /** * Drops all indices from the collection. @@ -118,27 +194,27 @@ public interface PersistentCollection extends EventAware, MetadataAware, Clos void dropAllIndices(); /** - * Inserts elements into this collection. If the element has an '_id' field, + * Inserts elements into this collection. If the element has an _id field, * then the value will be used as an unique key to identify the element - * in the collection. If the element does not have any '_id' field, - * then nitrite will generate a new {@link org.dizitart.no2.collection.NitriteId} and will add it to the '_id' + * in the collection. If the element does not have any _id field, + * then nitrite will generate a new {@link org.dizitart.no2.collection.NitriteId} and will add it to the _id * field. *

* If any of the value is already indexed in the collection, then after insertion the * index will also be updated. *

- * [icon="{@docRoot}/note.png"] - * NOTE: This operations will notify all {@link CollectionEventListener} - * instances registered to this collection with change type - * {@link EventType#Insert}. + *

+ * NOTE: This operations will notify all {@link CollectionEventListener} + * instances registered to this collection with change type {@link EventType#Insert}. + *

* * @param elements an array of element for batch insertion. * @return the result of the write operation. - * @throws org.dizitart.no2.exceptions.ValidationException if `elements` is `null`. - * @throws org.dizitart.no2.exceptions.InvalidIdException if the '_id' field's value contains `null`. - * @throws org.dizitart.no2.exceptions.InvalidIdException if the '_id' field's value contains non comparable type, i.e. type that does not implement {@link Comparable}. - * @throws org.dizitart.no2.exceptions.InvalidIdException if the '_id' field contains value which is not of the same java type as of other element's '_id' field value in the collection. - * @throws org.dizitart.no2.exceptions.UniqueConstraintException if the value of '_id' field clashes with the '_id' field of another element in the repository. + * @throws org.dizitart.no2.exceptions.ValidationException if elements is null. + * @throws org.dizitart.no2.exceptions.InvalidIdException if the _id field's value contains {@code null}. + * @throws org.dizitart.no2.exceptions.InvalidIdException if the _id field's value contains non comparable type, i.e. type that does not implement {@link Comparable}. + * @throws org.dizitart.no2.exceptions.InvalidIdException if the _id field contains value which is not of the same java type as of other element's _id field value in the collection. + * @throws org.dizitart.no2.exceptions.UniqueConstraintException if the value of _id field clashes with the _id field of another element in the repository. * @throws org.dizitart.no2.exceptions.UniqueConstraintException if a value of the element is indexed and it violates the unique constraint in the collection(if any). * @see NitriteId * @see WriteResult @@ -146,61 +222,59 @@ public interface PersistentCollection extends EventAware, MetadataAware, Clos WriteResult insert(T[] elements); /** - * Updates `element` in the collection. Specified `element` must have an id. + * Updates the {@code element} in the collection. Specified {@code element} must have an id. *

- * [icon="{@docRoot}/note.png"] - * NOTE: This operations will notify all {@link CollectionEventListener} - * instances registered to this collection with change type - * {@link EventType#Update}. + * NOTE: This operations will notify all {@link CollectionEventListener} + * instances registered to this collection with change type + * {@link EventType#Update}. + *

* * @param element the element to update. * @return the result of the update operation. - * @throws org.dizitart.no2.exceptions.ValidationException if the `element` is `null`. - * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the `element` does not have any id. + * @throws org.dizitart.no2.exceptions.ValidationException if the element is {@code null}. + * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the element does not have any id. */ default WriteResult update(T element) { return update(element, false); } /** - * Updates `element` in the collection. Specified `element` must have an id. - * If the `element` is not found in the collection, it will be inserted only if `upsert` - * is set to `true`. + * Updates {@code element} in the collection. Specified {@code element} must have an id. + * If the {@code element} is not found in the collection, it will be inserted only if {@code insertIfAbsent} + * is set to {@code true}. *

- * [icon="{@docRoot}/note.png"] + * * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type - * {@link EventType#Update} - * or {@link EventType#Insert}. + * {@link EventType#Update} or {@link EventType#Insert}. + *

* * @param element the element to update. - * @param insertIfAbsent if set to `true`, `element` will be inserted if not found. + * @param insertIfAbsent if set to {@code true}, {@code element} will be inserted if not found. * @return the result of the update operation. - * @throws org.dizitart.no2.exceptions.ValidationException if the `element` is `null`. - * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the `element` - * does not have any id field. + * @throws org.dizitart.no2.exceptions.ValidationException if the {@code element} is {@code null}. + * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the {@code element} does not have any id field. */ WriteResult update(T element, boolean insertIfAbsent); /** - * Deletes the `element` from the collection. The `element` must have an id. + * Deletes the {@code element} from the collection. The {@code element} must have an id. + * *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Remove}. + *

* * @param element the element * @return the result of the remove operation. - * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the `element` does not - * have any id field. + * @throws org.dizitart.no2.exceptions.NotIdentifiableException if the {@code element} does not have any id field. */ WriteResult remove(T element); /** * Removes all element from the collection. - * - * */ + */ void clear(); /** @@ -213,14 +287,14 @@ default WriteResult update(T element) { void drop(); /** - * Returns `true` if the collection is dropped; otherwise, `false`. + * Returns {@code true} if the collection is dropped; otherwise, {@code false}. * * @return a boolean value indicating if the collection has been dropped or not. */ boolean isDropped(); /** - * Returns `true` if the collection is open; otherwise, `false`. + * Returns {@code true} if the collection is open; otherwise, {@code false}. * * @return a boolean value indicating if the collection has been closed or not. */ diff --git a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java index a3921546b..7afa2db25 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import static org.dizitart.no2.common.Constants.DAEMON_THREAD_NAME; @@ -81,8 +82,8 @@ public Thread createThread(Runnable runnable) { }; } - public static void runAsync(Runnable runnable) { - commonPool.submit(runnable); + public static Future runAsync(Runnable runnable) { + return commonPool.submit(runnable); } public static void shutdownThreadPools() { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java index 17648771f..ad2cd8f62 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java @@ -17,10 +17,13 @@ package org.dizitart.no2.common.util; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.mapper.NitriteMapper; +import java.util.ArrayList; import java.util.Objects; import static org.dizitart.no2.common.util.ObjectUtils.newInstance; @@ -87,6 +90,20 @@ public static boolean isSimilar(Document document, Document other, String... fie return result; } + public static FieldValues getValues(Document document, Fields fields) { + FieldValues fieldValues = new FieldValues(); + fieldValues.setNitriteId(document.getId()); + fieldValues.setFields(fields); + fieldValues.setValues(new ArrayList<>()); + + for (String field : fields.getFieldNames()) { + Object value = document.get(field); + fieldValues.getValues().add(new Pair<>(field, value)); + } + + return fieldValues; + } + private static Document removeValues(Document document) { if (document == null) return null; for (Pair entry : document) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java index f106d68f7..d8879b272 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java @@ -16,6 +16,8 @@ package org.dizitart.no2.common.util; +import org.dizitart.no2.common.UnknownType; + import java.lang.reflect.Array; import java.util.*; @@ -115,6 +117,14 @@ public static List listOf(T... items) { return Collections.emptyList(); } + @SafeVarargs + public static Set setOf(T... items) { + if (items != null) { + return new HashSet<>(Arrays.asList(items)); + } + return Collections.emptySet(); + } + public static long size(Iterable iterable) { if (iterable instanceof Collection) { return ((Collection) iterable).size(); @@ -127,6 +137,15 @@ public static long size(Iterable iterable) { return count; } + public static Class getElementType(Iterable iterable) { + if (iterable == null) return UnknownType.class; + Iterator iterator = iterable.iterator(); + if (iterator.hasNext()) { + return iterator.next().getClass(); + } + return UnknownType.class; + } + @SuppressWarnings({"unchecked", "rawtypes"}) static Object[] toArray(Iterable iterable) { if (iterable instanceof Collection) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/StringUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/StringUtils.java index 607a8786e..0659cdf00 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/StringUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/StringUtils.java @@ -16,6 +16,7 @@ package org.dizitart.no2.common.util; +import java.util.Arrays; import java.util.StringTokenizer; /** @@ -58,6 +59,10 @@ public static boolean isNullOrEmpty(CharSequence value) { * @since 4.0.0 */ public static String join(String separator, String[] strings) { + return join(separator, Arrays.asList(strings)); + } + + public static String join(String separator, Iterable strings) { StringBuilder sb = new StringBuilder(); int end = 0; for (String s : strings) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java index ca3a4f17d..9a2a51e46 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java @@ -21,6 +21,7 @@ import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; +import java.util.Arrays; import java.util.Collection; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; @@ -72,6 +73,12 @@ public static void notEmpty(Collection value, String message) { } } + public static void notEmpty(T[] value, String message) { + if (value.length == 0) { + throw new ValidationException(message); + } + } + /** * Validates if an object is `null`. * diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java index ec6807b04..12880f5e9 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java @@ -45,10 +45,10 @@ protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { if (getValue() == null || getValue() instanceof Comparable) { - if (getIndexer() instanceof ComparableIndexer) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else if (getIndexer() instanceof TextIndexer && getValue() instanceof String) { + } else if (getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String) { // eq filter is not compatible with TextIndexer setIsFieldIndexed(false); } else { @@ -83,7 +83,7 @@ public boolean apply(Pair element) { @Override public void setIsFieldIndexed(Boolean isFieldIndexed) { - if (!(getIndexer() instanceof TextIndexer && getValue() instanceof String)) { + if (!(getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String)) { super.setIsFieldIndexed(isFieldIndexed); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java index 73c5a8802..ab58d2440 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java @@ -41,8 +41,8 @@ class GreaterEqualFilter extends ComparisonFilter { protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findGreaterEqual(getCollectionName(), getField(), (Comparable) getValue()); } else { if (getValue() instanceof Comparable) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java index 58681e9b4..f4b4e5ff3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java @@ -41,8 +41,8 @@ protected GreaterThanFilter(String field, Comparable value) { protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findGreaterThan(getCollectionName(), getField(), (Comparable) getValue()); } else { if (getValue() instanceof Comparable) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java index c450e9bee..a46cdd211 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java @@ -49,8 +49,8 @@ protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && comparableSet != null) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && comparableSet != null) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findIn(getCollectionName(), getField(), comparableSet); } else { if (comparableSet != null && !comparableSet.isEmpty()) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java index 195291566..c7f051ba2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java @@ -22,7 +22,7 @@ import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.store.NitriteMap; import java.util.Set; @@ -40,7 +40,7 @@ public abstract class IndexAwareFilter extends FieldBasedFilter { private Boolean onIdField = false; @Getter @Setter - private Indexer indexer; + private NitriteIndexer nitriteIndexer; private Set indexedIdSet; private Set idSet; diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java new file mode 100644 index 000000000..75f9c97a2 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java @@ -0,0 +1,28 @@ +package org.dizitart.no2.filters; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.index.ComparableIndexer; +import org.dizitart.no2.store.NitriteMap; + +/** + * @author Anindya Chatterjee + */ +public class IndexedQuerySupport { + private ComparableIndexer comparableIndexer; + + public IndexedQuerySupport(ComparableIndexer comparableIndexer) { + this.comparableIndexer = comparableIndexer; + } + + public RecordStream findByFilter(NitriteMap indexMap, NitriteFilter filter, NitriteConfig nitriteConfig) { + + return null; + } + + public FieldValues calculateFieldValues(NitriteFilter filter) { + + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java index 8c5a98369..7b5af2aa6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java @@ -41,8 +41,8 @@ class LesserEqualFilter extends ComparisonFilter { protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findLesserEqual(getCollectionName(), getField(), (Comparable) getValue()); } else { if (getValue() instanceof Comparable) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java index d3ad9ec68..f99397e92 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java @@ -41,8 +41,8 @@ class LesserThanFilter extends ComparisonFilter { protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findLesserThan(getCollectionName(), getField(), (Comparable) getValue()); } else { if (getValue() instanceof Comparable) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java index d2cd71f8a..a5d57ab77 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java @@ -29,10 +29,10 @@ protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { if (getValue() == null || getValue() instanceof Comparable) { - if (getIndexer() instanceof ComparableIndexer) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findNotEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else if (getIndexer() instanceof TextIndexer && getValue() instanceof String) { + } else if (getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String) { // notEq filter is not compatible with TextIndexer setIsFieldIndexed(false); } else { @@ -67,7 +67,7 @@ public boolean apply(Pair element) { @Override public void setIsFieldIndexed(Boolean isFieldIndexed) { - if (!(getIndexer() instanceof TextIndexer && getValue() instanceof String)) { + if (!(getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String)) { super.setIsFieldIndexed(isFieldIndexed); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java index 5cd107c1f..1c80c7eb7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java @@ -49,8 +49,8 @@ protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof ComparableIndexer && comparableSet != null) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getIndexer(); + if (getNitriteIndexer() instanceof ComparableIndexer && comparableSet != null) { + ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); idSet = comparableIndexer.findNotIn(getCollectionName(), getField(), comparableSet); } else { if (comparableSet != null && !comparableSet.isEmpty()) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java new file mode 100644 index 000000000..8a4ef3553 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -0,0 +1,61 @@ +package org.dizitart.no2.filters; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.collection.operation.FindOptions; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.index.BaseNitriteIndexer; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.store.NitriteMap; + +/** + * @author Anindya Chatterjee + */ +public class QueryOptimizer { + private BaseNitriteIndexer nitriteIndexer; + private NitriteConfig nitriteConfig; + + public RecordStream> findOptimizedStream(Filter filter, + FindOptions findOptions) { + if (filter == null) { + return findOptimizedStreamByOption(findOptions); + } + + // 1. AND + // 2. OR (AND) + // 3. Union stream (for OR call recursively this method) + + if (filter instanceof AndFilter) { + AndFilter andFilter = (AndFilter) filter; + FieldValues fieldValues = decompose(andFilter); + IndexDescriptor descriptor = findSuitableIndex(fieldValues); + + if (nitriteIndexer.isCompoundIndex(descriptor)) { + NitriteMap indexMap = nitriteIndexer.getCompoundIndexMap(descriptor, + nitriteConfig.getNitriteStore(), fieldValues.getFirstValue().getClass()); + } + } + } + + private RecordStream> findOptimizedStreamByOption(FindOptions findOptions) { + return null; + } + + private FieldValues decompose(AndFilter filter) { + FieldValues fieldValues = new FieldValues(); + + Filter lhs = filter.getLhs(); + Filter rhs = filter.getRhs(); + + if (lhs instanceof ComparisonFilter) { + + } + } + + private IndexDescriptor findSuitableIndex(FieldValues fieldValues) { + return null; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java index 2effd4ec8..bc5186bd3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java @@ -38,8 +38,8 @@ class TextFilter extends StringFilter { protected Set findIndexedIdSet() { Set idSet = new LinkedHashSet<>(); if (getIsFieldIndexed()) { - if (getIndexer() instanceof TextIndexer) { - TextIndexer textIndexer = (TextIndexer) getIndexer(); + if (getNitriteIndexer() instanceof TextIndexer) { + TextIndexer textIndexer = (TextIndexer) getNitriteIndexer(); idSet = textIndexer.findText(getCollectionName(), getField(), getStringValue()); } else { throw new FilterException(getField() + " is not full-text indexed"); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java new file mode 100644 index 000000000..6f5ea5768 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java @@ -0,0 +1,62 @@ +package org.dizitart.no2.index; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.UnknownType; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import static org.dizitart.no2.common.Constants.INDEX_PREFIX; +import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; + +/** + * @author Anindya Chatterjee + */ +public abstract class BaseNitriteIndexer implements NitriteIndexer { + + @Override + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + NitriteMap indexMap; + if (isCompoundIndex(indexDescriptor)) { + indexMap = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); + } else { + indexMap = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); + } + indexMap.clear(); + indexMap.drop(); + } + + public boolean isCompoundIndex(IndexDescriptor indexDescriptor) { + return indexDescriptor.getFields().getFieldNames().size() > 1; + } + + @SuppressWarnings("rawtypes") + public NitriteMap> getSimpleIndexMap(IndexDescriptor indexDescriptor, + NitriteStore nitriteStore, + Class keyType) { + String mapName = getIndexMapName(indexDescriptor); + return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListSet.class); + } + + @SuppressWarnings("rawtypes") + public NitriteMap> getCompoundIndexMap(IndexDescriptor indexDescriptor, + NitriteStore nitriteStore, + Class keyType) { + String mapName = getIndexMapName(indexDescriptor); + return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListMap.class); + } + + protected String getIndexMapName(IndexDescriptor indexDescriptor) { + return INDEX_PREFIX + + INTERNAL_NAME_SEPARATOR + + indexDescriptor.getCollectionName() + + INTERNAL_NAME_SEPARATOR + + indexDescriptor.getFields().getEncodedName() + + INTERNAL_NAME_SEPARATOR + + getIndexType(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java index 7eb7f3c30..e02297111 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java @@ -17,304 +17,401 @@ package org.dizitart.no2.index; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.UnknownType; +import org.dizitart.no2.common.*; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.common.util.Iterables; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.IndexedQuerySupport; +import org.dizitart.no2.filters.NitriteFilter; +import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; +import static org.dizitart.no2.common.util.Iterables.getElementType; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; -import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; -import static org.dizitart.no2.common.util.ValidationUtils.*; +import static org.dizitart.no2.common.util.ValidationUtils.validateArrayIndexField; +import static org.dizitart.no2.common.util.ValidationUtils.validateIterableIndexField; /** * @author Anindya Chatterjee */ @SuppressWarnings("rawtypes") -public abstract class ComparableIndexer implements Indexer { - private NitriteStore nitriteStore; +public abstract class ComparableIndexer extends BaseNitriteIndexer { + protected IndexedQuerySupport querySupport; + + public ComparableIndexer() { + querySupport = new IndexedQuerySupport(this); + } abstract boolean isUnique(); - public ComparableIndexer clone() throws CloneNotSupportedException { - return (ComparableIndexer) super.clone(); + @Override + public void initialize(NitriteConfig nitriteConfig) { } @Override - public void initialize(NitriteConfig nitriteConfig) { - this.nitriteStore = nitriteConfig.getNitriteStore(); + public RecordStream findByFilter(String collectionName, Filter filter, NitriteConfig nitriteConfig) { + if (filter instanceof NitriteFilter) { + NitriteFilter nitriteFilter = (NitriteFilter) filter; + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); + Collection descriptors = indexCatalog.listIndexDescriptors(collectionName); + + + FieldValues fieldValues = querySupport.calculateFieldValues(nitriteFilter); + IndexDescriptor descriptor = new IndexDescriptor(getIndexType(), fieldValues.getFields(), collectionName); + + NitriteMap indexMap = findSuitableIndexMap(descriptor, fieldValues, nitriteConfig.getNitriteStore()); + + + return querySupport.findByFilter(indexMap, nitriteFilter, nitriteConfig); + } else { + throw new FilterException(filter.getClass().getName() + " is not supported"); + } } + //region Write Index + @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - validateIndexField(fieldValue, field); - addIndexEntry(collection.getName(), nitriteId, field, fieldValue); + public void writeIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + if (isCompoundIndex(indexDescriptor)) { + writeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } else { + writeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - validateIndexField(fieldValue, field); - NitriteMap> indexMap = null; - - if (fieldValue == null) { - indexMap = getIndexMap(collection.getName(), field, UnknownType.class); - removeElementFromIndexMap(indexMap, nitriteId, field, null); - } else if (fieldValue instanceof Comparable) { - indexMap = getIndexMap(collection.getName(), field, fieldValue.getClass()); - removeElementFromIndexMap(indexMap, nitriteId, field, (Comparable) fieldValue); - } else if (fieldValue.getClass().isArray()) { - Object[] array = convertToObjectArray(fieldValue); + public void removeIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + if (isCompoundIndex(indexDescriptor)) { + removeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } else { + removeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + } + } + + private void writeCompoundIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object firstValue = fieldValues.get(firstField); + + // NOTE: only first field can have array or iterable value, subsequent fields can not + validateIndexField(firstValue, firstField); + + if (firstValue == null) { + NitriteMap> indexMap + = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); + + addCompoundIndexElement(indexMap, fieldValues, null); + } else if (firstValue instanceof Comparable) { + NitriteMap> indexMap + = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), firstValue.getClass()); + + addCompoundIndexElement(indexMap, fieldValues, (Comparable) firstValue); + } else if (firstValue.getClass().isArray()) { + Object[] array = convertToObjectArray(firstValue); + NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); for (Object item : array) { - if (indexMap == null) { - indexMap = getIndexMap(collection.getName(), field, item.getClass()); - } - removeElementFromIndexMap(indexMap, nitriteId, field, (Comparable) item); + addCompoundIndexElement(indexMap, fieldValues, (Comparable) item); } - } else if (fieldValue instanceof Iterable) { - Iterable iterable = (Iterable) fieldValue; + } else if (firstValue instanceof Iterable) { + Iterable iterable = (Iterable) firstValue; + NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), getElementType(iterable)); + for (Object item : iterable) { - if (indexMap == null) { - indexMap = getIndexMap(collection.getName(), field, item.getClass()); - } - removeElementFromIndexMap(indexMap, nitriteId, field, (Comparable) item); + addCompoundIndexElement(indexMap, fieldValues, (Comparable) item); } } } - @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { - validateIndexField(newValue, field); - validateIndexField(oldValue, field); - addIndexEntry(collection.getName(), nitriteId, field, newValue); - removeIndex(collection, nitriteId, field, oldValue); - } + private void writeSimpleIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); - @Override - public void dropIndex(NitriteMap collection, String field) { - // no action required - } + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); - public Set findEqual(String collectionName, String field, Comparable value) { - NitriteMap> indexMap = - value != null ? getIndexMap(collectionName, field, value.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); + if (element == null) { + NitriteMap> indexMap + = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - Set resultSet = null; - if (indexMap != null) { - resultSet = indexMap.get(value); - } + addSimpleIndexElement(indexMap, fieldValues, null); + } else if (element instanceof Comparable) { + NitriteMap> indexMap + = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), element.getClass()); - if (resultSet == null) { - resultSet = new LinkedHashSet<>(); - } - return resultSet; - } + addSimpleIndexElement(indexMap, fieldValues, (Comparable) element); + } else if (element.getClass().isArray()) { + Object[] array = convertToObjectArray(element); + NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - public Set findNotEqual(String collectionName, String field, Comparable value) { - NitriteMap> indexMap = - value != null ? getIndexMap(collectionName, field, value.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); + for (Object item : array) { + addSimpleIndexElement(indexMap, fieldValues, (Comparable) item); + } + } else if (element instanceof Iterable) { + Iterable iterable = (Iterable) element; + NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), getElementType(iterable)); - Set resultSet = new LinkedHashSet<>(); - if (indexMap != null) { - for (Pair> entry : indexMap.entries()) { - if (!deepEquals(entry.getFirst(), value)) { - resultSet.addAll(entry.getSecond()); - } + for (Object item : iterable) { + addSimpleIndexElement(indexMap, fieldValues, (Comparable) item); } } - - return resultSet; } - public Set findGreaterThan(String collectionName, String field, Comparable comparable) { - Set resultSet = new LinkedHashSet<>(); - NitriteMap> indexMap = - comparable != null ? getIndexMap(collectionName, field, comparable.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); - - if (indexMap != null) { - Comparable higherKey = indexMap.higherKey(comparable); - while (higherKey != null) { - resultSet.addAll(indexMap.get(higherKey)); - higherKey = indexMap.higherKey(higherKey); - } + private void addCompoundIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableMap subMap = indexMap.get(element); + if (subMap == null) { + SortOrder sortOrder = fieldValues.getFields().getFirstKey().getSecond(); + subMap = sortOrder == SortOrder.Ascending ? new ConcurrentSkipListMap<>() + : new ConcurrentSkipListMap<>(Collections.reverseOrder()); } - return resultSet; + populateSubMap(subMap, fieldValues, 1); + indexMap.put(element, subMap); } - public Set findGreaterEqual(String collectionName, String field, Comparable comparable) { - Set resultSet = new LinkedHashSet<>(); - NitriteMap> indexMap = - comparable != null ? getIndexMap(collectionName, field, comparable.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); - - if (indexMap != null) { - Comparable ceilingKey = indexMap.ceilingKey(comparable); - while (ceilingKey != null) { - resultSet.addAll(indexMap.get(ceilingKey)); - ceilingKey = indexMap.higherKey(ceilingKey); + @SuppressWarnings("unchecked") + private void populateSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { + for (int i = startIndex; i < fieldValues.getValues().size(); i++) { + Pair pair = fieldValues.getValues().get(i); + Object value = pair.getSecond(); + if (value == null) { + value = DBNull.getInstance(); } - } - return resultSet; - } + if (!(value instanceof Comparable)) { + throw new IndexingException(value + " is not comparable"); + } - public Set findLesserThan(String collectionName, String field, Comparable comparable) { - Set resultSet = new LinkedHashSet<>(); - NitriteMap> indexMap = - comparable != null ? getIndexMap(collectionName, field, comparable.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); - - if (indexMap != null) { - Comparable lowerKey = indexMap.lowerKey(comparable); - while (lowerKey != null) { - resultSet.addAll(indexMap.get(lowerKey)); - lowerKey = indexMap.lowerKey(lowerKey); + if (i == fieldValues.getValues().size() - 1) { + NavigableSet nitriteIds = (NavigableSet) subMap.get(value); + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + subMap.put(value, nitriteIds); + } else { + NavigableMap subMap2 = (NavigableMap) subMap.get(value); + if (subMap2 == null) { + SortOrder sortOrder = fieldValues.getFields().getSortOrder(pair.getFirst()); + subMap2 = sortOrder == SortOrder.Ascending ? new ConcurrentSkipListMap<>() + : new ConcurrentSkipListMap<>(Collections.reverseOrder()); + } + + populateSubMap(subMap2, fieldValues, startIndex + 1); + subMap.put(value, subMap2); } } + } - return resultSet; + @SuppressWarnings("unchecked") + private void addSimpleIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableSet nitriteIds = (NavigableSet) indexMap.get(element); + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + indexMap.put(element, nitriteIds); } - public Set findLesserEqual(String collectionName, String field, Comparable comparable) { - Set resultSet = new LinkedHashSet<>(); - NitriteMap> indexMap = - comparable != null ? getIndexMap(collectionName, field, comparable.getClass()) - : getIndexMap(collectionName, field, UnknownType.class); - - if (indexMap != null) { - Comparable floorKey = indexMap.floorKey(comparable); - while (floorKey != null) { - resultSet.addAll(indexMap.get(floorKey)); - floorKey = indexMap.lowerKey(floorKey); - } + private NavigableSet addNitriteIds(NavigableSet nitriteIds, FieldValues fieldValues) { + if (nitriteIds == null) { + nitriteIds = new ConcurrentSkipListSet<>(); } - return resultSet; + if (isUnique() && nitriteIds.size() == 1 + && !nitriteIds.contains(fieldValues.getNitriteId())) { + // if key is already exists for unique type, throw error + throw new UniqueConstraintException("unique key constraint violation for " + fieldValues.getFields()); + } + + nitriteIds.add(fieldValues.getNitriteId()); + return nitriteIds; } - public Set findIn(String collectionName, String field, Collection> values) { - notNull(values, "values cannot be null"); - notEmpty(values, "values cannot be empty"); + private void removeCompoundIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); - Set resultSet = new LinkedHashSet<>(); - Class type = Iterables.firstOrNull(values).getClass(); - NitriteMap> indexMap = getIndexMap(collectionName, field, type); + String firstField = fieldNames.get(0); + Object firstValue = fieldValues.get(firstField); - if (indexMap != null) { - for (Comparable comparable : indexMap.keySet()) { - if (values.contains(comparable)) { - resultSet.addAll(indexMap.get(comparable)); - } - } - } + // NOTE: only first field can have array or iterable value, subsequent fields can not + validateIndexField(firstValue, firstField); - return resultSet; - } + if (firstValue == null) { + NitriteMap> indexMap + = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - public Set findNotIn(String collectionName, String field, Collection> values) { - notNull(values, "values cannot be null"); + removeCompoundIndexElement(indexMap, fieldValues, null); + } else if (firstValue instanceof Comparable) { + NitriteMap> indexMap + = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), firstValue.getClass()); - Set resultSet = new LinkedHashSet<>(); - Class type = Iterables.firstOrNull(values).getClass(); - NitriteMap> indexMap = getIndexMap(collectionName, field, type); + removeCompoundIndexElement(indexMap, fieldValues, (Comparable) firstValue); + } else if (firstValue.getClass().isArray()) { + Object[] array = convertToObjectArray(firstValue); + NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - if (indexMap != null) { - for (Comparable comparable : indexMap.keySet()) { - if (!values.contains(comparable)) { - resultSet.addAll(indexMap.get(comparable)); - } + for (Object item : array) { + removeCompoundIndexElement(indexMap, fieldValues, (Comparable) item); } - } - - return resultSet; - } + } else if (firstValue instanceof Iterable) { + Iterable iterable = (Iterable) firstValue; + NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), getElementType(iterable)); - private void validateIndexField(Object value, String field) { - if (value == null) return; - if (value instanceof Iterable) { - validateIterableIndexField((Iterable) value, field); - } else if (value.getClass().isArray()) { - validateArrayIndexField(value, field); - } else { - if (!(value instanceof Comparable)) { - throw new ValidationException(value + " is not comparable"); + for (Object item : iterable) { + removeCompoundIndexElement(indexMap, fieldValues, (Comparable) item); } } } - private void addIndexEntry(String collectionName, NitriteId id, String field, Object element) { - NitriteMap> indexMap - = getIndexMap(collectionName, field, UnknownType.class); + private void removeSimpleIndexEntry(IndexDescriptor indexDescriptor, + FieldValues fieldValues, + NitriteConfig nitriteConfig) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); if (element == null) { - addElementToIndexMap(indexMap, id, field, null); + NitriteMap> indexMap + = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); + + removeSimpleIndexElement(indexMap, fieldValues, null); } else if (element instanceof Comparable) { - addElementToIndexMap(indexMap, id, field, (Comparable) element); + NitriteMap> indexMap + = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), element.getClass()); + + removeSimpleIndexElement(indexMap, fieldValues, (Comparable) element); } else if (element.getClass().isArray()) { Object[] array = convertToObjectArray(element); + NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); + for (Object item : array) { - addElementToIndexMap(indexMap, id, field, (Comparable) item); + removeSimpleIndexElement(indexMap, fieldValues, (Comparable) item); } } else if (element instanceof Iterable) { Iterable iterable = (Iterable) element; + NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, + nitriteConfig.getNitriteStore(), getElementType(iterable)); + for (Object item : iterable) { - addElementToIndexMap(indexMap, id, field, (Comparable) item); + removeSimpleIndexElement(indexMap, fieldValues, (Comparable) item); } } } - private void addElementToIndexMap(NitriteMap> indexMap, - NitriteId id, String field, Comparable element) { - // create the nitriteId list associated with the value - ConcurrentSkipListSet nitriteIdList - = indexMap.get(element); - - if (nitriteIdList == null) { - nitriteIdList = new ConcurrentSkipListSet<>(); + @SuppressWarnings("unchecked") + private void removeSimpleIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableSet nitriteIds = (NavigableSet) indexMap.get(element); + if (nitriteIds != null && !nitriteIds.isEmpty()) { + nitriteIds.remove(fieldValues.getNitriteId()); + if (nitriteIds.size() == 0) { + indexMap.remove(element); + } else { + indexMap.put(element, nitriteIds); + } } + } - if (isUnique() && nitriteIdList.size() == 1 - && !nitriteIdList.contains(id)) { - // if key is already exists for unique type, throw error - throw new UniqueConstraintException("unique key constraint violation for " + field); + private void removeCompoundIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableMap subMap = indexMap.get(element); + if (subMap != null && !subMap.isEmpty()) { + deleteFromSubMap(subMap, fieldValues, 1); + indexMap.put(element, subMap); } - - nitriteIdList.add(id); - indexMap.put(element, nitriteIdList); } - private void removeElementFromIndexMap(NitriteMap> indexMap, - NitriteId nitriteId, String field, Comparable element) { - // create the nitrite list associated with the value - ConcurrentSkipListSet nitriteIdList = indexMap.get(element); - if (nitriteIdList != null && !nitriteIdList.isEmpty()) { - nitriteIdList.remove(nitriteId); - if (nitriteIdList.size() == 0) { - indexMap.remove(element); + @SuppressWarnings("unchecked") + private void deleteFromSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { + for (int i = startIndex; i < fieldValues.getValues().size(); i++) { + Pair pair = fieldValues.getValues().get(i); + Object value = pair.getSecond(); + if (value == null) { + value = DBNull.getInstance(); + } + + if (!(value instanceof Comparable)) { + continue; + } + + if (i == fieldValues.getValues().size() - 1) { + NavigableSet nitriteIds = (NavigableSet) subMap.get(value); + nitriteIds = removeNitriteIds(nitriteIds, fieldValues); + if (nitriteIds == null || nitriteIds.isEmpty()) { + subMap.remove(value); + } else { + subMap.put(value, nitriteIds); + } } else { - indexMap.put(element, nitriteIdList); + NavigableMap subMap2 = (NavigableMap) subMap.get(value); + if (subMap2 == null) { + continue; + } + + deleteFromSubMap(subMap2, fieldValues, startIndex + 1); + subMap.put(value, subMap2); } } } - @SuppressWarnings("rawtypes") - private NitriteMap> getIndexMap( - String collectionName, String field, Class keyType) { + private NavigableSet removeNitriteIds(NavigableSet nitriteIds, FieldValues fieldValues) { + if (nitriteIds != null && !nitriteIds.isEmpty()) { + nitriteIds.remove(fieldValues.getNitriteId()); + } + return nitriteIds; + } + + private void validateIndexField(Object value, String field) { + if (value == null) return; + if (value instanceof Iterable) { + validateIterableIndexField((Iterable) value, field); + } else if (value.getClass().isArray()) { + validateArrayIndexField(value, field); + } else { + if (!(value instanceof Comparable)) { + throw new ValidationException(value + " is not comparable"); + } + } + } - String mapName = getIndexMapName(collectionName, field); - return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListSet.class); + //endregion + + private NitriteMap findSuitableIndexMap(IndexDescriptor descriptor, + FieldValues fieldValues, + NitriteStore nitriteStore) { + // get all indices of a collection + // find the suitable index (prefix included) + // find the index map + // get value by prefix using filter (if compound) + // get value by filter (if simple) + return null; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexEntry.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java similarity index 75% rename from nitrite/src/main/java/org/dizitart/no2/index/IndexEntry.java rename to nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index 99ee89858..e9bee5136 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexEntry.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -18,6 +18,7 @@ import lombok.*; import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.Fields; import java.io.IOException; import java.io.ObjectInputStream; @@ -32,12 +33,13 @@ * * @author Anindya Chatterjee * @see NitriteCollection#createIndex(String, IndexOptions) + * @see NitriteCollection#createIndex(Fields, IndexOptions) * @since 1.0 */ @ToString @EqualsAndHashCode @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class IndexEntry implements Comparable, Serializable { +public class IndexDescriptor implements Comparable, Serializable { private static final long serialVersionUID = 1576690829L; /** @@ -50,12 +52,12 @@ public class IndexEntry implements Comparable, Serializable { private String indexType; /** - * Gets the target field for the index. + * Gets the target fields for the index. * - * @return the target field. + * @return the target fields. */ @Getter - private String field; + private Fields fields; /** * Gets the collection name. @@ -69,36 +71,36 @@ public class IndexEntry implements Comparable, Serializable { * Instantiates a new Index. * * @param indexType the index type - * @param field the value + * @param fields the value * @param collectionName the collection name */ - public IndexEntry(String indexType, String field, String collectionName) { + public IndexDescriptor(String indexType, Fields fields, String collectionName) { notNull(indexType, "indexType cannot be null"); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); notNull(collectionName, "collectionName cannot be null"); notEmpty(collectionName, "collectionName cannot be empty"); this.indexType = indexType; - this.field = field; + this.fields = fields; this.collectionName = collectionName; } @Override - public int compareTo(IndexEntry other) { - String string = collectionName + field + indexType; - String otherString = other.collectionName + other.field + other.indexType; + public int compareTo(IndexDescriptor other) { + String string = collectionName + fields + indexType; + String otherString = other.collectionName + other.fields + other.indexType; return string.compareTo(otherString); } private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeUTF(indexType); - stream.writeUTF(field); + stream.writeObject(fields); stream.writeUTF(collectionName); } - private void readObject(ObjectInputStream stream) throws IOException { + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { indexType = stream.readUTF(); - field = stream.readUTF(); + fields = (Fields) stream.readObject(); collectionName = stream.readUTF(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexMeta.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexMeta.java index cb04a58ae..9729eccfa 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexMeta.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexMeta.java @@ -36,18 +36,18 @@ public class IndexMeta implements Serializable { private static final long serialVersionUID = 1576690663L; - private IndexEntry indexEntry; + private IndexDescriptor indexDescriptor; private String indexMap; private AtomicBoolean isDirty; private void writeObject(ObjectOutputStream stream) throws IOException { - stream.writeObject(indexEntry); + stream.writeObject(indexDescriptor); stream.writeUTF(indexMap); stream.writeObject(isDirty); } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - indexEntry = (IndexEntry) stream.readObject(); + indexDescriptor = (IndexDescriptor) stream.readObject(); indexMap = stream.readUTF(); isDirty = (AtomicBoolean) stream.readObject(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/Indexer.java b/nitrite/src/main/java/org/dizitart/no2/index/Indexer.java deleted file mode 100644 index 1ced8e8f3..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/index/Indexer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.index; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.module.NitritePlugin; -import org.dizitart.no2.store.NitriteMap; - -import static org.dizitart.no2.common.Constants.INDEX_PREFIX; -import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; - -/** - * @author Anindya Chatterjee. - */ -public interface Indexer extends NitritePlugin, Cloneable { - String getIndexType(); - - void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue); - - void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue); - - void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue); - - void dropIndex(NitriteMap collection, String field); - - Indexer clone() throws CloneNotSupportedException; - - default String getIndexMapName(String collectionName, String field) { - return INDEX_PREFIX + - INTERNAL_NAME_SEPARATOR + - collectionName + - INTERNAL_NAME_SEPARATOR + - field + - INTERNAL_NAME_SEPARATOR + - getIndexType(); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java new file mode 100644 index 000000000..d77b279ac --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2020. Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.module.NitritePlugin; + +/** + * @author Anindya Chatterjee. + */ +public interface NitriteIndexer extends NitritePlugin { + String getIndexType(); + + void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig); + + void writeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig); + + void removeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig); + + RecordStream findByFilter(String collectionName, Filter filter, NitriteConfig nitriteConfig); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java index a73574964..d9083c4e6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java @@ -19,6 +19,7 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.IndexingException; @@ -117,8 +118,8 @@ public void updateIndex(NitriteMap collection, NitriteId ni } @Override - public void dropIndex(NitriteMap collection, String field) { - indexCatalog.dropIndexEntry(collection.getName(), field); + public void dropIndex(NitriteMap collection, Fields field) { + indexCatalog.dropIndexDescriptor(collection.getName(), field); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java index 0c11c7713..a7ba89d43 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java @@ -31,7 +31,7 @@ * @see FluentFilter#text(String) * @since 1.0 */ -public interface TextIndexer extends Indexer { +public interface TextIndexer extends NitriteIndexer { /** * Finds matching text using full-text index. * diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java index db7c6fb48..39e7a40c4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java @@ -5,7 +5,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.Generator; /** @@ -21,7 +21,7 @@ public class AddField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexEntry indexEntry = indexCatalog.findIndexEntry(collectionName, fieldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); for (Pair pair : nitriteMap.entries()) { Document document = pair.getSecond(); @@ -34,8 +34,8 @@ public void execute(Nitrite nitrite) { nitriteMap.put(pair.getFirst(), document); } - if (indexEntry != null) { - operations.createIndex(fieldName, indexEntry.getIndexType(), false); + if (indexDescriptor != null) { + operations.createIndex(fieldName, indexDescriptor.getIndexType(), false); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java index 9c34d4bf7..cec45fdc0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java @@ -5,7 +5,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.TypeConverter; /** @@ -31,9 +31,9 @@ public void execute(Nitrite nitrite) { nitriteMap.put(entry.getFirst(), document); } - IndexEntry indexEntry = indexCatalog.findIndexEntry(collectionName, fieldName); - if (indexEntry != null) { - operations.rebuildIndex(indexEntry, false); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); + if (indexDescriptor != null) { + operations.rebuildIndex(indexDescriptor, false); } } } \ No newline at end of file diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java index b9a4f0272..6e840351d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java @@ -5,7 +5,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; /** * @author Anindya Chatterjee @@ -19,14 +19,14 @@ public class DeleteField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexEntry indexEntry = indexCatalog.findIndexEntry(collectionName, fieldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); document.remove(fieldName); nitriteMap.put(entry.getFirst(), document); } - if (indexEntry != null) { + if (indexDescriptor != null) { operations.dropIndex(fieldName); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java index 4092710b8..13bcfdca5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java @@ -6,7 +6,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.CollectionOperations; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; @@ -32,10 +32,10 @@ public void execute(Nitrite nitrite) { } IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); - Collection indexEntries = indexCatalog.listIndexEntries(oldName); - for (IndexEntry indexEntry : indexEntries) { - String field = indexEntry.getField(); - String indexType = indexEntry.getIndexType(); + Collection indexEntries = indexCatalog.listIndexDescriptors(oldName); + for (IndexDescriptor indexDescriptor : indexEntries) { + String field = indexDescriptor.getFields(); + String indexType = indexDescriptor.getIndexType(); newOperations.createIndex(field, indexType, false); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java index 15631ce0a..2c8a6bbd4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java @@ -5,7 +5,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.IndexCatalog; /** @@ -21,7 +21,7 @@ public class RenameField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - boolean indexExists = indexCatalog.hasIndexEntry(collectionName, oldName); + boolean indexExists = indexCatalog.hasIndexDescriptor(collectionName, oldName); for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); if (document.containsKey(oldName)) { @@ -35,8 +35,8 @@ public void execute(Nitrite nitrite) { if (indexExists) { IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); - IndexEntry indexEntry = indexCatalog.findIndexEntry(collectionName, oldName); - String indexType = indexEntry.getIndexType(); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, oldName); + String indexType = indexDescriptor.getIndexType(); operations.dropIndex(oldName); operations.createIndex(newName, indexType, false); diff --git a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java b/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java index d041e7ef8..ffb7f011b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java @@ -36,7 +36,7 @@ @Slf4j @Getter public class PluginManager { - private final Map indexerMap; + private final Map indexerMap; private NitriteMapper nitriteMapper; private NitriteStore nitriteStore; private final NitriteConfig nitriteConfig; @@ -76,8 +76,8 @@ public void initializePlugins() { } if (!indexerMap.isEmpty()) { - for (Indexer indexer : indexerMap.values()) { - initializePlugin(indexer); + for (NitriteIndexer nitriteIndexer : indexerMap.values()) { + initializePlugin(nitriteIndexer); } } } @@ -117,13 +117,13 @@ private void loadIfNitriteMapper(NitritePlugin plugin) { } private synchronized void loadIfIndexer(NitritePlugin plugin) { - if (plugin instanceof Indexer) { - Indexer indexer = (Indexer) plugin; - if (indexerMap.containsKey(indexer.getIndexType())) { + if (plugin instanceof NitriteIndexer) { + NitriteIndexer nitriteIndexer = (NitriteIndexer) plugin; + if (indexerMap.containsKey(nitriteIndexer.getIndexType())) { throw new PluginException("multiple Indexer found for type " - + indexer.getIndexType()); + + nitriteIndexer.getIndexType()); } - this.indexerMap.put(indexer.getIndexType(), indexer); + this.indexerMap.put(nitriteIndexer.getIndexType(), nitriteIndexer); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java index 8d46de855..e8ae27347 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java @@ -21,9 +21,10 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.store.NitriteStore; @@ -53,33 +54,33 @@ class DefaultObjectRepository implements ObjectRepository { } @Override - public void createIndex(String field, IndexOptions indexOptions) { - collection.createIndex(field, indexOptions); + public void createIndex(Fields fields, IndexOptions indexOptions) { + collection.createIndex(fields, indexOptions); } @Override - public void rebuildIndex(String field, boolean isAsync) { - collection.rebuildIndex(field, isAsync); + public void rebuildIndex(Fields fields, boolean isAsync) { + collection.rebuildIndex(fields, isAsync); } @Override - public Collection listIndices() { + public Collection listIndices() { return collection.listIndices(); } @Override - public boolean hasIndex(String field) { - return collection.hasIndex(field); + public boolean hasIndex(Fields fields) { + return collection.hasIndex(fields); } @Override - public boolean isIndexing(String field) { - return collection.isIndexing(field); + public boolean isIndexing(Fields fields) { + return collection.isIndexing(fields); } @Override - public void dropIndex(String field) { - collection.dropIndex(field); + public void dropIndex(Fields fields) { + collection.dropIndex(fields); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java index cf8062468..ec6997f10 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java @@ -46,29 +46,25 @@ *

* An object repository is observable like its underlying {@link NitriteCollection}. *

- * [[app-listing]] - * [source,java] - * .Create a repository - * -- + *

Create a repository

+ *
+ * {@code
  * // create/open a database
  * Nitrite db = Nitrite.builder()
- * .openOrCreate("user", "password");
- * 

- * // create an object repository - * ObjectRepository<Employee> employeeStore = db.getRepository(Employee.class); - *

- * // observe any change to the repository - * employeeStore.register(new ChangeListener() { + * .openOrCreate("user", "password"); * - * @param the type of the object to store. - * @author Anindya Chatterjee. + * // create an object repository + * ObjectRepository employeeStore = db.getRepository(Employee.class); * * // insert an object * Employee emp = new Employee(); * emp.setName("John Doe"); * employeeStore.insert(emp); - *

- * -- + * } + *

+ * + * @param the type of the object to store. + * @author Anindya Chatterjee. * @see EventAware * @see Document * @see NitriteId @@ -88,16 +84,16 @@ public interface ObjectRepository extends PersistentCollection { * If any of the value is already indexed in the repository, then after insertion the * index will also be updated. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Insert}. + *

* * @param object the object to insert * @param others other objects to insert in a batch. * @return the result of the write operation. - * @throws ValidationException if `object` is `null`. - * @throws InvalidIdException if the id value contains `null` value. + * @throws ValidationException if {@code object} is {@code null}. + * @throws InvalidIdException if the id value contains {@code null} value. * @throws InvalidIdException if the id value contains non comparable type, i.e. type that does not implement {@link Comparable}. * @throws InvalidIdException if the id contains value which is not of the same java type as of other objects' id in the collection. * @throws UniqueConstraintException if the value of id value clashes with the id of another object in the collection. @@ -124,26 +120,24 @@ default WriteResult insert(T object, T... others) { /** * Updates object in the repository. If the filter does not find - * any object in the collection, then the `update` object will be inserted. + * any object in the collection, then the {@code update} object will be inserted. *

- * If the `filter` is `null`, it will update all objects in the collection. + * If the {@code filter} is {@code null}, it will update all objects in the collection. *

- * [icon="{@docRoot}/alert.png"] - * [CAUTION] - * ==== - * If the `update` object has a non `null` value in the id value, this value + * CAUTION: + * If the {@code update} object has a non {@code null} value in the id value, this value * will be removed before update. - * ==== + *

*

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update}. + *

* * @param filter the filter to apply to select objects from the collection. * @param update the modifications to apply. * @return the result of the update operation. - * @throws ValidationException if the `update` object is `null`. + * @throws ValidationException if the {@code update} object is {@code null}. */ default WriteResult update(Filter filter, T update) { return update(filter, update, false); @@ -151,95 +145,88 @@ default WriteResult update(Filter filter, T update) { /** * Updates object in the repository. Update operation can be customized - * with the help of `updateOptions`. + * with the help of {@code updateOptions}. *

- * If the `filter` is `null`, it will update all objects in the collection unless - * `justOnce` is set to `true` in `updateOptions`. + * If the {@code filter} is {@code null}, it will update all objects in the collection unless + * {@code justOnce} is set to {@code true} in {@code updateOptions}. *

- * [icon="{@docRoot}/alert.png"] - * [CAUTION] - * ==== - * If the `update` object has a non `null` value in the id value, this value + * CAUTION: + * If the {@code update} object has a non {@code null} value in the id value, this value * will be removed before update. - * ==== + *

*

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type - * {@link EventType#Update} or - * {@link EventType#Insert}. + * {@link EventType#Update} or {@link EventType#Insert}. + *

* * @param filter the filter to apply to select objects from the collection. * @param update the modifications to apply. - * @param insertIfAbsent if set to `true`, `update` object will be inserted if not found. + * @param insertIfAbsent if set to {@code true}, {@code update} object will be inserted if not found. * @return the result of the update operation. - * @throws ValidationException if the `update` object is `null`. - * @throws ValidationException if `updateOptions` is `null`. + * @throws ValidationException if the {@code update} object is {@code null}. + * @throws ValidationException if {@code updateOptions} is {@code null}. */ WriteResult update(Filter filter, T update, boolean insertIfAbsent); /** - * Updates object in the repository by setting the field specified in `document`. + * Updates object in the repository by setting the field specified in {@code document}. *

- * If the `filter` is `null`, it will update all objects in the collection. + * If the {@code filter} is {@code null}, it will update all objects in the collection. *

- * [icon="{@docRoot}/alert.png"] - * [CAUTION] - * ==== - * The `update` document should not contain `_id` field. - * ==== + * CAUTION: + * The {@code update} document should not contain {@code _id} field. + *

*

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update}. + *

* * @param filter the filter to apply to select objects from the collection. * @param update the modifications to apply. * @return the result of the update operation. - * @throws ValidationException if the `update` object is `null`. + * @throws ValidationException if the {@code update} object is {@code null}. */ default WriteResult update(Filter filter, Document update) { return update(filter, update, false); } /** - * Updates object in the repository by setting the field specified in `document`. + * Updates object in the repository by setting the field specified in {@code document}. * Update operation can either update the first matching object or all matching - * objects depending on the value of `justOnce`. + * objects depending on the value of {@code justOnce}. *

- * If the `filter` is `null`, it will update all objects in the collection unless - * `justOnce` is set to `true`. + * If the {@code filter} is {@code null}, it will update all objects in the collection unless + * {@code justOnce} is set to {@code true}. *

- * [icon="{@docRoot}/alert.png"] - * [CAUTION] - * ==== - * The `update` document should not contain `_id` field. - * ==== + * CAUTION: + * The {@code update} document should not contain {@code _id} field. + *

*

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update}. - * + *

+ * * @param filter the filter to apply to select objects from the collection. * @param update the modifications to apply. * @param justOnce indicates if update should be applied on first matching object or all. * @return the result of the update operation. - * @throws ValidationException if the `update` object is `null`. + * @throws ValidationException if the {@code update} object is {@code null}. */ WriteResult update(Filter filter, Document update, boolean justOnce); /** * Removes matching elements from the collection. *

- * If the `filter` is `null`, it will remove all objects from the collection. + * If the {@code filter} is {@code null}, it will remove all objects from the collection. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Remove}. - * + *

+ * * @param filter the filter to apply to select elements from collection. * @return the result of the remove operation. */ @@ -249,16 +236,16 @@ default WriteResult remove(Filter filter) { /** * Removes object from the collection. Remove operation can be customized by - * `removeOptions`. + * {@code removeOptions}. *

- * If the `filter` is `null`, it will remove all objects in the collection unless - * `justOnce` is set to `true` in `removeOptions`. + * If the {@code filter} is {@code null}, it will remove all objects in the collection unless + * {@code justOnce} is set to {@code true} in {@code removeOptions}. *

- * [icon="{@docRoot}/note.png"] * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Remove}. - * + *

+ * * @param filter the filter to apply to select objects from collection. * @param justOne indicates if only one element will be removed or all of them. * @return the result of the remove operation. @@ -278,13 +265,13 @@ default WriteResult remove(Filter filter) { *

* See {@link Filter} for all available filters. *

- * [icon="{@docRoot}/note.png"] * NOTE: If there is an index on the value specified in the filter, this operation * will take advantage of the index. + *

* * @param filter the filter to apply to select objects from collection. * @return a cursor to all selected objects. - * @throws ValidationException if `filter` is null. + * @throws ValidationException if {@code filter} is null. * @see Filter * @see Cursor#project(Class) */ @@ -292,14 +279,14 @@ default WriteResult remove(Filter filter) { /** * Gets a single element from the repository by its id. If no element - * is found, it will return `null`. The object must have a field annotated with {@link Id}, + * is found, it will return {@code null}. The object must have a field annotated with {@link Id}, * otherwise this call will throw {@link InvalidIdException}. * * @param the type parameter * @param id the id value * @return the unique object associated with the id. - * @throws ValidationException if `id` is `null`. - * @throws InvalidIdException if the id value is `null`, or the type is not compatible. + * @throws ValidationException if `id` is {@code null}. + * @throws InvalidIdException if the id value is {@code null}, or the type is not compatible. * @throws NotIdentifiableException if the object has no field marked with {@link Id}. */ T getById(I id); diff --git a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java index 24eae380b..fabea140d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java @@ -16,7 +16,8 @@ package org.dizitart.no2.store; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; import java.util.Collection; @@ -39,88 +40,88 @@ public IndexCatalog(NitriteStore nitriteStore) { this.nitriteStore = nitriteStore; } - public boolean hasIndexEntry(String collectionName, String field) { - NitriteMap indexMetaMap = getIndexMetaMap(collectionName); - if (!indexMetaMap.containsKey(field)) return false; + public boolean hasIndexDescriptor(String collectionName, Fields fields) { + NitriteMap indexMetaMap = getIndexMetaMap(collectionName); + if (!indexMetaMap.containsKey(fields)) return false; - IndexMeta indexMeta = indexMetaMap.get(field); + IndexMeta indexMeta = indexMetaMap.get(fields); return indexMeta != null; } - public IndexEntry createIndexEntry(String collectionName, String field, String indexType) { - IndexEntry index = new IndexEntry(indexType, field, collectionName); + public IndexDescriptor createIndexDescriptor(String collectionName, Fields fields, String indexType) { + IndexDescriptor index = new IndexDescriptor(indexType, fields, collectionName); IndexMeta indexMeta = new IndexMeta(); - indexMeta.setIndexEntry(index); + indexMeta.setIndexDescriptor(index); indexMeta.setIsDirty(new AtomicBoolean(false)); indexMeta.setIndexMap(getIndexMapName(index)); - getIndexMetaMap(collectionName).put(field, indexMeta); + getIndexMetaMap(collectionName).put(fields, indexMeta); return index; } - public IndexEntry findIndexEntry(String collectionName, String field) { - IndexMeta meta = getIndexMetaMap(collectionName).get(field); + public IndexDescriptor findIndexDescriptor(String collectionName, Fields fields) { + IndexMeta meta = getIndexMetaMap(collectionName).get(fields); if (meta != null) { - return meta.getIndexEntry(); + return meta.getIndexDescriptor(); } return null; } - public boolean isDirtyIndex(String collectionName, String field) { - IndexMeta meta = getIndexMetaMap(collectionName).get(field); + public boolean isDirtyIndex(String collectionName, Fields fields) { + IndexMeta meta = getIndexMetaMap(collectionName).get(fields); return meta != null && meta.getIsDirty().get(); } - public Collection listIndexEntries(String collectionName) { - Set indexSet = new LinkedHashSet<>(); + public Collection listIndexDescriptors(String collectionName) { + Set indexSet = new LinkedHashSet<>(); for (IndexMeta indexMeta : getIndexMetaMap(collectionName).values()) { - indexSet.add(indexMeta.getIndexEntry()); + indexSet.add(indexMeta.getIndexDescriptor()); } return Collections.unmodifiableSet(indexSet); } - public void dropIndexEntry(String collectionName, String field) { - IndexMeta meta = getIndexMetaMap(collectionName).get(field); - if (meta != null && meta.getIndexEntry() != null) { + public void dropIndexDescriptor(String collectionName, Fields fields) { + IndexMeta meta = getIndexMetaMap(collectionName).get(fields); + if (meta != null && meta.getIndexDescriptor() != null) { String indexMapName = meta.getIndexMap(); nitriteStore.openMap(indexMapName, Object.class, Object.class).drop(); } - getIndexMetaMap(collectionName).remove(field); + getIndexMetaMap(collectionName).remove(fields); } - public void beginIndexing(String collectionName, String field) { - markDirty(collectionName, field, true); + public void beginIndexing(String collectionName, Fields fields) { + markDirty(collectionName, fields, true); } - public void endIndexing(String collectionName, String field) { - markDirty(collectionName, field, false); + public void endIndexing(String collectionName, Fields fields) { + markDirty(collectionName, fields, false); } - private NitriteMap getIndexMetaMap(String collectionName) { + private NitriteMap getIndexMetaMap(String collectionName) { String indexMetaName = getIndexMetaName(collectionName); - return nitriteStore.openMap(indexMetaName, String.class, IndexMeta.class); + return nitriteStore.openMap(indexMetaName, Fields.class, IndexMeta.class); } private String getIndexMetaName(String collectionName) { return INDEX_META_PREFIX + INTERNAL_NAME_SEPARATOR + collectionName; } - private String getIndexMapName(IndexEntry index) { + private void markDirty(String collectionName, Fields fields, boolean dirty) { + IndexMeta meta = getIndexMetaMap(collectionName).get(fields); + if (meta != null && meta.getIndexDescriptor() != null) { + meta.getIsDirty().set(dirty); + } + } + + private String getIndexMapName(IndexDescriptor index) { return INDEX_PREFIX + INTERNAL_NAME_SEPARATOR + index.getCollectionName() + INTERNAL_NAME_SEPARATOR + - index.getField() + + index.getFields().getEncodedName() + INTERNAL_NAME_SEPARATOR + index.getIndexType(); } - - private void markDirty(String collectionName, String field, boolean dirty) { - IndexMeta meta = getIndexMetaMap(collectionName).get(field); - if (meta != null && meta.getIndexEntry() != null) { - meta.getIsDirty().set(dirty); - } - } } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java index 93956096f..d2117f7e6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java @@ -127,6 +127,9 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { */ RecordStream> entries(); + + RecordStream> reversedEntries(); + /** * Get the smallest key that is larger than the given key, or null if no * such key exists. diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java index ac1f5ce5f..92db60239 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java @@ -1,6 +1,6 @@ package org.dizitart.no2.store.memory; -import org.dizitart.no2.common.NullEntry; +import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.util.Comparables; @@ -19,7 +19,7 @@ */ public class InMemoryMap implements NitriteMap { private final NavigableMap backingMap; - private final NavigableMap nullEntryMap; + private final NavigableMap nullEntryMap; private final NitriteStore nitriteStore; private final String mapName; @@ -35,7 +35,7 @@ public InMemoryMap(String mapName, NitriteStore nitriteStore) { @Override public boolean containsKey(Key key) { if (key == null) { - return nullEntryMap.containsKey(NullEntry.getInstance()); + return nullEntryMap.containsKey(DBNull.getInstance()); } return backingMap.containsKey(key); } @@ -43,7 +43,7 @@ public boolean containsKey(Key key) { @Override public Value get(Key key) { if (key == null) { - return nullEntryMap.get(NullEntry.getInstance()); + return nullEntryMap.get(DBNull.getInstance()); } return backingMap.get(key); } @@ -74,7 +74,7 @@ public RecordStream values() { public Value remove(Key key) { Value value; if (key == null) { - value = nullEntryMap.remove(NullEntry.getInstance()); + value = nullEntryMap.remove(DBNull.getInstance()); } else { value = backingMap.remove(key); } @@ -86,7 +86,7 @@ public Value remove(Key key) { public RecordStream keySet() { return RecordStream.fromIterable(() -> new Iterator() { final Iterator keyIterator = backingMap.keySet().iterator(); - final Iterator nullEntryIterator = nullEntryMap.keySet().iterator(); + final Iterator nullEntryIterator = nullEntryMap.keySet().iterator(); @Override public boolean hasNext() { @@ -112,7 +112,7 @@ public Key next() { public void put(Key key, Value value) { notNull(value, "value cannot be null"); if (key == null) { - nullEntryMap.put(NullEntry.getInstance(), value); + nullEntryMap.put(DBNull.getInstance(), value); } else { Map.Entry firstEntry = backingMap.firstEntry(); if (firstEntry != null) { @@ -144,30 +144,12 @@ public Value putIfAbsent(Key key, Value value) { @Override public RecordStream> entries() { - return RecordStream.fromIterable(() -> new Iterator>() { - private final Iterator> entryIterator = backingMap.entrySet().iterator(); - private final Iterator> nullEntryIterator = nullEntryMap.entrySet().iterator(); - - @Override - public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return entryIterator.hasNext(); - } - return true; - } + return getStream(backingMap, nullEntryMap); + } - @Override - public Pair next() { - if (nullEntryIterator.hasNext()) { - Map.Entry entry = nullEntryIterator.next(); - return new Pair<>(null, entry.getValue()); - } else { - Map.Entry entry = entryIterator.next(); - return new Pair<>(entry.getKey(), entry.getValue()); - } - } - }); + @Override + public RecordStream> reversedEntries() { + return getStream(backingMap.descendingMap(), nullEntryMap.descendingMap()); } @Override @@ -217,4 +199,34 @@ public void drop() { public void close() { } + + private RecordStream> getStream(NavigableMap primaryMap, + NavigableMap nullEntryMap) { + return RecordStream.fromIterable(() -> new Iterator>() { + private final Iterator> entryIterator = + primaryMap.entrySet().iterator(); + private final Iterator> nullEntryIterator = + nullEntryMap.entrySet().iterator(); + + @Override + public boolean hasNext() { + boolean result = nullEntryIterator.hasNext(); + if (!result) { + return entryIterator.hasNext(); + } + return true; + } + + @Override + public Pair next() { + if (nullEntryIterator.hasNext()) { + Map.Entry entry = nullEntryIterator.next(); + return new Pair<>(null, entry.getValue()); + } else { + Map.Entry entry = entryIterator.next(); + return new Pair<>(entry.getKey(), entry.getValue()); + } + } + }); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java index a9dc85a26..b6dd35517 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java @@ -1,5 +1,6 @@ package org.dizitart.no2.transaction; +import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.*; @@ -7,12 +8,13 @@ import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.collection.operation.CollectionOperations; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; import org.dizitart.no2.common.event.NitriteEventBus; import org.dizitart.no2.exceptions.*; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.store.NitriteMap; @@ -34,6 +36,7 @@ /** * @author Anindya Chatterjee */ +@Data class DefaultTransactionalCollection implements NitriteCollection { private final NitriteCollection primary; private final TransactionContext transactionContext; @@ -267,17 +270,17 @@ public String getName() { } @Override - public void createIndex(String field, IndexOptions indexOptions) { + public void createIndex(Fields fields, IndexOptions indexOptions) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); // by default async is false while creating index try { writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(field, IndexType.Unique, false); + collectionOperations.createIndex(fields, IndexType.Unique, false); } else { - collectionOperations.createIndex(field, indexOptions.getIndexType(), + collectionOperations.createIndex(fields, indexOptions.getIndexType(), indexOptions.isAsync()); } } finally { @@ -286,46 +289,46 @@ public void createIndex(String field, IndexOptions indexOptions) { JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.CreateIndex); - journalEntry.setCommit(() -> primary.createIndex(field, indexOptions)); - journalEntry.setRollback(() -> primary.dropIndex(field)); + journalEntry.setCommit(() -> primary.createIndex(fields, indexOptions)); + journalEntry.setRollback(() -> primary.dropIndex(fields)); transactionContext.getJournal().add(journalEntry); } @Override - public void rebuildIndex(String field, boolean isAsync) { + public void rebuildIndex(Fields fields, boolean isAsync) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); - IndexEntry indexEntry; + IndexDescriptor indexDescriptor; try { readLock.lock(); - indexEntry = collectionOperations.findIndex(field); + indexDescriptor = collectionOperations.findIndex(fields); } finally { readLock.unlock(); } - if (indexEntry != null) { - validateRebuildIndex(indexEntry); + if (indexDescriptor != null) { + validateRebuildIndex(indexDescriptor); try { writeLock.lock(); - collectionOperations.rebuildIndex(indexEntry, isAsync); + collectionOperations.rebuildIndex(indexDescriptor, isAsync); } finally { writeLock.unlock(); } } else { - throw new IndexingException(field + " is not indexed"); + throw new IndexingException(fields + " is not indexed"); } JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.RebuildIndex); - journalEntry.setCommit(() -> primary.rebuildIndex(field, isAsync)); - journalEntry.setRollback(() -> primary.rebuildIndex(field, isAsync)); + journalEntry.setCommit(() -> primary.rebuildIndex(fields, isAsync)); + journalEntry.setRollback(() -> primary.rebuildIndex(fields, isAsync)); transactionContext.getJournal().add(journalEntry); } @Override - public Collection listIndices() { + public Collection listIndices() { checkOpened(); try { @@ -337,59 +340,59 @@ public Collection listIndices() { } @Override - public boolean hasIndex(String field) { + public boolean hasIndex(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); try { readLock.lock(); - return collectionOperations.hasIndex(field); + return collectionOperations.hasIndex(fields); } finally { readLock.unlock(); } } @Override - public boolean isIndexing(String field) { + public boolean isIndexing(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); try { readLock.lock(); - return collectionOperations.isIndexing(field); + return collectionOperations.isIndexing(fields); } finally { readLock.unlock(); } } @Override - public void dropIndex(String field) { + public void dropIndex(Fields fields) { checkOpened(); - notNull(field, "field cannot be null"); + notNull(fields, "fields cannot be null"); try { writeLock.lock(); - collectionOperations.dropIndex(field); + collectionOperations.dropIndex(fields); } finally { writeLock.unlock(); } - final AtomicReference indexEntry = new AtomicReference<>(); + final AtomicReference indexEntry = new AtomicReference<>(); JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.DropIndex); journalEntry.setCommit(() -> { - for (IndexEntry entry : primary.listIndices()) { - if (entry.getField().equals(field)) { + for (IndexDescriptor entry : primary.listIndices()) { + if (entry.getFields().equals(fields)) { indexEntry.set(entry); break; } } - primary.dropIndex(field); + primary.dropIndex(fields); }); journalEntry.setRollback(() -> { if (indexEntry.get() != null) { - primary.createIndex(indexEntry.get().getField(), + primary.createIndex(indexEntry.get().getFields(), indexOptions(indexEntry.get().getIndexType())); } }); @@ -407,7 +410,7 @@ public void dropAllIndices() { writeLock.unlock(); } - List indexEntries = new ArrayList<>(); + List indexEntries = new ArrayList<>(); JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.DropAllIndices); @@ -416,8 +419,9 @@ public void dropAllIndices() { primary.dropAllIndices(); }); journalEntry.setRollback(() -> { - for (IndexEntry indexEntry : indexEntries) { - primary.createIndex(indexEntry.getField(), indexOptions(indexEntry.getIndexType())); + for (IndexDescriptor indexDescriptor : indexEntries) { + primary.createIndex(indexDescriptor.getFields(), + indexOptions(indexDescriptor.getIndexType())); } }); transactionContext.getJournal().add(journalEntry); @@ -462,7 +466,7 @@ public void drop() { isDropped = true; List documentList = new ArrayList<>(); - List indexEntries = new ArrayList<>(); + List indexEntries = new ArrayList<>(); JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.DropCollection); @@ -474,8 +478,9 @@ public void drop() { journalEntry.setRollback(() -> { NitriteCollection collection = nitrite.getCollection(collectionName); - for (IndexEntry indexEntry : indexEntries) { - collection.createIndex(indexEntry.getField(), indexOptions(indexEntry.getIndexType())); + for (IndexDescriptor indexDescriptor : indexEntries) { + collection.createIndex(indexDescriptor.getFields(), + indexOptions(indexDescriptor.getIndexType())); } for (Document document : documentList) { @@ -624,11 +629,11 @@ private void closeEventBus() { eventBus = null; } - private void validateRebuildIndex(IndexEntry indexEntry) { - notNull(indexEntry, "index cannot be null"); + private void validateRebuildIndex(IndexDescriptor indexDescriptor) { + notNull(indexDescriptor, "indexEntry cannot be null"); - if (isIndexing(indexEntry.getField())) { - throw new IndexingException("indexing on value " + indexEntry.getField() + " is currently running"); + if (isIndexing(indexDescriptor.getFields())) { + throw new IndexingException("indexing on value " + indexDescriptor.getFields() + " is currently running"); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java index b7513d63d..b96b3af2b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java @@ -5,9 +5,10 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; @@ -43,33 +44,33 @@ public DefaultTransactionalRepository(Class type, } @Override - public void createIndex(String field, IndexOptions indexOptions) { - backingCollection.createIndex(field, indexOptions); + public void createIndex(Fields fields, IndexOptions indexOptions) { + backingCollection.createIndex(fields, indexOptions); } @Override - public void rebuildIndex(String field, boolean isAsync) { - backingCollection.rebuildIndex(field, isAsync); + public void rebuildIndex(Fields fields, boolean isAsync) { + backingCollection.rebuildIndex(fields, isAsync); } @Override - public Collection listIndices() { + public Collection listIndices() { return backingCollection.listIndices(); } @Override - public boolean hasIndex(String field) { - return backingCollection.hasIndex(field); + public boolean hasIndex(Fields fields) { + return backingCollection.hasIndex(fields); } @Override - public boolean isIndexing(String field) { - return backingCollection.isIndexing(field); + public boolean isIndexing(Fields fields) { + return backingCollection.isIndexing(fields); } @Override - public void dropIndex(String field) { - backingCollection.dropIndex(field); + public void dropIndex(Fields fields) { + backingCollection.dropIndex(fields); } @Override @@ -88,6 +89,7 @@ public WriteResult insert(T[] elements) { @Override public WriteResult update(T element, boolean insertIfAbsent) { notNull(element, "a null object cannot be used for update"); + return update(operations.createUniqueFilter(element), element, insertIfAbsent); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java index e1e493fc0..e1816adca 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java @@ -3,7 +3,7 @@ import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.module.NitriteModule; import org.dizitart.no2.store.NitriteStore; @@ -18,7 +18,7 @@ class TransactionalConfig extends NitriteConfig { private final NitriteConfig config; private final TransactionalStore transactionalStore; - private final Map indexerMap; + private final Map indexerMap; public TransactionalConfig(NitriteConfig config, TransactionalStore transactionalStore) { this.config = config; @@ -27,18 +27,18 @@ public TransactionalConfig(NitriteConfig config, TransactionalStore transacti } @Override - public Indexer findIndexer(String indexType) { + public NitriteIndexer findIndexer(String indexType) { if (indexerMap.containsKey(indexType)) { return indexerMap.get(indexType); } try { - Indexer indexer = config.findIndexer(indexType).clone(); - if (indexer != null) { - indexer.initialize(this); - indexerMap.put(indexType, indexer); + NitriteIndexer nitriteIndexer = config.findIndexer(indexType).clone(); + if (nitriteIndexer != null) { + nitriteIndexer.initialize(this); + indexerMap.put(indexType, nitriteIndexer); } - return indexer; + return nitriteIndexer; } catch (CloneNotSupportedException e) { log.error("Failed to clone indexer", e); throw new NitriteIOException("error while cloning indexer", e); diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java index 5e97fde74..564c64cf2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java @@ -146,49 +146,12 @@ public V putIfAbsent(K key, V value) { @Override public RecordStream> entries() { - if (cleared) { - return RecordStream.empty(); - } - - return () -> new Iterator>() { - private final Iterator> primaryIterator = primary.entries().iterator(); - private final Iterator> iterator = backingMap.entries().iterator(); - private Pair nextPair; - private boolean nextPairSet = false; - - @Override - public boolean hasNext() { - return nextPairSet || setNextId(); - } - - @Override - public Pair next() { - if (!nextPairSet && !setNextId()) { - throw new NoSuchElementException(); - } - nextPairSet = false; - return nextPair; - } - - private boolean setNextId() { - if (iterator.hasNext()) { - nextPair = iterator.next(); - nextPairSet = true; - return true; - } - - while (primaryIterator.hasNext()) { - final Pair pair = primaryIterator.next(); - if (!tombstones.contains(pair.getFirst())) { - nextPair = pair; - nextPairSet = true; - return true; - } - } + return getStream(primary.entries(), backingMap.entries()); + } - return false; - } - }; + @Override + public RecordStream> reversedEntries() { + return getStream(primary.reversedEntries(), backingMap.reversedEntries()); } @Override @@ -311,4 +274,51 @@ public void close() { backingMap.clear(); tombstones.clear(); } + + private RecordStream> getStream(RecordStream> primaryStream, + RecordStream> backingStream) { + if (cleared) { + return RecordStream.empty(); + } + + return () -> new Iterator>() { + private final Iterator> primaryIterator = primaryStream.iterator(); + private final Iterator> iterator = backingStream.iterator(); + private Pair nextPair; + private boolean nextPairSet = false; + + @Override + public boolean hasNext() { + return nextPairSet || setNextId(); + } + + @Override + public Pair next() { + if (!nextPairSet && !setNextId()) { + throw new NoSuchElementException(); + } + nextPairSet = false; + return nextPair; + } + + private boolean setNextId() { + if (iterator.hasNext()) { + nextPair = iterator.next(); + nextPairSet = true; + return true; + } + + while (primaryIterator.hasNext()) { + final Pair pair = primaryIterator.next(); + if (!tombstones.contains(pair.getFirst())) { + nextPair = pair; + nextPairSet = true; + return true; + } + } + + return false; + } + }; + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/IndexEntryTest.java b/nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java similarity index 72% rename from nitrite/src/test/java/org/dizitart/no2/IndexEntryTest.java rename to nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java index f6ae305a8..a3523c032 100644 --- a/nitrite/src/test/java/org/dizitart/no2/IndexEntryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; import org.junit.Rule; import org.junit.Test; @@ -26,22 +26,22 @@ /** * @author Anindya Chatterjee. */ -public class IndexEntryTest { +public class IndexDescriptorTest { @Rule public Retry retry = new Retry(3); @Test public void testIndexEquals() { - IndexEntry index = new IndexEntry(IndexType.Fulltext, "test", "testColl"); - IndexEntry index2 = new IndexEntry(IndexType.Fulltext, "test", "testColl"); + IndexDescriptor index = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); + IndexDescriptor index2 = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); assertEquals(index, index2); } @Test public void testIndexCompare() { - IndexEntry index = new IndexEntry(IndexType.Fulltext, "test", "testColl"); - IndexEntry index2 = new IndexEntry(IndexType.Fulltext, "test", "testColl"); + IndexDescriptor index = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); + IndexDescriptor index2 = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); assertEquals(index.toString(), "IndexEntry(indexType=Fulltext, field=test, collectionName=testColl)"); assertEquals(index.compareTo(index2), 0); diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 167920bed..8acc5b2f5 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -20,7 +20,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.exceptions.SecurityException; -import org.dizitart.no2.index.Indexer; +import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.module.PluginManager; @@ -163,7 +163,7 @@ public void testFieldSeparator() { assertEquals(document.get("colorCodes::1::color"), "Green"); } - private static class CustomIndexer implements Indexer { + private static class CustomIndexer implements NitriteIndexer { @Override public String getIndexType() { @@ -191,7 +191,7 @@ public void dropIndex(NitriteMap collection, String field) } @Override - public Indexer clone() throws CloneNotSupportedException { + public NitriteIndexer clone() throws CloneNotSupportedException { return null; } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java index 161e52626..1a9bdb9ab 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java @@ -19,7 +19,7 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; import org.junit.Test; @@ -136,9 +136,9 @@ public void testCreateIndexAsync() { public void testRebuildIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); insert(); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), false); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), false); } } @@ -148,9 +148,9 @@ public void testRebuildIndexAsync() { insert(); await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); - for (IndexEntry idx : indices) { - collection.rebuildIndex(idx.getField(), true); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getFields(), true); await().until(bodyIndexingCompleted()); } } @@ -158,14 +158,14 @@ public void testRebuildIndexAsync() { @Test public void testRebuildIndexOnRunningIndex() { collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexEntry idx = indices.iterator().next(); + Collection indices = collection.listIndices(); + IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getField(), true); + collection.rebuildIndex(idx.getFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java index 75eabb727..fa390f93a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java @@ -16,7 +16,7 @@ public class EqualsFilterTest { @Test public void testFindIndexedIdSet() { EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setIndexer(new NitriteTextIndexer()); + equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); equalsFilter.setIsFieldIndexed(null); assertEquals(0, equalsFilter.findIndexedIdSet().size()); } @@ -39,7 +39,7 @@ public void testFindIndexedIdSet3() { public void testFindIndexedIdSet4() { EqualsFilter equalsFilter = new EqualsFilter("field", "value"); equalsFilter.setIsFieldIndexed(true); - equalsFilter.setIndexer(new NitriteTextIndexer()); + equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); equalsFilter.setIsFieldIndexed(null); assertEquals(0, equalsFilter.findIndexedIdSet().size()); } @@ -106,7 +106,7 @@ public void testSetIsFieldIndexed() { public void testSetIsFieldIndexed2() { EqualsFilter equalsFilter = new EqualsFilter("field", 42); equalsFilter.setObjectFilter(true); - equalsFilter.setIndexer(null); + equalsFilter.setNitriteIndexer(null); equalsFilter.setIsFieldIndexed(true); assertTrue(equalsFilter.getIsFieldIndexed()); } @@ -114,7 +114,7 @@ public void testSetIsFieldIndexed2() { @Test public void testSetIsFieldIndexed3() { EqualsFilter equalsFilter = new EqualsFilter("field", 42); - equalsFilter.setIndexer(new NitriteTextIndexer()); + equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); equalsFilter.setIsFieldIndexed(true); assertTrue(equalsFilter.getValue() instanceof Integer); assertTrue(equalsFilter.getIsFieldIndexed()); diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java index fbe0ec347..e701ab618 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java @@ -42,7 +42,7 @@ public void testFindIndexedIdSet4() { @Test public void testFindIndexedIdSet5() { NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setIndexer(new NitriteTextIndexer()); + notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); notEqualsFilter.setIsFieldIndexed(null); assertEquals(0, notEqualsFilter.findIndexedIdSet().size()); } @@ -51,7 +51,7 @@ public void testFindIndexedIdSet5() { public void testFindIndexedIdSet6() { NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); notEqualsFilter.setIsFieldIndexed(true); - notEqualsFilter.setIndexer(new NitriteTextIndexer()); + notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); notEqualsFilter.setIsFieldIndexed(null); assertEquals(0, notEqualsFilter.findIndexedIdSet().size()); } @@ -98,7 +98,7 @@ public void testApply2() { @Test public void testSetIsFieldIndexed() { NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", 42); - notEqualsFilter.setIndexer(new NitriteTextIndexer()); + notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); notEqualsFilter.setIsFieldIndexed(true); assertTrue(notEqualsFilter.getValue() instanceof Integer); assertTrue(notEqualsFilter.getIsFieldIndexed()); @@ -108,7 +108,7 @@ public void testSetIsFieldIndexed() { public void testSetIsFieldIndexed2() { NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", 42); notEqualsFilter.setObjectFilter(true); - notEqualsFilter.setIndexer(null); + notEqualsFilter.setNitriteIndexer(null); notEqualsFilter.setIsFieldIndexed(true); assertTrue(notEqualsFilter.getIsFieldIndexed()); } @@ -123,7 +123,7 @@ public void testSetIsFieldIndexed3() { @Test public void testSetIsFieldIndexed4() { NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setIndexer(new NitriteTextIndexer()); + notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); notEqualsFilter.setIsFieldIndexed(true); assertTrue(notEqualsFilter.getValue() instanceof String); } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java index bc146b614..b32e1e30e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java @@ -15,7 +15,7 @@ public void testFindIndexedIdSet() { @Test public void testFindIndexedIdSet2() { TextFilter textFilter = new TextFilter("field", "value"); - textFilter.setIndexer(null); + textFilter.setNitriteIndexer(null); textFilter.setIsFieldIndexed(true); assertThrows(FilterException.class, () -> textFilter.findIndexedIdSet()); } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java new file mode 100644 index 000000000..926c16930 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java @@ -0,0 +1,28 @@ +package org.dizitart.no2.index; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class IndexDescriptorTest { + @Test + public void testConstructor() { + IndexDescriptor actualIndexDescriptor = new IndexDescriptor("indexType", "field", "collectionName"); + assertEquals("indexType", actualIndexDescriptor.getIndexType()); + assertEquals("collectionName", actualIndexDescriptor.getCollectionName()); + assertEquals("field", actualIndexDescriptor.getFields()); + } + + @Test + public void testCompareTo() { + IndexDescriptor indexDescriptor = new IndexDescriptor("", "", "collectionName"); + assertEquals(-14, indexDescriptor.compareTo(new IndexDescriptor("indexType", "field", "collectionName"))); + } + + @Test + public void testCompareTo2() { + IndexDescriptor indexDescriptor = new IndexDescriptor("indexType", "field", "collectionName"); + assertEquals(0, indexDescriptor.compareTo(new IndexDescriptor("indexType", "field", "collectionName"))); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexEntryTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexEntryTest.java deleted file mode 100644 index da403c815..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexEntryTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.dizitart.no2.index; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class IndexEntryTest { - @Test - public void testConstructor() { - IndexEntry actualIndexEntry = new IndexEntry("indexType", "field", "collectionName"); - assertEquals("indexType", actualIndexEntry.getIndexType()); - assertEquals("collectionName", actualIndexEntry.getCollectionName()); - assertEquals("field", actualIndexEntry.getField()); - } - - @Test - public void testCompareTo() { - IndexEntry indexEntry = new IndexEntry("", "", "collectionName"); - assertEquals(-14, indexEntry.compareTo(new IndexEntry("indexType", "field", "collectionName"))); - } - - @Test - public void testCompareTo2() { - IndexEntry indexEntry = new IndexEntry("indexType", "field", "collectionName"); - assertEquals(0, indexEntry.compareTo(new IndexEntry("indexType", "field", "collectionName"))); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java index e012507f7..7612946b0 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java @@ -26,7 +26,7 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.store.NitriteStore; import org.junit.After; @@ -122,7 +122,7 @@ public void rebuildIndex(String field, boolean isAsync) { } @Override - public Collection listIndices() { + public Collection listIndices() { return null; } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java index 7c0813651..3c259a8a8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.data.*; @@ -68,7 +68,7 @@ public void testRebuildIndex() { @Test public void testListIndexes() { - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); @@ -80,7 +80,7 @@ public void testListIndexes() { public void testDropIndex() { testListIndexes(); companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); } @@ -88,7 +88,7 @@ public void testDropIndex() { public void testDropAllIndex() { testListIndexes(); companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); + Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 0); } diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java index 52f8cbb5a..96caf0239 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java @@ -29,7 +29,7 @@ /** * @author Anindya Chatterjee */ -public final class FlowableCursor extends FlowableReadableStream { +public final class FlowableCursor extends FlowableRecordStream { private final Callable> supplier; @@ -88,18 +88,18 @@ public FlowableCursor limit(int offset, int size) { return new FlowableCursor<>(sortSupplier); } - public

FlowableReadableStream

project(Class

projectionType) { + public

FlowableRecordStream

project(Class

projectionType) { Callable> projectionSupplier = () -> { Cursor cursor = ObjectHelper.requireNonNull(supplier.call(), "The supplier supplied is null"); return cursor.project(projectionType); }; - return FlowableReadableStream.create(projectionSupplier); + return FlowableRecordStream.create(projectionSupplier); } - public FlowableReadableStream join(FlowableCursor foreignCursor, Lookup lookup, - Class type) { + public FlowableRecordStream join(FlowableCursor foreignCursor, Lookup lookup, + Class type) { Callable> joinSupplier = () -> { Cursor cursor = ObjectHelper.requireNonNull(supplier.call(), "The supplier supplied is null"); @@ -109,6 +109,6 @@ public FlowableReadableStream join(FlowableCursor { +public final class FlowableDocumentCursor extends FlowableRecordStream { private final Callable supplier; @@ -89,16 +89,16 @@ public FlowableDocumentCursor limit(int offset, int size) { return new FlowableDocumentCursor(sortSupplier); } - public FlowableReadableStream project(Document projection) { + public FlowableRecordStream project(Document projection) { Callable> projectionSupplier = () -> { DocumentCursor documentCursor = ObjectHelper.requireNonNull(supplier.call(), "The supplier supplied is null"); return documentCursor.project(projection); }; - return FlowableReadableStream.create(projectionSupplier); + return FlowableRecordStream.create(projectionSupplier); } - public FlowableReadableStream join(FlowableDocumentCursor foreignCursor, Lookup lookup) { + public FlowableRecordStream join(FlowableDocumentCursor foreignCursor, Lookup lookup) { Callable> joinSupplier = () -> { DocumentCursor documentCursor = ObjectHelper.requireNonNull(supplier.call(), "The supplier supplied is null"); @@ -108,6 +108,6 @@ public FlowableReadableStream join(FlowableDocumentCursor foreignCurso return documentCursor.join(foreignDocumentCursor, lookup); }; - return FlowableReadableStream.create(joinSupplier); + return FlowableRecordStream.create(joinSupplier); } } diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableReadableStream.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableRecordStream.java similarity index 81% rename from rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableReadableStream.java rename to rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableRecordStream.java index 70da16f9c..057324ece 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableReadableStream.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableRecordStream.java @@ -26,17 +26,17 @@ /** * @author Anindya Chatterjee */ -public abstract class FlowableReadableStream extends FlowableIterable { +public abstract class FlowableRecordStream extends FlowableIterable { private final Callable> supplier; - FlowableReadableStream(Callable> supplier) { + FlowableRecordStream(Callable> supplier) { super(supplier); this.supplier = supplier; } - static FlowableReadableStream create(Callable> supplier) { - return new FlowableReadableStream(supplier) { + static FlowableRecordStream create(Callable> supplier) { + return new FlowableRecordStream(supplier) { }; } diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxNitriteCollectionImpl.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxNitriteCollectionImpl.java index 9e4448887..f03ee8abc 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxNitriteCollectionImpl.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxNitriteCollectionImpl.java @@ -28,7 +28,7 @@ import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import java.util.Collection; @@ -92,7 +92,7 @@ public Completable rebuildIndex(String field, boolean async) { } @Override - public Single> listIndices() { + public Single> listIndices() { return Single.fromCallable(nitriteCollection::listIndices); } diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java index 9349efadc..f3d3c67ff 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java @@ -27,7 +27,7 @@ import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; @@ -123,7 +123,7 @@ public Completable rebuildIndex(String field, boolean async) { } @Override - public Single> listIndices() { + public Single> listIndices() { return Single.fromCallable(repository::listIndices); } diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxPersistentCollection.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxPersistentCollection.java index fbf6e0861..ec9ae381d 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxPersistentCollection.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxPersistentCollection.java @@ -22,7 +22,7 @@ import org.dizitart.no2.collection.events.CollectionEventInfo; import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.index.IndexEntry; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import java.util.Collection; @@ -35,7 +35,7 @@ public interface RxPersistentCollection { Completable rebuildIndex(String field, boolean async); - Single> listIndices(); + Single> listIndices(); Single hasIndex(String field); From 773f4422b9d0a96c1a2ddc04e4dd683389dd2980 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Fri, 23 Oct 2020 13:21:10 +0530 Subject: [PATCH 02/13] work in progress --- TODO.md | 7 + nitrite-android-example/build.gradle | 4 +- nitrite-bom/build.gradle | 2 +- .../mapdb/collection/CollectionIndexTest.java | 8 +- .../no2/collection/CollectionIndexTest.java | 8 +- .../dizitart/no2/rocksdb/RocksDBStore.java | 4 +- .../rocksdb/formatter/NitriteSerializers.java | 2 +- .../collection/CollectionIndexTest.java | 8 +- .../no2/support/NitriteJsonImporter.java | 6 +- .../collection/DefaultNitriteCollection.java | 4 +- .../operation/DocumentIndexWriter.java | 4 +- .../operation/FilteredRecordStream.java | 2 +- .../collection/operation/IndexOperations.java | 10 +- .../collection/operation/ReadOperations.java | 6 - .../org/dizitart/no2/common/FieldValues.java | 13 ++ .../java/org/dizitart/no2/common/Fields.java | 19 +- .../org/dizitart/no2/filters/AndFilter.java | 15 +- .../java/org/dizitart/no2/filters/Filter.java | 23 --- .../org/dizitart/no2/filters/FilterStep.java | 7 + .../dizitart/no2/filters/LogicalFilter.java | 16 +- .../org/dizitart/no2/filters/OrFilter.java | 16 +- .../dizitart/no2/filters/QueryOptimizer.java | 173 +++++++++++++++--- .../no2/index/BaseNitriteIndexer.java | 23 +-- .../dizitart/no2/index/ComparableIndexer.java | 4 +- .../dizitart/no2/index/IndexDescriptor.java | 16 +- .../no2/migration/commands/Rename.java | 2 +- .../org/dizitart/no2/store/IndexCatalog.java | 20 +- .../DefaultTransactionalCollection.java | 12 +- .../no2/collection/CollectionIndexTest.java | 8 +- .../no2/index/IndexDescriptorTest.java | 2 +- 30 files changed, 286 insertions(+), 158 deletions(-) create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java diff --git a/TODO.md b/TODO.md index e88537ed5..b0fe2bdb8 100644 --- a/TODO.md +++ b/TODO.md @@ -153,4 +153,11 @@ https://docs.yugabyte.com/latest/architecture/docdb/persistence/ https://blog.yugabyte.com/enhancing-rocksdb-for-speed-scale/ +## Query Optimization + - https://www.javatpoint.com/dbms-transforming-relational-expressions + - http://www.cbcb.umd.edu/confcour/Spring2014/CMSC424/query_optimization.pdf + - https://www.tutorialcup.com/dbms/query-optimization.htm + - https://www.geeksforgeeks.org/query-optimization-in-relational-algebra/ + + diff --git a/nitrite-android-example/build.gradle b/nitrite-android-example/build.gradle index 5f13d0ace..47e15a0b3 100644 --- a/nitrite-android-example/build.gradle +++ b/nitrite-android-example/build.gradle @@ -46,7 +46,7 @@ android { exclude 'META-INF/LGPL2.1' } - compileSdkVersion 29 + compileSdkVersion 28 defaultConfig { applicationId "org.dizitart.no2.example.android" @@ -94,7 +94,7 @@ dependencies { annotationProcessor "org.projectlombok:lombok:1.18.14" testImplementation 'junit:junit:4.13.1' - testAnnotationProcessor "org.projectlombok:lombok:1.18.12" + testAnnotationProcessor "org.projectlombok:lombok:1.18.14" androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } diff --git a/nitrite-bom/build.gradle b/nitrite-bom/build.gradle index 5d434edb6..a2db0e5fc 100644 --- a/nitrite-bom/build.gradle +++ b/nitrite-bom/build.gradle @@ -34,7 +34,7 @@ dependencies { api "org.mapdb:mapdb:3.0.8" api "com.h2database:h2-mvstore:1.4.200" api "com.squareup.okhttp3:okhttp:4.9.0" - api "org.rocksdb:rocksdbjni:6.11.6" + api "org.rocksdb:rocksdbjni:6.13.3" api "com.esotericsoftware:kryo:4.0.2" api "org.locationtech.jts:jts-core:1.17.1" api "commons-codec:commons-codec:1.15" diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java index 8727f6c85..84994ee00 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java @@ -142,7 +142,7 @@ public void testRebuildIndex() { insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), false); + collection.rebuildIndex(idx.getIndexFields(), false); } } @@ -154,7 +154,7 @@ public void testRebuildIndexAsync() { Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); await().until(bodyIndexingCompleted()); } } @@ -165,11 +165,11 @@ public void testRebuildIndexOnRunningIndex() { Collection indices = collection.listIndices(); IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java index 1a9bdb9ab..774338f70 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java @@ -138,7 +138,7 @@ public void testRebuildIndex() { insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), false); + collection.rebuildIndex(idx.getIndexFields(), false); } } @@ -150,7 +150,7 @@ public void testRebuildIndexAsync() { Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); await().until(bodyIndexingCompleted()); } } @@ -161,11 +161,11 @@ public void testRebuildIndexOnRunningIndex() { Collection indices = collection.listIndices(); IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java index 9a2002160..179ce532f 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java @@ -11,6 +11,7 @@ import org.dizitart.no2.store.NitriteRTree; import org.dizitart.no2.store.events.StoreEventListener; import org.dizitart.no2.store.events.StoreEvents; +import org.rocksdb.RocksDB; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -139,6 +140,7 @@ private void initEventBus() { } private static String getRocksDbVersion() { - return "6.11.4"; + RocksDB.Version version = RocksDB.rocksdbVersion(); + return version.toString(); } } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java index 226d3d396..5602cda6a 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java @@ -110,7 +110,7 @@ private static class IndexEntrySerializer extends Serializer { @Override public void write(Kryo kryo, Output output, IndexDescriptor object) { output.writeString(object.getCollectionName()); - output.writeString(object.getFields()); + output.writeString(object.getIndexFields()); output.writeString(object.getIndexType()); } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java index d56218dea..b21c4445d 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java @@ -142,7 +142,7 @@ public void testRebuildIndex() { insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), false); + collection.rebuildIndex(idx.getIndexFields(), false); } } @@ -154,7 +154,7 @@ public void testRebuildIndexAsync() { Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); await().until(bodyIndexingCompleted()); } } @@ -165,11 +165,11 @@ public void testRebuildIndexOnRunningIndex() { Collection indices = collection.listIndices(); IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java index 76882c677..4ec53e189 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java @@ -181,9 +181,9 @@ private void readIndices(PersistentCollection collection) throws IOException String data = parser.readValueAs(String.class); IndexDescriptor index = (IndexDescriptor) readEncodedObject(data); if (collection != null && index != null - && index.getFields() != null - && !collection.hasIndex(index.getFields())) { - collection.createIndex(index.getFields(), + && index.getIndexFields() != null + && !collection.hasIndex(index.getIndexFields())) { + collection.createIndex(index.getIndexFields(), IndexOptions.indexOptions(index.getIndexType())); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 5392c5ab0..2d69ecffb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -409,8 +409,8 @@ private void checkOpened() { private void validateRebuildIndex(IndexDescriptor indexDescriptor) { notNull(indexDescriptor, "index cannot be null"); - if (isIndexing(indexDescriptor.getFields())) { - throw new IndexingException("indexing on value " + indexDescriptor.getFields() + " is currently running"); + if (isIndexing(indexDescriptor.getIndexFields())) { + throw new IndexingException("indexing on value " + indexDescriptor.getIndexFields() + " is currently running"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java index 434345d56..da872a28d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java @@ -116,7 +116,7 @@ private void initialize() { private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { if (indexDescriptor != null) { - Fields fields = indexDescriptor.getFields(); + Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); // Object fieldValue = document.get(field); @@ -136,7 +136,7 @@ private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document d private void removeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { if (indexDescriptor != null) { - Fields fields = indexDescriptor.getFields(); + Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); // Object fieldValue = document.get(field); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java index 8adeafbed..2581bbdac 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java @@ -30,7 +30,7 @@ /** * @author Anindya Chatterjee. */ -class FilteredRecordStream implements RecordStream> { +public class FilteredRecordStream implements RecordStream> { private final RecordStream> recordStream; private final Filter filter; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index 3f223eeaf..884c96b94 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -79,7 +79,7 @@ void createIndex(Fields fields, String indexType, boolean isAsync) { // call to this method is already synchronized, only one thread per field // can access it only if rebuild is already not running for that field void buildIndex(IndexDescriptor indexDescriptor, boolean isAsync, boolean rebuild) { - final Fields fields = indexDescriptor.getFields(); + final Fields fields = indexDescriptor.getIndexFields(); if (getBuildFlag(fields).compareAndSet(false, true)) { if (isAsync) { rebuildExecutor.submit(() -> buildIndexInternal(indexDescriptor, rebuild)); @@ -88,7 +88,7 @@ void buildIndex(IndexDescriptor indexDescriptor, boolean isAsync, boolean rebuil } return; } - throw new IndexingException("indexing is already running on " + indexDescriptor.getFields()); + throw new IndexingException("indexing is already running on " + indexDescriptor.getIndexFields()); } void dropIndex(Fields fields) { @@ -121,7 +121,7 @@ void dropAllIndices() { List> futures = new ArrayList<>(); for (IndexDescriptor index : listIndexes()) { - futures.add(runAsync(() -> dropIndex(index.getFields()))); + futures.add(runAsync(() -> dropIndex(index.getIndexFields()))); } for (Future future : futures) { @@ -180,7 +180,7 @@ private void updateIndexDescriptorCache() { } private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild) { - Fields fields = indexDescriptor.getFields(); + Fields fields = indexDescriptor.getIndexFields(); try { alert(EventType.IndexStart, fields); // first put dirty marker @@ -196,7 +196,7 @@ private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); - FieldValues fieldValues = DocumentUtils.getValues(document, indexDescriptor.getFields()); + FieldValues fieldValues = DocumentUtils.getValues(document, indexDescriptor.getIndexFields()); nitriteIndexer.writeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); } } finally { diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java index 9fc37b8ec..0a74a5f61 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java @@ -60,12 +60,6 @@ public DocumentCursor find(Filter filter, FindOptions findOptions) { return find(findOptions); } - // get all indices for this collection - // find the suitable index (prefix included) - // find the index map - // supply indexmap, collectionmap to filter - - prepareFilter(filter); RecordStream> recordStream = findSuitableStream(filter, findOptions); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java index 0c6598041..4a6761a75 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -43,4 +43,17 @@ public Object getValueAt(int index) { return values.get(index).getSecond(); } + + public Fields getFields() { + if (fields != null) { + return fields; + } + + this.fields = new Fields(); + fields.setFieldList(new ArrayList<>()); + for (Pair value : getValues()) { + fields.getFieldList().add(new Pair<>(value.getFirst(), null)); + } + return fields; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java index f472ef254..d7227e7fd 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -27,7 +27,7 @@ public class Fields implements Comparable, Serializable { private List> fieldList; private transient List fieldNames; - private Fields() { + public Fields() { fieldList = new ArrayList<>(); } @@ -76,6 +76,23 @@ public String getEncodedName() { return StringUtils.join(INTERNAL_NAME_SEPARATOR, getFieldNames()); } + public boolean isPrefix(Fields otherFields) { + if (otherFields == null) return false; + List> otherFieldList = otherFields.getFieldList(); + if (otherFieldList != null) { + if (otherFieldList.size() > fieldList.size()) return false; + for (int i = 0; i < otherFieldList.size(); i++) { + String field = fieldList.get(i).getFirst(); + String otherField = otherFieldList.get(i).getFirst(); + if (!field.contentEquals(otherField)) { + return false; + } + } + return true; + } + return false; + } + @Override public String toString() { StringBuilder stringBuilder = new StringBuilder("["); diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java index 8b70cb6c6..9caf54bde 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java @@ -22,20 +22,14 @@ import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import java.util.Arrays; -import java.util.List; - /** * @author Anindya Chatterjee */ @Getter public class AndFilter extends LogicalFilter { - private final Filter rhs; - private final Filter lhs; AndFilter(Filter lhs, Filter rhs) { - this.lhs = lhs; - this.rhs = rhs; + super(lhs, rhs); if (rhs instanceof TextFilter) { throw new FilterException("text filter must be the first filter in and operation"); @@ -44,11 +38,6 @@ public class AndFilter extends LogicalFilter { @Override public boolean apply(Pair element) { - return lhs.apply(element) && rhs.apply(element); - } - - @Override - public List getFilters() { - return Arrays.asList(lhs, rhs); + return getLhs().apply(element) && getRhs().apply(element); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java index bbec9084a..ef0c733d7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java @@ -203,14 +203,6 @@ static Filter byId(NitriteId nitriteId) { * Creates an and filter which performs a logical AND operation on two filters and selects * the documents that satisfy both filters. *

- * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value as 30 and - * // 'name' field has value as John Doe - * collection.find(where("age").eq(30).and(where("name").eq("John Doe"))); - * -- * * @param filter other filter * @return the and filter @@ -223,14 +215,6 @@ default Filter and(Filter filter) { * Creates an or filter which performs a logical OR operation on two filters and selects * the documents that satisfy at least one of the filter. *

- * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value as 30 or - * // 'name' field has value as John Doe - * collection.find(where("age").eq(30).or(where("name").eq("John Doe"))); - * -- * * @param filter other filter * @return the or filter @@ -244,13 +228,6 @@ default Filter or(Filter filter) { * the documents that *_do not_* satisfy the `filter`. This also includes documents * that do not contain the value. *

- * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value not equals to 30 - * collection.find(where("age").eq("age").not()); - * -- * * @return the not filter */ diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java b/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java new file mode 100644 index 000000000..4acc2de28 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java @@ -0,0 +1,7 @@ +package org.dizitart.no2.filters; + +/** + * @author Anindya Chatterjee + */ +public class FilterStep { +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java index 4a9fbb722..55bcf9851 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java @@ -16,11 +16,25 @@ package org.dizitart.no2.filters; +import lombok.Getter; + +import java.util.Arrays; import java.util.List; /** * @author Anindya Chatterjee. */ +@Getter public abstract class LogicalFilter extends NitriteFilter { - public abstract List getFilters(); + private final Filter rhs; + private final Filter lhs; + + public LogicalFilter(Filter lhs, Filter rhs) { + this.lhs = lhs; + this.rhs = rhs; + } + + public List getFilters() { + return Arrays.asList(lhs, rhs); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java index ec53df2d6..820467f61 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java @@ -21,29 +21,17 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import java.util.Arrays; -import java.util.List; - /** * @author Anindya Chatterjee */ @Getter public class OrFilter extends LogicalFilter { - private final Filter rhs; - private final Filter lhs; - OrFilter(Filter lhs, Filter rhs) { - this.lhs = lhs; - this.rhs = rhs; - } - - @Override - public List getFilters() { - return Arrays.asList(lhs, rhs); + super(lhs, rhs); } @Override public boolean apply(Pair element) { - return lhs.apply(element) || rhs.apply(element); + return getLhs().apply(element) || getRhs().apply(element); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java index 8a4ef3553..49fe6b895 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -5,57 +5,186 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.FindOptions; import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.BaseNitriteIndexer; import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import static org.dizitart.no2.filters.FluentFilter.$; +import static org.dizitart.no2.filters.FluentFilter.where; + + /** * @author Anindya Chatterjee */ public class QueryOptimizer { - private BaseNitriteIndexer nitriteIndexer; - private NitriteConfig nitriteConfig; + private final NitriteConfig nitriteConfig; + + public QueryOptimizer(NitriteConfig nitriteConfig) { + this.nitriteConfig = nitriteConfig; + } + + public FilterStep optimizeFilter(NitriteMap primaryCollection, + Filter filter, + FindOptions findOptions) { - public RecordStream> findOptimizedStream(Filter filter, + } + + private void flattenFilter(Filter filter) { + Stack filterStack = new Stack<>(); + List andComponents = new ArrayList<>(); + List orComponents = new ArrayList<>(); + + if (filter instanceof LogicalFilter) { + LogicalFilter logicalFilter = (LogicalFilter) filter; + for (Filter f : logicalFilter.getFilters()) { + if (!(f instanceof OrFilter)) { + andComponents.add(f); + } else { + orComponents.add(f); + } + } + } + } + + @SuppressWarnings("unchecked") + public RecordStream> findOptimizedStream(NitriteMap primaryCollection, + Filter filter, FindOptions findOptions) { if (filter == null) { - return findOptimizedStreamByOption(findOptions); + return optimizedStream(null, findOptions, primaryCollection); } - // 1. AND - // 2. OR (AND) - // 3. Union stream (for OR call recursively this method) - if (filter instanceof AndFilter) { AndFilter andFilter = (AndFilter) filter; - FieldValues fieldValues = decompose(andFilter); - IndexDescriptor descriptor = findSuitableIndex(fieldValues); - - if (nitriteIndexer.isCompoundIndex(descriptor)) { - NitriteMap indexMap = nitriteIndexer.getCompoundIndexMap(descriptor, - nitriteConfig.getNitriteStore(), fieldValues.getFirstValue().getClass()); + FieldValues fieldValues = decomposeAnd(andFilter); + NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); + return optimizedStream(filter, findOptions, primaryCollection, indexMap); + } else if (filter instanceof OrFilter) { + OrFilter orFilter = (OrFilter) filter; + List fieldValuesList = decomposeOr(orFilter); + List> indexedMaps = new ArrayList<>(); + + for (FieldValues fieldValues : fieldValuesList) { + NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); + if (indexMap != null) { + indexedMaps.add(indexMap); + } } + + return optimizedStream(filter, findOptions, primaryCollection, indexedMaps.toArray(new NitriteMap[0])); + } else if (filter instanceof IndexAwareFilter) { + FieldValues fieldValues = decomposeFilter(filter); + NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); + return optimizedStream(filter, findOptions, primaryCollection, indexMap); + } else { + return optimizedStream(filter, findOptions, primaryCollection); } } - private RecordStream> findOptimizedStreamByOption(FindOptions findOptions) { - return null; + private FieldValues decomposeFilter(Filter filter) { + FieldValues fieldValues = new FieldValues(); + if (filter instanceof ComparisonFilter) { + ComparisonFilter comparisonFilter = (ComparisonFilter) filter; + fieldValues.getValues().add(new Pair<>(comparisonFilter.getField(), comparisonFilter.getComparable())); + } else if (filter instanceof AndFilter) { + AndFilter andFilter = (AndFilter) filter; + FieldValues fv = decomposeAnd(andFilter); + fieldValues.getValues().addAll(fv.getValues()); + } + return fieldValues; } - private FieldValues decompose(AndFilter filter) { + private FieldValues decomposeAnd(AndFilter filter) { FieldValues fieldValues = new FieldValues(); Filter lhs = filter.getLhs(); Filter rhs = filter.getRhs(); - if (lhs instanceof ComparisonFilter) { - + // if there are any OR filter in any of the arms, nitrite will not consider it + FieldValues lhsFieldValues = decomposeFilter(lhs); + FieldValues rhsFieldValues = decomposeFilter(rhs); + fieldValues.getValues().addAll(lhsFieldValues.getValues()); + fieldValues.getValues().addAll(rhsFieldValues.getValues()); + return fieldValues; + } + + private List decomposeOr(OrFilter filter) { + List fieldValues = new ArrayList<>(); + + Filter lhs = filter.getLhs(); + Filter rhs = filter.getRhs(); + + if (lhs instanceof OrFilter) { + fieldValues.addAll(decomposeOr((OrFilter) lhs)); + } else { + fieldValues.add(decomposeFilter(lhs)); + } + + if (rhs instanceof OrFilter) { + fieldValues.addAll(decomposeOr((OrFilter) rhs)); + } else { + fieldValues.add(decomposeFilter(rhs)); + } + + return fieldValues; + } + + private NitriteMap, ?> findSuitableIndexMap(String collectionName, FieldValues fieldValues) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); + IndexDescriptor descriptor = null; + + if (indexCatalog != null) { + NavigableMap indexScore = new TreeMap<>(Collections.reverseOrder()); + + Fields fields = fieldValues.getFields(); + Collection indexDescriptors = indexCatalog.listIndexDescriptors(collectionName); + for (IndexDescriptor indexDescriptor : indexDescriptors) { + Fields indexFields = indexDescriptor.getIndexFields(); + if (indexFields.isPrefix(fields)) { + int keySize = indexFields.getFieldNames().size(); + int score = IndexType.Unique.equals(indexDescriptor.getIndexType()) ? keySize + 10 : keySize; + indexScore.put(score, indexDescriptor); + } + } + + if (!indexScore.isEmpty()) { + descriptor = indexScore.firstEntry().getValue(); + } } + + return getIndexMap(descriptor, fieldValues); } - private IndexDescriptor findSuitableIndex(FieldValues fieldValues) { - return null; + private NitriteMap, ?> getIndexMap(IndexDescriptor indexDescriptor, FieldValues fieldValues) { + if (indexDescriptor == null) return null; + + String indexMapName = nitriteConfig.getNitriteStore().getIndexCatalog().getIndexMapName(indexDescriptor); + Class keyType = fieldValues.getFirstValue() == null ? Comparable.class + : fieldValues.getFirstValue().getClass(); + Class valueType = indexDescriptor.isCompoundIndex() ? ConcurrentSkipListMap.class + : ConcurrentSkipListSet.class; + + return nitriteConfig.getNitriteStore().openMap(indexMapName, keyType, valueType); + } + + + @SafeVarargs + private final RecordStream> optimizedStream(Filter filter, + FindOptions findOptions, + NitriteMap primaryCollection, + NitriteMap, ?>... indexMaps) { + if (filter == null) { + return primaryCollection.entries(); + } + + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java index 6f5ea5768..d04863de1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java @@ -10,9 +10,6 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; -import static org.dizitart.no2.common.Constants.INDEX_PREFIX; -import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; - /** * @author Anindya Chatterjee */ @@ -21,7 +18,7 @@ public abstract class BaseNitriteIndexer implements NitriteIndexer { @Override public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { NitriteMap indexMap; - if (isCompoundIndex(indexDescriptor)) { + if (indexDescriptor.isCompoundIndex()) { indexMap = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); } else { indexMap = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); @@ -30,15 +27,11 @@ public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConf indexMap.drop(); } - public boolean isCompoundIndex(IndexDescriptor indexDescriptor) { - return indexDescriptor.getFields().getFieldNames().size() > 1; - } - @SuppressWarnings("rawtypes") public NitriteMap> getSimpleIndexMap(IndexDescriptor indexDescriptor, NitriteStore nitriteStore, Class keyType) { - String mapName = getIndexMapName(indexDescriptor); + String mapName = getIndexMapName(indexDescriptor, nitriteStore); return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListSet.class); } @@ -46,17 +39,11 @@ public NitriteMap> getSimpleIndexMap(IndexDescriptor public NitriteMap> getCompoundIndexMap(IndexDescriptor indexDescriptor, NitriteStore nitriteStore, Class keyType) { - String mapName = getIndexMapName(indexDescriptor); + String mapName = getIndexMapName(indexDescriptor, nitriteStore); return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListMap.class); } - protected String getIndexMapName(IndexDescriptor indexDescriptor) { - return INDEX_PREFIX + - INTERNAL_NAME_SEPARATOR + - indexDescriptor.getCollectionName() + - INTERNAL_NAME_SEPARATOR + - indexDescriptor.getFields().getEncodedName() + - INTERNAL_NAME_SEPARATOR + - getIndexType(); + protected String getIndexMapName(IndexDescriptor indexDescriptor, NitriteStore nitriteStore) { + return nitriteStore.getIndexCatalog().getIndexMapName(indexDescriptor); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java index e02297111..42e88672a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java @@ -83,7 +83,7 @@ public RecordStream findByFilter(String collectionName, Filter filter public void writeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { - if (isCompoundIndex(indexDescriptor)) { + if (indexDescriptor.isCompoundIndex()) { writeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); } else { writeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); @@ -94,7 +94,7 @@ public void writeIndexEntry(IndexDescriptor indexDescriptor, public void removeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { - if (isCompoundIndex(indexDescriptor)) { + if (indexDescriptor.isCompoundIndex()) { removeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); } else { removeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index e9bee5136..746d13b9e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -57,7 +57,7 @@ public class IndexDescriptor implements Comparable, Serializabl * @return the target fields. */ @Getter - private Fields fields; + private Fields indexFields; /** * Gets the collection name. @@ -81,26 +81,30 @@ public IndexDescriptor(String indexType, Fields fields, String collectionName) { notEmpty(collectionName, "collectionName cannot be empty"); this.indexType = indexType; - this.fields = fields; + this.indexFields = fields; this.collectionName = collectionName; } @Override public int compareTo(IndexDescriptor other) { - String string = collectionName + fields + indexType; - String otherString = other.collectionName + other.fields + other.indexType; + String string = collectionName + indexFields + indexType; + String otherString = other.collectionName + other.indexFields + other.indexType; return string.compareTo(otherString); } + public boolean isCompoundIndex() { + return indexFields.getFieldNames().size() > 1; + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeUTF(indexType); - stream.writeObject(fields); + stream.writeObject(indexFields); stream.writeUTF(collectionName); } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { indexType = stream.readUTF(); - fields = (Fields) stream.readObject(); + indexFields = (Fields) stream.readObject(); collectionName = stream.readUTF(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java index 13bcfdca5..687ce64a7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java @@ -34,7 +34,7 @@ public void execute(Nitrite nitrite) { IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); Collection indexEntries = indexCatalog.listIndexDescriptors(oldName); for (IndexDescriptor indexDescriptor : indexEntries) { - String field = indexDescriptor.getFields(); + String field = indexDescriptor.getIndexFields(); String indexType = indexDescriptor.getIndexType(); newOperations.createIndex(field, indexType, false); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java index fabea140d..a1d08e378 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java @@ -99,6 +99,16 @@ public void endIndexing(String collectionName, Fields fields) { markDirty(collectionName, fields, false); } + public String getIndexMapName(IndexDescriptor descriptor) { + return INDEX_PREFIX + + INTERNAL_NAME_SEPARATOR + + descriptor.getCollectionName() + + INTERNAL_NAME_SEPARATOR + + descriptor.getIndexFields().getEncodedName() + + INTERNAL_NAME_SEPARATOR + + descriptor.getIndexType(); + } + private NitriteMap getIndexMetaMap(String collectionName) { String indexMetaName = getIndexMetaName(collectionName); return nitriteStore.openMap(indexMetaName, Fields.class, IndexMeta.class); @@ -114,14 +124,4 @@ private void markDirty(String collectionName, Fields fields, boolean dirty) { meta.getIsDirty().set(dirty); } } - - private String getIndexMapName(IndexDescriptor index) { - return INDEX_PREFIX + - INTERNAL_NAME_SEPARATOR + - index.getCollectionName() + - INTERNAL_NAME_SEPARATOR + - index.getFields().getEncodedName() + - INTERNAL_NAME_SEPARATOR + - index.getIndexType(); - } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java index b6dd35517..015809d7c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java @@ -383,7 +383,7 @@ public void dropIndex(Fields fields) { journalEntry.setChangeType(ChangeType.DropIndex); journalEntry.setCommit(() -> { for (IndexDescriptor entry : primary.listIndices()) { - if (entry.getFields().equals(fields)) { + if (entry.getIndexFields().equals(fields)) { indexEntry.set(entry); break; } @@ -392,7 +392,7 @@ public void dropIndex(Fields fields) { }); journalEntry.setRollback(() -> { if (indexEntry.get() != null) { - primary.createIndex(indexEntry.get().getFields(), + primary.createIndex(indexEntry.get().getIndexFields(), indexOptions(indexEntry.get().getIndexType())); } }); @@ -420,7 +420,7 @@ public void dropAllIndices() { }); journalEntry.setRollback(() -> { for (IndexDescriptor indexDescriptor : indexEntries) { - primary.createIndex(indexDescriptor.getFields(), + primary.createIndex(indexDescriptor.getIndexFields(), indexOptions(indexDescriptor.getIndexType())); } }); @@ -479,7 +479,7 @@ public void drop() { NitriteCollection collection = nitrite.getCollection(collectionName); for (IndexDescriptor indexDescriptor : indexEntries) { - collection.createIndex(indexDescriptor.getFields(), + collection.createIndex(indexDescriptor.getIndexFields(), indexOptions(indexDescriptor.getIndexType())); } @@ -632,8 +632,8 @@ private void closeEventBus() { private void validateRebuildIndex(IndexDescriptor indexDescriptor) { notNull(indexDescriptor, "indexEntry cannot be null"); - if (isIndexing(indexDescriptor.getFields())) { - throw new IndexingException("indexing on value " + indexDescriptor.getFields() + " is currently running"); + if (isIndexing(indexDescriptor.getIndexFields())) { + throw new IndexingException("indexing on value " + indexDescriptor.getIndexFields() + " is currently running"); } } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java index 1a9bdb9ab..774338f70 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java @@ -138,7 +138,7 @@ public void testRebuildIndex() { insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), false); + collection.rebuildIndex(idx.getIndexFields(), false); } } @@ -150,7 +150,7 @@ public void testRebuildIndexAsync() { Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); await().until(bodyIndexingCompleted()); } } @@ -161,11 +161,11 @@ public void testRebuildIndexOnRunningIndex() { Collection indices = collection.listIndices(); IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); boolean error = false; try { - collection.rebuildIndex(idx.getFields(), true); + collection.rebuildIndex(idx.getIndexFields(), true); } catch (IndexingException ie) { error = true; } finally { diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java index 926c16930..af1884fd9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java @@ -10,7 +10,7 @@ public void testConstructor() { IndexDescriptor actualIndexDescriptor = new IndexDescriptor("indexType", "field", "collectionName"); assertEquals("indexType", actualIndexDescriptor.getIndexType()); assertEquals("collectionName", actualIndexDescriptor.getCollectionName()); - assertEquals("field", actualIndexDescriptor.getFields()); + assertEquals("field", actualIndexDescriptor.getIndexFields()); } @Test From 58489a093b9d776932f1ce773c60b292144ec4cc Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Sun, 15 Nov 2020 18:18:59 +0530 Subject: [PATCH 03/13] work in progress --- .../dizitart/no2/mapper/JacksonExtension.java | 2 +- .../dizitart/no2/mapper/JacksonMapper.java | 2 +- .../mapper/extensions/NitriteIdExtension.java | 2 +- .../no2/spatial/mapper/GeometryExtension.java | 2 +- .../operation/DocumentIndexWriter.java | 6 +- .../collection/operation/IndexOperations.java | 13 +- .../org/dizitart/no2/common/FieldNames.java | 28 +++ .../org/dizitart/no2/common/FieldValues.java | 4 +- .../java/org/dizitart/no2/common/Fields.java | 32 ++-- .../dizitart/no2/common/FilterFieldNames.java | 23 +++ .../dizitart/no2/common/IndexFieldNames.java | 23 +++ .../org/dizitart/no2/filters/AndFilter.java | 16 +- .../no2/filters/FieldBasedFilter.java | 24 +++ .../java/org/dizitart/no2/filters/Filter.java | 44 +++-- .../dizitart/no2/filters/LogicalFilter.java | 12 +- .../org/dizitart/no2/filters/OrFilter.java | 10 +- .../dizitart/no2/filters/QueryOptimizer.java | 161 ++++++++++++++++-- .../dizitart/no2/index/IndexDescriptor.java | 3 +- .../no2/index/NitriteTextIndexer.java | 1 - .../no2/migration/commands/AddField.java | 6 +- .../no2/migration/commands/BaseCommand.java | 3 - .../migration/commands/ChangeDataType.java | 4 +- .../no2/migration/commands/DeleteField.java | 6 +- .../no2/migration/commands/Rename.java | 3 +- .../no2/migration/commands/RenameField.java | 12 +- .../no2/store/AbstractNitriteStore.java | 6 +- .../org/dizitart/no2/store/IndexCatalog.java | 52 +++++- .../org/dizitart/kno2/BackportJavaTimeTest.kt | 2 +- 28 files changed, 393 insertions(+), 109 deletions(-) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java index 2020b2048..fe2643bdb 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java @@ -24,6 +24,6 @@ * @author Anindya Chatterjee */ public interface JacksonExtension { - List> getDataTypes(); + List> getSupportedTypes(); Module getModule(); } diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java index e9789712d..5224ed104 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java @@ -164,7 +164,7 @@ protected Document convertToDocument(Source source) { } private void loadJacksonExtension(JacksonExtension jacksonExtension, ObjectMapper objectMapper) { - for (Class dataType : jacksonExtension.getDataTypes()) { + for (Class dataType : jacksonExtension.getSupportedTypes()) { addValueType(dataType); } objectMapper.registerModule(jacksonExtension.getModule()); diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java index 6cb872e84..ca49157bd 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java @@ -34,7 +34,7 @@ public class NitriteIdExtension implements JacksonExtension { @Override - public List> getDataTypes() { + public List> getSupportedTypes() { return listOf(NitriteId.class); } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java index e9528391b..9f905d71c 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java @@ -38,7 +38,7 @@ public class GeometryExtension implements JacksonExtension { public static final String GEOMETRY_ID = "geometry:"; @Override - public List> getDataTypes() { + public List> getSupportedTypes() { return listOf(Geometry.class); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java index da872a28d..1b5ce10c2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java @@ -38,7 +38,6 @@ class DocumentIndexWriter { private final NitriteMap nitriteMap; private final IndexOperations indexOperations; private String collectionName; - private IndexCatalog indexCatalog; DocumentIndexWriter(NitriteConfig nitriteConfig, NitriteMap nitriteMap, @@ -109,12 +108,13 @@ void updateIndexEntry(Document oldDocument, Document newDocument) { private void initialize() { NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); - this.indexCatalog = nitriteStore.getIndexCatalog(); this.collectionName = nitriteMap.getName(); } private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { + IndexCatalog indexCatalog = nitriteMap.getStore().getIndexCatalog(); + if (indexDescriptor != null) { Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); @@ -135,6 +135,8 @@ private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document d private void removeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { + IndexCatalog indexCatalog = nitriteMap.getStore().getIndexCatalog(); + if (indexDescriptor != null) { Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index 884c96b94..eef327b0c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -17,7 +17,6 @@ import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; import java.util.ArrayList; import java.util.Collection; @@ -40,7 +39,6 @@ class IndexOperations implements AutoCloseable { private final EventBus, CollectionEventListener> eventBus; private String collectionName; - private IndexCatalog indexCatalog; private Map indexBuildRegistry; private ExecutorService rebuildExecutor; private Collection indexDescriptorCache; @@ -62,6 +60,7 @@ public void close() { void createIndex(Fields fields, String indexType, boolean isAsync) { IndexDescriptor indexDescriptor; + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); if (!hasIndexEntry(fields)) { // if no index create index indexDescriptor = indexCatalog.createIndexDescriptor(collectionName, fields, indexType); @@ -96,6 +95,7 @@ void dropIndex(Fields fields) { throw new IndexingException("cannot drop index as indexing is running on " + fields); } + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); IndexDescriptor indexDescriptor = findIndexDescriptor(fields); if (indexDescriptor != null) { String indexType = indexDescriptor.getIndexType(); @@ -139,6 +139,7 @@ void dropAllIndices() { } boolean isIndexing(Fields field) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); // has an index will only return true, if there is an index on // the value and indexing is not running on it return indexCatalog.hasIndexDescriptor(collectionName, field) @@ -146,6 +147,7 @@ boolean isIndexing(Fields field) { } boolean hasIndexEntry(Fields field) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); return indexCatalog.hasIndexDescriptor(collectionName, field); } @@ -154,7 +156,8 @@ Collection listIndexes() { } IndexDescriptor findIndexDescriptor(Fields field) { - return indexCatalog.findIndexDescriptor(collectionName, field); + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); + return indexCatalog.findIndexDescriptorExact(collectionName, field); } AtomicBoolean getBuildFlag(Fields field) { @@ -167,8 +170,6 @@ AtomicBoolean getBuildFlag(Fields field) { } private void initialize() { - NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); - this.indexCatalog = nitriteStore.getIndexCatalog(); this.collectionName = nitriteMap.getName(); this.indexBuildRegistry = new ConcurrentHashMap<>(); this.rebuildExecutor = ThreadPoolManager.workerPool(); @@ -176,10 +177,12 @@ private void initialize() { } private void updateIndexDescriptorCache() { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); indexDescriptorCache = indexCatalog.listIndexDescriptors(collectionName); } private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); Fields fields = indexDescriptor.getIndexFields(); try { alert(EventType.IndexStart, fields); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java new file mode 100644 index 000000000..328fa39a5 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java @@ -0,0 +1,28 @@ +package org.dizitart.no2.common; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Objects; +import java.util.Set; + +/** + * @author Anindya Chatterjee + */ +@Getter @Setter +public class FieldNames { + private Set names; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FieldNames)) return false; + FieldNames that = (FieldNames) o; + return Objects.equals(getNames(), that.getNames()); + } + + @Override + public int hashCode() { + return Objects.hash(getNames()); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java index 4a6761a75..f6e1eb870 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -50,9 +50,9 @@ public Fields getFields() { } this.fields = new Fields(); - fields.setFieldList(new ArrayList<>()); + fields.setDescriptor(new ArrayList<>()); for (Pair value : getValues()) { - fields.getFieldList().add(new Pair<>(value.getFirst(), null)); + fields.getDescriptor().add(new Pair<>(value.getFirst(), null)); } return fields; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java index d7227e7fd..179181cba 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -24,16 +24,16 @@ public class Fields implements Comparable, Serializable { private static final long serialVersionUID = 1601646404L; // order of the given fields matter - private List> fieldList; - private transient List fieldNames; + private List> descriptor; + private transient FieldNames fieldNames; public Fields() { - fieldList = new ArrayList<>(); + descriptor = new ArrayList<>(); } public static Fields single(String field) { Fields fields = new Fields(); - fields.fieldList.add(new Pair<>(field, SortOrder.Ascending)); + fields.descriptor.add(new Pair<>(field, SortOrder.Ascending)); return fields; } @@ -43,28 +43,28 @@ public static Fields multiple(Pair... fields) { notEmpty(fields, "fields cannot be empty"); Fields f = new Fields(); - f.fieldList.addAll(Arrays.asList(fields)); + f.descriptor.addAll(Arrays.asList(fields)); return f; } - public List getFieldNames() { + public FieldNames getFieldNames() { if (fieldNames != null) { return fieldNames; } fieldNames = new ArrayList<>(); - for (Pair pair : fieldList) { + for (Pair pair : descriptor) { fieldNames.add(pair.getFirst()); } return fieldNames; } public Pair getFirstKey() { - return fieldList.get(0); + return descriptor.get(0); } public SortOrder getSortOrder(String fieldName) { - for (Pair pair : fieldList) { + for (Pair pair : descriptor) { if (pair.getFirst().equals(fieldName)) { return pair.getSecond(); } @@ -78,11 +78,11 @@ public String getEncodedName() { public boolean isPrefix(Fields otherFields) { if (otherFields == null) return false; - List> otherFieldList = otherFields.getFieldList(); + List> otherFieldList = otherFields.getDescriptor(); if (otherFieldList != null) { - if (otherFieldList.size() > fieldList.size()) return false; + if (otherFieldList.size() > descriptor.size()) return false; for (int i = 0; i < otherFieldList.size(); i++) { - String field = fieldList.get(i).getFirst(); + String field = descriptor.get(i).getFirst(); String otherField = otherFieldList.get(i).getFirst(); if (!field.contentEquals(otherField)) { return false; @@ -97,7 +97,7 @@ public boolean isPrefix(Fields otherFields) { public String toString() { StringBuilder stringBuilder = new StringBuilder("["); int count = 0; - for (Pair field : fieldList) { + for (Pair field : descriptor) { count++; stringBuilder.append("{") .append(field.getFirst()) @@ -105,7 +105,7 @@ public String toString() { .append(field.getSecond()) .append("}"); - if (count != fieldList.size()) { + if (count != descriptor.size()) { stringBuilder.append(", "); } } @@ -134,11 +134,11 @@ public int compareTo(Fields other) { } private void writeObject(ObjectOutputStream stream) throws IOException { - stream.writeObject(fieldList); + stream.writeObject(descriptor); } @SuppressWarnings("unchecked") private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - fieldList = (List>) stream.readObject(); + descriptor = (List>) stream.readObject(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java new file mode 100644 index 000000000..4636ce651 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java @@ -0,0 +1,23 @@ +package org.dizitart.no2.common; + +import lombok.Getter; +import lombok.Setter; +import org.dizitart.no2.filters.Filter; + +/** + * @author Anindya Chatterjee + */ +@Getter @Setter +public class FilterFieldNames extends FieldNames { + private Filter filter; + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java new file mode 100644 index 000000000..ad27d7b49 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java @@ -0,0 +1,23 @@ +package org.dizitart.no2.common; + +import lombok.Getter; +import lombok.Setter; +import org.dizitart.no2.index.IndexDescriptor; + +/** + * @author Anindya Chatterjee + */ +@Getter @Setter +public class IndexFieldNames extends FieldNames { + private IndexDescriptor indexDescriptor; + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java index 9caf54bde..845fb0d13 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java @@ -28,16 +28,22 @@ @Getter public class AndFilter extends LogicalFilter { - AndFilter(Filter lhs, Filter rhs) { - super(lhs, rhs); + AndFilter(Filter... filters) { + super(filters); - if (rhs instanceof TextFilter) { - throw new FilterException("text filter must be the first filter in and operation"); + for (int i = 1; i < filters.length; i++) { + if (filters[i] instanceof TextFilter) { + throw new FilterException("text filter must be the first filter in AND operation"); + } } } @Override public boolean apply(Pair element) { - return getLhs().apply(element) && getRhs().apply(element); + boolean result = true; + for (Filter filter : getFilters()) { + result = result && filter.apply(element); + } + return result; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java index 06a160a68..52d10c8d0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java @@ -49,6 +49,30 @@ protected FieldBasedFilter(String field, Object value) { this.value = value; } + /** + * Creates an and filter which performs a logical AND operation on two filters and selects + * the documents that satisfy both filters. + *

+ * + * @param filter other filter + * @return the and filter + */ + public Filter and(Filter filter) { + return new AndFilter(this, filter); + } + + /** + * Creates an or filter which performs a logical OR operation on two filters and selects + * the documents that satisfy at least one of the filter. + *

+ * + * @param filter other filter + * @return the or filter + */ + public Filter or(Filter filter) { + return new OrFilter(this, filter); + } + protected Set> convertValues(Set> values) { if (getObjectFilter()) { NitriteMapper nitriteMapper = getNitriteConfig().nitriteMapper(); diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java index ef0c733d7..346e3df30 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java @@ -20,8 +20,10 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.FilterException; import static org.dizitart.no2.common.Constants.DOC_ID; +import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; /** * An interface to specify filtering criteria during find operation. When @@ -190,6 +192,24 @@ static Filter byId(NitriteId nitriteId) { return new EqualsFilter(DOC_ID, nitriteId.getIdValue()); } + static Filter and(Filter... filters) { + notEmpty(filters, "at least two filters must be specified"); + if (filters.length < 2) { + throw new FilterException("at least two filters must be specified"); + } + + return new AndFilter(filters); + } + + static Filter or(Filter... filters) { + notEmpty(filters, "at least two filters must be specified"); + if (filters.length < 2) { + throw new FilterException("at least two filters must be specified"); + } + + return new OrFilter(filters); + } + /** * Filters a document map and returns the set of {@link NitriteId}s of * matching {@link Document}s. @@ -199,30 +219,6 @@ static Filter byId(NitriteId nitriteId) { */ boolean apply(Pair element); - /** - * Creates an and filter which performs a logical AND operation on two filters and selects - * the documents that satisfy both filters. - *

- * - * @param filter other filter - * @return the and filter - */ - default Filter and(Filter filter) { - return new AndFilter(this, filter); - } - - /** - * Creates an or filter which performs a logical OR operation on two filters and selects - * the documents that satisfy at least one of the filter. - *

- * - * @param filter other filter - * @return the or filter - */ - default Filter or(Filter filter) { - return new OrFilter(this, filter); - } - /** * Creates a not filter which performs a logical NOT operation on a `filter` and selects * the documents that *_do not_* satisfy the `filter`. This also includes documents diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java index 55bcf9851..7cb47cc3e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java @@ -26,15 +26,9 @@ */ @Getter public abstract class LogicalFilter extends NitriteFilter { - private final Filter rhs; - private final Filter lhs; + private final List filters; - public LogicalFilter(Filter lhs, Filter rhs) { - this.lhs = lhs; - this.rhs = rhs; - } - - public List getFilters() { - return Arrays.asList(lhs, rhs); + public LogicalFilter(Filter... filters) { + this.filters = Arrays.asList(filters); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java index 820467f61..c5fcd3331 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java @@ -26,12 +26,16 @@ */ @Getter public class OrFilter extends LogicalFilter { - OrFilter(Filter lhs, Filter rhs) { - super(lhs, rhs); + OrFilter(Filter... filters) { + super(filters); } @Override public boolean apply(Pair element) { - return getLhs().apply(element) || getRhs().apply(element); + boolean result = false; + for (Filter filter : getFilters()) { + result = result || filter.apply(element); + } + return result; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java index 49fe6b895..985da7cef 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -7,6 +7,7 @@ import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; @@ -17,9 +18,6 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; -import static org.dizitart.no2.filters.FluentFilter.$; -import static org.dizitart.no2.filters.FluentFilter.where; - /** * @author Anindya Chatterjee @@ -27,6 +25,29 @@ public class QueryOptimizer { private final NitriteConfig nitriteConfig; + /* + * 1. If And filter + * 1.1 flatten the filter using depth first traversal + * 1.2 check each filter, group OR & AND, single field filters + * 1.3 scan through single field filter or and filter if there is any match for composite index + * 1.3.1 if matching composite index found, get index stream + * 1.3.2 group remaining filters as a new and filter and apply on indexed stream from 1.3.1 + * 1.4 if no matching composite index found, scan for simple index + * 1.4.1 if found, get indexed stream + * 1.4.2 group remaining filter as a new and filter and apply on index stream from 1.4.1 + * 1.5 if no matching index found, collscan and apply filter + * + * 2. If OR filter + * 1.1 If every simple field is indexed or and filter composite indexed + * 1.1.1 + * 1.2 If one of the fields is not indexed, get collscan and apply filter + * + * 3. If simple filter + * 3.1 Check if index exists, send indexed stream + * 3.2 If no index found, collscan + * + * */ + public QueryOptimizer(NitriteConfig nitriteConfig) { this.nitriteConfig = nitriteConfig; } @@ -37,22 +58,132 @@ public FilterStep optimizeFilter(NitriteMap primaryCollecti } - private void flattenFilter(Filter filter) { - Stack filterStack = new Stack<>(); - List andComponents = new ArrayList<>(); - List orComponents = new ArrayList<>(); - - if (filter instanceof LogicalFilter) { - LogicalFilter logicalFilter = (LogicalFilter) filter; - for (Filter f : logicalFilter.getFilters()) { - if (!(f instanceof OrFilter)) { - andComponents.add(f); - } else { - orComponents.add(f); + private void flattenFilter(String collectionName, Filter filter) { + if (filter instanceof AndFilter) { + List flattenedFilter = ((AndFilter) filter).getFilters(); + Pair optimizedAnd = optimize(collectionName, flattenedFilter); + } + + } + + private Pair optimize(String collectionName, List flattenedFilter) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); + for (int i = 0; i < flattenedFilter.size(); i++) { + List filters = flattenedFilter.subList(0, i + 1); + Fields fields = getFields(filters); + } + + + for (Filter filter : flattenedFilter) { + if (filter instanceof FieldBasedFilter) { + FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; + Fields fields = Fields.single(fieldBasedFilter.getField()); + Set descriptors = indexCatalog.findMatchingIndexDescriptor(collectionName, fields); + if (descriptors != null) { + } } + if (filter instanceof AndFilter) { + + } } + +// TODO: use fieldNames as object to create cache and compare + + + return null; } + + private Fields getFields(List filters) { + Fields fields = new Fields(); + for (Filter filter : filters) { + if (filter instanceof FieldBasedFilter) { + FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; + fields.getDescriptor().add(new Pair<>(fieldBasedFilter.getField(), SortOrder.Ascending)); + } + } + return null; + } + + private void optimize2(String collectionName, List flattenedFilter) { + IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); + Map> group = new HashMap<>(); + + for (int i = 0; i < flattenedFilter.size(); i++) { + Filter filter = flattenedFilter.get(0); + if (filter instanceof FieldBasedFilter) { + FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; + Fields fields = Fields.single(fieldBasedFilter.getField()); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, fields); + if (indexDescriptor != null) { + List filters = group.get(indexDescriptor); + if (filters == null) { + filters = new ArrayList<>(); + } + filters.add(filter); + group.put(indexDescriptor, filters); + } + } + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @SuppressWarnings("unchecked") public RecordStream> findOptimizedStream(NitriteMap primaryCollection, diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index 746d13b9e..2c2eb368f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -36,8 +36,7 @@ * @see NitriteCollection#createIndex(Fields, IndexOptions) * @since 1.0 */ -@ToString -@EqualsAndHashCode +@Data @NoArgsConstructor(access = AccessLevel.PRIVATE) public class IndexDescriptor implements Comparable, Serializable { private static final long serialVersionUID = 1576690829L; diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java index d9083c4e6..99808fe90 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java @@ -43,7 +43,6 @@ @SuppressWarnings("rawtypes") public class NitriteTextIndexer implements TextIndexer { private final TextTokenizer textTokenizer; - private IndexCatalog indexCatalog; private NitriteStore nitriteStore; public NitriteTextIndexer() { diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java index 39e7a40c4..f18d9d826 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java @@ -8,6 +8,8 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.Generator; +import static org.dizitart.no2.common.Fields.single; + /** * @author Anindya Chatterjee */ @@ -21,7 +23,7 @@ public class AddField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); for (Pair pair : nitriteMap.entries()) { Document document = pair.getSecond(); @@ -35,7 +37,7 @@ public void execute(Nitrite nitrite) { } if (indexDescriptor != null) { - operations.createIndex(fieldName, indexDescriptor.getIndexType(), false); + operations.createIndex(single(fieldName), indexDescriptor.getIndexType(), false); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java index 3e273f8a0..4de2f75f3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java @@ -4,7 +4,6 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.CollectionOperations; -import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; @@ -13,13 +12,11 @@ */ abstract class BaseCommand implements Command { protected NitriteStore nitriteStore; - protected IndexCatalog indexCatalog; protected NitriteMap nitriteMap; protected CollectionOperations operations; void initialize(Nitrite nitrite, String collectionName) { nitriteStore = nitrite.getStore(); - indexCatalog = nitriteStore.getIndexCatalog(); nitriteMap = nitriteStore.openMap(collectionName, NitriteId.class, Document.class); operations = new CollectionOperations(collectionName, nitriteMap, nitrite.getConfig(), null); diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java index cec45fdc0..423974b57 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java @@ -8,6 +8,8 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.TypeConverter; +import static org.dizitart.no2.common.Fields.single; + /** * @author Anindya Chatterjee */ @@ -31,7 +33,7 @@ public void execute(Nitrite nitrite) { nitriteMap.put(entry.getFirst(), document); } - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); if (indexDescriptor != null) { operations.rebuildIndex(indexDescriptor, false); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java index 6e840351d..2f295c059 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java @@ -7,6 +7,8 @@ import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; +import static org.dizitart.no2.common.Fields.single; + /** * @author Anindya Chatterjee */ @@ -19,7 +21,7 @@ public class DeleteField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, fieldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); document.remove(fieldName); @@ -27,7 +29,7 @@ public void execute(Nitrite nitrite) { } if (indexDescriptor != null) { - operations.dropIndex(fieldName); + operations.dropIndex(single(fieldName)); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java index 687ce64a7..c641a74b6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java @@ -5,6 +5,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.CollectionOperations; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.IndexCatalog; @@ -34,7 +35,7 @@ public void execute(Nitrite nitrite) { IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); Collection indexEntries = indexCatalog.listIndexDescriptors(oldName); for (IndexDescriptor indexDescriptor : indexEntries) { - String field = indexDescriptor.getIndexFields(); + Fields field = indexDescriptor.getIndexFields(); String indexType = indexDescriptor.getIndexType(); newOperations.createIndex(field, indexType, false); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java index 2c8a6bbd4..cdc867abc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java @@ -8,6 +8,8 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.IndexCatalog; +import static org.dizitart.no2.common.Fields.single; + /** * @author Anindya Chatterjee */ @@ -21,7 +23,8 @@ public class RenameField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - boolean indexExists = indexCatalog.hasIndexDescriptor(collectionName, oldName); + IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); + boolean indexExists = indexCatalog.hasIndexDescriptor(collectionName, single(oldName)); for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); if (document.containsKey(oldName)) { @@ -34,12 +37,11 @@ public void execute(Nitrite nitrite) { } if (indexExists) { - IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptor(collectionName, oldName); + IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(oldName)); String indexType = indexDescriptor.getIndexType(); - operations.dropIndex(oldName); - operations.createIndex(newName, indexType, false); + operations.dropIndex(single(oldName)); + operations.createIndex(single(newName), indexType, false); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java index d6928e34b..fc66470d0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java @@ -29,6 +29,7 @@ public abstract class AbstractNitriteStore protected final NitriteEventBus eventBus; protected NitriteConfig nitriteConfig; + private IndexCatalog indexCatalog; protected AbstractNitriteStore() { eventBus = new StoreEventBus(); @@ -87,7 +88,10 @@ public void beforeClose() { @Override public IndexCatalog getIndexCatalog() { - return new IndexCatalog(this); + if (indexCatalog == null) { + indexCatalog = new IndexCatalog(this); + } + return indexCatalog; } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java index a1d08e378..5f6aad44b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java @@ -17,13 +17,13 @@ package org.dizitart.no2.store; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import static org.dizitart.no2.common.Constants.*; @@ -61,7 +61,7 @@ public IndexDescriptor createIndexDescriptor(String collectionName, Fields field return index; } - public IndexDescriptor findIndexDescriptor(String collectionName, Fields fields) { + public IndexDescriptor findIndexDescriptorExact(String collectionName, Fields fields) { IndexMeta meta = getIndexMetaMap(collectionName).get(fields); if (meta != null) { return meta.getIndexDescriptor(); @@ -69,6 +69,48 @@ public IndexDescriptor findIndexDescriptor(String collectionName, Fields fields) return null; } + public Set findMatchingIndexDescriptor(String collectionName, Fields queryFields) { + Collection indexDescriptors = listIndexDescriptors(collectionName); + Map> descriptorMap = new ConcurrentHashMap<>(); + + // get actual index descriptors + for (IndexDescriptor indexDescriptor : indexDescriptors) { + // create all possible combinations of fields in the same order + // if the index field is [a,b,c] then combinations would be + // like - [[a], [a,b], [a,b,c]] + List fieldsCombinations = new ArrayList<>(); + + Fields indexFields = indexDescriptor.getIndexFields(); + + // create combinations of fields + for (Pair pair : indexFields.getDescriptor()) { + Fields fields = new Fields(); + if (!fieldsCombinations.isEmpty()) { + // get the last field combination and add the current field from the pair + // [a,b] + c -> [a,b,c] + Fields lastFields = fieldsCombinations.get(fieldsCombinations.size() - 1); + fields.getDescriptor().addAll(lastFields.getDescriptor()); + } + fields.getDescriptor().add(pair); + fieldsCombinations.add(fields); + } + + // for each combination, create a map with the index + // so, if the Ix1 is on fields [a,b,c], then cache would + // be like - [a] -> Ix1, [a,b] -> Ix1, [a,b,c] -> Ix1 + for (Fields fields : fieldsCombinations) { + Set descriptorList = descriptorMap.get(fields); + if (descriptorList == null) { + descriptorList = new HashSet<>(); + } + descriptorList.add(indexDescriptor); + descriptorMap.put(fields, descriptorList); + } + } + + return descriptorMap.get(queryFields); + } + public boolean isDirtyIndex(String collectionName, Fields fields) { IndexMeta meta = getIndexMetaMap(collectionName).get(fields); return meta != null && meta.getIsDirty().get(); diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt index 07180fd9f..cdb3292da 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt @@ -73,7 +73,7 @@ class BackportJavaTimeTest { } } - override fun getDataTypes(): List> { + override fun getSupportedTypes(): List> { return listOf(LocalDateTime::class.java) } } From c021c641d4f5b962085b3f3a96d2d7ab09f37281 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Sun, 29 Nov 2020 10:58:39 +0530 Subject: [PATCH 04/13] work in progress --- .../dizitart/no2/sync/MessageTemplate.java | 4 +- .../java/org/dizitart/no2/sync/Replica.java | 2 +- .../no2/sync/ReplicationTemplate.java | 2 +- .../dizitart/no2/sync/net/DataGateSocket.java | 33 +++++----- .../dizitart/no2/integration/ReplicaTest.java | 16 ++--- .../server/SimpleDataGateServer.java | 4 +- .../org/dizitart/no2/common/FieldNames.java | 65 +++++++++++++++++-- .../org/dizitart/no2/common/FieldValues.java | 4 +- .../java/org/dizitart/no2/common/Fields.java | 30 ++++----- ...FieldNames.java => IndexedFieldNames.java} | 6 +- .../dizitart/no2/filters/QueryOptimizer.java | 2 +- .../dizitart/no2/index/ComparableIndexer.java | 8 +-- .../org/dizitart/no2/store/IndexCatalog.java | 37 +++++++---- 13 files changed, 139 insertions(+), 74 deletions(-) rename nitrite/src/main/java/org/dizitart/no2/common/{IndexFieldNames.java => IndexedFieldNames.java} (73%) diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageTemplate.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageTemplate.java index 937eb8d38..89e1f0062 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageTemplate.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageTemplate.java @@ -25,8 +25,8 @@ */ @Slf4j public class MessageTemplate implements AutoCloseable { - private Config config; - private ReplicationTemplate replica; + private final Config config; + private final ReplicationTemplate replica; private DataGateSocket dataGateSocket; private MessageDispatcher dispatcher; diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/Replica.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/Replica.java index 0cde3dce7..d8417fdd2 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/Replica.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/Replica.java @@ -26,7 +26,7 @@ */ @Slf4j public final class Replica implements AutoCloseable { - private ReplicationTemplate replicationTemplate; + private final ReplicationTemplate replicationTemplate; Replica(Config config) { this.replicationTemplate = new ReplicationTemplate(config); diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java index 1338f1e4b..ac7feea96 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/ReplicationTemplate.java @@ -47,7 +47,7 @@ @Slf4j @Getter public class ReplicationTemplate implements ReplicationOperation { - private Config config; + private final Config config; private MessageFactory messageFactory; private MessageTemplate messageTemplate; private LastWriteWinMap crdt; diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/net/DataGateSocket.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/net/DataGateSocket.java index 5bed77b4f..d8e61713e 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/net/DataGateSocket.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/net/DataGateSocket.java @@ -24,6 +24,7 @@ import org.dizitart.no2.sync.Config; import org.dizitart.no2.sync.ReplicationException; import org.dizitart.no2.sync.message.DataGateMessage; +import org.jetbrains.annotations.NotNull; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; @@ -44,24 +45,22 @@ public class DataGateSocket { private final static int RECONNECT_INTERVAL = 10 * 1000; private final static long RECONNECT_MAX_TIME = 120 * 1000; - + private final OkHttpClient httpClient; + private final Request request; + private final Lock lock; + private final ObjectMapper objectMapper; + private final Config config; + private final Callable networkConnectivityChecker; private WebSocket mWebSocket; - private OkHttpClient httpClient; - private Request request; private int currentStatus = Status.DISCONNECTED; private boolean manualClose; private DataGateSocketListener listener; - private Lock lock; private int reconnectCount = 0; private Timer reconnectTimer; - private ObjectMapper objectMapper; - private Config config; private CountDownLatch latch; - private Callable networkConnectivityChecker; - - private WebSocketListener webSocketListener = new WebSocketListener() { + private final WebSocketListener webSocketListener = new WebSocketListener() { @Override - public void onOpen(WebSocket webSocket, final Response response) { + public void onOpen(@NotNull WebSocket webSocket, @NotNull final Response response) { mWebSocket = webSocket; setCurrentStatus(Status.CONNECTED); if (latch != null) { @@ -75,35 +74,35 @@ public void onOpen(WebSocket webSocket, final Response response) { } @Override - public void onMessage(WebSocket webSocket, final String text) { + public void onMessage(@NotNull WebSocket webSocket, @NotNull final String text) { if (listener != null) { listener.onMessage(text); } } @Override - public void onMessage(WebSocket webSocket, ByteString bytes) { + public void onMessage(@NotNull WebSocket webSocket, @NotNull ByteString bytes) { if (listener != null) { listener.onMessage(bytes); } } @Override - public void onClosing(WebSocket webSocket, int code, String reason) { + public void onClosing(@NotNull WebSocket webSocket, int code, @NotNull String reason) { if (listener != null) { listener.onClosing(code, reason); } } @Override - public void onClosed(WebSocket webSocket, int code, String reason) { + public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) { if (listener != null) { listener.onClosed(code, reason); } } @Override - public void onFailure(WebSocket webSocket, Throwable t, Response response) { + public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, Response response) { if (listener != null) { listener.onFailure(t, response); } @@ -172,7 +171,9 @@ private void initWebSocket() { lock.lockInterruptibly(); try { latch = new CountDownLatch(1); - httpClient.newWebSocket(request, webSocketListener); + if (httpClient != null) { + httpClient.newWebSocket(request, webSocketListener); + } latch.await(); } finally { lock.unlock(); diff --git a/nitrite-replication/src/test/java/org/dizitart/no2/integration/ReplicaTest.java b/nitrite-replication/src/test/java/org/dizitart/no2/integration/ReplicaTest.java index fe63cbba9..4e1e33252 100644 --- a/nitrite-replication/src/test/java/org/dizitart/no2/integration/ReplicaTest.java +++ b/nitrite-replication/src/test/java/org/dizitart/no2/integration/ReplicaTest.java @@ -22,11 +22,11 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.integration.server.Repository; +import org.dizitart.no2.integration.server.SimpleDataGateServer; import org.dizitart.no2.sync.Replica; import org.dizitart.no2.sync.ReplicationTemplate; import org.dizitart.no2.sync.crdt.LastWriteWinMap; -import org.dizitart.no2.integration.server.Repository; -import org.dizitart.no2.integration.server.SimpleDataGateServer; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -56,14 +56,13 @@ @Slf4j public class ReplicaTest { private static SimpleDataGateServer server; + @Rule + public Retry retry = new Retry(3); private String dbFile; private ExecutorService executorService; private Repository repository; private Nitrite db; - @Rule - public Retry retry = new Retry(3); - public static String getRandomTempDbFile() { String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; File file = new File(dataDir); @@ -103,9 +102,10 @@ public void testSingleUserSingleReplica() { db = createDb(dbFile); NitriteCollection collection = db.getCollection("testSingleUserSingleReplica"); - Document document = createDocument().put("firstName", "Anindya") - .put("lastName", "Chatterjee") - .put("address", createDocument("street", "1234 Abcd Street") + Document document = createDocument() + .put("firstName", "Anindya") + .put("lastName", "Chatterjee") + .put("address", createDocument("street", "1234 Abcd Street") .put("pin", 123456)); collection.insert(document); diff --git a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateServer.java b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateServer.java index 1cb3e1df6..3279f3aec 100644 --- a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateServer.java +++ b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateServer.java @@ -23,9 +23,9 @@ * @author Anindya Chatterjee */ public class SimpleDataGateServer { - private int port; + private final int port; private Server server; - private Repository repository; + private final Repository repository; public SimpleDataGateServer(int port) { this.port = port; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java index 328fa39a5..5937e769b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java @@ -3,26 +3,79 @@ import lombok.Getter; import lombok.Setter; -import java.util.Objects; -import java.util.Set; +import java.util.*; /** * @author Anindya Chatterjee */ @Getter @Setter -public class FieldNames { - private Set names; +public class FieldNames extends AbstractSet { + private List names; + + public FieldNames() { + names = new ArrayList<>(); + } + + public FieldNames(Collection collection) { + names = new ArrayList<>(); + addAll(collection); + } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof FieldNames)) return false; FieldNames that = (FieldNames) o; - return Objects.equals(getNames(), that.getNames()); + return Objects.equals(names, that.names); } @Override public int hashCode() { - return Objects.hash(getNames()); + return Objects.hash(names); + } + + @Override + public Iterator iterator() { + return names.listIterator(); + } + + @Override + public int size() { + return names.size(); + } + + @Override + public boolean isEmpty() { + return names.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return names.contains(o); + } + + @Override + public boolean add(String s) { + names.remove(s); + return names.add(s); + } + + @Override + public boolean remove(Object o) { + return names.remove(o); + } + + @Override + public void clear() { + names.clear(); + } + + @Override + public String toString() { + return names.toString(); + } + + public String get(int index) { + return names.get(index); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java index f6e1eb870..080bbba10 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -50,9 +50,9 @@ public Fields getFields() { } this.fields = new Fields(); - fields.setDescriptor(new ArrayList<>()); + fields.setSortSpecs(new ArrayList<>()); for (Pair value : getValues()) { - fields.getDescriptor().add(new Pair<>(value.getFirst(), null)); + fields.getSortSpecs().add(new Pair<>(value.getFirst(), null)); } return fields; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java index 179181cba..3d31464ed 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -24,16 +24,16 @@ public class Fields implements Comparable, Serializable { private static final long serialVersionUID = 1601646404L; // order of the given fields matter - private List> descriptor; + private List> sortSpecs; private transient FieldNames fieldNames; public Fields() { - descriptor = new ArrayList<>(); + sortSpecs = new ArrayList<>(); } public static Fields single(String field) { Fields fields = new Fields(); - fields.descriptor.add(new Pair<>(field, SortOrder.Ascending)); + fields.sortSpecs.add(new Pair<>(field, SortOrder.Ascending)); return fields; } @@ -43,7 +43,7 @@ public static Fields multiple(Pair... fields) { notEmpty(fields, "fields cannot be empty"); Fields f = new Fields(); - f.descriptor.addAll(Arrays.asList(fields)); + f.sortSpecs.addAll(Arrays.asList(fields)); return f; } @@ -52,19 +52,19 @@ public FieldNames getFieldNames() { return fieldNames; } - fieldNames = new ArrayList<>(); - for (Pair pair : descriptor) { + fieldNames = new FieldNames(); + for (Pair pair : sortSpecs) { fieldNames.add(pair.getFirst()); } return fieldNames; } public Pair getFirstKey() { - return descriptor.get(0); + return sortSpecs.get(0); } public SortOrder getSortOrder(String fieldName) { - for (Pair pair : descriptor) { + for (Pair pair : sortSpecs) { if (pair.getFirst().equals(fieldName)) { return pair.getSecond(); } @@ -78,11 +78,11 @@ public String getEncodedName() { public boolean isPrefix(Fields otherFields) { if (otherFields == null) return false; - List> otherFieldList = otherFields.getDescriptor(); + List> otherFieldList = otherFields.getSortSpecs(); if (otherFieldList != null) { - if (otherFieldList.size() > descriptor.size()) return false; + if (otherFieldList.size() > sortSpecs.size()) return false; for (int i = 0; i < otherFieldList.size(); i++) { - String field = descriptor.get(i).getFirst(); + String field = sortSpecs.get(i).getFirst(); String otherField = otherFieldList.get(i).getFirst(); if (!field.contentEquals(otherField)) { return false; @@ -97,7 +97,7 @@ public boolean isPrefix(Fields otherFields) { public String toString() { StringBuilder stringBuilder = new StringBuilder("["); int count = 0; - for (Pair field : descriptor) { + for (Pair field : sortSpecs) { count++; stringBuilder.append("{") .append(field.getFirst()) @@ -105,7 +105,7 @@ public String toString() { .append(field.getSecond()) .append("}"); - if (count != descriptor.size()) { + if (count != sortSpecs.size()) { stringBuilder.append(", "); } } @@ -134,11 +134,11 @@ public int compareTo(Fields other) { } private void writeObject(ObjectOutputStream stream) throws IOException { - stream.writeObject(descriptor); + stream.writeObject(sortSpecs); } @SuppressWarnings("unchecked") private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - descriptor = (List>) stream.readObject(); + sortSpecs = (List>) stream.readObject(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java similarity index 73% rename from nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java rename to nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java index ad27d7b49..bf4c50724 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/IndexFieldNames.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java @@ -4,12 +4,14 @@ import lombok.Setter; import org.dizitart.no2.index.IndexDescriptor; +import java.util.Set; + /** * @author Anindya Chatterjee */ @Getter @Setter -public class IndexFieldNames extends FieldNames { - private IndexDescriptor indexDescriptor; +public class IndexedFieldNames extends FieldNames { + private Set supportedIndices; @Override public boolean equals(Object o) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java index 985da7cef..3ebd6f1b5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -99,7 +99,7 @@ private Fields getFields(List filters) { for (Filter filter : filters) { if (filter instanceof FieldBasedFilter) { FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; - fields.getDescriptor().add(new Pair<>(fieldBasedFilter.getField(), SortOrder.Ascending)); + fields.getSortSpecs().add(new Pair<>(fieldBasedFilter.getField(), SortOrder.Ascending)); } } return null; diff --git a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java index 42e88672a..59fee6bf0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java @@ -105,7 +105,7 @@ private void writeCompoundIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { Fields fields = fieldValues.getFields(); - List fieldNames = fields.getFieldNames(); + FieldNames fieldNames = fields.getFieldNames(); String firstField = fieldNames.get(0); Object firstValue = fieldValues.get(firstField); @@ -146,7 +146,7 @@ private void writeSimpleIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { Fields fields = fieldValues.getFields(); - List fieldNames = fields.getFieldNames(); + FieldNames fieldNames = fields.getFieldNames(); String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); @@ -251,7 +251,7 @@ private void removeCompoundIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { Fields fields = fieldValues.getFields(); - List fieldNames = fields.getFieldNames(); + FieldNames fieldNames = fields.getFieldNames(); String firstField = fieldNames.get(0); Object firstValue = fieldValues.get(firstField); @@ -292,7 +292,7 @@ private void removeSimpleIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig) { Fields fields = fieldValues.getFields(); - List fieldNames = fields.getFieldNames(); + FieldNames fieldNames = fields.getFieldNames(); String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); diff --git a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java index 5f6aad44b..16337f8ea 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java @@ -16,7 +16,9 @@ package org.dizitart.no2.store; +import org.dizitart.no2.common.FieldNames; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.IndexedFieldNames; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; @@ -69,46 +71,53 @@ public IndexDescriptor findIndexDescriptorExact(String collectionName, Fields fi return null; } - public Set findMatchingIndexDescriptor(String collectionName, Fields queryFields) { + public Set findIndexSupportedFields(String collectionName) { Collection indexDescriptors = listIndexDescriptors(collectionName); - Map> descriptorMap = new ConcurrentHashMap<>(); + Map> fieldIndexMap = new ConcurrentHashMap<>(); // get actual index descriptors for (IndexDescriptor indexDescriptor : indexDescriptors) { // create all possible combinations of fields in the same order // if the index field is [a,b,c] then combinations would be // like - [[a], [a,b], [a,b,c]] - List fieldsCombinations = new ArrayList<>(); - + List fieldsCombinations = new ArrayList<>(); Fields indexFields = indexDescriptor.getIndexFields(); // create combinations of fields - for (Pair pair : indexFields.getDescriptor()) { - Fields fields = new Fields(); + for (Pair pair : indexFields.getSortSpecs()) { + FieldNames fn = new FieldNames(); if (!fieldsCombinations.isEmpty()) { // get the last field combination and add the current field from the pair // [a,b] + c -> [a,b,c] - Fields lastFields = fieldsCombinations.get(fieldsCombinations.size() - 1); - fields.getDescriptor().addAll(lastFields.getDescriptor()); + FieldNames lastFields = fieldsCombinations.get(fieldsCombinations.size() - 1); + fn.getNames().addAll(lastFields.getNames()); } - fields.getDescriptor().add(pair); - fieldsCombinations.add(fields); + fn.getNames().add(pair.getFirst()); + fieldsCombinations.add(fn); } // for each combination, create a map with the index // so, if the Ix1 is on fields [a,b,c], then cache would // be like - [a] -> Ix1, [a,b] -> Ix1, [a,b,c] -> Ix1 - for (Fields fields : fieldsCombinations) { - Set descriptorList = descriptorMap.get(fields); + for (FieldNames fields : fieldsCombinations) { + Set descriptorList = fieldIndexMap.get(fields); if (descriptorList == null) { descriptorList = new HashSet<>(); } descriptorList.add(indexDescriptor); - descriptorMap.put(fields, descriptorList); + fieldIndexMap.put(fields, descriptorList); } } - return descriptorMap.get(queryFields); + Set resultSet = new HashSet<>(); + for (Map.Entry> entry : fieldIndexMap.entrySet()) { + IndexedFieldNames fieldNames = new IndexedFieldNames(); + fieldNames.setNames(entry.getKey().getNames()); + fieldNames.setSupportedIndices(entry.getValue()); + resultSet.add(fieldNames); + } + + return resultSet; } public boolean isDirtyIndex(String collectionName, Fields fields) { From c02c3bbbac1b937dfdc26f136ce70073ecdafe54 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Mon, 30 Nov 2020 19:52:03 +0530 Subject: [PATCH 05/13] work in progress --- .../java/org/dizitart/no2/NitriteTest.java | 15 +- .../dizitart/no2/filters/QueryOptimizer.java | 145 ++++-------------- .../org/dizitart/no2/filters/QueryPlan.java | 12 ++ 3 files changed, 48 insertions(+), 124 deletions(-) create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java index 31849ffcb..3ba85eebb 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java @@ -62,6 +62,7 @@ import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; import static org.dizitart.no2.common.Constants.META_MAP_NAME; import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.filters.Filter.and; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.*; @@ -465,21 +466,21 @@ public void testReadCompatibility() throws IOException { NitriteCollection collection = db.getCollection("test"); // text filter has be the first filter in and clause - List cursor = collection.find(where("second_key").text("fox") - .and(where("first_key").eq(1))).toList(); + List cursor = collection.find( + and(where("second_key").text("fox"), where("first_key").eq(1))).toList(); assertEquals(cursor.size(), 1); assertEquals(cursor.get(0).get("third_key"), 0.5); ObjectRepository repository = db.getRepository(Receipt.class); ObjectRepository orangeRepository = db.getRepository(Receipt.class, "orange"); - List list = repository.find(where("synced").eq(true) - .and(where("status").eq(Receipt.Status.PREPARING.toString()))).toList(); + List list = repository.find( + and(where("synced").eq(true), where("status").eq(Receipt.Status.PREPARING.toString()))).toList(); assertEquals(list.size(), 1); assertEquals(list.get(0).clientRef, "1"); - list = orangeRepository.find(where("synced").eq(false) - .and(where("status").eq(Receipt.Status.PREPARING.toString()))).toList(); + list = orangeRepository.find( + and(where("synced").eq(false), where("status").eq(Receipt.Status.PREPARING.toString()))).toList(); assertEquals(list.size(), 0); assertNotNull(repository.getAttributes()); @@ -501,7 +502,7 @@ public void testIssue212() { } collection.insert(doc1, doc2); - collection.update(where("key").eq("key").and(where("second_key").eq("second_key")), + collection.update(and(where("key").eq("key"), where("second_key").eq("second_key")), doc, UpdateOptions.updateOptions(true)); for (Document document : collection.find()) { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java index 3ebd6f1b5..08e76d230 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -4,10 +4,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.FindOptions; -import org.dizitart.no2.common.FieldValues; -import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.*; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; @@ -26,27 +23,27 @@ public class QueryOptimizer { private final NitriteConfig nitriteConfig; /* - * 1. If And filter - * 1.1 flatten the filter using depth first traversal - * 1.2 check each filter, group OR & AND, single field filters - * 1.3 scan through single field filter or and filter if there is any match for composite index - * 1.3.1 if matching composite index found, get index stream - * 1.3.2 group remaining filters as a new and filter and apply on indexed stream from 1.3.1 - * 1.4 if no matching composite index found, scan for simple index - * 1.4.1 if found, get indexed stream - * 1.4.2 group remaining filter as a new and filter and apply on index stream from 1.4.1 - * 1.5 if no matching index found, collscan and apply filter - * - * 2. If OR filter - * 1.1 If every simple field is indexed or and filter composite indexed - * 1.1.1 - * 1.2 If one of the fields is not indexed, get collscan and apply filter - * - * 3. If simple filter - * 3.1 Check if index exists, send indexed stream - * 3.2 If no index found, collscan - * - * */ + * 1. If And filter + * 1.1 flatten the filter using depth first traversal + * 1.2 check each filter, group OR & AND, single field filters + * 1.3 scan through single field filter or and filter if there is any match for composite index + * 1.3.1 if matching composite index found, get index stream + * 1.3.2 group remaining filters as a new and filter and apply on indexed stream from 1.3.1 + * 1.4 if no matching composite index found, scan for simple index + * 1.4.1 if found, get indexed stream + * 1.4.2 group remaining filter as a new and filter and apply on index stream from 1.4.1 + * 1.5 if no matching index found, collscan and apply filter + * + * 2. If OR filter + * 1.1 If every simple field is indexed or and filter composite indexed + * 1.1.1 + * 1.2 If one of the fields is not indexed, get collscan and apply filter + * + * 3. If simple filter + * 3.1 Check if index exists, send indexed stream + * 3.2 If no index found, collscan + * + * */ public QueryOptimizer(NitriteConfig nitriteConfig) { this.nitriteConfig = nitriteConfig; @@ -55,115 +52,29 @@ public QueryOptimizer(NitriteConfig nitriteConfig) { public FilterStep optimizeFilter(NitriteMap primaryCollection, Filter filter, FindOptions findOptions) { - + return null; } private void flattenFilter(String collectionName, Filter filter) { if (filter instanceof AndFilter) { List flattenedFilter = ((AndFilter) filter).getFilters(); - Pair optimizedAnd = optimize(collectionName, flattenedFilter); + Pair optimizedAnd = optimizeAnd(collectionName, flattenedFilter); } } - private Pair optimize(String collectionName, List flattenedFilter) { + private Pair optimizeAnd(String collectionName, List flattenedFilter) { IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - for (int i = 0; i < flattenedFilter.size(); i++) { - List filters = flattenedFilter.subList(0, i + 1); - Fields fields = getFields(filters); - } - - - for (Filter filter : flattenedFilter) { - if (filter instanceof FieldBasedFilter) { - FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; - Fields fields = Fields.single(fieldBasedFilter.getField()); - Set descriptors = indexCatalog.findMatchingIndexDescriptor(collectionName, fields); - if (descriptors != null) { - - } - } - if (filter instanceof AndFilter) { - - } - } - -// TODO: use fieldNames as object to create cache and compare + Set indexedFieldNames = indexCatalog.findIndexSupportedFields(collectionName); + Set filterFieldNames = getFieldNames(flattenedFilter); return null; } - private Fields getFields(List filters) { - Fields fields = new Fields(); - for (Filter filter : filters) { - if (filter instanceof FieldBasedFilter) { - FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; - fields.getSortSpecs().add(new Pair<>(fieldBasedFilter.getField(), SortOrder.Ascending)); - } - } + private Set getFieldNames(List filters) { return null; } - - private void optimize2(String collectionName, List flattenedFilter) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - Map> group = new HashMap<>(); - - for (int i = 0; i < flattenedFilter.size(); i++) { - Filter filter = flattenedFilter.get(0); - if (filter instanceof FieldBasedFilter) { - FieldBasedFilter fieldBasedFilter = (FieldBasedFilter) filter; - Fields fields = Fields.single(fieldBasedFilter.getField()); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, fields); - if (indexDescriptor != null) { - List filters = group.get(indexDescriptor); - if (filters == null) { - filters = new ArrayList<>(); - } - filters.add(filter); - group.put(indexDescriptor, filters); - } - } - } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java new file mode 100644 index 000000000..4e11fd711 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java @@ -0,0 +1,12 @@ +package org.dizitart.no2.filters; + +import lombok.Data; + +/** + * @author Anindya Chatterjee + */ +@Data +public class QueryPlan { + private Filter indexedFilter; + private Filter nonIndexedFilter; +} From 2bb20978931c872b0b6d205e4d658e116c0a9dbd Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Wed, 9 Dec 2020 12:07:08 +0530 Subject: [PATCH 06/13] work in progress --- nitrite-replication/build.gradle | 6 +++--- .../org/dizitart/no2/integration/server/Repository.java | 2 +- .../no2/integration/server/SimpleDataGateEndpoint.java | 6 +++--- .../java/org/dizitart/no2/store/AbstractNitriteStore.java | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/nitrite-replication/build.gradle b/nitrite-replication/build.gradle index 86f2774b6..c6c6dfec0 100644 --- a/nitrite-replication/build.gradle +++ b/nitrite-replication/build.gradle @@ -52,9 +52,9 @@ dependencies { testImplementation project(path: ':nitrite-mvstore-adapter', configuration: 'default') testAnnotationProcessor "org.projectlombok:lombok:1.18.12" - testImplementation "jakarta.websocket:jakarta.websocket-api:1.1.2" - testImplementation "org.glassfish.tyrus:tyrus-server:1.17" - testImplementation "org.glassfish.tyrus:tyrus-container-grizzly-server:1.17" + testImplementation "jakarta.websocket:jakarta.websocket-api:2.0.0" + testImplementation "org.glassfish.tyrus:tyrus-server:2.0.0" + testImplementation "org.glassfish.tyrus:tyrus-container-grizzly-server:2.0.0" testImplementation "org.awaitility:awaitility:4.0.3" testImplementation "org.apache.logging.log4j:log4j-slf4j-impl:2.13.3" testImplementation "org.apache.logging.log4j:log4j-core:2.13.3" diff --git a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/Repository.java b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/Repository.java index 62412847e..bfc433ce9 100644 --- a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/Repository.java +++ b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/Repository.java @@ -16,11 +16,11 @@ package org.dizitart.no2.integration.server; +import jakarta.websocket.Session; import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.sync.crdt.LastWriteWinMap; -import javax.websocket.Session; import java.util.*; import java.util.concurrent.ConcurrentHashMap; diff --git a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateEndpoint.java b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateEndpoint.java index 5ac758609..f5b2e925c 100644 --- a/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateEndpoint.java +++ b/nitrite-replication/src/test/java/org/dizitart/no2/integration/server/SimpleDataGateEndpoint.java @@ -18,6 +18,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.collection.NitriteCollection; @@ -30,9 +33,6 @@ import org.dizitart.no2.sync.crdt.LastWriteWinState; import org.dizitart.no2.sync.message.*; -import javax.websocket.*; -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.*; diff --git a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java index fc66470d0..f235fdc5d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java @@ -91,6 +91,7 @@ public IndexCatalog getIndexCatalog() { if (indexCatalog == null) { indexCatalog = new IndexCatalog(this); } + return indexCatalog; } From 7347108d65772df71a42a99edf1a598c3d5d446d Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Mon, 21 Dec 2020 22:43:41 +0530 Subject: [PATCH 07/13] work in progress --- .../dizitart/no2/filters/QueryOptimizer.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java index 08e76d230..1e8c1aafa 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java @@ -52,15 +52,30 @@ public QueryOptimizer(NitriteConfig nitriteConfig) { public FilterStep optimizeFilter(NitriteMap primaryCollection, Filter filter, FindOptions findOptions) { + List flattenedFilters = new ArrayList<>(); + if (filter instanceof AndFilter) { + List filters = flattenAndFilter((AndFilter) filter); + flattenedFilters.addAll(filters); + } else { + flattenedFilters.add(filter); + } + return null; } - private void flattenFilter(String collectionName, Filter filter) { - if (filter instanceof AndFilter) { - List flattenedFilter = ((AndFilter) filter).getFilters(); - Pair optimizedAnd = optimizeAnd(collectionName, flattenedFilter); + private List flattenAndFilter(AndFilter andFilter) { + List flattenedFilters = new ArrayList<>(); + if (andFilter != null) { + for (Filter filter : andFilter.getFilters()) { + if (filter instanceof AndFilter) { + List filters = flattenAndFilter((AndFilter) filter); + flattenedFilters.addAll(filters); + } else { + flattenedFilters.add(filter); + } + } } - + return flattenedFilters; } private Pair optimizeAnd(String collectionName, List flattenedFilter) { @@ -73,6 +88,7 @@ private Pair optimizeAnd(String collectionName, List fla } private Set getFieldNames(List filters) { + // send only eligible field names, ignore OR filers as they can't be used for composite index return null; } From 151fb7665dc5e6885a76d6ec7466654bbe045c73 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Fri, 2 Apr 2021 01:47:26 +0530 Subject: [PATCH 08/13] work in progress --- README.md | 12 +- .../no2/mapper/JacksonMapperModule.java | 2 + .../no2/test/migrate/MigrationTest.java | 36 +- .../java/org/dizitart/no2/mapdb/MapDBMap.java | 2 +- .../org/dizitart/no2/mapdb/MapDBStore.java | 7 +- .../no2/mapdb/NitriteBuilderTest.java | 17 +- .../no2/mapdb/migrate/MigrationTest.java | 36 +- .../repository/RepositoryFactoryTest.java | 35 +- .../dizitart/no2/mvstore/MVStoreModule.java | 2 + .../dizitart/no2/mvstore/NitriteMVMap.java | 2 +- .../no2/mvstore/NitriteMVRTreeMap.java | 8 +- .../dizitart/no2/mvstore/NitriteMVStore.java | 26 +- .../org/dizitart/no2/NitriteBuilderTest.java | 16 +- .../operation/DocumentCursorTest.java | 3 +- .../operation/JoinedDocumentStreamTest.java | 1 + .../dizitart/no2/migrate/MigrationTest.java | 36 +- .../no2/repository/RepositoryFactoryTest.java | 12 +- .../dizitart/no2/sync/MessageDispatcher.java | 4 +- .../org/dizitart/no2/rocksdb/RocksDBMap.java | 2 +- .../dizitart/no2/rocksdb/RocksDBModule.java | 2 + .../no2/rocksdb/RocksDBReference.java | 1 + .../dizitart/no2/rocksdb/RocksDBStore.java | 8 +- .../no2/rocksdb/NitriteBuilderTest.java | 17 +- .../no2/rocksdb/migrate/MigrationTest.java | 36 +- .../repository/RepositoryFactoryTest.java | 36 +- .../no2/spatial/IntersectsFilter.java | 17 +- .../dizitart/no2/spatial/SpatialFilter.java | 12 +- .../dizitart/no2/spatial/SpatialModule.java | 2 + .../dizitart/no2/spatial/WithinFilter.java | 17 +- .../main/java/org/dizitart/no2/Nitrite.java | 36 +- .../java/org/dizitart/no2/NitriteBuilder.java | 24 +- .../java/org/dizitart/no2/NitriteConfig.java | 41 +- .../org/dizitart/no2/NitriteDatabase.java | 22 +- .../no2/collection/CollectionFactory.java | 13 +- .../collection/DefaultNitriteCollection.java | 85 +-- .../org/dizitart/no2/collection/Document.java | 106 ++++ .../no2/collection/DocumentCursor.java | 72 +-- .../dizitart/no2/collection/FindOptions.java | 74 +++ .../org/dizitart/no2/collection/FindPlan.java | 54 ++ .../no2/collection/NitriteCollection.java | 31 +- .../no2/collection/NitriteDocument.java | 179 +++++- .../no2/collection/SnowflakeIdGenerator.java | 2 +- .../events/CollectionEventListener.java | 8 - .../no2/collection/meta/Attributes.java | 54 ++ .../operation/CollectionOperations.java | 202 +++++-- .../operation/DocumentIndexWriter.java | 59 +- .../collection/operation/FindOptimizer.java | 224 +++++++ .../no2/collection/operation/FindOptions.java | 21 - .../collection/operation/IndexManager.java | 221 +++++++ .../collection/operation/IndexOperations.java | 90 +-- .../collection/operation/ReadOperations.java | 175 +++--- .../operation/SortedDocumentCursor.java | 154 ----- .../collection/operation/StreamGenerator.java | 11 - .../operation/UnionStreamIterator.java | 78 --- .../collection/operation/WriteOperations.java | 80 +-- .../collection/operation/WriteResultImpl.java | 3 +- .../java/org/dizitart/no2/common/DBNull.java | 1 + .../org/dizitart/no2/common/FieldNames.java | 81 --- .../org/dizitart/no2/common/FieldValues.java | 34 +- .../java/org/dizitart/no2/common/Fields.java | 136 ++--- .../dizitart/no2/common/FilterFieldNames.java | 23 - .../no2/common/IndexedFieldNames.java | 25 - .../no2/common/PersistentCollection.java | 138 ++--- .../org/dizitart/no2/common/RecordStream.java | 58 +- .../dizitart/no2/common/SortableFields.java | 88 +++ .../org/dizitart/no2/common/UnknownType.java | 3 + .../no2/common/concurrent/LockService.java | 18 + .../common/concurrent/ThreadPoolManager.java | 18 +- .../no2/common/crypto/AESEncryptor.java | 127 ++++ .../dizitart/no2/common/crypto/Encryptor.java | 44 ++ .../dizitart/no2/common/event/EventBus.java | 5 - .../streams}/BoundedDocumentStream.java | 72 ++- .../no2/common/streams/DocumentSorter.java | 108 ++++ .../streams/DocumentStream.java} | 76 ++- .../streams/FilteredStream.java} | 35 +- .../streams}/IndexedStream.java | 39 +- .../streams}/JoinedDocumentStream.java | 48 +- .../streams}/ProjectedDocumentStream.java | 41 +- .../common/streams/SortedDocumentStream.java | 58 ++ .../no2/common/streams/UnionStream.java | 97 +++ .../org/dizitart/no2/common/tuples/Pair.java | 15 + .../dizitart/no2/common/tuples/Quartet.java | 24 + .../dizitart/no2/common/tuples/Quintet.java | 27 + .../dizitart/no2/common/tuples/Triplet.java | 18 + .../org/dizitart/no2/common/util/Base64.java | 550 ++++++++++++++++++ .../dizitart/no2/common/util/Comparables.java | 10 + .../dizitart/no2/common/util/CryptoUtils.java | 67 +++ .../dizitart/no2/common/util/IndexUtils.java | 58 ++ .../dizitart/no2/common/util/Iterables.java | 5 +- .../no2/common/util/SecureString.java | 21 +- .../no2/exceptions/MigrationException.java | 8 + .../no2/exceptions/PluginException.java | 14 + .../no2/exceptions/TransactionException.java | 14 + .../org/dizitart/no2/filters/AndFilter.java | 8 + .../no2/filters/ComparableFilter.java | 89 +++ .../no2/filters/ComparisonFilter.java | 36 -- .../dizitart/no2/filters/EqualsFilter.java | 51 +- .../no2/filters/FieldBasedFilter.java | 59 +- .../java/org/dizitart/no2/filters/Filter.java | 178 +----- .../org/dizitart/no2/filters/FilterStep.java | 7 - .../dizitart/no2/filters/FluentFilter.java | 151 ++--- .../no2/filters/GreaterEqualFilter.java | 65 ++- .../no2/filters/GreaterThanFilter.java | 60 +- .../org/dizitart/no2/filters/InFilter.java | 71 +-- .../no2/filters/IndexAwareFilter.java | 68 --- .../dizitart/no2/filters/IndexScanFilter.java | 51 ++ .../no2/filters/IndexedQuerySupport.java | 28 - .../no2/filters/LesserEqualFilter.java | 63 +- .../no2/filters/LesserThanFilter.java | 61 +- .../dizitart/no2/filters/LogicalFilter.java | 9 + .../dizitart/no2/filters/NitriteFilter.java | 27 + .../dizitart/no2/filters/NotEqualsFilter.java | 67 +-- .../org/dizitart/no2/filters/NotInFilter.java | 77 +-- .../org/dizitart/no2/filters/OrFilter.java | 8 + .../dizitart/no2/filters/QueryOptimizer.java | 248 -------- .../org/dizitart/no2/filters/QueryPlan.java | 12 - .../dizitart/no2/filters/StringFilter.java | 16 +- .../org/dizitart/no2/filters/TextFilter.java | 153 ++++- .../no2/index/BaseNitriteIndexer.java | 49 -- .../org/dizitart/no2/index/BoundingBox.java | 22 + .../dizitart/no2/index/ComparableIndexer.java | 408 ++----------- .../org/dizitart/no2/index/CompoundIndex.java | 317 ++++++++++ .../dizitart/no2/index/IndexDescriptor.java | 8 +- .../org/dizitart/no2/index/IndexOptions.java | 29 - .../org/dizitart/no2/index/IndexScanner.java | 210 +++++++ .../org/dizitart/no2/index/IndexType.java | 14 + .../org/dizitart/no2/index/NitriteIndex.java | 136 +++++ .../dizitart/no2/index/NitriteIndexer.java | 54 +- .../no2/index/NitriteTextIndexer.java | 285 ++------- .../dizitart/no2/index/NonUniqueIndexer.java | 3 + .../dizitart/no2/index/SingleFieldIndex.java | 200 +++++++ .../org/dizitart/no2/index/TextIndex.java | 229 ++++++++ .../org/dizitart/no2/index/TextIndexer.java | 44 -- .../org/dizitart/no2/index/UniqueIndexer.java | 3 + .../no2/index/fulltext/TextTokenizer.java | 7 +- .../dizitart/no2/mapper/MappableMapper.java | 76 ++- .../dizitart/no2/mapper/NitriteMapper.java | 24 + .../no2/migration/CollectionInstruction.java | 83 ++- .../dizitart/no2/migration/Composable.java | 8 - .../no2/migration/CustomInstruction.java | 8 + .../no2/migration/DatabaseInstruction.java | 58 +- .../org/dizitart/no2/migration/Generator.java | 10 + .../dizitart/no2/migration/Instruction.java | 30 +- .../no2/migration/InstructionType.java | 68 +++ .../dizitart/no2/migration/Instructions.java | 66 +++ .../org/dizitart/no2/migration/Migration.java | 25 +- .../no2/migration/MigrationManager.java | 48 +- .../dizitart/no2/migration/MigrationStep.java | 3 + ...truction.java => NitriteInstructions.java} | 7 +- .../no2/migration/RepositoryInstruction.java | 121 +++- .../dizitart/no2/migration/TypeConverter.java | 11 + .../no2/migration/commands/AddField.java | 7 +- .../no2/migration/commands/BaseCommand.java | 21 + .../migration/commands/ChangeDataType.java | 11 +- .../no2/migration/commands/ChangeIdField.java | 15 +- .../no2/migration/commands/Command.java | 8 + .../no2/migration/commands/CreateIndex.java | 8 +- .../no2/migration/commands/DeleteField.java | 11 +- .../dizitart/no2/migration/commands/Drop.java | 3 + .../no2/migration/commands/DropIndex.java | 12 +- .../no2/migration/commands/Rename.java | 11 +- .../no2/migration/commands/RenameField.java | 39 +- .../org/dizitart/no2/module/ModuleConfig.java | 33 ++ .../dizitart/no2/module/NitriteModule.java | 44 +- .../dizitart/no2/module/NitritePlugin.java | 8 + .../dizitart/no2/module/PluginManager.java | 22 + .../dizitart/no2/processors/Processor.java | 44 ++ .../no2/processors/ProcessorChain.java | 77 +++ .../StringFieldEncryptionProcessor.java | 118 ++++ .../org/dizitart/no2/repository/Cursor.java | 45 +- .../repository/DefaultObjectRepository.java | 39 +- .../dizitart/no2/repository/ObjectCursor.java | 19 +- .../no2/repository/ObjectRepository.java | 37 +- .../no2/repository/RepositoryFactory.java | 46 +- .../no2/repository/RepositoryOperations.java | 69 ++- .../no2/repository/annotations/Entity.java | 15 + .../no2/repository/annotations/Index.java | 10 +- .../no2/repository/annotations/Indices.java | 9 +- .../annotations/InheritIndices.java | 3 +- .../no2/store/AbstractNitriteStore.java | 79 ++- .../dizitart/no2/store/DatabaseMetaData.java | 13 + .../org/dizitart/no2/store/IndexCatalog.java | 178 ------ .../org/dizitart/no2/store/NitriteMap.java | 85 +-- .../org/dizitart/no2/store/NitriteRTree.java | 36 +- .../org/dizitart/no2/store/NitriteStore.java | 44 +- .../org/dizitart/no2/store/StoreCatalog.java | 156 +++++ .../org/dizitart/no2/store/StoreConfig.java | 6 +- .../org/dizitart/no2/store/StoreModule.java | 8 + ...ty.java => UserAuthenticationService.java} | 101 ++-- .../dizitart/no2/store/UserCredential.java | 4 +- .../dizitart/no2/store/events/EventInfo.java | 3 + .../no2/store/events/StoreEventBus.java | 5 +- .../no2/store/events/StoreEventListener.java | 9 + .../no2/store/events/StoreEvents.java | 18 + .../no2/store/memory/InMemoryConfig.java | 6 + .../no2/store/memory/InMemoryMap.java | 13 +- .../store/memory/InMemoryModuleBuilder.java | 17 + .../no2/store/memory/InMemoryRTree.java | 61 ++ .../no2/store/memory/InMemoryStore.java | 17 +- .../no2/store/memory/InMemoryStoreModule.java | 13 + .../dizitart/no2/transaction/ChangeType.java | 54 +- .../org/dizitart/no2/transaction/Command.java | 6 + .../DefaultTransactionalCollection.java | 112 ++-- .../DefaultTransactionalRepository.java | 45 +- .../no2/transaction/JournalEntry.java | 3 + .../no2/transaction/NitriteTransaction.java | 23 +- .../org/dizitart/no2/transaction/Session.java | 31 +- .../org/dizitart/no2/transaction/State.java | 26 + .../dizitart/no2/transaction/Transaction.java | 45 +- .../no2/transaction/TransactionContext.java | 3 +- .../no2/transaction/TransactionalConfig.java | 32 +- .../no2/transaction/TransactionalMap.java | 7 +- .../no2/transaction/TransactionalRTree.java | 6 + .../no2/transaction/TransactionalStore.java | 11 +- .../dizitart/no2/transaction/UndoEntry.java | 1 + .../no2/CollectionFieldIndexTest.java | 6 +- .../org/dizitart/no2/CustomFilterTest.java | 2 +- .../org/dizitart/no2/DbTestOperations.java | 49 +- .../org/dizitart/no2/IndexDescriptorTest.java | 49 -- .../org/dizitart/no2/MultiThreadedTest.java | 10 +- .../org/dizitart/no2/NitriteBuilderTest.java | 26 +- .../dizitart/no2/NitriteCorruptedTest.java | 2 +- .../org/dizitart/no2/NitriteSecurityTest.java | 4 +- .../org/dizitart/no2/NitriteStressTest.java | 4 +- .../java/org/dizitart/no2/NitriteTest.java | 27 +- .../org/dizitart/no2/SerializabilityTest.java | 2 +- .../java/org/dizitart/no2/StressTest.java | 8 +- .../no2/collection/CollectionDeleteTest.java | 2 +- .../CollectionFindByIndexNegativeTest.java | 4 +- .../collection/CollectionFindByIndexTest.java | 95 +-- .../CollectionFindNegativeTest.java | 15 +- .../no2/collection/CollectionFindTest.java | 155 ++--- .../CollectionIndexNegativeTest.java | 10 +- .../no2/collection/CollectionIndexTest.java | 58 +- .../no2/collection/CollectionUpdateTest.java | 6 +- .../no2/collection/NitriteCollectionTest.java | 2 +- .../operation/BoundedDocumentStreamTest.java | 87 --- .../operation/DocumentCursorImplTest.java | 52 -- .../operation/DocumentCursorTest.java | 5 +- .../operation/FilteredRecordStreamTest.java | 45 -- .../operation/IndexedStreamTest.java | 36 -- .../operation/JoinedDocumentStreamTest.java | 16 +- .../ProjectedDocumentStreamTest.java | 24 - .../operation/ReadOperationsTest.java | 32 - .../operation/SortedDocumentCursorTest.java | 123 ---- .../operation/UnionStreamIteratorTest.java | 22 - .../operation/WriteOperationsTest.java | 31 - .../operation/WriteResultImplTest.java | 10 +- .../dizitart/no2/common/event/EventTest.java | 4 +- .../no2/common/util/DocumentUtilsTest.java | 4 +- .../no2/filters/BetweenFilterTest.java | 48 -- .../no2/filters/EqualsFilterTest.java | 101 +--- .../no2/filters/FluentFilterTest.java | 14 +- .../no2/filters/NotEqualsFilterTest.java | 104 +--- .../dizitart/no2/filters/RegexFilterTest.java | 6 +- .../dizitart/no2/filters/TextFilterTest.java | 30 - .../no2/index/IndexDescriptorTest.java | 28 - .../dizitart/no2/index/IndexOptionsTest.java | 8 - .../repository/BaseObjectRepositoryTest.java | 3 +- .../repository/CustomFieldSeparatorTest.java | 2 +- .../no2/repository/NitriteIdAsIdTest.java | 2 +- .../ObjectRepositoryNegativeTest.java | 4 +- .../no2/repository/ObjectRepositoryTest.java | 2 +- .../no2/repository/ProjectionTest.java | 9 +- .../no2/repository/RepositoryFactoryTest.java | 33 +- .../no2/repository/RepositoryJoinTest.java | 6 +- .../RepositoryModificationTest.java | 8 +- .../no2/repository/RepositorySearchTest.java | 26 +- .../no2/repository/UnAnnotatedObjectTest.java | 19 +- .../UniversalTextTokenizerTest.java | 4 +- .../no2/store/memory/InMemoryMapTest.java | 9 +- .../no2/store/memory/InMemoryStoreTest.java | 2 +- .../TransactionCollectionTest.java | 36 +- .../TransactionRepositoryTest.java | 28 +- .../kotlin/org/dizitart/kno2/KNO2Module.kt | 2 + 275 files changed, 7704 insertions(+), 4975 deletions(-) create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/collection/operation/UnionStreamIterator.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/SortableFields.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java rename nitrite/src/main/java/org/dizitart/no2/{collection/operation => common/streams}/BoundedDocumentStream.java (62%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java rename nitrite/src/main/java/org/dizitart/no2/{collection/operation/DocumentCursorImpl.java => common/streams/DocumentStream.java} (65%) rename nitrite/src/main/java/org/dizitart/no2/{collection/operation/FilteredRecordStream.java => common/streams/FilteredStream.java} (77%) rename nitrite/src/main/java/org/dizitart/no2/{collection/operation => common/streams}/IndexedStream.java (71%) rename nitrite/src/main/java/org/dizitart/no2/{collection/operation => common/streams}/JoinedDocumentStream.java (70%) rename nitrite/src/main/java/org/dizitart/no2/{collection/operation => common/streams}/ProjectedDocumentStream.java (71%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/util/Base64.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/util/CryptoUtils.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/util/IndexUtils.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/ComparisonFilter.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/NitriteIndex.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/migration/Composable.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/migration/Instructions.java rename nitrite/src/main/java/org/dizitart/no2/migration/{NitriteInstruction.java => NitriteInstructions.java} (87%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/processors/Processor.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java delete mode 100644 nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java rename nitrite/src/main/java/org/dizitart/no2/store/{StoreSecurity.java => UserAuthenticationService.java} (68%) delete mode 100644 nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/BoundedDocumentStreamTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorImplTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/FilteredRecordStreamTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexedStreamTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/ProjectedDocumentStreamTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/SortedDocumentCursorTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/UnionStreamIteratorTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteOperationsTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java diff --git a/README.md b/README.md index 4b8fd793e..7b2ad1c85 100644 --- a/README.md +++ b/README.md @@ -248,13 +248,13 @@ try (Session session = db.createSession()) { Migration migration1 = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { - instruction.forDatabase() + public void migrate(Instruction instructions) { + instructions.forDatabase() // make a non-secure db to secure db .addPassword("test-user", "test-password"); - // create instruction for existing repository - instruction.forRepository(OldClass.class, null) + // create instructions for existing repository + instructions.forRepository(OldClass.class, null) // rename the repository (in case of entity name changes) .renameRepository("migrated", null) @@ -288,8 +288,8 @@ Migration migration1 = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { Migration migration2 = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forCollection("test") + public void migrate(Instruction instructions) { + instructions.forCollection("test") .addField("fullName", "Dummy Name"); } }; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java index 5ac1f1b6e..de37d5b5a 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java @@ -21,6 +21,8 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** * @author Anindya Chatterjee */ diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java index 504fc4551..87de6b589 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java @@ -9,7 +9,7 @@ import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.mapper.JacksonMapperModule; -import org.dizitart.no2.migration.Instruction; +import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.mvstore.MVStoreModule; @@ -78,7 +78,7 @@ public void testRepositoryMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -135,7 +135,7 @@ public void testCollectionMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -166,11 +166,11 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forDatabase() + public void migrate(Instructions instructions) { + instructions.forDatabase() .changePassword("test-user", "test-password", "password"); - instruction.forCollection("testCollectionMigrate") + instructions.forCollection("testCollectionMigrate") .dropIndex("firstName") .deleteField("bloodGroup") .addField("name", document -> faker.name().fullName()) @@ -217,7 +217,7 @@ public void testOpenWithoutSchemaVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testOpenWithoutSchemaVersion") @@ -269,7 +269,7 @@ public void testDescendingSchema() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testDescendingSchema") @@ -295,9 +295,9 @@ public void migrate(Instruction instruction) { migration = new Migration(2, Constants.INITIAL_SCHEMA_VERSION) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instructions) { - instruction.forCollection("testDescendingSchema") + instructions.forCollection("testDescendingSchema") .rename("test"); } }; @@ -333,7 +333,7 @@ public void testMigrationWithoutVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testMigrationWithoutVersion") @@ -374,7 +374,7 @@ public void testWrongSchemaVersionNoMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testWrongSchemaVersionNoMigration") .rename("test") @@ -403,8 +403,8 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forCollection("test") + public void migrate(Instructions instructions) { + instructions.forCollection("test") .rename("testWrongSchemaVersionNoMigration"); } }; @@ -443,7 +443,7 @@ public void testReOpenAfterMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testReOpenAfterMigration") .rename("test") @@ -511,7 +511,7 @@ public void testMultipleMigrations() { Migration migration1 = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testMultipleMigrations") .rename("test"); @@ -520,7 +520,7 @@ public void migrate(Instruction instruction) { Migration migration2 = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("fullName", "Dummy Name"); } @@ -545,7 +545,7 @@ public void migrate(Instruction instruction) { Migration migration3 = new Migration(3, 4) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("age", 10); } diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java index 27635a93a..6669414f1 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java @@ -100,7 +100,7 @@ public V remove(K k) { } @Override - public RecordStream keySet() { + public RecordStream keys() { return RecordStream.fromIterable(() -> new Iterator() { final Iterator keyIterator = bTreeMap.keyIterator(); final Iterator nullEntryIterator = nullEntryMap.keyIterator(); diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java index 85c579539..dd2276c0b 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java @@ -59,8 +59,13 @@ public void commit() { } @Override - public void close() { + public void close() throws Exception { db.close(); + + for (NitriteMap nitriteMap : nitriteMapRegistry.values()) { + nitriteMap.close(); + } + alert(StoreEvents.Closed); } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java index dbc63bd74..949a75f7e 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java @@ -20,17 +20,20 @@ import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.StoreConfig; import org.junit.After; import org.junit.Before; @@ -43,6 +46,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.LinkedHashSet; import java.util.Random; import static org.dizitart.no2.collection.Document.createDocument; @@ -315,30 +319,31 @@ public String getIndexType() { } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void validateIndex(Fields fields) { } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void dropIndex(NitriteMap collection, String field) { + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public NitriteIndexer clone() throws CloneNotSupportedException { + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { return null; } + @Override public void initialize(NitriteConfig nitriteConfig) { diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java index ad1f00e27..e520f97da 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java @@ -10,7 +10,7 @@ import org.dizitart.no2.index.IndexType; import org.dizitart.no2.mapdb.MapDBModule; import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.migration.Instruction; +import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.repository.ObjectRepository; @@ -77,7 +77,7 @@ public void testRepositoryMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -133,7 +133,7 @@ public void testCollectionMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -163,11 +163,11 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forDatabase() + public void migrate(Instructions instructions) { + instructions.forDatabase() .changePassword("test-user", "test-password", "password"); - instruction.forCollection("testCollectionMigrate") + instructions.forCollection("testCollectionMigrate") .dropIndex("firstName") .deleteField("bloodGroup") .addField("name", document -> faker.name().fullName()) @@ -213,7 +213,7 @@ public void testOpenWithoutSchemaVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testOpenWithoutSchemaVersion") @@ -263,7 +263,7 @@ public void testDescendingSchema() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testDescendingSchema") @@ -288,9 +288,9 @@ public void migrate(Instruction instruction) { migration = new Migration(2, Constants.INITIAL_SCHEMA_VERSION) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instructions) { - instruction.forCollection("testDescendingSchema") + instructions.forCollection("testDescendingSchema") .rename("test"); } }; @@ -325,7 +325,7 @@ public void testMigrationWithoutVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testMigrationWithoutVersion") @@ -365,7 +365,7 @@ public void testWrongSchemaVersionNoMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testWrongSchemaVersionNoMigration") .rename("test") @@ -393,8 +393,8 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forCollection("test") + public void migrate(Instructions instructions) { + instructions.forCollection("test") .rename("testWrongSchemaVersionNoMigration"); } }; @@ -432,7 +432,7 @@ public void testReOpenAfterMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testReOpenAfterMigration") .rename("test") @@ -499,7 +499,7 @@ public void testMultipleMigrations() { Migration migration1 = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testMultipleMigrations") .rename("test"); @@ -508,7 +508,7 @@ public void migrate(Instruction instruction) { Migration migration2 = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("fullName", "Dummy Name"); } @@ -532,7 +532,7 @@ public void migrate(Instruction instruction) { Migration migration3 = new Migration(3, 4) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("age", 10); } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java index 25e4821dc..7f099ec98 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java @@ -20,6 +20,7 @@ import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; @@ -93,12 +94,7 @@ public WriteResult remove(Filter filter, boolean justOne) { } @Override - public DocumentCursor find() { - return null; - } - - @Override - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { return null; } @@ -118,7 +114,17 @@ public void createIndex(String field, IndexOptions indexOptions) { } @Override - public void rebuildIndex(String field, boolean isAsync) { + public void createIndex(Fields fields, IndexOptions indexOptions) { + + } + + @Override + public void rebuildIndex(String field) { + + } + + @Override + public void rebuildIndex(Fields fields) { } @@ -132,16 +138,31 @@ public boolean hasIndex(String field) { return false; } + @Override + public boolean hasIndex(Fields fields) { + return false; + } + @Override public boolean isIndexing(String field) { return false; } + @Override + public boolean isIndexing(Fields fields) { + return false; + } + @Override public void dropIndex(String field) { } + @Override + public void dropIndex(Fields fields) { + + } + @Override public void dropAllIndices() { diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java index 5bf41152e..d5f0478f0 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java @@ -25,6 +25,8 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** * A {@link NitriteModule} which provides h2's mvstore as a storage engine. * diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java index 5dc1dac1c..533a9e7a8 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java @@ -79,7 +79,7 @@ public Value remove(Key key) { } @Override - public RecordStream keySet() { + public RecordStream keys() { return RecordStream.fromIterable(mvMap.keySet()); } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java index cbf7de411..1fd2970a5 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java @@ -29,8 +29,7 @@ * @since 1.0 * @author Anindya Chatterjee */ -class NitriteMVRTreeMap - implements NitriteRTree { +class NitriteMVRTreeMap implements NitriteRTree { private final MVRTreeMap mvMap; NitriteMVRTreeMap(MVRTreeMap mvMap) { @@ -91,4 +90,9 @@ public NitriteId next() { } }); } + + @Override + public void close() throws Exception { + //nothing to close + } } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java index f78cd26d7..90fc6d47f 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java @@ -39,10 +39,12 @@ public class NitriteMVStore extends AbstractNitriteStore { private MVStore mvStore; private final Map> nitriteMapRegistry; + private final Map> nitriteRTreeMapRegistry; public NitriteMVStore() { super(); this.nitriteMapRegistry = new ConcurrentHashMap<>(); + this.nitriteRTreeMapRegistry = new ConcurrentHashMap<>(); } @Override @@ -74,10 +76,20 @@ public void commit() { } @Override - public void close() { + public void close() throws Exception { if (getStoreConfig().autoCompact()) { compact(); } + + // close nitrite maps + for (NitriteMap nitriteMap : nitriteMapRegistry.values()) { + nitriteMap.close(); + } + + for (NitriteRTree rTree : nitriteRTreeMapRegistry.values()) { + rTree.close(); + } + mvStore.close(); alert(StoreEvents.Closed); } @@ -109,9 +121,15 @@ public void removeMap(String name) { @Override @SuppressWarnings({"unchecked", "rawtypes"}) - public NitriteRTree openRTree(String name, Class keyType, Class valueType) { - MVRTreeMap map = mvStore.openMap(name, new MVRTreeMap.Builder<>()); - return new NitriteMVRTreeMap(map); + public NitriteRTree openRTree(String mapName, Class keyType, Class valueType) { + if (nitriteRTreeMapRegistry.containsKey(mapName)) { + return (NitriteMVRTreeMap) nitriteRTreeMapRegistry.get(mapName); + } + + MVRTreeMap map = mvStore.openMap(mapName, new MVRTreeMap.Builder<>()); + NitriteMVRTreeMap nitriteMVRTreeMap = new NitriteMVRTreeMap(map); + nitriteRTreeMapRegistry.put(mapName, nitriteMVRTreeMap); + return nitriteMVRTreeMap; } @Override diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index a27e3dbb8..5164f3a30 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -17,11 +17,15 @@ package org.dizitart.no2; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; @@ -30,7 +34,6 @@ import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.StoreConfig; import org.junit.After; import org.junit.Before; @@ -43,6 +46,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.LinkedHashSet; import java.util.Random; import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; @@ -323,27 +327,27 @@ public String getIndexType() { } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void validateIndex(Fields fields) { } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void dropIndex(NitriteMap collection, String field) { + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public NitriteIndexer clone() throws CloneNotSupportedException { + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { return null; } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java index bc23b70e5..e6a7a0e23 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java @@ -22,6 +22,7 @@ import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.DocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; import org.junit.After; import org.junit.Rule; @@ -50,7 +51,7 @@ public void testFindResult() { collection.insert(createDocument("first", "second")); DocumentCursor result = collection.find(); - assertTrue(result instanceof DocumentCursorImpl); + assertTrue(result instanceof DocumentStream); } @Test(expected = InvalidOperationException.class) diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java index 6cd178a39..ad94cbe73 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java @@ -20,6 +20,7 @@ import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.streams.JoinedDocumentStream; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java index ef7d4d06d..162474d9c 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java @@ -9,7 +9,7 @@ import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.migration.Instruction; +import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.mvstore.MVStoreModule; @@ -77,7 +77,7 @@ public void testRepositoryMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -134,7 +134,7 @@ public void testCollectionMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -165,11 +165,11 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forDatabase() + public void migrate(Instructions instructions) { + instructions.forDatabase() .changePassword("test-user", "test-password", "password"); - instruction.forCollection("testCollectionMigrate") + instructions.forCollection("testCollectionMigrate") .dropIndex("firstName") .deleteField("bloodGroup") .addField("name", document -> faker.name().fullName()) @@ -216,7 +216,7 @@ public void testOpenWithoutSchemaVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testOpenWithoutSchemaVersion") @@ -268,7 +268,7 @@ public void testDescendingSchema() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testDescendingSchema") @@ -294,9 +294,9 @@ public void migrate(Instruction instruction) { migration = new Migration(2, Constants.INITIAL_SCHEMA_VERSION) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instructions) { - instruction.forCollection("testDescendingSchema") + instructions.forCollection("testDescendingSchema") .rename("test"); } }; @@ -332,7 +332,7 @@ public void testMigrationWithoutVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testMigrationWithoutVersion") @@ -373,7 +373,7 @@ public void testWrongSchemaVersionNoMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testWrongSchemaVersionNoMigration") .rename("test") @@ -402,8 +402,8 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forCollection("test") + public void migrate(Instructions instructions) { + instructions.forCollection("test") .rename("testWrongSchemaVersionNoMigration"); } }; @@ -442,7 +442,7 @@ public void testReOpenAfterMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testReOpenAfterMigration") .rename("test") @@ -510,7 +510,7 @@ public void testMultipleMigrations() { Migration migration1 = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testMultipleMigrations") .rename("test"); @@ -519,7 +519,7 @@ public void migrate(Instruction instruction) { Migration migration2 = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("fullName", "Dummy Name"); } @@ -544,7 +544,7 @@ public void migrate(Instruction instruction) { Migration migration3 = new Migration(3, 4) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("age", 10); } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java index 7612946b0..080a6de79 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java @@ -92,12 +92,7 @@ public WriteResult remove(Filter filter, boolean justOne) { } @Override - public DocumentCursor find() { - return null; - } - - @Override - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { return null; } @@ -116,11 +111,6 @@ public void createIndex(String field, IndexOptions indexOptions) { } - @Override - public void rebuildIndex(String field, boolean isAsync) { - - } - @Override public Collection listIndices() { return null; diff --git a/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageDispatcher.java b/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageDispatcher.java index 9286f6745..a279130d4 100644 --- a/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageDispatcher.java +++ b/nitrite-replication/src/main/java/org/dizitart/no2/sync/MessageDispatcher.java @@ -34,8 +34,8 @@ */ @Slf4j class MessageDispatcher implements DataGateSocketListener, AutoCloseable { - private ReplicationTemplate replicationTemplate; - private MessageTransformer transformer; + private final ReplicationTemplate replicationTemplate; + private final MessageTransformer transformer; private ExecutorService executorService; public MessageDispatcher(Config config, ReplicationTemplate replicationTemplate) { diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java index da4fc9675..ec9a3f7d2 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java @@ -136,7 +136,7 @@ public V remove(K k) { } @Override - public RecordStream keySet() { + public RecordStream keys() { return RecordStream.fromIterable(new KeySet<>(rocksDB, columnFamilyHandle, objectFormatter, getKeyType())); } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java index eb151697a..54e303fcb 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java @@ -8,6 +8,8 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + public class RocksDBModule implements StoreModule { @Setter(AccessLevel.PACKAGE) diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java index 8071aebbd..f209be1be 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java @@ -50,6 +50,7 @@ public RocksDBReference() { @Override public void close() throws RocksDBException { + // if nitrite maps are already closed, this will affect nothing columnFamilyHandleRegistry.values().forEach(AbstractImmutableNativeReference::close); columnFamilyHandleRegistry.clear(); diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java index 179ce532f..0d05b7fae 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java @@ -67,12 +67,18 @@ public void commit() { } @Override - public void close() { + public void close() throws Exception { try { if (!closed.get()) { + // close nitrite maps + for (NitriteMap nitriteMap : nitriteMapRegistry.values()) { + nitriteMap.close(); + } + reference.close(); closed.compareAndSet(false, true); } + alert(StoreEvents.Closed); } catch (Exception e) { log.error("Error while closing the database", e); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java index f2f29da6c..8cac9ceb4 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java @@ -21,17 +21,20 @@ import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.StoreConfig; import org.junit.After; import org.junit.Before; @@ -42,6 +45,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.LinkedHashSet; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; @@ -264,30 +268,31 @@ public String getIndexType() { } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void validateIndex(Fields fields) { } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void dropIndex(NitriteMap collection, String field) { + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public NitriteIndexer clone() throws CloneNotSupportedException { + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { return null; } + @Override public void initialize(NitriteConfig nitriteConfig) { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java index 1ca248b9e..5bea38957 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java @@ -9,7 +9,7 @@ import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.migration.Instruction; +import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.repository.ObjectRepository; @@ -77,7 +77,7 @@ public void testRepositoryMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -133,7 +133,7 @@ public void testCollectionMigrate() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forDatabase() .addPassword("test-user", "test-password"); @@ -163,11 +163,11 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forDatabase() + public void migrate(Instructions instructions) { + instructions.forDatabase() .changePassword("test-user", "test-password", "password"); - instruction.forCollection("testCollectionMigrate") + instructions.forCollection("testCollectionMigrate") .dropIndex("firstName") .deleteField("bloodGroup") .addField("name", document -> faker.name().fullName()) @@ -213,7 +213,7 @@ public void testOpenWithoutSchemaVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testOpenWithoutSchemaVersion") @@ -263,7 +263,7 @@ public void testDescendingSchema() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testDescendingSchema") @@ -288,9 +288,9 @@ public void migrate(Instruction instruction) { migration = new Migration(2, Constants.INITIAL_SCHEMA_VERSION) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instructions) { - instruction.forCollection("testDescendingSchema") + instructions.forCollection("testDescendingSchema") .rename("test"); } }; @@ -325,7 +325,7 @@ public void testMigrationWithoutVersion() { Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .rename("testMigrationWithoutVersion") @@ -365,7 +365,7 @@ public void testWrongSchemaVersionNoMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testWrongSchemaVersionNoMigration") .rename("test") @@ -393,8 +393,8 @@ public void migrate(Instruction instruction) { migration = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { - instruction.forCollection("test") + public void migrate(Instructions instructions) { + instructions.forCollection("test") .rename("testWrongSchemaVersionNoMigration"); } }; @@ -432,7 +432,7 @@ public void testReOpenAfterMigration() { Migration migration = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testReOpenAfterMigration") .rename("test") @@ -499,7 +499,7 @@ public void testMultipleMigrations() { Migration migration1 = new Migration(1, 2) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("testMultipleMigrations") .rename("test"); @@ -508,7 +508,7 @@ public void migrate(Instruction instruction) { Migration migration2 = new Migration(2, 3) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("fullName", "Dummy Name"); } @@ -532,7 +532,7 @@ public void migrate(Instruction instruction) { Migration migration3 = new Migration(3, 4) { @Override - public void migrate(Instruction instruction) { + public void migrate(Instructions instruction) { instruction.forCollection("test") .addField("age", 10); } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java index 64540be80..248f13df7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java @@ -20,6 +20,7 @@ import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; @@ -87,22 +88,22 @@ public void cleanUp() throws IOException { private static class DummyCollection implements NitriteCollection { @Override - public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { + public WriteResult insert(Document document, Document... documents) { return null; } @Override - public WriteResult remove(Filter filter, boolean justOne) { + public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { return null; } @Override - public DocumentCursor find() { + public WriteResult remove(Filter filter, boolean justOne) { return null; } @Override - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { return null; } @@ -122,7 +123,17 @@ public void createIndex(String field, IndexOptions indexOptions) { } @Override - public void rebuildIndex(String field, boolean isAsync) { + public void createIndex(Fields fields, IndexOptions indexOptions) { + + } + + @Override + public void rebuildIndex(String field) { + + } + + @Override + public void rebuildIndex(Fields fields) { } @@ -136,16 +147,31 @@ public boolean hasIndex(String field) { return false; } + @Override + public boolean hasIndex(Fields fields) { + return false; + } + @Override public boolean isIndexing(String field) { return false; } + @Override + public boolean isIndexing(Fields fields) { + return false; + } + @Override public void dropIndex(String field) { } + @Override + public void dropIndex(Fields fields) { + + } + @Override public void dropAllIndices() { diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java index 2b5ab8574..1d3f8db9c 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java @@ -17,12 +17,10 @@ package org.dizitart.no2.spatial; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.index.IndexScanner; import org.locationtech.jts.geom.Geometry; import java.util.LinkedHashSet; -import java.util.Set; /** * @author Anindya Chatterjee @@ -33,16 +31,7 @@ protected IntersectsFilter(String field, Geometry geometry) { } @Override - protected Set findIndexedIdSet() { - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof SpatialIndexer && getValue() != null) { - SpatialIndexer spatialIndexer = (SpatialIndexer) getNitriteIndexer(); - RecordStream idSet = spatialIndexer.findIntersects(getCollectionName(), getField(), getValue()); - return idSet.toSet(); - } else { - throw new FilterException(getValue() + " is not a Geometry"); - } - } - return new LinkedHashSet<>(); + public LinkedHashSet applyOnIndex(IndexScanner indexScanner) { + return false } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java index 20118b30f..eb563a437 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java @@ -20,16 +20,13 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.filters.IndexAwareFilter; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.filters.ComparableFilter; import org.locationtech.jts.geom.Geometry; -import java.util.Set; - /** * @author Anindya Chatterjee */ -public abstract class SpatialFilter extends IndexAwareFilter { +public abstract class SpatialFilter extends ComparableFilter { private final Geometry geometry; protected SpatialFilter(String field, Geometry geometry) { @@ -42,11 +39,6 @@ public Geometry getValue() { return geometry; } - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("spatial filters cannot be applied on _id field"); - } - @Override public boolean apply(Pair element) { throw new FilterException(getField() + " is not indexed with spatial index"); diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java index a556977a2..220602046 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java @@ -21,6 +21,8 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** * @author Anindya Chatterjee */ diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java index 7afe310f7..38e13d12c 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java @@ -17,12 +17,10 @@ package org.dizitart.no2.spatial; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.index.IndexScanner; import org.locationtech.jts.geom.Geometry; import java.util.LinkedHashSet; -import java.util.Set; /** * @author Anindya Chatterjee @@ -33,16 +31,7 @@ protected WithinFilter(String field, Geometry geometry) { } @Override - protected Set findIndexedIdSet() { - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof SpatialIndexer && getValue() != null) { - SpatialIndexer spatialIndexer = (SpatialIndexer) getNitriteIndexer(); - RecordStream idSet = spatialIndexer.findWithin(getCollectionName(), getField(), getValue()); - return idSet.toSet(); - } else { - throw new FilterException(getValue() + " is not a Geometry"); - } - } - return new LinkedHashSet<>(); + public LinkedHashSet applyOnIndex(IndexScanner indexScanner) { + return false } } diff --git a/nitrite/src/main/java/org/dizitart/no2/Nitrite.java b/nitrite/src/main/java/org/dizitart/no2/Nitrite.java index 3a1bd9429..ecccf3568 100644 --- a/nitrite/src/main/java/org/dizitart/no2/Nitrite.java +++ b/nitrite/src/main/java/org/dizitart/no2/Nitrite.java @@ -25,7 +25,6 @@ import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.transaction.Session; -import java.io.Closeable; import java.util.Map; import java.util.Set; @@ -40,19 +39,19 @@ * @author Anindya Chatterjee * @since 1.0 */ -public interface Nitrite extends Closeable { +public interface Nitrite extends AutoCloseable { + /** + * Returns an instance of a {@link NitriteBuilder}. + * + * @return the nitrite builder + */ static NitriteBuilder builder() { return new NitriteBuilder(); } /** - * Closes the database. Unsaved changes are written to disk for a file based store. - */ - void close(); - - /** - * Commits the changes. For file based store, it saves the changes + * Commits the unsaved changes. For file based store, it saves the changes * to disk if there are any unsaved changes. *

* No need to call it after every change, if auto-commit is not disabled @@ -139,14 +138,14 @@ static NitriteBuilder builder() { /** * Checks whether the store has any unsaved changes. * - * @return `true` if there are unsaved changes; otherwise `false`. + * @return true if there are unsaved changes; otherwise false. */ boolean hasUnsavedChanges(); /** * Checks whether the store is closed. * - * @return `true` if closed; otherwise `false`. + * @return true if closed; otherwise false. */ boolean isClosed(); @@ -171,7 +170,6 @@ static NitriteBuilder builder() { */ DatabaseMetaData getDatabaseMetaData(); - /** * Creates a {@link Session} for transaction. * @@ -183,7 +181,7 @@ static NitriteBuilder builder() { * Checks whether a particular {@link NitriteCollection} exists in the store. * * @param name the name of the collection. - * @return `true` if the collection exists; otherwise `false`. + * @return true if the collection exists; otherwise false. */ default boolean hasCollection(String name) { checkOpened(); @@ -195,7 +193,7 @@ default boolean hasCollection(String name) { * * @param the type parameter * @param type the type of the object - * @return `true` if the repository exists; otherwise `false`. + * @return true if the repository exists; otherwise false. */ default boolean hasRepository(Class type) { checkOpened(); @@ -206,9 +204,9 @@ default boolean hasRepository(Class type) { * Checks whether a particular keyed-{@link ObjectRepository} exists in the store. * * @param the type parameter. - * @param key the key, which will be appended to the repositories name. * @param type the type of the object. - * @return `true` if the repository exists; otherwise `false`. + * @param key the key, which will be appended to the repositories name. + * @return true if the repository exists; otherwise false. */ default boolean hasRepository(Class type, String key) { checkOpened(); @@ -216,6 +214,11 @@ default boolean hasRepository(Class type, String key) { && listKeyedRepository().get(key).contains(type.getName()); } + /** + * Validate the collection name. + * + * @param name the name + */ default void validateCollectionName(String name) { notNull(name, "name cannot be null"); notEmpty(name, "name cannot be empty"); @@ -227,6 +230,9 @@ default void validateCollectionName(String name) { } } + /** + * Checks if the store is opened. + */ default void checkOpened() { if (getStore() == null || getStore().isClosed()) { throw new NitriteIOException("store is closed"); diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java index 68de2b89a..48ddc97d2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java @@ -35,6 +35,9 @@ public class NitriteBuilder { @Getter private final NitriteConfig nitriteConfig; + /** + * Instantiates a new {@link NitriteBuilder}. + */ NitriteBuilder() { this.nitriteConfig = new NitriteConfig(); } @@ -62,6 +65,12 @@ public NitriteBuilder loadModule(NitriteModule module) { return this; } + /** + * Adds instructions to perform during schema migration. + * + * @param migrations the migrations + * @return the nitrite builder + */ public NitriteBuilder addMigrations(Migration... migrations) { for (Migration migration : migrations) { this.nitriteConfig.addMigration(migration); @@ -69,6 +78,12 @@ public NitriteBuilder addMigrations(Migration... migrations) { return this; } + /** + * Sets the current schema version. + * + * @param version the version + * @return the nitrite builder + */ public NitriteBuilder schemaVersion(Integer version) { this.nitriteConfig.schemaVersion(version); return this; @@ -80,9 +95,8 @@ public NitriteBuilder schemaVersion(Integer version) { * exists, then it will create a new file store and open; otherwise it will * open the existing file store. *

- * - * - * NOTE: If the database is corrupted somehow then at the time of opening, it will + *

+ * NOTE: If the database is corrupted somehow then at the time of opening, it will * try to repair it using the last known good version. If still it fails to * recover, then it will throw a {@link org.dizitart.no2.exceptions.NitriteIOException}. * @@ -106,8 +120,8 @@ public Nitrite openOrCreate() { * While opening an existing database, it will use the specified credentials * to open it. *

- * - * NOTE: If the database is corrupted somehow then at the time of opening, it will + *

+ * NOTE: If the database is corrupted somehow then at the time of opening, it will * try to repair it using the last known good version. If still it fails to * recover, then it will throw a {@link org.dizitart.no2.exceptions.NitriteIOException}. * diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java index 4ee8d82d7..1d20b3377 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java @@ -45,16 +45,18 @@ @ToString public class NitriteConfig { /** - * Gets the embedded field separator character. Default value - * is `.` unless set explicitly. - * - * @return the embedded field separator character. + * Indicates if this {@link NitriteConfig} is already configured. */ - @Getter - private static String fieldSeparator = "."; + protected boolean configured = false; + /** + * Returns the {@link PluginManager} instance. + */ @Getter(AccessLevel.PACKAGE) - private final PluginManager pluginManager; + protected final PluginManager pluginManager; + + @Getter + private static String fieldSeparator = "."; @Getter private final Map> migrations; @@ -62,8 +64,9 @@ public class NitriteConfig { @Getter private Integer schemaVersion = Constants.INITIAL_SCHEMA_VERSION; - private boolean configured = false; - + /** + * Instantiates a new {@link NitriteConfig}. + */ public NitriteConfig() { this.pluginManager = new PluginManager(this); this.migrations = new HashMap<>(); @@ -84,7 +87,7 @@ public void fieldSeparator(String separator) { } /** - * Loads {@link NitritePlugin} instances. + * Loads {@link NitritePlugin} instances defined in the {@link NitriteModule}. * * @param module the {@link NitriteModule} instances. * @return the {@link NitriteConfig} instance. @@ -98,6 +101,12 @@ public NitriteConfig loadModule(NitriteModule module) { return this; } + /** + * Adds schema migration instructions. + * + * @param migration the migration + * @return the nitrite config + */ @SuppressWarnings("Java8MapApi") public NitriteConfig addMigration(Migration migration) { if (configured) { @@ -122,6 +131,12 @@ public NitriteConfig addMigration(Migration migration) { return this; } + /** + * Sets the current schema version. + * + * @param version the version + * @return the nitrite config + */ public NitriteConfig schemaVersion(Integer version) { if (configured) { throw new InvalidOperationException("cannot add schema version info after database" + @@ -134,7 +149,6 @@ public NitriteConfig schemaVersion(Integer version) { /** * Auto configures nitrite database with default configuration values and * default built-in plugins. - * */ public void autoConfigure() { if (configured) { @@ -178,7 +192,10 @@ public NitriteStore getNitriteStore() { return pluginManager.getNitriteStore(); } - void initialized() { + /** + * Initializes this {@link NitriteConfig} instance. + */ + void initialize() { this.configured = true; this.pluginManager.initializePlugins(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java index 81e5c2d6a..4acfe2f0b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java @@ -30,6 +30,7 @@ import org.dizitart.no2.store.DatabaseMetaData; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.UserAuthenticationService; import org.dizitart.no2.transaction.Session; import java.io.File; @@ -39,10 +40,10 @@ import static org.dizitart.no2.common.Constants.NITRITE_VERSION; import static org.dizitart.no2.common.Constants.STORE_INFO; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.store.StoreSecurity.authenticate; /** * @author Anindya Chatterjee. + * @since 4.0 */ @Slf4j class NitriteDatabase implements Nitrite { @@ -190,7 +191,7 @@ private void validateUserCredentials(String username, String password) { private void initialize(String username, String password) { try { - nitriteConfig.initialized(); + nitriteConfig.initialize(); store = nitriteConfig.getNitriteStore(); boolean isExisting = isExisting(); @@ -200,17 +201,28 @@ private void initialize(String username, String password) { MigrationManager migrationManager = new MigrationManager(this); migrationManager.doMigrate(); - authenticate(store, username, password, isExisting); + UserAuthenticationService userAuthenticationService = new UserAuthenticationService(store); + userAuthenticationService.authenticate(username, password, isExisting); } catch (NitriteException e) { log.error("Error while initializing the database", e); if (store != null && !store.isClosed()) { - store.close(); + try { + store.close(); + } catch (Exception ex) { + log.error("Error while closing the database", ex); + throw new NitriteIOException("failed to close database", ex); + } } throw e; } catch (Exception e) { log.error("Error while initializing the database", e); if (store != null && !store.isClosed()) { - store.close(); + try { + store.close(); + } catch (Exception ex) { + log.error("Error while closing the database"); + throw new NitriteIOException("failed to close database", ex); + } } throw new NitriteIOException("failed to initialize database", e); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java b/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java index bc2de5860..c923cdc5b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java @@ -18,17 +18,17 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.StoreCatalog; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.locks.Lock; -import static org.dizitart.no2.common.Constants.COLLECTION_CATALOG; -import static org.dizitart.no2.common.Constants.TAG_COLLECTIONS; import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; import static org.dizitart.no2.common.util.ValidationUtils.notNull; @@ -84,11 +84,8 @@ private NitriteCollection createCollection(String name, NitriteConfig nitriteCon } collectionMap.put(name, collection); - NitriteMap catalogMap = store.openMap(COLLECTION_CATALOG, String.class, Document.class); - Document document = catalogMap.get(TAG_COLLECTIONS); - if (document == null) document = Document.createDocument(); - document.put(name, true); - catalogMap.put(TAG_COLLECTIONS, document); + StoreCatalog storeCatalog = store.getCatalog(); + storeCatalog.writeCollectionEntry(name); } return collection; @@ -102,6 +99,8 @@ public void clear() { collection.close(); } collectionMap.clear(); + } catch (Exception e) { + throw new NitriteIOException("failed to close a collection", e); } finally { lock.unlock(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 2d69ecffb..533bfc819 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -35,15 +35,18 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import java.util.Arrays; import java.util.Collection; import java.util.concurrent.locks.Lock; import static org.dizitart.no2.collection.UpdateOptions.updateOptions; import static org.dizitart.no2.common.util.DocumentUtils.createUniqueFilter; -import static org.dizitart.no2.common.util.ValidationUtils.*; +import static org.dizitart.no2.common.util.ValidationUtils.containsNull; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** * @author Anindya Chatterjee. @@ -74,6 +77,20 @@ class DefaultNitriteCollection implements NitriteCollection { initialize(); } + @Override + public void addProcessor(Processor processor) { + checkOpened(); + notNull(processor, "a null processor cannot be added"); + collectionOperations.addProcessor(processor); + } + + @Override + public void removeProcessor(Processor processor) { + checkOpened(); + notNull(processor, "a null processor cannot be removed"); + collectionOperations.removeProcessor(processor); + } + public WriteResult insert(Document[] documents) { checkOpened(); notNull(documents, "a null document cannot be inserted"); @@ -155,52 +172,42 @@ public void clear() { } } - public DocumentCursor find() { - checkOpened(); - try { - readLock.lock(); - return collectionOperations.find(); - } finally { - readLock.unlock(); - } - } - - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { checkOpened(); try { readLock.lock(); - return collectionOperations.find(filter); + return collectionOperations.find(filter, findOptions); } finally { readLock.unlock(); } } - public void createIndex(Fields fields, IndexOptions indexOptions) { + public void createIndex(IndexOptions indexOptions, String... fields) { checkOpened(); notNull(fields, "fields cannot be null"); - // by default async is false while creating index + Fields indexFields = Fields.withNames(fields); try { writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(fields, IndexType.Unique, false); + collectionOperations.createIndex(indexFields, IndexType.Unique); } else { - collectionOperations.createIndex(fields, indexOptions.getIndexType(), - indexOptions.isAsync()); + collectionOperations.createIndex(indexFields, indexOptions.getIndexType()); } } finally { writeLock.unlock(); } } - public void rebuildIndex(Fields fields, boolean isAsync) { + public void rebuildIndex(String... fields) { checkOpened(); notNull(fields, "fields cannot be null"); IndexDescriptor indexDescriptor; + Fields indexFields = Fields.withNames(fields); try { readLock.lock(); - indexDescriptor = collectionOperations.findIndex(fields); + indexDescriptor = collectionOperations.findIndex(indexFields); } finally { readLock.unlock(); } @@ -210,12 +217,12 @@ public void rebuildIndex(Fields fields, boolean isAsync) { try { writeLock.lock(); - collectionOperations.rebuildIndex(indexDescriptor, isAsync); + collectionOperations.rebuildIndex(indexDescriptor); } finally { writeLock.unlock(); } } else { - throw new IndexingException(fields + " is not indexed"); + throw new IndexingException(Arrays.toString(fields) + " is not indexed"); } } @@ -230,37 +237,40 @@ public Collection listIndices() { } } - public boolean hasIndex(Fields fields) { + public boolean hasIndex(String... fields) { checkOpened(); notNull(fields, "fields cannot be null"); + Fields indexFields = Fields.withNames(fields); try { readLock.lock(); - return collectionOperations.hasIndex(fields); + return collectionOperations.hasIndex(indexFields); } finally { readLock.unlock(); } } - public boolean isIndexing(Fields fields) { + public boolean isIndexing(String... fields) { checkOpened(); notNull(fields, "field cannot be null"); + Fields indexFields = Fields.withNames(fields); try { readLock.lock(); - return collectionOperations.isIndexing(fields); + return collectionOperations.isIndexing(indexFields); } finally { readLock.unlock(); } } - public void dropIndex(Fields fields) { + public void dropIndex(String... fields) { checkOpened(); notNull(fields, "fields cannot be null"); + Fields indexFields = Fields.withNames(fields); try { writeLock.lock(); - collectionOperations.dropIndex(fields); + collectionOperations.dropIndex(indexFields); } finally { writeLock.unlock(); } @@ -299,17 +309,25 @@ public void drop() { writeLock.unlock(); } isDropped = true; - close(); + try { + close(); + } catch (Exception e) { + throw new NitriteIOException("failed to close the database", e); + } } public boolean isOpen() { if (nitriteStore == null || nitriteStore.isClosed() || isDropped) { - close(); + try { + close(); + } catch (Exception e) { + throw new NitriteIOException("failed to close the database", e); + } return false; } else return true; } - public void close() { + public void close() throws Exception { if (collectionOperations != null) { collectionOperations.close(); } @@ -378,7 +396,7 @@ public void setAttributes(Attributes attributes) { } } - private void closeEventBus() { + private void closeEventBus() throws Exception { if (eventBus != null) { eventBus.close(); } @@ -409,7 +427,8 @@ private void checkOpened() { private void validateRebuildIndex(IndexDescriptor indexDescriptor) { notNull(indexDescriptor, "index cannot be null"); - if (isIndexing(indexDescriptor.getIndexFields())) { + String[] indexFields = indexDescriptor.getIndexFields().getFieldNames().toArray(new String[0]); + if (isIndexing(indexFields)) { throw new IndexingException("indexing on value " + indexDescriptor.getIndexFields() + " is currently running"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/Document.java b/nitrite/src/main/java/org/dizitart/no2/collection/Document.java index 2e561b9b1..871600e46 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/Document.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/Document.java @@ -26,47 +26,143 @@ import static org.dizitart.no2.common.Constants.*; /** + * A representation of a nitrite document. + * + * @since 1.0 * @author Anindya Chatterjee */ public interface Document extends Iterable>, Cloneable, Serializable { + /** + * Creates a new empty document. + * + * @return the document + */ static Document createDocument() { return new NitriteDocument(); } + /** + * Creates a new document initialized with the given key/value pair. + * + * @param key the key + * @param value the value + * @return the document + */ static Document createDocument(String key, Object value) { LinkedHashMap document = new LinkedHashMap<>(); document.put(key, value); return new NitriteDocument(document); } + /** + * Creates a new document initialized with the given map. + * + * @param documentMap the map + * @return the document + */ static Document createDocument(Map documentMap) { LinkedHashMap document = new LinkedHashMap<>(documentMap); return new NitriteDocument(document); } + /** + * Associates the specified value with the specified key in this document. + *

+ * NOTE: An embedded field is also supported. + *

+ * + * @param key the key + * @param value the value + * @return the document + */ Document put(final String key, final Object value); + /** + * Returns the value to which the specified key is associated with, + * or null if this document contains no mapping for the key. + * + * @param key the key + * @return the object + */ Object get(String key); + /** + * Returns the value of type {@code } to which the specified + * key is associated, or null if this document contains no mapping + * for the key. + * + * @param the type parameter + * @param key the key + * @param type the type + * @return the value + */ T get(String key, Class type); + /** + * Return the nitrite id associated with this document. + * + * @return the nitrite id + */ NitriteId getId(); + /** + * Retrieves all fields (top level and embedded) associated + * with this document. + * + * @return the fields + */ Set getFields(); + /** + * Checks if this document has a nitrite id. + * + * @return the boolean + */ boolean hasId(); + /** + * Removes the key and its value from the document. + * + * @param key the key + */ void remove(String key); + /** + * Creates and returns a copy of this document. + * + * @return document + * */ Document clone(); + /** + * Returns the number of entries in the document. + * + * @return the int + */ int size(); + /** + * Merges a document in this document. + * + * @param update the update + * @return the document + */ Document merge(Document update); + /** + * Checks if a key exists in the document. + * + * @param key the key + * @return the boolean + */ boolean containsKey(String key); + /** + * Gets the document revision number. + * + * @return the revision + */ default Integer getRevision() { if (!containsKey(DOC_REVISION)) { return 0; @@ -74,6 +170,11 @@ default Integer getRevision() { return get(DOC_REVISION, Integer.class); } + /** + * Gets the source of this document. + * + * @return the source + */ default String getSource() { if (!containsKey(DOC_SOURCE)) { return ""; @@ -81,6 +182,11 @@ default String getSource() { return get(DOC_SOURCE, String.class); } + /** + * Gets last modified time of this document since epoch. + * + * @return the last modified since epoch + */ default Long getLastModifiedSinceEpoch() { if (!containsKey(DOC_MODIFIED)) { return 0L; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java b/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java index a3ef2e4c2..ea0dacca3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DocumentCursor.java @@ -16,45 +16,45 @@ package org.dizitart.no2.collection; -import org.dizitart.no2.common.*; -import org.dizitart.no2.common.tuples.Pair; - -import java.text.Collator; - -import static org.dizitart.no2.common.Fields.multiple; +import org.dizitart.no2.common.Lookup; +import org.dizitart.no2.common.RecordStream; /** * An interface to iterate over database {@code find()} results. It provides a * mechanism to iterate over all {@link NitriteId}s of the result. - *

- * [[app-listing]] - * [source,java] - * .Example of {@link DocumentCursor} - * -- + *

+ * {@code
+ * // create/open a database
+ * Nitrite db = Nitrite.builder()
+ *      .openOrCreate("user", "password");
+ *
  * // create/open a database
  * Nitrite db = Nitrite.builder()
- * .openOrCreate("user", "password");
- * 

+ * .openOrCreate("user", "password"); + * * // create a collection named - test * NitriteCollection collection = db.getCollection("test"); - *

+ * * // returns all ids un-filtered * DocumentCursor result = collection.find(); - *

+ * * for (Document doc : result) { - * // use your logic with the retrieved doc here + * // use your logic with the retrieved doc here * } - *

- * -- + * + * }* + *
* * @author Anindya Chatterjee * @since 4.0 */ public interface DocumentCursor extends RecordStream { - - DocumentCursor sort(Fields fields, Collator collator, NullOrder nullOrder); - - DocumentCursor skipLimit(long skip, long size); + /** + * Gets a filter plan for the query. + * + * @return the filter plan + */ + FindPlan getFindPlan(); /** * Gets a lazy iterable containing all the selected keys of the result documents. @@ -77,32 +77,4 @@ public interface DocumentCursor extends RecordStream { * @since 2.1.0 */ RecordStream join(DocumentCursor foreignCursor, Lookup lookup); - - default DocumentCursor skip(long skip) { - return skipLimit(skip, size()); - } - - default DocumentCursor limit(long limit) { - return skipLimit(0, limit); - } - - default DocumentCursor sort(String field) { - return sort(field, SortOrder.Ascending); - } - - default DocumentCursor sort(String field, SortOrder sortOrder) { - return sort(multiple(new Pair<>(field, sortOrder)), NullOrder.Default); - } - - default DocumentCursor sort(Fields fields) { - return sort(fields, null, NullOrder.Default); - } - - default DocumentCursor sort(Fields fields, Collator collator) { - return sort(fields, collator, NullOrder.Default); - } - - default DocumentCursor sort(Fields fields, NullOrder nullOrder) { - return sort(fields, null, nullOrder); - } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java b/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java new file mode 100644 index 000000000..1554d0883 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.dizitart.no2.common.NullOrder; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.SortableFields; + +import java.text.Collator; + +/** + * The options for find operation. + * + * @since 1.0 + * @author Anindya Chatterjee + */ +@Data +@Accessors(fluent = true, chain = true) +public class FindOptions { + private SortableFields orderBy; + private Collator collator; + private NullOrder nullOrder; + private long skip; + private long limit; + + public static FindOptions orderBy(String fieldName, SortOrder sortOrder) { + SortableFields fields = new SortableFields(); + fields.addField(fieldName, sortOrder); + + FindOptions findOptions = new FindOptions(); + findOptions.orderBy(fields); + return findOptions; + } + + public static FindOptions skipBy(long skip) { + FindOptions findOptions = new FindOptions(); + findOptions.skip(skip); + return findOptions; + } + + public static FindOptions limitBy(long limit) { + FindOptions findOptions = new FindOptions(); + findOptions.limit(limit); + return findOptions; + } + + public FindOptions thenOrderBy(String fieldName, SortOrder sortOrder) { + if (orderBy != null) { + orderBy.addField(fieldName, sortOrder); + } else { + SortableFields fields = new SortableFields(); + fields.addField(fieldName, sortOrder); + orderBy = fields; + } + return this; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java new file mode 100644 index 000000000..bb93173ab --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection; + +import lombok.Data; +import org.dizitart.no2.common.NullOrder; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.IndexScanFilter; +import org.dizitart.no2.index.IndexDescriptor; + +import java.text.Collator; +import java.util.List; +import java.util.Map; + +/** + * Represents an execution plan of a find operation after optimization. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +@Data +public class FindPlan { + private IndexDescriptor indexDescriptor; + private IndexScanFilter indexScanFilter; + private Map indexScanOrder; + + private Filter collectionScanFilter; + private List> blockingSortOrder; + + private Long skip; + private Long limit; + + private Collator collator; + private NullOrder nullOrder; + + private List subPlans; +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java index fca4c3ee8..dbe8ff951 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java @@ -19,7 +19,6 @@ import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.events.EventAware; import org.dizitart.no2.collection.events.EventType; -import org.dizitart.no2.collection.operation.FindOptions; import org.dizitart.no2.common.PersistentCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; @@ -193,11 +192,9 @@ default WriteResult remove(Filter filter) { * @return a cursor to all documents in the collection. */ default DocumentCursor find() { - return find(new FindOptions()); + return find(Filter.ALL, null); } - DocumentCursor find(FindOptions findOptions); - /** * Applies a filter on the collection and returns a cursor to the * selected documents. @@ -215,9 +212,33 @@ default DocumentCursor find() { * @see DocumentCursor#project(Document) */ default DocumentCursor find(Filter filter) { - return find(filter, new FindOptions()); + return find(filter, null); } + /** + * Returns a customized cursor to all documents in the collection. + * + * @param findOptions specifies pagination, sort options for the cursor. + * @return a cursor to all selected documents. + * @see org.dizitart.no2.common.SortOrder + */ + default DocumentCursor find(FindOptions findOptions) { + return find(Filter.ALL, findOptions); + } + + /** + * Applies a filter on the collection and returns a customized cursor to the + * selected documents. + * + *

+ * NOTE: If there is an index on the value specified in the filter, this operation + * will take advantage of the index. + *

+ * + * @param filter the filter to apply to select documents from collection. + * @param findOptions specifies pagination, sort options for the cursor. + * @return a cursor to all selected documents. + */ DocumentCursor find(Filter filter, FindOptions findOptions); /** diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java index c8ab8c944..9adfd2d40 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java @@ -38,12 +38,14 @@ import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** + * A default implementation of nitrite document. + * + * @since 4.0 * @author Anindya Chatterjee */ class NitriteDocument extends LinkedHashMap implements Document { private static final long serialVersionUID = 1477462374L; private static final List reservedFields = listOf(DOC_ID, DOC_REVISION, DOC_SOURCE, DOC_MODIFIED); -// private final String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); NitriteDocument() { super(); @@ -54,56 +56,66 @@ class NitriteDocument extends LinkedHashMap implements Document } @Override - public Document put(String key, Object value) { - if (isNullOrEmpty(key)) { + public Document put(String field, Object value) { + // field name cannot be empty or null + if (isNullOrEmpty(field)) { throw new InvalidOperationException("document does not support empty or null key"); } - if (DOC_ID.contentEquals(key) && !validId(value)) { + // _id field can not be set manually + if (DOC_ID.contentEquals(field) && !validId(value)) { throw new InvalidOperationException("_id is an auto generated value and cannot be set"); } + // value must be serializable if (value != null && !Serializable.class.isAssignableFrom(value.getClass())) { throw new ValidationException("type " + value.getClass().getName() + " does not implement java.io.Serializable"); } - String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); - if (key.contains(NitriteConfig.getFieldSeparator())) { - String[] splits = key.split(regex); + // if field name contains field separator, split the fields, and put the value + // accordingly associated with th embedded field. + if (isEmbedded(field)) { + String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); + String[] splits = field.split(regex); deepPut(splits, value); } else { - super.put(key, value); + super.put(field, value); } return this; } @Override - public Object get(String key) { - if (key != null - && key.contains(NitriteConfig.getFieldSeparator()) - && !containsKey(key)) { - return deepGet(key); + public Object get(String field) { + if (field != null + && isEmbedded(field) + && !containsKey(field)) { + // if field is an embedded field, get it by deep scan + return deepGet(field); } - return super.get(key); + return super.get(field); } @Override - public T get(String key, Class type) { + public T get(String field, Class type) { notNull(type, "type cannot be null"); - return type.cast(get(key)); + return type.cast(get(field)); } @Override public NitriteId getId() { String id; try { + // if _id field is not populated already, create a new id + // and set, otherwise return the existing id if (!containsKey(DOC_ID)) { id = newId().getIdValue(); super.put(DOC_ID, id); } else { id = (String) get(DOC_ID); } + + // create a nitrite id instance from the string value return createId(id); } catch (ClassCastException cce) { throw new InvalidIdException("invalid _id found " + get(DOC_ID)); @@ -112,6 +124,7 @@ public NitriteId getId() { @Override public Set getFields() { + // get all fields except from the reserved ones return getFieldsInternal(""); } @@ -121,21 +134,36 @@ public boolean hasId() { } @Override - public void remove(String key) { - if (key.contains(NitriteConfig.getFieldSeparator())) { + public void remove(String field) { + if (isEmbedded(field)) { + // if the field is an embedded field, + // run a deep scan and remove the last field String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); - String[] splits = key.split(regex); + String[] splits = field.split(regex); deepRemove(splits); } else { - super.remove(key); + // remove the field from this document + super.remove(field); } } @Override @SuppressWarnings("unchecked") public Document clone() { - Map clone = (Map) super.clone(); - return new NitriteDocument(clone); + Map cloned = (Map) super.clone(); + + // create the clone of any embedded documents as well + for (Map.Entry entry : cloned.entrySet()) { + if (entry.getValue() instanceof Document) { + Document value = (Document) entry.getValue(); + + // this will recursively take care any embedded document + // of the clone as well + Document clonedValue = value.clone(); + cloned.put(entry.getKey(), clonedValue); + } + } + return new NitriteDocument(cloned); } @Override @@ -191,18 +219,27 @@ public Iterator> iterator() { private Set getFieldsInternal(String prefix) { Set fields = new HashSet<>(); + // iterate top level keys for (Pair entry : this) { + // ignore the reserved fields if (reservedFields.contains(entry.getFirst())) continue; Object value = entry.getSecond(); if (value instanceof NitriteDocument) { + // if the value is a document, traverse its fields recursively, + // prefix would be the field name of the document if (isNullOrEmpty(prefix)) { + // level-1 fields fields.addAll(((NitriteDocument) value).getFieldsInternal(entry.getFirst())); } else { + // level-n fields, separated by field separator fields.addAll(((NitriteDocument) value).getFieldsInternal(prefix + NitriteConfig.getFieldSeparator() + entry.getFirst())); } } else if (!(value instanceof Iterable)) { + // if there is no more embedded document, add the field to the list + // and if this is an embedded document then prefix its name by parent fields, + // separated by field separator if (isNullOrEmpty(prefix)) { fields.add(entry.getFirst()); } else { @@ -214,7 +251,8 @@ private Set getFieldsInternal(String prefix) { } private Object deepGet(String field) { - if (field.contains(NitriteConfig.getFieldSeparator())) { + if (isEmbedded(field)) { + // for embedded field, run a deep scan return getByEmbeddedKey(field); } else { return null; @@ -227,15 +265,25 @@ private void deepPut(String[] splits, Object value) { } String key = splits[0]; if (splits.length == 1) { + // if last key, simply put in the current document put(key, value); } else { + // get the object for the current level Object val = get(key); + + // get the remaining embedded fields for next level scan String[] remaining = Arrays.copyOfRange(splits, 1, splits.length); + if (val instanceof NitriteDocument) { + // if the current level value is embedded doc, scan to the next level ((NitriteDocument) val).deepPut(remaining, value); } else if (val == null) { + // if current level value is null, create a new document + // and try to create next level embedded doc by next level scan NitriteDocument subDoc = new NitriteDocument(); subDoc.deepPut(remaining, value); + + // put the newly created document in current level put(key, subDoc); } } @@ -247,17 +295,26 @@ private void deepRemove(String[] splits) { } String key = splits[0]; if (splits.length == 1) { + // if last key, simply remove the current document remove(key); } else { + // get the object for the current level Object val = get(key); + + // get the remaining embedded fields for next level scan String[] remaining = Arrays.copyOfRange(splits, 1, splits.length); + if (val instanceof NitriteDocument) { + // if the current level value is embedded doc, scan to the next level NitriteDocument subDoc = (NitriteDocument) val; - ((NitriteDocument) val).deepRemove(remaining); + subDoc.deepRemove(remaining); if (subDoc.size() == 0) { + // if the next level document is an empty one + // remove the current level document also super.remove(key); } } else if (val == null) { + // if current level value is null, remove the key super.remove(key); } } @@ -265,11 +322,14 @@ private void deepRemove(String[] splits) { private Object getByEmbeddedKey(String embeddedKey) { String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); + + // split the key String[] path = embeddedKey.split(regex); if (path.length < 1) { return null; } + // get current level value and scan to next level using remaining keys return recursiveGet(get(path[0]), Arrays.copyOfRange(path, 1, path.length)); } @@ -284,68 +344,116 @@ private Object recursiveGet(Object object, String[] remainingPath) { } if (object instanceof Document) { + // if the current level value is document, scan to the next level with remaining keys return recursiveGet(((Document) object).get(remainingPath[0]), Arrays.copyOfRange(remainingPath, 1, remainingPath.length)); } if (object.getClass().isArray()) { + // if the current level value is an array + + // get the first key String accessor = remainingPath[0]; + + // convert current value to object array Object[] array = convertToObjectArray(object); + if (isInteger(accessor)) { + // if the current key is an integer + + // convert the key as an integer index int index = asInteger(accessor); + + // check index lower bound if (index < 0) { throw new ValidationException("invalid array index " + index + " to access item inside a document"); } + // check index upper bound if (index >= array.length) { throw new ValidationException("index " + index + " is not less than the size of the array " + array.length); } + // get the value at the index from the array + // if there are remaining keys, scan to the next level return recursiveGet(array[index], Arrays.copyOfRange(remainingPath, 1, remainingPath.length)); } else { + // if the current key is not an integer, then decompose the + // object array into a list and scan each of the element of the + // list using remaining keys and return a list of all returned + // elements from each of the list items. return decompose(listOf(array), remainingPath); } } if (object instanceof Iterable) { + // if the current level value is an iterable + + // get the first key String accessor = remainingPath[0]; + + // convert current value to object iterable Iterable iterable = (Iterable) object; + + // create a list from the iterable List collection = Iterables.toList(iterable); + if (isInteger(accessor)) { + // if the current key is an integer + + // convert the key as an integer index int index = asInteger(accessor); + + // check index lower bound if (index < 0) { throw new ValidationException("invalid collection index " + index + " to access item inside a document"); } + // check index upper bound if (index >= collection.size()) { throw new ValidationException("index " + accessor + " is not less than the size of the list " + collection.size()); } + // get the value at the index from the list + // if there are remaining keys, scan to the next level return recursiveGet(collection.get(index), Arrays.copyOfRange(remainingPath, 1, remainingPath.length)); } else { + // if the current key is not an integer, then decompose the + // list and scan each of the element of the + // list using remaining keys and return a list of all returned + // elements from each of the list items. return decompose(collection, remainingPath); } } + // if no match found return null return null; } @SuppressWarnings("unchecked") private List decompose(List collection, String[] remainingPath) { Set items = new HashSet<>(); + + // iterate each item for (Object item : collection) { - Object value = recursiveGet(item, remainingPath); - if (value != null) { - if (value instanceof Iterable) { - List list = Iterables.toList((Iterable) value); + + // scan the item using remaining keys + Object result = recursiveGet(item, remainingPath); + + if (result != null) { + if (result instanceof Iterable) { + // if the result is iterable, return everything as a list + List list = Iterables.toList((Iterable) result); items.addAll(list); - } else if (value.getClass().isArray()) { - List list = Arrays.asList(convertToObjectArray(value)); + } else if (result.getClass().isArray()) { + // if the result is an array, return everything as list + List list = Arrays.asList(convertToObjectArray(result)); items.addAll(list); } else { - items.add(value); + // if its neither a iterable not an array, return the item + items.add(result); } } } @@ -354,21 +462,30 @@ private List decompose(List collection, String[] remainingPath) private int asInteger(String number) { try { + // parse the string as an integer return Integer.parseInt(number); } catch (NumberFormatException e) { + // if parsing fails, return invalid integer for document access return -1; } } private boolean isInteger(String value) { try { + // try parse the string as an integer Integer.parseInt(value); return true; } catch (NumberFormatException e) { + // if parsing fails, then value is not an integer return false; } } + private boolean isEmbedded(String field) { + // if the field contains separator character, then it is an embedded field + return field.contains(NitriteConfig.getFieldSeparator()); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeInt(size()); for (Pair pair : this) { diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/SnowflakeIdGenerator.java b/nitrite/src/main/java/org/dizitart/no2/collection/SnowflakeIdGenerator.java index 9e6ad19fa..097629475 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/SnowflakeIdGenerator.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/SnowflakeIdGenerator.java @@ -36,7 +36,7 @@ *
  • 1 unused sign bit, always set to 0
  • * *

    - * Original code can be found here - https://github.com/apache/marmotta/blob/master/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/generator/SnowflakeIDGenerator.java + * This is a derivative work of - https://github.com/apache/marmotta/blob/master/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/generator/SnowflakeIDGenerator.java *

    * * @author Sebastian Schaffert (sschaffert@apache.org) diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/events/CollectionEventListener.java b/nitrite/src/main/java/org/dizitart/no2/collection/events/CollectionEventListener.java index f14beaea1..290f1493f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/events/CollectionEventListener.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/events/CollectionEventListener.java @@ -23,14 +23,6 @@ * An interface when implemented makes an object be * able to listen to any changes in a {@link NitriteCollection} * or {@link ObjectRepository}. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - *

    - * // observe any change to the collection - * collection.subscribe(new EventListener() { * * @author Anindya Chatterjee. * @since 4.0 diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/meta/Attributes.java b/nitrite/src/main/java/org/dizitart/no2/collection/meta/Attributes.java index 8fd129818..07562d701 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/meta/Attributes.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/meta/Attributes.java @@ -35,26 +35,61 @@ */ @EqualsAndHashCode public class Attributes implements Serializable { + /** + * The constant CREATED_TIME. + */ public static final String CREATED_TIME = "createdTime"; + /** + * The constant LAST_MODIFIED_TIME. + */ public static final String LAST_MODIFIED_TIME = "lastModifiedTime"; + /** + * The constant OWNER. + */ public static final String OWNER = "owner"; + /** + * The constant UNIQUE_ID. + */ public static final String UNIQUE_ID = "uuid"; + /** + * The constant LAST_SYNCED. + */ public static final String LAST_SYNCED = "lastSynced"; + /** + * The constant SYNC_LOCK. + */ public static final String SYNC_LOCK = "syncLock"; + /** + * The constant EXPIRY_WAIT. + */ public static final String EXPIRY_WAIT = "expiryWait"; + /** + * The constant TOMBSTONE. + */ public static final String TOMBSTONE = "tombstone"; + /** + * The constant REPLICA. + */ public static final String REPLICA = "replica"; private static final long serialVersionUID = 1481284930L; @Getter @Setter private Map attributes; + /** + * Instantiates a new Attributes. + */ public Attributes() { attributes = new ConcurrentHashMap<>(); set(CREATED_TIME, Long.toString(System.currentTimeMillis())); set(UNIQUE_ID, java.util.UUID.randomUUID().toString()); } + /** + * Instantiates a new Attributes. + * + * @param collection the collection + */ public Attributes(String collection) { attributes = new ConcurrentHashMap<>(); set(OWNER, collection); @@ -62,16 +97,35 @@ public Attributes(String collection) { set(UNIQUE_ID, java.util.UUID.randomUUID().toString()); } + /** + * Set attributes. + * + * @param key the key + * @param value the value + * @return the attributes + */ public Attributes set(String key, String value) { attributes.put(LAST_MODIFIED_TIME, Long.toString(System.currentTimeMillis())); attributes.put(key, value); return this; } + /** + * Get string value of an attribute. + * + * @param key the key + * @return the string + */ public String get(String key) { return attributes.get(key); } + /** + * Check whether a key exists in the attributes. + * + * @param key the key + * @return the boolean + */ public boolean hasKey(String key) { return attributes.containsKey(key); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java index 94db9e238..98b999506 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java @@ -17,39 +17,46 @@ package org.dizitart.no2.collection.operation; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.collection.UpdateOptions; +import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventInfo; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.event.EventBus; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.StoreCatalog; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import static org.dizitart.no2.common.Constants.COLLECTION_CATALOG; /** + * The collection operations. + * * @author Anindya Chatterjee + * @since 1.0 */ -public class CollectionOperations { +public class CollectionOperations implements AutoCloseable { private final String collectionName; private final NitriteConfig nitriteConfig; private final NitriteMap nitriteMap; private final EventBus, CollectionEventListener> eventBus; + private ProcessorChain processorChain; private IndexOperations indexOperations; private WriteOperations writeOperations; private ReadOperations readOperations; + /** + * Instantiates a new Collection operations. + * + * @param collectionName the collection name + * @param nitriteMap the nitrite map + * @param nitriteConfig the nitrite config + * @param eventBus the event bus + */ public CollectionOperations(String collectionName, NitriteMap nitriteMap, NitriteConfig nitriteConfig, @@ -61,119 +68,220 @@ public CollectionOperations(String collectionName, initialize(); } - public void createIndex(Fields fields, String indexType, boolean async) { - indexOperations.createIndex(fields, indexType, async); + /** + * Adds a document processor. + * + * @param processor the processor + */ + public void addProcessor(Processor processor) { + processorChain.add(processor); + } + + /** + * Removes a document processor. + * + * @param processor the processor + */ + public void removeProcessor(Processor processor) { + processorChain.remove(processor); + } + + /** + * Creates index. + * + * @param fields the fields + * @param indexType the index type + */ + public void createIndex(Fields fields, String indexType) { + indexOperations.createIndex(fields, indexType); } + /** + * Finds index descriptor. + * + * @param fields the fields + * @return the index descriptor + */ public IndexDescriptor findIndex(Fields fields) { return indexOperations.findIndexDescriptor(fields); } - public void rebuildIndex(IndexDescriptor indexDescriptor, boolean async) { - indexOperations.buildIndex(indexDescriptor, async, true); + /** + * Rebuilds index. + * + * @param indexDescriptor the index descriptor + */ + public void rebuildIndex(IndexDescriptor indexDescriptor) { + indexOperations.buildIndex(indexDescriptor, true); } + /** + * Lists all indexes. + * + * @return the collection + */ public Collection listIndexes() { return indexOperations.listIndexes(); } + /** + * Checks if an index exists on the fields. + * + * @param fields the fields + * @return the boolean + */ public boolean hasIndex(Fields fields) { return indexOperations.hasIndexEntry(fields); } + /** + * Checks if indexing is going on the fields. + * + * @param fields the fields + * @return the boolean + */ public boolean isIndexing(Fields fields) { return indexOperations.isIndexing(fields); } + /** + * Drops index. + * + * @param fields the fields + */ public void dropIndex(Fields fields) { indexOperations.dropIndex(fields); } + /** + * Drops all indices. + */ public void dropAllIndices() { indexOperations.dropAllIndices(); } + /** + * Inserts documents to the collection. + * + * @param documents the documents + * @return the write result + */ public WriteResult insert(Document[] documents) { return writeOperations.insert(documents); } + /** + * Updates documents in the collection. + * + * @param filter the filter + * @param update the update + * @param updateOptions the update options + * @return the write result + */ public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { return writeOperations.update(filter, update, updateOptions); } + /** + * Removes document from the collection. + * + * @param document the document + * @return the write result + */ public WriteResult remove(Document document) { return writeOperations.remove(document); } + /** + * Removes document from collection. + * + * @param filter the filter + * @param justOnce the just once + * @return the write result + */ public WriteResult remove(Filter filter, boolean justOnce) { return writeOperations.remove(filter, justOnce); } - public DocumentCursor find() { - return readOperations.find(); - } - - public DocumentCursor find(Filter filter) { - return readOperations.find(filter); + /** + * Finds documents using filter. + * + * @param filter the filter + * @return the document cursor + */ + public DocumentCursor find(Filter filter, FindOptions findOptions) { + return readOperations.find(filter, findOptions); } + /** + * Gets document by id. + * + * @param nitriteId the nitrite id + * @return the by id + */ public Document getById(NitriteId nitriteId) { return readOperations.getById(nitriteId); } + /** + * Drops the collection. + */ public void dropCollection() { indexOperations.dropAllIndices(); dropNitriteMap(); } + /** + * Gets the size of the collection. + * + * @return the size + */ public long getSize() { return nitriteMap.size(); } + /** + * Gets the additional attributes for the collection. + * + * @return the attributes + */ public Attributes getAttributes() { return nitriteMap != null ? nitriteMap.getAttributes() : null; } + /** + * Sets additional attributes in the collection. + * + * @param attributes the attributes + */ public void setAttributes(Attributes attributes) { nitriteMap.setAttributes(attributes); } - public void close() { + public void close() throws Exception { if (indexOperations != null) { indexOperations.close(); } } private void initialize() { - this.indexOperations = new IndexOperations(nitriteConfig, nitriteMap, eventBus); - DocumentIndexWriter indexWriter = new DocumentIndexWriter(nitriteConfig, nitriteMap, indexOperations); - this.readOperations = new ReadOperations(collectionName, nitriteConfig, nitriteMap, indexWriter); - this.writeOperations = new WriteOperations(indexWriter, readOperations, nitriteMap, eventBus); + this.processorChain = new ProcessorChain(); + IndexManager indexManager = new IndexManager(collectionName, nitriteConfig); + this.indexOperations = new IndexOperations(nitriteConfig, nitriteMap, eventBus, indexManager); + this.readOperations = new ReadOperations(collectionName, indexOperations, + nitriteConfig, nitriteMap, processorChain); + + DocumentIndexWriter indexWriter = new DocumentIndexWriter(nitriteConfig, indexOperations); + this.writeOperations = new WriteOperations(indexWriter, readOperations, + nitriteMap, eventBus, processorChain); } private void dropNitriteMap() { - NitriteMap catalogueMap = nitriteMap.getStore().openMap(COLLECTION_CATALOG, - String.class, Document.class); - for (Pair entry : catalogueMap.entries()) { - String catalogue = entry.getFirst(); - Document document = entry.getSecond(); - - Set bin = new HashSet<>(); - boolean foundKey = false; - for (String field : document.getFields()) { - if (field.equals(nitriteMap.getName())) { - foundKey = true; - bin.add(field); - } - } - - for (String field : bin) { - document.remove(field); - } - catalogueMap.put(catalogue, document); - - if (foundKey) break; - } + // remove the collection name from the catalog + StoreCatalog catalog = nitriteMap.getStore().getCatalog(); + catalog.remove(nitriteMap.getName()); + + // drop the map nitriteMap.drop(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java index 1b5ce10c2..394cfb706 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java @@ -18,34 +18,27 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.util.DocumentUtils; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.store.IndexCatalog; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; import java.util.Collection; /** + * + * @since 4.0 * @author Anindya Chatterjee */ class DocumentIndexWriter { private final NitriteConfig nitriteConfig; - private final NitriteMap nitriteMap; private final IndexOperations indexOperations; - private String collectionName; DocumentIndexWriter(NitriteConfig nitriteConfig, - NitriteMap nitriteMap, IndexOperations indexOperations) { this.nitriteConfig = nitriteConfig; - this.nitriteMap = nitriteMap; this.indexOperations = indexOperations; - initialize(); } void writeIndexEntry(Document document) { @@ -79,80 +72,40 @@ void updateIndexEntry(Document oldDocument, Document newDocument) { String indexType = indexDescriptor.getIndexType(); NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); -// Fields fields = indexDescriptor.getFields(); -// Object newValue = newDocument.get(field); -// Object oldValue = oldDocument.get(field); -// -// if (newValue == null) continue; -// if (newValue instanceof Comparable && oldValue instanceof Comparable) { -// if (((Comparable) newValue).compareTo(oldValue) == 0) continue; -// } -// -// validateDocumentIndexField(newValue, fields); -// -// if (indexCatalog.isDirtyIndex(collectionName, fields) -// && !getBuildFlag(field).get()) { -// // rebuild will also take care of the current document -// rebuildIndex(indexDescriptor, true); -// } else { -// String indexType = indexDescriptor.getIndexType(); -// NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); -// nitriteIndexer.updateIndex(nitriteMap, nitriteId, field, newValue, oldValue); -// } - removeIndexEntryInternal(indexDescriptor, oldDocument, nitriteIndexer); writeIndexEntryInternal(indexDescriptor, newDocument, nitriteIndexer); } } } - private void initialize() { - NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); - this.collectionName = nitriteMap.getName(); - } - private void writeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { - IndexCatalog indexCatalog = nitriteMap.getStore().getIndexCatalog(); - if (indexDescriptor != null) { Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); -// Object fieldValue = document.get(field); -// validateDocumentIndexField(fieldValue, field); - // if dirty index and currently indexing is not running, rebuild - if (indexCatalog.isDirtyIndex(collectionName, fields) - && !indexOperations.getBuildFlag(fields).get()) { + if (indexOperations.shouldRebuildIndex(fields)) { // rebuild will also take care of the current document indexOperations.buildIndex(indexDescriptor, true); } else if (nitriteIndexer != null) { - nitriteIndexer.writeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + nitriteIndexer.writeIndexEntry(fieldValues, indexDescriptor, nitriteConfig); } } } private void removeIndexEntryInternal(IndexDescriptor indexDescriptor, Document document, NitriteIndexer nitriteIndexer) { - IndexCatalog indexCatalog = nitriteMap.getStore().getIndexCatalog(); - if (indexDescriptor != null) { Fields fields = indexDescriptor.getIndexFields(); FieldValues fieldValues = DocumentUtils.getValues(document, fields); -// Object fieldValue = document.get(field); -// if (fieldValue == null) return; -// -// validateDocumentIndexField(fieldValue, field); - // if dirty index and currently indexing is not running, rebuild - if (indexCatalog.isDirtyIndex(collectionName, fields) - && !indexOperations.getBuildFlag(fields).get()) { + if (indexOperations.shouldRebuildIndex(fields)) { // rebuild will also take care of the current document indexOperations.buildIndex(indexDescriptor, true); } else if (nitriteIndexer != null) { - nitriteIndexer.removeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + nitriteIndexer.removeIndexEntry(fieldValues, indexDescriptor, nitriteConfig); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java new file mode 100644 index 000000000..e7124906a --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.*; +import org.dizitart.no2.index.IndexDescriptor; + +import java.util.*; + +import static org.dizitart.no2.filters.Filter.and; + + +/** + * + * @since 4.0 + * @author Anindya Chatterjee + */ +class FindOptimizer { + + public FindPlan optimize(Filter filter, + FindOptions findOptions, + Collection indexDescriptors) { + FindPlan findPlan = createFilterPlan(indexDescriptors, filter); + readSortOption(findOptions, findPlan); + readLimitOption(findOptions, findPlan); + + if (findOptions != null) { + findPlan.setCollator(findOptions.collator()); + findPlan.setNullOrder(findOptions.nullOrder()); + } + return findPlan; + } + + private FindPlan createFilterPlan(Collection indexDescriptors, Filter filter) { + if (filter instanceof AndFilter) { + List filters = flattenAndFilter((AndFilter) filter); + return createAndPlan(indexDescriptors, filters); + } else if (filter instanceof OrFilter) { + return createOrPlan(indexDescriptors, ((OrFilter) filter).getFilters()); + } else { + List filters = Collections.singletonList(filter); + return createAndPlan(indexDescriptors, filters); + } + } + + private FindPlan createOrPlan(Collection indexDescriptors, List filters) { + FindPlan findPlan = new FindPlan(); + for (Filter filter : filters) { + if (filter instanceof AndFilter || filter instanceof OrFilter) { + findPlan.getSubPlans().clear(); + return findPlan; + } + + FindPlan subPlan = createFilterPlan(indexDescriptors, filter); + findPlan.getSubPlans().add(subPlan); + } + + for (FindPlan plan : findPlan.getSubPlans()) { + if (plan.getIndexDescriptor() == null) { + findPlan.getSubPlans().clear(); + return findPlan; + } + } + return findPlan; + } + + private FindPlan createAndPlan(Collection indexDescriptors, List filters) { + Map> indexFilterMap = new HashMap<>(); + + for (IndexDescriptor indexDescriptor : indexDescriptors) { + List fieldNames = indexDescriptor.getIndexFields().getFieldNames(); + + List indexedFilters = new ArrayList<>(); + for (String fieldName : fieldNames) { + boolean matchFound = false; + for (Filter filter : filters) { + if (filter instanceof FieldBasedFilter) { + String filterFieldName = ((FieldBasedFilter) filter).getField(); + if (filterFieldName.equals(fieldName)) { + indexedFilters.add(filter); + matchFound = true; + break; + } + } + } + + if (!matchFound) { + break; + } + } + + if (!indexedFilters.isEmpty()) { + indexFilterMap.put(indexDescriptor, indexedFilters); + } + } + + FindPlan findPlan = new FindPlan(); + List electedFilters = new ArrayList<>(); + for (Map.Entry> entry : indexFilterMap.entrySet()) { + if (entry.getValue().size() > electedFilters.size()) { + electedFilters = entry.getValue(); + findPlan.setIndexDescriptor(entry.getKey()); + } + } + + List nonElectedFilters = new ArrayList<>(); + for (Filter filter : filters) { + if (!electedFilters.contains(filter)) { + nonElectedFilters.add(filter); + } + } + + IndexScanFilter indexScanFilter; + if (electedFilters.size() == 1) { + indexScanFilter = new IndexScanFilter(Collections.singletonList(electedFilters.get(0))); + findPlan.setIndexScanFilter(indexScanFilter); + } else if (electedFilters.size() > 1) { + indexScanFilter = new IndexScanFilter(electedFilters); + findPlan.setIndexScanFilter(indexScanFilter); + } + + if (nonElectedFilters.size() == 1) { + findPlan.setCollectionScanFilter(nonElectedFilters.get(0)); + } else if (nonElectedFilters.size() > 1) { + Filter andFilter = and(nonElectedFilters.toArray(new Filter[0])); + findPlan.setCollectionScanFilter(andFilter); + } + + return findPlan; + } + + private List flattenAndFilter(AndFilter andFilter) { + List flattenedFilters = new ArrayList<>(); + if (andFilter != null) { + for (Filter filter : andFilter.getFilters()) { + if (filter instanceof AndFilter) { + List filters = flattenAndFilter((AndFilter) filter); + flattenedFilters.addAll(filters); + } else { + flattenedFilters.add(filter); + } + } + } + return flattenedFilters; + } + + private void readSortOption(FindOptions findOptions, FindPlan findPlan) { + IndexDescriptor indexDescriptor = findPlan.getIndexDescriptor(); + if (findOptions != null && findOptions.orderBy() != null) { + // get sort spec for find + List> findSortSpec = findOptions.orderBy().getSortingOrders(); + + if (indexDescriptor != null) { + // get index field names + List indexedFieldNames = indexDescriptor.getIndexFields().getFieldNames(); + + // get prefix length + int length = Math.min(indexedFieldNames.size(), findSortSpec.size()); + + boolean canUseIndex = false; + Map indexScanOrder = new HashMap<>(); + for (int i = 0; i < length; i++) { + String indexFieldName = indexedFieldNames.get(i); + Pair findPair = findSortSpec.get(i); + if (!indexFieldName.equals(findPair.getFirst())) { + // field mismatch in sort spec, can't use index for sorting + canUseIndex = false; + break; + } else { + canUseIndex = true; + boolean reverseScan = false; + + SortOrder findSortOrder = findPair.getSecond(); + if (findSortOrder != SortOrder.Ascending) { + // if sort order is different, reverse scan in index + reverseScan = true; + } + + // add to index scan order + indexScanOrder.put(indexFieldName, reverseScan); + } + } + + if (canUseIndex) { + findPlan.setIndexScanOrder(indexScanOrder); + if (length < findSortSpec.size()) { + List> remainder = findSortSpec.subList(length, findSortSpec.size() - 1); + findPlan.setBlockingSortOrder(remainder); + } + } else { + findPlan.setBlockingSortOrder(findSortSpec); + } + } + // no find options, so consider the index sorting order + findPlan.setBlockingSortOrder(findSortSpec); + } + } + + private void readLimitOption(FindOptions findOptions, FindPlan findPlan) { + if (findOptions != null) { + findPlan.setLimit(findOptions.limit()); + findPlan.setSkip(findOptions.skip()); + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java deleted file mode 100644 index 85da006a7..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptions.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import lombok.Data; -import lombok.experimental.Accessors; -import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.NullOrder; - -import java.text.Collator; - -/** - * @author Anindya Chatterjee - */ -@Data -@Accessors(fluent = true, chain = true) -public class FindOptions { - private Fields sortBy; - private Collator collator; - private NullOrder nullOrder; - private long skip; - private long limit; -} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java new file mode 100644 index 000000000..22ba13fa2 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexMeta; +import org.dizitart.no2.index.NitriteIndexer; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMetaMapName; + +/** + * Represents the index manager for a collection. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class IndexManager implements AutoCloseable { + private final NitriteConfig nitriteConfig; + private final NitriteStore nitriteStore; + private final String collectionName; + private final NitriteMap indexMetaMap; + private Collection indexDescriptorCache; + + /** + * Instantiates a new {@link IndexManager}. + * + * @param collectionName the collection name + * @param nitriteConfig the nitrite config + */ + public IndexManager(String collectionName, NitriteConfig nitriteConfig) { + this.collectionName = collectionName; + this.nitriteConfig = nitriteConfig; + this.nitriteStore = nitriteConfig.getNitriteStore(); + this.indexMetaMap = getIndexMetaMap(); + initialize(); + } + + /** + * Checks if an index descriptor already exists on the fields. + * + * @param fields the fields + * @return the boolean + */ + public boolean hasIndexDescriptor(Fields fields) { + if (!indexMetaMap.containsKey(fields)) return false; + + IndexMeta indexMeta = indexMetaMap.get(fields); + return indexMeta != null; + } + + /** + * Gets all defined index descriptors for the collection. + * + * @return the index descriptors + */ + public Collection getIndexDescriptors() { + if (indexDescriptorCache == null || indexDescriptorCache.isEmpty()) { + indexDescriptorCache = listIndexDescriptors(); + } + return indexDescriptorCache; + } + + public Collection findMatchingIndexDescriptors(Fields fields) { + Collection indexDescriptors = getIndexDescriptors(); + + for (IndexDescriptor indexDescriptor : indexDescriptors) { + if (indexDescriptor.getIndexFields().startsWith(fields)) { + indexDescriptors.add(indexDescriptor); + } + } + + return indexDescriptors; + } + + public IndexDescriptor findExactIndexDescriptor(Fields fields) { + IndexMeta meta = indexMetaMap.get(fields); + if (meta != null) { + return meta.getIndexDescriptor(); + } + return null; + } + + @Override + public void close() throws Exception { + if (indexMetaMap != null) { + indexMetaMap.close(); + } + } + + /** + * Is dirty index boolean. + * + * @param fields the fields + * @return the boolean + */ + boolean isDirtyIndex(Fields fields) { + IndexMeta meta = indexMetaMap.get(fields); + return meta != null && meta.getIsDirty().get(); + } + + /** + * List index descriptors collection. + * + * @return the collection + */ + Collection listIndexDescriptors() { + Set indexSet = new LinkedHashSet<>(); + for (IndexMeta indexMeta : indexMetaMap.values()) { + indexSet.add(indexMeta.getIndexDescriptor()); + } + return Collections.unmodifiableSet(indexSet); + } + + /** + * Create index descriptor index descriptor. + * + * @param fields the fields + * @param indexType the index type + * @return the index descriptor + */ + IndexDescriptor createIndexDescriptor(Fields fields, String indexType) { + validateIndexRequest(fields, indexType); + IndexDescriptor index = new IndexDescriptor(indexType, fields, collectionName); + + IndexMeta indexMeta = new IndexMeta(); + indexMeta.setIndexDescriptor(index); + indexMeta.setIsDirty(new AtomicBoolean(false)); + indexMeta.setIndexMap(deriveIndexMapName(index)); + + indexMetaMap.put(fields, indexMeta); + + updateIndexDescriptorCache(); + return index; + } + + /** + * Drop index descriptor. + * + * @param fields the fields + */ + void dropIndexDescriptor(Fields fields) { + IndexMeta meta = indexMetaMap.get(fields); + if (meta != null && meta.getIndexDescriptor() != null) { + String indexMapName = meta.getIndexMap(); + NitriteMap indexMap = nitriteStore.openMap(indexMapName, Object.class, Object.class); + indexMap.drop(); + } + + indexMetaMap.remove(fields); + updateIndexDescriptorCache(); + } + + /** + * Begin indexing. + * + * @param fields the fields + */ + void beginIndexing(Fields fields) { + markDirty(fields, true); + } + + /** + * End indexing. + * + * @param fields the fields + */ + void endIndexing(Fields fields) { + markDirty(fields, false); + } + + private void initialize() { + updateIndexDescriptorCache(); + } + + private void markDirty(Fields fields, boolean dirty) { + IndexMeta meta = indexMetaMap.get(fields); + if (meta != null && meta.getIndexDescriptor() != null) { + meta.getIsDirty().set(dirty); + } + } + + private NitriteMap getIndexMetaMap() { + String mapName = deriveIndexMetaMapName(this.collectionName); + return this.nitriteStore.openMap(mapName, Fields.class, IndexMeta.class); + } + + private void updateIndexDescriptorCache() { + indexDescriptorCache = listIndexDescriptors(); + } + + private void validateIndexRequest(Fields fields, String indexType) { + NitriteIndexer indexer = nitriteConfig.findIndexer(indexType); + indexer.validateIndex(fields); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index eef327b0c..93c3945fa 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -8,14 +8,12 @@ import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.concurrent.ThreadPoolManager; import org.dizitart.no2.common.event.EventBus; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.util.DocumentUtils; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; import java.util.ArrayList; @@ -24,7 +22,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; @@ -35,56 +32,45 @@ */ class IndexOperations implements AutoCloseable { private final NitriteConfig nitriteConfig; + private final IndexManager indexManager; private final NitriteMap nitriteMap; private final EventBus, CollectionEventListener> eventBus; - - private String collectionName; - private Map indexBuildRegistry; - private ExecutorService rebuildExecutor; - private Collection indexDescriptorCache; + private final Map indexBuildTracker; IndexOperations(NitriteConfig nitriteConfig, NitriteMap nitriteMap, - EventBus, CollectionEventListener> eventBus) { + EventBus, CollectionEventListener> eventBus, + IndexManager indexManager) { this.nitriteConfig = nitriteConfig; this.nitriteMap = nitriteMap; this.eventBus = eventBus; - initialize(); + this.indexManager = indexManager; + this.indexBuildTracker = new ConcurrentHashMap<>(); } @Override - public void close() { - if (rebuildExecutor != null) { - this.rebuildExecutor.shutdown(); - } + public void close() throws Exception { + indexManager.close(); } - void createIndex(Fields fields, String indexType, boolean isAsync) { + void createIndex(Fields fields, String indexType) { IndexDescriptor indexDescriptor; - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); if (!hasIndexEntry(fields)) { // if no index create index - indexDescriptor = indexCatalog.createIndexDescriptor(collectionName, fields, indexType); + indexDescriptor = indexManager.createIndexDescriptor(fields, indexType); } else { // if index already there throw throw new IndexingException("index already exists on " + fields); } - buildIndex(indexDescriptor, isAsync, false); - - // update descriptor cache - updateIndexDescriptorCache(); + buildIndex(indexDescriptor, false); } // call to this method is already synchronized, only one thread per field // can access it only if rebuild is already not running for that field - void buildIndex(IndexDescriptor indexDescriptor, boolean isAsync, boolean rebuild) { + void buildIndex(IndexDescriptor indexDescriptor, boolean rebuild) { final Fields fields = indexDescriptor.getIndexFields(); if (getBuildFlag(fields).compareAndSet(false, true)) { - if (isAsync) { - rebuildExecutor.submit(() -> buildIndexInternal(indexDescriptor, rebuild)); - } else { - buildIndexInternal(indexDescriptor, rebuild); - } + buildIndexInternal(indexDescriptor, rebuild); return; } throw new IndexingException("indexing is already running on " + indexDescriptor.getIndexFields()); @@ -95,30 +81,27 @@ void dropIndex(Fields fields) { throw new IndexingException("cannot drop index as indexing is running on " + fields); } - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); IndexDescriptor indexDescriptor = findIndexDescriptor(fields); if (indexDescriptor != null) { String indexType = indexDescriptor.getIndexType(); NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); nitriteIndexer.dropIndex(indexDescriptor, nitriteConfig); - indexCatalog.dropIndexDescriptor(collectionName, fields); - indexBuildRegistry.remove(fields); - - // update descriptor cache - updateIndexDescriptorCache(); + indexManager.dropIndexDescriptor(fields); + indexBuildTracker.remove(fields); } else { throw new IndexingException(fields + " is not indexed"); } } void dropAllIndices() { - for (Map.Entry entry : indexBuildRegistry.entrySet()) { + for (Map.Entry entry : indexBuildTracker.entrySet()) { if (entry.getValue() != null && entry.getValue().get()) { throw new IndexingException("cannot drop index as indexing is running on " + entry.getKey()); } } + // we can drop all indices in parallel List> futures = new ArrayList<>(); for (IndexDescriptor index : listIndexes()) { futures.add(runAsync(() -> dropIndex(index.getIndexFields()))); @@ -132,62 +115,47 @@ void dropAllIndices() { } } - indexBuildRegistry.clear(); - - // update descriptor cache - updateIndexDescriptorCache(); + indexBuildTracker.clear(); } boolean isIndexing(Fields field) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); // has an index will only return true, if there is an index on // the value and indexing is not running on it - return indexCatalog.hasIndexDescriptor(collectionName, field) + return indexManager.hasIndexDescriptor(field) && getBuildFlag(field).get(); } boolean hasIndexEntry(Fields field) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - return indexCatalog.hasIndexDescriptor(collectionName, field); + return indexManager.hasIndexDescriptor(field); } Collection listIndexes() { - return indexDescriptorCache; + return indexManager.getIndexDescriptors(); } IndexDescriptor findIndexDescriptor(Fields field) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - return indexCatalog.findIndexDescriptorExact(collectionName, field); + return indexManager.findExactIndexDescriptor(field); } AtomicBoolean getBuildFlag(Fields field) { - AtomicBoolean flag = indexBuildRegistry.get(field); + AtomicBoolean flag = indexBuildTracker.get(field); if (flag != null) return flag; flag = new AtomicBoolean(false); - indexBuildRegistry.put(field, flag); + indexBuildTracker.put(field, flag); return flag; } - private void initialize() { - this.collectionName = nitriteMap.getName(); - this.indexBuildRegistry = new ConcurrentHashMap<>(); - this.rebuildExecutor = ThreadPoolManager.workerPool(); - updateIndexDescriptorCache(); - } - - private void updateIndexDescriptorCache() { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - indexDescriptorCache = indexCatalog.listIndexDescriptors(collectionName); + boolean shouldRebuildIndex(Fields fields) { + return indexManager.isDirtyIndex(fields) && !getBuildFlag(fields).get(); } private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); Fields fields = indexDescriptor.getIndexFields(); try { alert(EventType.IndexStart, fields); // first put dirty marker - indexCatalog.beginIndexing(collectionName, fields); + indexManager.beginIndexing(fields); String indexType = indexDescriptor.getIndexType(); NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); @@ -200,12 +168,12 @@ private void buildIndexInternal(IndexDescriptor indexDescriptor, boolean rebuild for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); FieldValues fieldValues = DocumentUtils.getValues(document, indexDescriptor.getIndexFields()); - nitriteIndexer.writeIndexEntry(indexDescriptor, fieldValues, nitriteConfig); + nitriteIndexer.writeIndexEntry(fieldValues, indexDescriptor, nitriteConfig); } } finally { // remove dirty marker to denote indexing completed successfully // if dirty marker is found in any index, it needs to be rebuild - indexCatalog.endIndexing(collectionName, fields); + indexManager.endIndexing(fields); getBuildFlag(fields).set(false); alert(EventType.IndexEnd, fields); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java index 0a74a5f61..1ef870054 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java @@ -17,19 +17,22 @@ package org.dizitart.no2.collection.operation; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.collection.*; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.filters.*; +import org.dizitart.no2.common.streams.*; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.LogicalFilter; +import org.dizitart.no2.filters.NitriteFilter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; +import org.dizitart.no2.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; -import java.util.*; - -import static org.dizitart.no2.common.Constants.DOC_ID; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; /** * @author Anindya Chatterjee @@ -38,32 +41,32 @@ class ReadOperations { private final String collectionName; private final NitriteConfig nitriteConfig; private final NitriteMap nitriteMap; - private final DocumentIndexWriter documentIndexWriter; + private final FindOptimizer findOptimizer; + private final IndexOperations indexOperations; + private final ProcessorChain processorChain; ReadOperations(String collectionName, + IndexOperations indexOperations, NitriteConfig nitriteConfig, NitriteMap nitriteMap, - DocumentIndexWriter documentIndexWriter) { + ProcessorChain processorChain) { this.nitriteMap = nitriteMap; this.nitriteConfig = nitriteConfig; this.collectionName = collectionName; - this.documentIndexWriter = documentIndexWriter; - } - - public DocumentCursor find(FindOptions findOptions) { - RecordStream> recordStream = findSuitableStream(null, findOptions); - return new DocumentCursorImpl(recordStream); + this.indexOperations = indexOperations; + this.findOptimizer = new FindOptimizer(); + this.processorChain = processorChain; } public DocumentCursor find(Filter filter, FindOptions findOptions) { - if (filter == null || filter == Filter.ALL) { - return find(findOptions); + if (filter == null) { + filter = Filter.ALL; } prepareFilter(filter); - - RecordStream> recordStream = findSuitableStream(filter, findOptions); - return new DocumentCursorImpl(recordStream); + Collection indexDescriptors = indexOperations.listIndexes(); + FindPlan findPlan = findOptimizer.optimize(filter, findOptions, indexDescriptors); + return createCursor(findPlan); } Document getById(NitriteId nitriteId) { @@ -75,11 +78,6 @@ private void prepareFilter(Filter filter) { NitriteFilter nitriteFilter = (NitriteFilter) filter; prepareNitriteFilter(nitriteFilter); - if (filter instanceof IndexAwareFilter) { - IndexAwareFilter indexAwareFilter = (IndexAwareFilter) filter; - prepareIndexedFilter(indexAwareFilter); - } - if (filter instanceof LogicalFilter) { LogicalFilter logicalFilter = (LogicalFilter) filter; prepareLogicalFilter(logicalFilter); @@ -103,102 +101,59 @@ private void prepareLogicalFilter(LogicalFilter logicalFilter) { } } - private void prepareIndexedFilter(IndexAwareFilter indexAwareFilter) { - String field = indexAwareFilter.getField(); + private RecordStream> findSuitableStream(FindPlan findPlan) { + RecordStream> rawStream = null; - IndexDescriptor indexDescriptor = documentIndexWriter.findIndexDescriptor(field); + // filtering stage + IndexDescriptor indexDescriptor = findPlan.getIndexDescriptor(); if (indexDescriptor != null) { - String indexType = indexDescriptor.getIndexType(); - NitriteIndexer nitriteIndexer = documentIndexWriter.findIndexer(indexType); - if (nitriteIndexer != null) { - indexAwareFilter.setNitriteIndexer(nitriteIndexer); - indexAwareFilter.setIsFieldIndexed(true); - } - } else { - if (indexAwareFilter.getField().equals(DOC_ID)) { - // default _id index - indexAwareFilter.setOnIdField(true); - } - } - } + // get optimized filter + NitriteIndexer indexer = nitriteConfig.findIndexer(indexDescriptor.getIndexType()); + LinkedHashSet nitriteIds = indexer.findByFilter(findPlan, nitriteConfig); - private RecordStream> findSuitableStream(Filter filter, FindOptions findOptions) { - if (filter instanceof AndFilter) { - AndFilter andFilter = (AndFilter) filter; - Filter lhs = andFilter.getLhs(); - Filter rhs = andFilter.getRhs(); + // create indexed stream from optimized filter + RecordStream> indexedStream = new IndexedStream(nitriteIds, nitriteMap); - // TODO: check if compound index is supported - - if (lhs instanceof IndexAwareFilter && ((IndexAwareFilter) lhs).getIsFieldIndexed()) { - // Indexed AND Filter => IndexScan (LHS) -> Filter (RHS) - - return getFilteredStream(((IndexAwareFilter) lhs), rhs); - } else if (rhs instanceof IndexAwareFilter && ((IndexAwareFilter) rhs).getIsFieldIndexed()) { - // Non-Indexed AND Indexed => IndexScan (RHS) -> Filter (LHS) - - return getFilteredStream(((IndexAwareFilter) rhs), lhs); + // create filtered stream from above result and un-optimized filters + rawStream = new FilteredStream(indexedStream, findPlan.getCollectionScanFilter()); + } else { + // it means we don't have any index and we won't have any optimized filter + if (findPlan.getCollectionScanFilter() != null) { + rawStream = new FilteredStream(nitriteMap.entries(), findPlan.getCollectionScanFilter()); } else { - // Non-Indexed AND Filter => CollectionScan - - RecordStream> recordStream = nitriteMap.entries(); - return new FilteredRecordStream(recordStream, filter); + if (!findPlan.getSubPlans().isEmpty()) { + // or filters get all sub stream by finding suitable stream of all sub plans + List>> subStreams = new ArrayList<>(); + for (FindPlan subPlan : findPlan.getSubPlans()) { + RecordStream> suitableStream = findSuitableStream(subPlan); + subStreams.add(suitableStream); + } + // union of all suitable stream of all sub plans + rawStream = new UnionStream(subStreams); + } } - } else if (filter instanceof OrFilter) { - OrFilter orFilter = (OrFilter) filter; - Filter lhs = orFilter.getLhs(); - Filter rhs = orFilter.getRhs(); - - if (lhs instanceof IndexAwareFilter && ((IndexAwareFilter) lhs).getIsFieldIndexed() - && rhs instanceof IndexAwareFilter && ((IndexAwareFilter) rhs).getIsFieldIndexed()) { - // Indexed OR Indexed => IndexScan (LHS) Union IndexScan (RHS) - - final RecordStream> lhsStream - = getIndexedStream(((IndexAwareFilter) lhs)); - final RecordStream> rhsStream - = getIndexedStream(((IndexAwareFilter) rhs)); - - return getUnionStream(lhsStream, rhsStream); - } else { - // Non-Indexed OR Filter => CollectionScan - // Indexed OR Non-Indexed => CollectionScan + } - RecordStream> recordStream = nitriteMap.entries(); - return new FilteredRecordStream(recordStream, filter); + // sort and bound stage + if (rawStream != null) { + if (findPlan.getBlockingSortOrder() != null && !findPlan.getBlockingSortOrder().isEmpty()) { + rawStream = new SortedDocumentStream(findPlan, rawStream); } - } else if (filter instanceof IndexAwareFilter && ((IndexAwareFilter) filter).getIsFieldIndexed()) { - // Indexed => IndexScan - - IndexAwareFilter indexAwareFilter = (IndexAwareFilter) filter; - return getIndexedStream(indexAwareFilter); - } else { - // Non-Indexed => CollectionScan - RecordStream> recordStream = nitriteMap.entries(); - return new FilteredRecordStream(recordStream, filter); - } - } - - private RecordStream> getFilteredStream(IndexAwareFilter indexAwareFilter, - Filter rest) { - RecordStream> indexStream = getIndexedStream(indexAwareFilter); - if (rest != null) { - return new FilteredRecordStream(indexStream, rest); - } else { - return indexStream; + if (findPlan.getLimit() != null || findPlan.getSkip() != null) { + long limit = findPlan.getLimit() == null ? Long.MAX_VALUE : findPlan.getLimit(); + long skip = findPlan.getSkip() == null ? 0 : findPlan.getSkip(); + rawStream = new BoundedDocumentStream(skip, limit, rawStream); + } } - } - private RecordStream> getUnionStream( - RecordStream> lhsStream, - RecordStream> rhsStream) { - - return RecordStream.fromIterable(() -> new UnionStreamIterator(lhsStream, rhsStream)); + return rawStream; } - private RecordStream> getIndexedStream(IndexAwareFilter indexAwareFilter) { - // TODO: check if prefix of compound index is possible - - return new IndexedStream(indexAwareFilter, nitriteMap); + private DocumentCursor createCursor(FindPlan findPlan) { + RecordStream> recordStream = findSuitableStream(findPlan); + DocumentStream cursor = new DocumentStream(recordStream, processorChain); + cursor.setFindPlan(findPlan); + return cursor; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java deleted file mode 100644 index 04bec304d..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/SortedDocumentCursor.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection.operation; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.common.NullOrder; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.exceptions.ValidationException; - -import java.text.Collator; -import java.util.*; - -/** - * @author Anindya Chatterjee. - */ -class SortedDocumentCursor implements RecordStream> { - private final String field; - private final SortOrder sortOrder; - private final Collator collator; - private final NullOrder nullOrder; - private final RecordStream> recordStream; - - public SortedDocumentCursor(String field, - SortOrder sortOrder, - Collator collator, - NullOrder nullOrder, - RecordStream> recordStream) { - this.field = field; - this.sortOrder = sortOrder; - this.collator = collator; - this.nullOrder = nullOrder; - this.recordStream = recordStream; - } - - @Override - public Iterator> iterator() { - Iterator> iterator = recordStream == null ? Collections.emptyIterator() - : recordStream.iterator(); - return new SortedDocumentIterator(field, sortOrder, collator, nullOrder, iterator); - } - - static class SortedDocumentIterator implements Iterator> { - private final String field; - private final SortOrder sortOrder; - private final Collator collator; - private final NullOrder nullOrder; - private final Iterator> iterator; - private Iterator> sortedIterator; - - public SortedDocumentIterator(String field, - SortOrder sortOrder, - Collator collator, - NullOrder nullOrder, - Iterator> iterator) { - this.field = field; - this.sortOrder = sortOrder; - this.collator = collator; - this.nullOrder = nullOrder; - this.iterator = iterator; - initialize(); - } - - @Override - public boolean hasNext() { - return sortedIterator.hasNext(); - } - - @Override - public Pair next() { - return sortedIterator.next(); - } - - private void initialize() { - NavigableMap>> sortedMap; - if (collator != null) { - sortedMap = new TreeMap<>(collator); - } else { - sortedMap = new TreeMap<>(); - } - - Set> nullValueEntries = new HashSet<>(); - while (iterator.hasNext()) { - Pair next = iterator.next(); - Document document = next.getSecond(); - if (document == null) continue; - - Object value = document.get(field); - if (value != null) { - if (value.getClass().isArray() || value instanceof Iterable) { - throw new ValidationException("cannot sort on an array or collection object"); - } - } else { - nullValueEntries.add(next); - continue; - } - - List> pairs; - if (sortedMap.containsKey(value)) { - pairs = sortedMap.get(value); - } else { - pairs = new ArrayList<>(); - } - pairs.add(next); - sortedMap.put(value, pairs); - } - - List> sortedPairs; - if (sortOrder == SortOrder.Ascending) { - if (nullOrder == NullOrder.Default || nullOrder == NullOrder.First) { - sortedPairs = new ArrayList<>(nullValueEntries); - sortedPairs.addAll(flattenList(sortedMap.values())); - } else { - sortedPairs = flattenList(sortedMap.values()); - sortedPairs.addAll(nullValueEntries); - } - } else { - if (nullOrder == NullOrder.Default || nullOrder == NullOrder.Last) { - sortedPairs = flattenList(sortedMap.descendingMap().values()); - sortedPairs.addAll(nullValueEntries); - } else { - sortedPairs = new ArrayList<>(nullValueEntries); - sortedPairs.addAll(flattenList(sortedMap.descendingMap().values())); - } - } - - this.sortedIterator = sortedPairs.iterator(); - } - - private List flattenList(Collection> collection) { - List finalList = new ArrayList<>(); - for (List list : collection) { - finalList.addAll(list); - } - return finalList; - } - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java deleted file mode 100644 index 26e3f4127..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/StreamGenerator.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import org.dizitart.no2.common.RecordStream; - -/** - * - * @author Anindya Chatterjee - */ -public interface StreamGenerator { - RecordStream generate(FindOptions options); -} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/UnionStreamIterator.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/UnionStreamIterator.java deleted file mode 100644 index 0d3e42685..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/UnionStreamIterator.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection.operation; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.common.RecordStream; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * @author Anindya Chatterjee - */ -class UnionStreamIterator implements Iterator> { - private final Iterator> lhsIterator; - private final Iterator> rhsIterator; - private final Set nitriteIds = new HashSet<>(); - private Pair nextItem; - private boolean nextItemSet = false; - - public UnionStreamIterator(RecordStream> lhsStream, - RecordStream> rhsStream) { - lhsIterator = lhsStream.iterator(); - rhsIterator = rhsStream.iterator(); - } - - @Override - public boolean hasNext() { - return nextItemSet || setNextEntry(); - } - - @Override - public Pair next() { - if (!nextItemSet && !setNextEntry()) { - throw new NoSuchElementException(); - } - nextItemSet = false; - return nextItem; - } - - private boolean setNextEntry() { - while (lhsIterator.hasNext() || rhsIterator.hasNext()) { - if (lhsIterator.hasNext()) { - Pair pair = lhsIterator.next(); - nitriteIds.add(pair.getFirst()); - nextItem = pair; - nextItemSet = true; - return true; - } - - Pair pair = rhsIterator.next(); - if (!nitriteIds.contains(pair.getFirst())) { - nextItem = pair; - nextItemSet = true; - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java index 866fa689b..eceaa4440 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java @@ -17,10 +17,7 @@ package org.dizitart.no2.collection.operation; import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.collection.UpdateOptions; +import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventInfo; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.events.EventType; @@ -29,6 +26,7 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; import java.util.HashSet; @@ -45,15 +43,18 @@ class WriteOperations { private final ReadOperations readOperations; private final EventBus, CollectionEventListener> eventBus; private final NitriteMap nitriteMap; + private final ProcessorChain processorChain; WriteOperations(DocumentIndexWriter documentIndexWriter, ReadOperations readOperations, NitriteMap nitriteMap, - EventBus, CollectionEventListener> eventBus) { + EventBus, CollectionEventListener> eventBus, + ProcessorChain processorChain) { this.documentIndexWriter = documentIndexWriter; this.readOperations = readOperations; this.eventBus = eventBus; this.nitriteMap = nitriteMap; + this.processorChain = processorChain; } WriteResult insert(Document... documents) { @@ -78,8 +79,13 @@ WriteResult insert(Document... documents) { newDoc.remove(DOC_SOURCE); } - log.debug("Inserting document {} in {}", newDoc, nitriteMap.getName()); - Document already = nitriteMap.putIfAbsent(nitriteId, newDoc); + // run processors + Document unprocessed = newDoc.clone(); + Document processed = processorChain.processBeforeWrite(unprocessed); + log.debug("Document processed from {} to {} before insert", newDoc, processed); + + log.debug("Inserting processed document {} in {}", processed, nitriteMap.getName()); + Document already = nitriteMap.putIfAbsent(nitriteId, processed); if (already != null) { log.warn("Another document {} already exists with same id {}", already, nitriteId); @@ -88,7 +94,7 @@ WriteResult insert(Document... documents) { "entry with same id already exists in " + nitriteMap.getName()); } else { try { - documentIndexWriter.writeIndexEntry(newDoc); + documentIndexWriter.writeIndexEntry(processed); } catch (UniqueConstraintException | IndexingException e) { log.error("Index operation has failed during insertion for the document " + document + " in " + nitriteMap.getName(), e); @@ -99,9 +105,8 @@ WriteResult insert(Document... documents) { nitriteIds.add(nitriteId); - Document eventDoc = newDoc.clone(); CollectionEventInfo eventInfo = new CollectionEventInfo<>(); - eventInfo.setItem(eventDoc); + eventInfo.setItem(newDoc); eventInfo.setTimestamp(time); eventInfo.setEventType(EventType.Insert); eventInfo.setOriginator(source); @@ -116,12 +121,7 @@ WriteResult insert(Document... documents) { } WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { - DocumentCursor cursor; - if (filter == null || filter == Filter.ALL) { - cursor = readOperations.find(); - } else { - cursor = readOperations.find(filter); - } + DocumentCursor cursor = readOperations.find(filter, null); WriteResultImpl writeResult = new WriteResultImpl(); Document document = update.clone(); @@ -145,27 +145,32 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) break; } - Document item = doc.clone(); + Document newDoc = doc.clone(); Document oldDocument = doc.clone(); String source = document.getSource(); long time = System.currentTimeMillis(); - NitriteId nitriteId = item.getId(); - log.debug("Document to update {} in {}", item, nitriteMap.getName()); + NitriteId nitriteId = newDoc.getId(); + log.debug("Document to update {} in {}", newDoc, nitriteMap.getName()); if (!REPLICATOR.contentEquals(document.getSource())) { document.remove(DOC_SOURCE); - item.merge(document); - int rev = item.getRevision(); - item.put(DOC_REVISION, rev + 1); - item.put(DOC_MODIFIED, time); + newDoc.merge(document); + int rev = newDoc.getRevision(); + newDoc.put(DOC_REVISION, rev + 1); + newDoc.put(DOC_MODIFIED, time); } else { document.remove(DOC_SOURCE); - item.merge(document); + newDoc.merge(document); } - nitriteMap.put(nitriteId, item); - log.debug("Document {} updated in {}", item, nitriteMap.getName()); + // run processor + Document unprocessed = newDoc.clone(); + Document processed = processorChain.processBeforeWrite(unprocessed); + log.debug("Document processed from {} to {} before update", newDoc, processed); + + nitriteMap.put(nitriteId, processed); + log.debug("Document {} updated in {}", processed, nitriteMap.getName()); // if 'update' only contains id value, affected count = 0 if (document.size() > 0) { @@ -173,18 +178,17 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) } try { - documentIndexWriter.updateIndexEntry(oldDocument, item); + documentIndexWriter.updateIndexEntry(oldDocument, processed); } catch (UniqueConstraintException | IndexingException e) { log.error("Index operation failed during update, reverting changes for the document " + oldDocument + " in " + nitriteMap.getName(), e); nitriteMap.put(nitriteId, oldDocument); - documentIndexWriter.updateIndexEntry(item, oldDocument); + documentIndexWriter.updateIndexEntry(processed, oldDocument); throw e; } CollectionEventInfo eventInfo = new CollectionEventInfo<>(); - Document eventDoc = item.clone(); - eventInfo.setItem(eventDoc); + eventInfo.setItem(newDoc); eventInfo.setEventType(EventType.Update); eventInfo.setTimestamp(time); eventInfo.setOriginator(source); @@ -209,13 +213,7 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) } WriteResult remove(Filter filter, boolean justOnce) { - DocumentCursor cursor; - if (filter == null || filter == Filter.ALL) { - cursor = readOperations.find(); - } else { - cursor = readOperations.find(filter); - } - + DocumentCursor cursor = readOperations.find(filter, null); WriteResultImpl result = new WriteResultImpl(); long count = 0; @@ -223,8 +221,12 @@ WriteResult remove(Filter filter, boolean justOnce) { if (document != null) { count++; - Document item = document.clone(); - CollectionEventInfo eventInfo = removeAndCreateEvent(item, result); + // run processor + Document unprocessed = document.clone(); + Document processed = processorChain.processAfterRead(unprocessed); + log.debug("Document processed from {} to {} after remove", document, processed); + + CollectionEventInfo eventInfo = removeAndCreateEvent(processed, result); if (eventInfo != null) { alert(EventType.Remove, eventInfo); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteResultImpl.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteResultImpl.java index 4ba363118..284c8e768 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteResultImpl.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteResultImpl.java @@ -47,8 +47,7 @@ public int getAffectedCount() { @Override public Iterator iterator() { - Iterator iterator = nitriteIds == null ? Collections.emptyIterator() + return nitriteIds == null ? Collections.emptyIterator() : nitriteIds.iterator(); - return iterator; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java index 1e2d95b7a..f80d1d4e5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java @@ -6,6 +6,7 @@ * This class acts as a surrogate for null key. * * @author Anindya Chatterjee + * @since 1.0 */ public class DBNull implements Comparable, Serializable { private static final long serialVersionUID = 1598819770L; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java deleted file mode 100644 index 5937e769b..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldNames.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.dizitart.no2.common; - -import lombok.Getter; -import lombok.Setter; - -import java.util.*; - -/** - * @author Anindya Chatterjee - */ -@Getter @Setter -public class FieldNames extends AbstractSet { - private List names; - - public FieldNames() { - names = new ArrayList<>(); - } - - public FieldNames(Collection collection) { - names = new ArrayList<>(); - addAll(collection); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FieldNames)) return false; - FieldNames that = (FieldNames) o; - return Objects.equals(names, that.names); - } - - @Override - public int hashCode() { - return Objects.hash(names); - } - - @Override - public Iterator iterator() { - return names.listIterator(); - } - - @Override - public int size() { - return names.size(); - } - - @Override - public boolean isEmpty() { - return names.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return names.contains(o); - } - - @Override - public boolean add(String s) { - names.remove(s); - return names.add(s); - } - - @Override - public boolean remove(Object o) { - return names.remove(o); - } - - @Override - public void clear() { - names.clear(); - } - - @Override - public String toString() { - return names.toString(); - } - - public String get(int index) { - return names.get(index); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java index 080bbba10..551443a1e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -3,13 +3,15 @@ import lombok.Data; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.ValidationException; import java.util.ArrayList; import java.util.List; /** + * Represents a {@link Fields} and their corresponding values from a document. + * * @author Anindya Chatterjee + * @since 4.0 */ @Data public class FieldValues { @@ -17,10 +19,19 @@ public class FieldValues { private Fields fields; private List> values; + /** + * Instantiates a new Field values. + */ public FieldValues() { values = new ArrayList<>(); } + /** + * Get the value of the field. + * + * @param field the field + * @return the value + */ public Object get(String field) { if (fields.getFieldNames().contains(field)) { for (Pair value : values) { @@ -32,27 +43,20 @@ public Object get(String field) { return null; } - public Object getFirstValue() { - return getValueAt(0); - } - - public Object getValueAt(int index) { - if (index > values.size() - 1) { - throw new ValidationException("invalid index provided"); - } - - return values.get(index).getSecond(); - } - + /** + * Gets the {@link Fields}. + * + * @return the fields + */ public Fields getFields() { if (fields != null) { return fields; } this.fields = new Fields(); - fields.setSortSpecs(new ArrayList<>()); + fields.setFieldNames(new ArrayList<>()); for (Pair value : getValues()) { - fields.getSortSpecs().add(new Pair<>(value.getFirst(), null)); + fields.getFieldNames().add(value.getFirst()); } return fields; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java index 3d31464ed..a7da3de9b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -1,7 +1,7 @@ package org.dizitart.no2.common; -import lombok.Data; -import org.dizitart.no2.common.tuples.Pair; +import lombok.AccessLevel; +import lombok.Setter; import org.dizitart.no2.common.util.StringUtils; import java.io.IOException; @@ -10,6 +10,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; @@ -17,74 +18,81 @@ import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** + * Represents a list of document fields. + * * @author Anindya Chatterjee + * @since 4.0 */ -@Data public class Fields implements Comparable, Serializable { private static final long serialVersionUID = 1601646404L; - // order of the given fields matter - private List> sortSpecs; - private transient FieldNames fieldNames; + /** + * The Field names. + */ +// order of the given fields matter + @Setter(AccessLevel.PACKAGE) + protected List fieldNames; + /** + * Instantiates a new Fields. + */ public Fields() { - sortSpecs = new ArrayList<>(); + fieldNames = new ArrayList<>(); } - public static Fields single(String field) { - Fields fields = new Fields(); - fields.sortSpecs.add(new Pair<>(field, SortOrder.Ascending)); - return fields; - } - - @SafeVarargs - public static Fields multiple(Pair... fields) { + /** + * Creates a {@link Fields} instance with field names. + * + * @param fields the fields + * @return the fields + */ + public static Fields withNames(String... fields) { notNull(fields, "fields cannot be null"); notEmpty(fields, "fields cannot be empty"); Fields f = new Fields(); - f.sortSpecs.addAll(Arrays.asList(fields)); + f.fieldNames.addAll(Arrays.asList(fields)); return f; } - public FieldNames getFieldNames() { - if (fieldNames != null) { - return fieldNames; - } - fieldNames = new FieldNames(); - for (Pair pair : sortSpecs) { - fieldNames.add(pair.getFirst()); - } - return fieldNames; - } - - public Pair getFirstKey() { - return sortSpecs.get(0); - } - - public SortOrder getSortOrder(String fieldName) { - for (Pair pair : sortSpecs) { - if (pair.getFirst().equals(fieldName)) { - return pair.getSecond(); - } - } - return null; + /** + * Adds a new field name. + * + * @param field the field + * @return the fields + */ + public Fields addField(String field) { + fieldNames.add(field); + return this; } - public String getEncodedName() { - return StringUtils.join(INTERNAL_NAME_SEPARATOR, getFieldNames()); + /** + * Gets the field names. + * + * @return the field names + */ + public List getFieldNames() { + return Collections.unmodifiableList(fieldNames); } - public boolean isPrefix(Fields otherFields) { - if (otherFields == null) return false; - List> otherFieldList = otherFields.getSortSpecs(); - if (otherFieldList != null) { - if (otherFieldList.size() > sortSpecs.size()) return false; - for (int i = 0; i < otherFieldList.size(); i++) { - String field = sortSpecs.get(i).getFirst(); - String otherField = otherFieldList.get(i).getFirst(); - if (!field.contentEquals(otherField)) { + /** + * Starts with boolean. + * + * @param other the other + * @return the boolean + */ + public boolean startsWith(Fields other) { + if (other != null) { + int length = Math.min(fieldNames.size(), other.fieldNames.size()); + + // if other is greater then it is not a prefix of this field + if (other.fieldNames.size() > length) return false; + + for (int i = 0; i < length; i++) { + String thisField = fieldNames.get(i); + String otherField = other.fieldNames.get(i); + if (!thisField.equals(otherField)) { return false; } } @@ -93,24 +101,18 @@ public boolean isPrefix(Fields otherFields) { return false; } + /** + * Gets the encoded name for this {@link Fields}. + * + * @return the encoded name + */ + public String getEncodedName() { + return StringUtils.join(INTERNAL_NAME_SEPARATOR, getFieldNames()); + } + @Override public String toString() { - StringBuilder stringBuilder = new StringBuilder("["); - int count = 0; - for (Pair field : sortSpecs) { - count++; - stringBuilder.append("{") - .append(field.getFirst()) - .append(": ") - .append(field.getSecond()) - .append("}"); - - if (count != sortSpecs.size()) { - stringBuilder.append(", "); - } - } - stringBuilder.append("]"); - return stringBuilder.toString(); + return fieldNames.toString(); } @Override @@ -134,11 +136,11 @@ public int compareTo(Fields other) { } private void writeObject(ObjectOutputStream stream) throws IOException { - stream.writeObject(sortSpecs); + stream.writeObject(fieldNames); } @SuppressWarnings("unchecked") private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - sortSpecs = (List>) stream.readObject(); + fieldNames = (List) stream.readObject(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java deleted file mode 100644 index 4636ce651..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/common/FilterFieldNames.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dizitart.no2.common; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.filters.Filter; - -/** - * @author Anindya Chatterjee - */ -@Getter @Setter -public class FilterFieldNames extends FieldNames { - private Filter filter; - - @Override - public boolean equals(Object o) { - return super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java b/nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java deleted file mode 100644 index bf4c50724..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/common/IndexedFieldNames.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dizitart.no2.common; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.index.IndexDescriptor; - -import java.util.Set; - -/** - * @author Anindya Chatterjee - */ -@Getter @Setter -public class IndexedFieldNames extends FieldNames { - private Set supportedIndices; - - @Override - public boolean equals(Object o) { - return super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java index f0413719e..c085aa066 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java @@ -25,15 +25,12 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.store.NitriteStore; -import java.io.Closeable; import java.util.Collection; -import static org.dizitart.no2.common.Fields.multiple; -import static org.dizitart.no2.common.Fields.single; - /** * The interface Persistent collection. * @@ -43,46 +40,40 @@ * @see ObjectRepository * @since 1.0 */ -public interface PersistentCollection extends EventAware, MetadataAware, Closeable { +public interface PersistentCollection extends EventAware, MetadataAware, AutoCloseable { + /** - * Creates an index on the {@code field}, if not already exists. - * If {@code indexOptions} is {@code null}, it will use default options. - *

    - *

    - * The default indexing option is - + * Adds a data processor to this collection. * - *

      - *
    • {@code indexOptions.setAsync(false);}
    • - *
    • {@code indexOptions.setIndexType(IndexType.Unique);}
    • - *
    + * @param processor the processor + */ + void addProcessor(Processor processor); + + /** + * Removes a data processor from this collection. * - *

    - * NOTE: - *

      - *
    • _id value of the document is always indexed. But full-text indexing is not supported on _id value.
    • - *
    • Indexing on non-comparable value is not supported.
    • - *
    - *

    + * @param processor the processor + */ + void removeProcessor(Processor processor); + + /** + * Creates an unique index on the {@code fields}, if not already exists. * - * @param field the field to be indexed. - * @param indexOptions index options. + * @param fields the fields to be indexed. * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on the field. - * @see org.dizitart.no2.index.IndexOptions - * @see IndexType */ - default void createIndex(String field, IndexOptions indexOptions) { - createIndex(single(field), indexOptions); + default void createIndex(String... fields) { + createIndex(null, fields); } /** - * Creates an index on {@code fields}, if not already exists. + * Creates an index on the {@code fields}, if not already exists. * If {@code indexOptions} is {@code null}, it will use default options. *

    *

    * The default indexing option is - * *

      - *
    • {@code indexOptions.setAsync(false);}
    • *
    • {@code indexOptions.setIndexType(IndexType.Unique);}
    • *
    * @@ -94,33 +85,22 @@ default void createIndex(String field, IndexOptions indexOptions) { * *

    * - * @param fields the fields - * @param indexOptions the index options - * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on the fields. + * @param indexOptions index options. + * @param fields the fields to be indexed. + * @throws org.dizitart.no2.exceptions.IndexingException if an index already exists on the field. * @see org.dizitart.no2.index.IndexOptions * @see IndexType */ - void createIndex(Fields fields, IndexOptions indexOptions); + void createIndex(IndexOptions indexOptions, String... fields); /** * Rebuilds index on the {@code field} if it exists. * - * @param field the field to be indexed. - * @param isAsync if set to {@code true}, the indexing will run in background; otherwise, in foreground. + * @param fields the fields to be indexed. * @throws org.dizitart.no2.exceptions.IndexingException if the {@code field} is not indexed. */ - default void rebuildIndex(String field, boolean isAsync) { - rebuildIndex(single(field), isAsync); - } + void rebuildIndex(String... fields); - /** - * Rebuilds index on {@code fields} if it exists. - * - * @param fields the fields to be indexed. - * @param isAsync if set to {@code true}, the indexing will run in background; otherwise, in foreground. - * @throws org.dizitart.no2.exceptions.IndexingException if the {@code fields} is not indexed. - */ - void rebuildIndex(Fields fields, boolean isAsync); /** * Gets a set of all indices in the collection. @@ -131,32 +111,12 @@ default void rebuildIndex(String field, boolean isAsync) { Collection listIndices(); /** - * Checks if the {@code field} is already indexed or not. + * Checks if the {@code fields} is already indexed or not. * - * @param field the field to check. + * @param fields the fields to check. * @return {@code true} if the {@code field} is indexed; otherwise, {@code false}. */ - default boolean hasIndex(String field) { - return hasIndex(single(field)); - } - - /** - * Checks if the fields are already indexed or not. - * - * @param fields the fields to check - * @return {@code true} if the {@code fields} are indexed; otherwise, {@code false}. - */ - boolean hasIndex(Fields fields); - - /** - * Checks if indexing operation is currently ongoing for the {@code field}. - * - * @param field the field to check. - * @return {@code true} if indexing is currently running; otherwise, {@code false}. - */ - default boolean isIndexing(String field) { - return isIndexing(single(field)); - } + boolean hasIndex(String... fields); /** * Checks if indexing operation is currently ongoing for the {@code fields}. @@ -164,27 +124,16 @@ default boolean isIndexing(String field) { * @param fields the fields to check. * @return {@code true} if indexing is currently running; otherwise, {@code false}. */ - boolean isIndexing(Fields fields); + boolean isIndexing(String... fields); - /** - * Drops the index on the {@code field}. - * - * @param field the index of the {@code field} to drop. - * @throws org.dizitart.no2.exceptions.IndexingException if indexing is currently running on the {@code field}. - * @throws org.dizitart.no2.exceptions.IndexingException if the {@code field} is not indexed. - */ - default void dropIndex(String field) { - dropIndex(multiple(field)); - } - /** * Drops the index on the {@code fields}. * - * @param fields the index of the {@code fields} to drop. + * @param fields the index on the {@code fields} to drop. * @throws org.dizitart.no2.exceptions.IndexingException if indexing is currently running on the {@code fields}. - * @throws org.dizitart.no2.exceptions.IndexingException if the {@code fields} is not indexed. + * @throws org.dizitart.no2.exceptions.IndexingException if the {@code fields} are not indexed. */ - void dropIndex(Fields fields); + void dropIndex(String... fields); /** * Drops all indices from the collection. @@ -204,8 +153,8 @@ default void dropIndex(String field) { * index will also be updated. *

    *

    - * NOTE: This operations will notify all {@link CollectionEventListener} - * instances registered to this collection with change type {@link EventType#Insert}. + * NOTE: This operations will notify all {@link CollectionEventListener} + * instances registered to this collection with change type {@link EventType#Insert}. *

    * * @param elements an array of element for batch insertion. @@ -224,9 +173,9 @@ default void dropIndex(String field) { /** * Updates the {@code element} in the collection. Specified {@code element} must have an id. *

    - * NOTE: This operations will notify all {@link CollectionEventListener} - * instances registered to this collection with change type - * {@link EventType#Update}. + * NOTE: This operations will notify all {@link CollectionEventListener} + * instances registered to this collection with change type + * {@link EventType#Update}. *

    * * @param element the element to update. @@ -243,7 +192,7 @@ default WriteResult update(T element) { * If the {@code element} is not found in the collection, it will be inserted only if {@code insertIfAbsent} * is set to {@code true}. *

    - * + *

    * NOTE: This operations will notify all {@link CollectionEventListener} * instances registered to this collection with change type * {@link EventType#Update} or {@link EventType#Insert}. @@ -300,15 +249,6 @@ default WriteResult update(T element) { */ boolean isOpen(); - /** - * Closes the collection for further access. If a collection once closed - * can only be opened via {@link org.dizitart.no2.Nitrite#getCollection(String)} or - * {@link org.dizitart.no2.Nitrite#getRepository(Class)} operation. - *

    - * Any access to a closed collection would result into a {@link IllegalStateException}. - */ - void close(); - /** * Returns the size of the {@link PersistentCollection}. * diff --git a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java index cf88a21e5..35e040377 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java @@ -21,13 +21,32 @@ import java.util.*; /** + * Represents a record stream which can be iterated in a for loop. + * + * @param the type parameter * @author Anindya Chatterjee. + * @since 1.0 */ public interface RecordStream extends Iterable { + /** + * Creates a {@link RecordStream} from an {@link Iterable}. + * + * @param the type parameter + * @param iterable the iterable + * @return the record stream + */ static RecordStream fromIterable(Iterable iterable) { return iterable::iterator; } + /** + * Creates a {@link RecordStream} by combining two {@link Iterable}s. + * + * @param the type parameter + * @param first the first + * @param second the second + * @return the record stream + */ static RecordStream fromCombined(Iterable first, Iterable second) { return RecordStream.fromIterable(() -> new Iterator() { private final Iterator firstIterator = first != null ? first.iterator() : Collections.emptyIterator(); @@ -53,6 +72,14 @@ public T next() { }); } + /** + * Creates a {@link RecordStream} by eliminating elements from an {@link Iterable}. + * + * @param the type parameter + * @param iterable the iterable + * @param elements the elements + * @return the record stream + */ static RecordStream except(Iterable iterable, Collection elements) { return RecordStream.fromIterable(() -> new Iterator() { private final Iterator iterator = iterable != null ? iterable.iterator() : Collections.emptyIterator(); @@ -87,31 +114,56 @@ private boolean setNextId() { }); } + /** + * Creates an empty {@link RecordStream}. + * + * @param the type parameter + * @return the record stream + */ static RecordStream empty() { return RecordStream.fromIterable(Collections.emptySet()); } + /** + * Gets the size of the {@link RecordStream}. + * + * @return the long + */ default long size() { return Iterables.size(this); } + /** + * Creates a {@link List} from a {@link RecordStream} by iterating it. + * + * @return the list + */ default List toList() { return Iterables.toList(this); } + /** + * Creates a {@link Set} from a {@link RecordStream} by iterating it. + * + * @return the set + */ default Set toSet() { return Iterables.toSet(this); } + /** + * Checks if this {@link RecordStream} has any elements or not. + * + * @return the boolean + */ default boolean isEmpty() { return !iterator().hasNext(); } /** - * Gets the first element of the result or - * `null` if it is empty. + * Gets the first element of the result or null if it is empty. * - * @return the first element or `null` + * @return the first element or null */ default T firstOrNull() { return Iterables.firstOrNull(this); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/SortableFields.java b/nitrite/src/main/java/org/dizitart/no2/common/SortableFields.java new file mode 100644 index 000000000..7b2b67642 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/SortableFields.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import lombok.AccessLevel; +import lombok.Setter; +import org.dizitart.no2.common.tuples.Pair; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; + +/** + * Represents a list of document field with + * sorting direction for find query. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class SortableFields extends Fields { + @Setter(AccessLevel.PACKAGE) + private List> sortingOrders; + + /** + * Instantiates a new {@link SortableFields}. + */ + public SortableFields() { + super(); + sortingOrders = new ArrayList<>(); + } + + /** + * Creates a {@link SortableFields} instance with field names. + * + * @param fields the fields + * @return the fields + */ + public static SortableFields withNames(String... fields) { + notNull(fields, "fields cannot be null"); + notEmpty(fields, "fields cannot be empty"); + + SortableFields sortableFields = new SortableFields(); + for (String field : fields) { + sortableFields.addField(field, SortOrder.Ascending); + } + return sortableFields; + } + + /** + * Adds the sort order for a field. + * + * @param field the field + * @param sortOrder the sort order + * @return the sortable fields + */ + public SortableFields addField(String field, SortOrder sortOrder) { + super.fieldNames.add(field); + this.sortingOrders.add(Pair.pair(field, sortOrder)); + return this; + } + + /** + * Gets the sort by field specifications. + * + * @return the sort specs + */ + public List> getSortingOrders() { + return Collections.unmodifiableList(sortingOrders); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/UnknownType.java b/nitrite/src/main/java/org/dizitart/no2/common/UnknownType.java index b048f96e8..db54acd0b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/UnknownType.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/UnknownType.java @@ -1,7 +1,10 @@ package org.dizitart.no2.common; /** + * Represents an unknown type. + * * @author Anindya Chatterjee + * @since 4.0 */ public class UnknownType implements Comparable { @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/LockService.java b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/LockService.java index 3ddda4235..37c20625a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/LockService.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/LockService.java @@ -6,15 +6,27 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; /** + * The lock service. + * * @author Anindya Chatterjee + * @since 4.0 */ public class LockService { private final Map lockRegistry; + /** + * Instantiates a new Lock service. + */ public LockService() { this.lockRegistry = new HashMap<>(); } + /** + * Gets read lock. + * + * @param name the name + * @return the read lock + */ public synchronized Lock getReadLock(String name) { if (lockRegistry.containsKey(name)) { ReentrantReadWriteLock rwLock = lockRegistry.get(name); @@ -25,6 +37,12 @@ public synchronized Lock getReadLock(String name) { return rwLock.readLock(); } + /** + * Gets write lock. + * + * @param name the name + * @return the write lock + */ public synchronized Lock getWriteLock(String name) { if (lockRegistry.containsKey(name)) { ReentrantReadWriteLock rwLock = lockRegistry.get(name); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java index 7afa2db25..a3f84158b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/concurrent/ThreadPoolManager.java @@ -31,7 +31,7 @@ * A factory class for creating {@link ExecutorService}. * * @author Anindya Chatterjee. - * @since 4.0.0 + * @since 4.0 */ @Slf4j public class ThreadPoolManager { @@ -70,6 +70,13 @@ public static ExecutorService getThreadPool(int size, String threadName) { return threadPool; } + /** + * Returns a new {@link ErrorAwareThreadFactory} where thread name + * will be set to the name specified. + * + * @param name the name + * @return the error aware thread factory + */ public static ErrorAwareThreadFactory threadFactory(String name) { return new ErrorAwareThreadFactory() { @Override @@ -82,10 +89,19 @@ public Thread createThread(Runnable runnable) { }; } + /** + * Submits a runnable task asynchronously on common pool. + * + * @param runnable the runnable task + * @return the future + */ public static Future runAsync(Runnable runnable) { return commonPool.submit(runnable); } + /** + * Shuts down all thread pools. + */ public static void shutdownThreadPools() { for (ExecutorService threadPool : threadPools) { synchronized (lock) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java new file mode 100644 index 000000000..b757129ba --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.crypto; + +import org.dizitart.no2.common.util.Base64; +import org.dizitart.no2.common.util.CryptoUtils; +import org.dizitart.no2.common.util.SecureString; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * A password based AES string encryption utility. + * + *

    + * NOTE: This is a derivative work of https://mkyong.com/java/java-symmetric-key-cryptography-example/ + *

    + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class AESEncryptor implements Encryptor { + private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding"; + private static final int TAG_LENGTH_BIT = 128; + private static final int IV_LENGTH_BYTE = 12; + private static final int SALT_LENGTH_BYTE = 16; + private static final Charset UTF_8 = StandardCharsets.UTF_8; + + private final SecureString password; + + /** + * Instantiates a new Encryptor. + * + * @param password the password + */ + public AESEncryptor(String password) { + this.password = new SecureString(password); + } + + /** + * Returns a base64 encoded AES encrypted string. + * + * @param plainText the text as byte array + * @return the encrypted string + * @throws Exception the exception + */ + @Override + public String encrypt(byte[] plainText) throws Exception { + // 16 bytes salt + byte[] salt = CryptoUtils.getRandomNonce(SALT_LENGTH_BYTE); + + // GCM recommended 12 bytes iv? + byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE); + + // secret key from password + SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); + + Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); + + // ASE-GCM needs GCMParameterSpec + cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + + byte[] cipherText = cipher.doFinal(plainText); + + // prefix IV and Salt to cipher text + byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length) + .put(iv) + .put(salt) + .put(cipherText) + .array(); + + // string representation, base64, send this string to other for decryption. + return Base64.encodeToString(cipherTextWithIvSalt, Base64.URL_SAFE); + } + + /** + * Returns the decrypted string encoded by AES. + * + *

    + * NOTE: The same password, salt and iv are needed to decrypt it. + *

    + * @param encryptedText the encrypted text + * @return the plain text decrypted string + * @throws Exception the exception + */ + @Override + public String decrypt(String encryptedText) throws Exception { + byte[] decode = Base64.decode(encryptedText.getBytes(UTF_8), Base64.URL_SAFE); + + // get back the iv and salt from the cipher text + ByteBuffer bb = ByteBuffer.wrap(decode); + byte[] iv = new byte[IV_LENGTH_BYTE]; + bb.get(iv); + + byte[] salt = new byte[SALT_LENGTH_BYTE]; + bb.get(salt); + + byte[] cipherText = new byte[bb.remaining()]; + bb.get(cipherText); + + // get back the aes key from the same password and salt + SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); + Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); + cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + byte[] plainText = cipher.doFinal(cipherText); + return new String(plainText, UTF_8); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java b/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java new file mode 100644 index 000000000..3ca4fc0c7 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.crypto; + +/** + * Represents a symmetric key string encryptor. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public interface Encryptor { + /** + * Returns a base64 encoded encrypted string. + * + * @param plainText the plain text + * @return the encrypted string + * @throws Exception the exception + */ + String encrypt(byte[] plainText) throws Exception; + + /** + * Returns the decrypted string, encoded by this encryptor. + * + * @param encryptedText the encrypted text + * @return the string + * @throws Exception the exception + */ + String decrypt(String encryptedText) throws Exception; +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java b/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java index f73f208be..afafa07ad 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java @@ -49,9 +49,4 @@ public interface EventBus extends AutoCloseable { * @param eventInfo the event related information */ void post(EventInfo eventInfo); - - /** - * Closes the event bus and de-registers all event listeners. - */ - void close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java similarity index 62% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java index 35bc2bc19..8dc79fc84 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/BoundedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.ValidationException; import java.util.Collections; @@ -27,59 +28,82 @@ import java.util.NoSuchElementException; /** + * Represents a bounded document stream. + * + * @since 1.0 * @author Anindya Chatterjee. */ -class BoundedDocumentStream implements RecordStream> { +public class BoundedDocumentStream implements RecordStream> { private final RecordStream> recordStream; - private final long offset; + private final long skip; private final long limit; - BoundedDocumentStream(RecordStream> recordStream, final long offset, final long limit) { - if (offset < 0) { - throw new ValidationException("offset parameter must not be negative"); + /** + * Instantiates a new Bounded document stream. + * + * @param skip the skip + * @param limit the limit + * @param recordStream the record stream + */ + public BoundedDocumentStream(Long skip, Long limit, RecordStream> recordStream) { + this.skip = skip; + this.limit = limit; + + if (skip < 0) { + throw new ValidationException("skip parameter must not be negative"); } if (limit < 0) { throw new ValidationException("limit parameter must not be negative"); } this.recordStream = recordStream; - this.offset = offset; - this.limit = limit; } @Override public Iterator> iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new BoundedIterator<>(iterator, offset, limit); + return new BoundedIterator<>(iterator, skip, limit); } + /** + * The type Bounded iterator. + * + * @param the type parameter + */ public static class BoundedIterator implements Iterator { private final Iterator iterator; - private final long offset; - private final long size; + private final long skip; + private final long limit; private long pos; - public BoundedIterator(final Iterator iterator, final long offset, final long size) { + /** + * Instantiates a new Bounded iterator. + * + * @param iterator the iterator + * @param skip the skip + * @param limit the limit + */ + public BoundedIterator(final Iterator iterator, final long skip, final long limit) { if (iterator == null) { throw new ValidationException("iterator must not be null"); } - if (offset < 0) { - throw new ValidationException("offset parameter must not be negative."); + if (skip < 0) { + throw new ValidationException("skip parameter must not be negative."); } - if (size < 0) { - throw new ValidationException("size parameter must not be negative."); + if (limit < 0) { + throw new ValidationException("limit parameter must not be negative."); } this.iterator = iterator; - this.offset = offset; - this.size = size; + this.skip = skip; + this.limit = limit; pos = 0; initialize(); } private void initialize() { - while (pos < offset && iterator.hasNext()) { + while (pos < skip && iterator.hasNext()) { iterator.next(); pos++; } @@ -94,7 +118,7 @@ public boolean hasNext() { } private boolean checkBounds() { - return pos - offset + 1 > size; + return pos - skip + 1 > limit; } @Override @@ -109,7 +133,7 @@ public T next() { @Override public void remove() { - if (pos <= offset) { + if (pos <= skip) { throw new IllegalStateException("remove() cannot be called before calling next()"); } iterator.remove(); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java new file mode 100644 index 000000000..014e5221c --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.NullOrder; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; + +import java.text.Collator; +import java.util.Comparator; +import java.util.List; + +/** + * Sorts documents based on the sort order provided. + * + *

    + * By default null is considered the lowest value, + * unless ordering explicitly specified by {@link NullOrder}. + *

    + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class DocumentSorter implements Comparator> { + private final Collator collator; + private final NullOrder nullOrder; + private final List> sortOrder; + + /** + * Instantiates a new Document sorter. + * + * @param collator the collator + * @param nullOrder the null order + * @param sortOrder the sort order + */ + public DocumentSorter(Collator collator, NullOrder nullOrder, + List> sortOrder) { + this.collator = collator; + this.nullOrder = nullOrder; + this.sortOrder = sortOrder; + } + + @Override + @SuppressWarnings( { "rawtypes", "unchecked" }) + public int compare(Pair pair1, Pair pair2) { + if (sortOrder != null && !sortOrder.isEmpty()) { + for (Pair pair : sortOrder) { + Document doc1 = pair1.getSecond(); + Document doc2 = pair2.getSecond(); + + Comparable c1 = doc1.get(pair.getFirst(), Comparable.class); + Comparable c2 = doc2.get(pair.getFirst(), Comparable.class); + + boolean nullPresent = false; + int result; + + if (c1 == null && c2 != null) { + nullPresent = true; + if (nullOrder == NullOrder.First || nullOrder == NullOrder.Default) { + result = -1; + } else { + result = 1; + } + } else if (c1 != null && c2 == null) { + nullPresent = true; + if (nullOrder == NullOrder.First || nullOrder == NullOrder.Default) { + result = 1; + } else { + result = -1; + } + } else if (c2 == null) { + nullPresent = true; + result = 0; + } else if (c1 instanceof String && c2 instanceof String && collator != null) { + result = collator.compare(c1, c2); + } else { + result = c1.compareTo(c2); + } + + if (!nullPresent && pair.getSecond() == SortOrder.Descending) { + result *= -1; + } + + if (result != 0) { + return result; + } + } + } + return 0; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java similarity index 65% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java index 71f96fad1..df15f0e9d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentCursorImpl.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java @@ -1,76 +1,79 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; +import lombok.Getter; +import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.*; +import org.dizitart.no2.common.Lookup; +import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.processors.ProcessorChain; -import java.text.Collator; import java.util.Collections; import java.util.Iterator; /** + * Represents a nitrite document stream. + * + * @since 4.0 * @author Anindya Chatterjee. */ -class DocumentCursorImpl implements DocumentCursor { +public class DocumentStream implements DocumentCursor { private final RecordStream> recordStream; - private FindOptions findOptions; - - DocumentCursorImpl(RecordStream> recordStream) { + private final ProcessorChain processorChain; + + @Getter @Setter + private FindPlan findPlan; + + /** + * Instantiates a new Document stream. + * + * @param recordStream the record stream + * @param processorChain the processor chain + */ + public DocumentStream(RecordStream> recordStream, + ProcessorChain processorChain) { this.recordStream = recordStream; - } - - @Override - public DocumentCursor sort(Fields fields, Collator collator, NullOrder nullOrder) { - findOptions = new FindOptions(); - findOptions.collator(collator); - findOptions.nullOrder(nullOrder); - findOptions.sortBy(fields); - - return new DocumentCursorImpl(new SortedDocumentCursor(field, sortOrder, collator, - nullOrder, recordStream)); - } - - @Override - public DocumentCursor skipLimit(long skip, long limit) { - return new DocumentCursorImpl(new BoundedDocumentStream(recordStream, skip, limit)); + this.processorChain = processorChain; } @Override public RecordStream project(Document projection) { validateProjection(projection); - return new ProjectedDocumentStream(recordStream, projection); + return new ProjectedDocumentStream(recordStream, projection, processorChain); } @Override public RecordStream join(DocumentCursor foreignCursor, Lookup lookup) { - return new JoinedDocumentStream(recordStream, foreignCursor, lookup); + return new JoinedDocumentStream(recordStream, foreignCursor, lookup, processorChain); } @Override public Iterator iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new DocumentCursorIterator(iterator); + return new DocumentCursorIterator(iterator, processorChain); } private void validateProjection(Document projection) { @@ -91,9 +94,18 @@ private void validateKeyValuePair(Pair kvp) { private static class DocumentCursorIterator implements Iterator { private final Iterator> iterator; - - DocumentCursorIterator(Iterator> iterator) { + private final ProcessorChain processorChain; + + /** + * Instantiates a new Document cursor iterator. + * + * @param iterator the iterator + * @param processorChain the processor chain + */ + DocumentCursorIterator(Iterator> iterator, + ProcessorChain processorChain) { this.iterator = iterator; + this.processorChain = processorChain; } @Override @@ -106,7 +118,9 @@ public Document next() { Pair next = iterator.next(); Document document = next.getSecond(); if (document != null) { - return document.clone(); + Document copy = document.clone(); + copy = processorChain.processAfterRead(copy); + return copy; } return null; } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java similarity index 77% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java index 2581bbdac..b9360740f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FilteredRecordStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.filters.Filter; @@ -28,13 +29,22 @@ import java.util.NoSuchElementException; /** + * Represents a filtered nitrite document stream. + * * @author Anindya Chatterjee. + * @since 4.0 */ -public class FilteredRecordStream implements RecordStream> { +public class FilteredStream implements RecordStream> { private final RecordStream> recordStream; private final Filter filter; - FilteredRecordStream(RecordStream> recordStream, Filter filter) { + /** + * Instantiates a new Filtered stream. + * + * @param recordStream the record stream + * @param filter the filter + */ + public FilteredStream(RecordStream> recordStream, Filter filter) { this.recordStream = recordStream; this.filter = filter; } @@ -43,15 +53,28 @@ public class FilteredRecordStream implements RecordStream> iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); + + if (filter == Filter.ALL) { + return iterator; + } return new FilteredIterator(iterator, filter); } + /** + * The type Filtered iterator. + */ static class FilteredIterator implements Iterator> { private final Iterator> iterator; private final Filter filter; private Pair nextPair; private boolean nextPairSet = false; + /** + * Instantiates a new Filtered iterator. + * + * @param iterator the iterator + * @param filter the filter + */ public FilteredIterator(Iterator> iterator, Filter filter) { this.iterator = iterator; this.filter = filter; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexedStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java similarity index 71% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexedStream.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java index a9e214b43..059da827b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexedStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java @@ -1,45 +1,51 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.filters.IndexAwareFilter; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.store.NitriteMap; import java.util.Iterator; import java.util.Set; /** + * Represents a nitrite nitrite stream backed by an index. + * * @author Anindya Chatterjee + * @since 4.0 */ -class IndexedStream implements RecordStream> { - private final Set nitriteIds; +public class IndexedStream implements RecordStream> { private final NitriteMap nitriteMap; + private final Set nitriteIds; - IndexedStream(IndexAwareFilter indexAwareFilter, + /** + * Instantiates a new Indexed stream. + * + * @param nitriteIds the nitrite ids + * @param nitriteMap the nitrite map + */ + public IndexedStream(Set nitriteIds, NitriteMap nitriteMap) { + this.nitriteIds = nitriteIds; this.nitriteMap = nitriteMap; - - nitriteIds = indexAwareFilter.getOnIdField() - ? indexAwareFilter.cachedIds(nitriteMap) - : indexAwareFilter.cachedIndexedIds(); } @Override @@ -47,10 +53,19 @@ public Iterator> iterator() { return new IndexedStreamIterator(nitriteIds.iterator(), nitriteMap); } + /** + * The type Indexed stream iterator. + */ static class IndexedStreamIterator implements Iterator> { private final Iterator iterator; private final NitriteMap nitriteMap; + /** + * Instantiates a new Indexed stream iterator. + * + * @param iterator the iterator + * @param nitriteMap the nitrite map + */ IndexedStreamIterator(Iterator iterator, NitriteMap nitriteMap) { this.iterator = iterator; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/JoinedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java similarity index 70% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/JoinedDocumentStream.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java index 886d0496e..4766cd0f2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/JoinedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -23,6 +24,7 @@ import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; +import org.dizitart.no2.processors.ProcessorChain; import java.util.Collections; import java.util.HashSet; @@ -32,19 +34,32 @@ import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; /** + * Represents a joined document stream. + * * @author Anindya Chatterjee. + * @since 1.0 */ -class JoinedDocumentStream implements RecordStream { +public class JoinedDocumentStream implements RecordStream { private final RecordStream> recordStream; private final DocumentCursor foreignCursor; private final Lookup lookup; - + private final ProcessorChain processorChain; + + /** + * Instantiates a new Joined document stream. + * + * @param recordStream the record stream + * @param foreignCursor the foreign cursor + * @param lookup the lookup + * @param processorChain the processor chain + */ JoinedDocumentStream(RecordStream> recordStream, DocumentCursor foreignCursor, - Lookup lookup) { + Lookup lookup, ProcessorChain processorChain) { this.recordStream = recordStream; this.foreignCursor = foreignCursor; this.lookup = lookup; + this.processorChain = processorChain; } @@ -52,7 +67,7 @@ class JoinedDocumentStream implements RecordStream { public Iterator iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new JoinedDocumentIterator(iterator); + return new JoinedDocumentIterator(iterator, processorChain); } @Override @@ -62,9 +77,18 @@ public String toString() { private class JoinedDocumentIterator implements Iterator { private final Iterator> iterator; - - JoinedDocumentIterator(Iterator> iterator) { + private final ProcessorChain processorChain; + + /** + * Instantiates a new Joined document iterator. + * + * @param iterator the iterator + * @param processorChain the processor chain + */ + JoinedDocumentIterator(Iterator> iterator, + ProcessorChain processorChain) { this.iterator = iterator; + this.processorChain = processorChain; } @Override @@ -77,7 +101,11 @@ public Document next() { Pair next = iterator.next(); Document document = next.getSecond(); if (document != null) { - return join(document.clone(), foreignCursor, lookup); + Document unprocessed = document.clone(); + + // process the document + Document processed = processorChain.processAfterRead(unprocessed); + return join(processed, foreignCursor, lookup); } return null; } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ProjectedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java similarity index 71% rename from nitrite/src/main/java/org/dizitart/no2/collection/operation/ProjectedDocumentStream.java rename to nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java index 26c58749c..604497c87 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ProjectedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java @@ -1,48 +1,62 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.common.streams; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; +import org.dizitart.no2.processors.ProcessorChain; import java.util.Collections; import java.util.Iterator; /** + * Represents a projected nitrite document stream. + * * @author Anindya Chatterjee. + * @since 1.0 */ -class ProjectedDocumentStream implements RecordStream { +public class ProjectedDocumentStream implements RecordStream { private final RecordStream> recordStream; private final Document projection; - + private final ProcessorChain processorChain; + + /** + * Instantiates a new Projected document stream. + * + * @param recordStream the record stream + * @param projection the projection + * @param processorChain the processor chain + */ public ProjectedDocumentStream(RecordStream> recordStream, - Document projection) { + Document projection, ProcessorChain processorChain) { this.recordStream = recordStream; this.projection = projection; + this.processorChain = processorChain; } @Override public Iterator iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new ProjectedDocumentIterator(iterator); + return new ProjectedDocumentIterator(iterator, processorChain); } @Override @@ -52,10 +66,18 @@ public String toString() { private class ProjectedDocumentIterator implements Iterator { private final Iterator> iterator; + private final ProcessorChain processorChain; private Document nextElement = null; - ProjectedDocumentIterator(Iterator> iterator) { + /** + * Instantiates a new Projected document iterator. + * + * @param iterator the iterator + * @param processorChain the processor chain + */ + ProjectedDocumentIterator(Iterator> iterator, ProcessorChain processorChain) { this.iterator = iterator; + this.processorChain = processorChain; nextMatch(); } @@ -101,6 +123,9 @@ private Document project(Document original) { result.remove(pair.getFirst()); } } + + // process the result + result = processorChain.processAfterRead(result); return result; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java new file mode 100644 index 000000000..2d065c28f --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Represents a sorted nitrite document stream + * + * @since 4.0 + * @author Anindya Chatterjee. + */ +public class SortedDocumentStream implements RecordStream> { + private final FindPlan findPlan; + private final RecordStream> recordStream; + + public SortedDocumentStream(FindPlan findPlan, + RecordStream> recordStream) { + this.findPlan = findPlan; + this.recordStream = recordStream; + } + + @Override + public Iterator> iterator() { + if (recordStream == null) return Collections.emptyIterator(); + + DocumentSorter documentSorter = new DocumentSorter(findPlan.getCollator(), + findPlan.getNullOrder(), findPlan.getBlockingSortOrder()); + + List> recordList = recordStream.toList(); + Collections.sort(recordList, documentSorter); + + return recordStream.iterator(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java new file mode 100644 index 000000000..486fa9fd2 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; + +import java.util.*; + +/** + * Represents an union of multiple nitrite document stream. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class UnionStream implements RecordStream> { + private final Collection>> streams; + + /** + * Instantiates a new Union stream. + * + * @param streams the streams + */ + public UnionStream(Collection>> streams) { + this.streams = streams; + } + + @Override + public Iterator> iterator() { + Queue>> iteratorQueue = new LinkedList<>(); + for (RecordStream> stream : streams) { + iteratorQueue.add(stream.iterator()); + } + return new UnionStreamIterator(iteratorQueue); + } + + /** + * The type Union stream iterator. + */ + public static class UnionStreamIterator implements Iterator> { + private final Queue>> iteratorQueue; + private Iterator> currentIterator; + + /** + * Instantiates a new Union stream iterator. + * + * @param iteratorQueue the iterator queue + */ + public UnionStreamIterator(Queue>> iteratorQueue) { + this.iteratorQueue = iteratorQueue; + } + + @Override + public boolean hasNext() { + updateCurrentIterator(); + return currentIterator.hasNext(); + } + + @Override + public Pair next() { + updateCurrentIterator(); + return currentIterator.next(); + } + + + private void updateCurrentIterator() { + if (currentIterator == null) { + if (iteratorQueue.isEmpty()) { + currentIterator = Collections.emptyIterator(); + } else { + currentIterator = iteratorQueue.remove(); + } + } + + while (!currentIterator.hasNext() && !iteratorQueue.isEmpty()) { + currentIterator = iteratorQueue.remove(); + } + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Pair.java b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Pair.java index 45fcf6a63..cf2298ad9 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Pair.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Pair.java @@ -28,6 +28,8 @@ /** * Represents a pair. * + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee. * @since 4.0 */ @@ -40,6 +42,19 @@ public class Pair implements Serializable { private A first; private B second; + /** + * Creates a new pair. + * + * @param the type parameter + * @param the type parameter + * @param first the first + * @param second the second + * @return the pair + */ + public static Pair pair(A first, B second) { + return new Pair<>(first, second); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeObject(first); stream.writeObject(second); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quartet.java b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quartet.java index 6ce5b86ae..6fb0cb6d7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quartet.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quartet.java @@ -10,7 +10,14 @@ import java.io.Serializable; /** + * Represents a quartet. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ @Data @NoArgsConstructor @@ -23,6 +30,23 @@ public class Quartet implements Serializable { private C third; private D fourth; + /** + * Creates a new quartet. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param a the a + * @param b the b + * @param c the c + * @param d the d + * @return the quartet + */ + public static Quartet quartet(A a, B b, C c, D d) { + return new Quartet<>(a, b, c, d); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeObject(first); stream.writeObject(second); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quintet.java b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quintet.java index 811e76473..be33599f4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quintet.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Quintet.java @@ -10,7 +10,15 @@ import java.io.Serializable; /** + * Represents a quintet. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ @Data @NoArgsConstructor @@ -24,6 +32,25 @@ public class Quintet implements Serializable { private D fourth; private E fifth; + /** + * Creates a new quintet. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param a the a + * @param b the b + * @param c the c + * @param d the d + * @param e the e + * @return the quintet + */ + public static Quintet quintet(A a, B b, C c, D d, E e) { + return new Quintet<>(a, b, c, d, e); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeObject(first); stream.writeObject(second); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Triplet.java b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Triplet.java index cd77853ed..d0ce767c0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/tuples/Triplet.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/tuples/Triplet.java @@ -12,6 +12,9 @@ /** * Represents a triplet. * + * @param the type parameter + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee. * @since 4.0 */ @@ -25,6 +28,21 @@ public class Triplet implements Serializable { private B second; private C third; + /** + * Creates a new triplet. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param a the a + * @param b the b + * @param c the c + * @return the triplet + */ + public static Triplet triplet(A a, B b, C c) { + return new Triplet<>(a, b, c); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeObject(first); stream.writeObject(second); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/Base64.java b/nitrite/src/main/java/org/dizitart/no2/common/util/Base64.java new file mode 100644 index 000000000..f27ddcfaf --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/Base64.java @@ -0,0 +1,550 @@ +package org.dizitart.no2.common.util; + +import java.nio.charset.StandardCharsets; + +/** + * Utilities for encoding and decoding the Base64 representation of + * binary data. + * + *

    + * This is a derivative work of android.util.Base64 class + * from Android Open Source Project + *

    + * + * @since 4.0 + * @author The Android Open Source Project + * @author Anindya Chatterjee + */ +public class Base64 { + /** + * Encoder flag bit to omit the padding '=' characters at the end + * of the output (if any). + */ + public static final int NO_PADDING = 1; + /** + * Encoder flag bit to omit all line terminators (i.e., the output + * will be on one long line). + */ + public static final int NO_WRAP = 2; + /** + * Encoder flag bit to indicate lines should be terminated with a + * CRLF pair instead of just an LF. Has no effect if {@code + * NO_WRAP} is specified as well. + */ + public static final int CRLF = 4; + /** + * Encoder/decoder flag bit to indicate using the "URL and + * filename safe" variant of Base64 (see RFC 3548 section 4) where + * {@code -} and {@code _} are used in place of {@code +} and + * {@code /}. + */ + public static final int URL_SAFE = 8; + + static abstract class Coder { + public byte[] output; + public int op; + } + // -------------------------------------------------------- + // decoding + // -------------------------------------------------------- + + /** + * Decode the Base64-encoded data in input and return the data in + * a new byte array. + * + *

    The padding '=' characters at the end are considered optional, but + * if any are present, there must be the correct number of them. + * + * @param input the input array to decode + * @param flags controls certain features of the decoded output. + * Pass {@code DEFAULT} to decode standard Base64. + * + * @throws IllegalArgumentException if the input contains + * incorrect padding + */ + public static byte[] decode(byte[] input, int flags) { + return decode(input, 0, input.length, flags); + } + /** + * Decode the Base64-encoded data in input and return the data in + * a new byte array. + * + *

    + * Instantiates a new Field based filter. * - * @param filter other filter - * @return the and filter + * @param field the field + * @param value the value */ - public Filter and(Filter filter) { - return new AndFilter(this, filter); + protected FieldBasedFilter(String field, Object value) { + this.field = field; + this.value = value; } /** - * Creates an or filter which performs a logical OR operation on two filters and selects - * the documents that satisfy at least one of the filter. - *

    + * Gets the value fo the filter. * - * @param filter other filter - * @return the or filter + * @return the value */ - public Filter or(Filter filter) { - return new OrFilter(this, filter); - } - - protected Set> convertValues(Set> values) { - if (getObjectFilter()) { - NitriteMapper nitriteMapper = getNitriteConfig().nitriteMapper(); - Set> convertedValues = new HashSet<>(); - - for (Comparable comparable : values) { - if (comparable == null - || !nitriteMapper.isValue(comparable)) { - throw new FilterException("search term " + comparable - + " is not a comparable"); - } - - if (nitriteMapper.isValue(comparable)) { - Comparable convertValue = nitriteMapper.convert(comparable, Comparable.class); - convertedValues.add(convertValue); - } - } - - return convertedValues; - } - return values; - } - public Object getValue() { if (this.processed) return value; diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java index 346e3df30..bb884ff63 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/Filter.java @@ -28,158 +28,17 @@ /** * An interface to specify filtering criteria during find operation. When * a filter is applied to a collection, based on the criteria it returns - * a set of {@link NitriteId}s of matching records. + * a set of matching records. *

    * Each filtering criteria is based on a value of a document. If the value * is indexed, the find operation takes the advantage of it and only scans * the index map for that value. But if the value is not indexed, it scans * the whole collection. - *

    - * The supported filters are: - *

    - * .Comparison Filters - * [width="80%",cols="2,4,10"] - * |=== - * |Filter |Method |Description - *

    - * |Equals - * |{@link FluentFilter#eq(Object)} - * |Matches values that are equal to a specified value. - *

    - * |Greater - * |{@link FluentFilter#gt(Comparable)} - * |Matches values that are greater than a specified value. - *

    - * |GreaterEquals - * |{@link FluentFilter#gte(Comparable)} - * |Matches values that are greater than or equal to a specified value. - *

    - * |Lesser - * |{@link FluentFilter#lt(Comparable)} - * |Matches values that are less than a specified value. - *

    - * |LesserEquals - * |{@link FluentFilter#lte(Comparable)} - * |Matches values that are less than or equal to a specified value. - *

    - * |In - * |{@link FluentFilter#in(Comparable[])} - * |Matches any of the values specified in an array. - * |=== - *

    - * .Logical Filters - * [width="80%",cols="2,4,10"] - * |=== - * |Filter |Method |Description - *

    - * |Not - * |{@link Filter#not()} - * |Inverts the effect of a filter and returns results that do not match the filter. - *

    - * |Or - * |{@link Filter#or(Filter)} - * |Joins filters with a logical OR returns all ids of the documents that match the conditions - * of either filter. - *

    - * |And - * |{@link Filter#and(Filter)} - * |Joins filters with a logical AND returns all ids of the documents that match the conditions - * of both filters. - * |=== - *

    - * .Array Filter - * [width="80%",cols="2,4,10"] - * |=== - * |Filter |Method |Description - *

    - * |Element Match - * |{@link FluentFilter#elemMatch(Filter)} - * |Matches documents that contain an array field with at least one element that matches - * the specified filter. - * |=== - *

    - * .Text Filters - * [width="80%",cols="2,4,10"] - * |=== - * |Filter |Method |Description - *

    - * |Text - * |{@link FluentFilter#text(String)} - * |Performs full-text search. - *

    - * |Regex - * |{@link FluentFilter#regex(String)} - * |Selects documents where values match a specified regular expression. - * |=== - *

    - * [[app-listing]] - * [source,java] - * .Example of various filters - * -- - *

    - * // returns the ids of the documents whose age field value is 30 - * collection.find(where("age").eq(30)); - *

    - * // age field value is greater than 30 - * collection.find(where("age").gt(30)); - *

    - * // age field value is not 30 - * collection.find(where("age").eq(30).not())); - *

    - * // age field value is 30 and salary greater than 10K - * collection.find(where("age").eq(30).and(where("salary").gt(10000))); - *

    - * // note field contains the string 'hello' - * collection.find(where("note").regex("hello")); - *

    - * // prices field contains price value between 10 to 20 - * collection.find(where("prices").elemMatch($.gt(10).and($.lt(20)))); - *

    - * -- - *

    - * A nitrite document can contain another document. To specify a field - * of a nested document a '.' operator is used. If a field is an array - * or list, array/list index can be used as a field to access a specific - * element in them. - *

    - * [[app-listing]] - * [source,java] - * .Example of nested document - * -- - * NitriteMapper nitriteMapper = new JacksonMapper(); - *

    - * // parse a json into a document - * doc = nitriteMapper.parse("{" + - * " score: 1034," + - * " location: { " + - * " state: 'NY', " + - * " city: 'New York', " + - * " address: {" + - * " line1: '40', " + - * " line2: 'ABC Street', " + - * " house: ['1', '2', '3'] " + - * " }" + - * " }," + - * " category: ['food', 'produce', 'grocery'], " + - * " objArray: [{ field: 1}, {field: 2}]" + - * "}"); - *

    - * // insert the doc into collection - * collection.insert(doc); - *

    - * // filter on nested document - * collection.find(where("location.address.line1").eq("40")); - *

    - * // filter on array using array index - * collection.find(where("location.address.house.2").eq("3")); - *

    - * // filter on object array - * collection.find(where("objArray.0.field").eq(1)); - *

    - * -- + *

    * * @author Anindya Chatterjee - * @see NitriteCollection#find(Filter) + * @see NitriteCollection#find(Filter) NitriteCollection#find(Filter) + * @see NitriteCollection#find(Filter, org.dizitart.no2.collection.FindOptions) NitriteCollection#find(Filter, org.dizitart.no2.collection.FindOptions) * @since 1.0 */ public interface Filter { @@ -188,10 +47,22 @@ public interface Filter { */ Filter ALL = element -> true; + /** + * Filter by id. + * + * @param nitriteId the nitrite id + * @return the filter + */ static Filter byId(NitriteId nitriteId) { return new EqualsFilter(DOC_ID, nitriteId.getIdValue()); } + /** + * And filter. + * + * @param filters the filters + * @return the filter + */ static Filter and(Filter... filters) { notEmpty(filters, "at least two filters must be specified"); if (filters.length < 2) { @@ -201,6 +72,12 @@ static Filter and(Filter... filters) { return new AndFilter(filters); } + /** + * Or filter. + * + * @param filters the filters + * @return the filter + */ static Filter or(Filter... filters) { notEmpty(filters, "at least two filters must be specified"); if (filters.length < 2) { @@ -211,17 +88,16 @@ static Filter or(Filter... filters) { } /** - * Filters a document map and returns the set of {@link NitriteId}s of - * matching {@link Document}s. + * Filters a document map and returns true if the criteria matches. * - * @param element the {@link org.dizitart.no2.store.NitriteMap} entry to check. - * @return a set of {@link NitriteId}s of matching documents. + * @param element the entry to check. + * @return boolean value to indicate if the filtering criteria matches the document. */ boolean apply(Pair element); /** - * Creates a not filter which performs a logical NOT operation on a `filter` and selects - * the documents that *_do not_* satisfy the `filter`. This also includes documents + * Creates a not filter which performs a logical NOT operation on a filter and selects + * the documents that *_do not_* satisfy the criteria. This also includes documents * that do not contain the value. *

    * diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java b/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java deleted file mode 100644 index 4acc2de28..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/FilterStep.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.dizitart.no2.filters; - -/** - * @author Anindya Chatterjee - */ -public class FilterStep { -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FluentFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/FluentFilter.java index 0ca71a42f..98d7d00bb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/FluentFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/FluentFilter.java @@ -16,18 +16,29 @@ package org.dizitart.no2.filters; -import org.dizitart.no2.index.TextIndexer; - /** + * A fluent api for the {@link Filter}. + * * @author Anindya Chatterjee. + * @since 4.0 */ public final class FluentFilter { + /** + * The where clause for elemMatch filter. + */ public static FluentFilter $ = where("$"); + private String field; private FluentFilter() { } + /** + * Where clause for fluent filter. + * + * @param field the field + * @return the fluent filter + */ public static FluentFilter where(String field) { FluentFilter filter = new FluentFilter(); filter.field = field; @@ -37,99 +48,67 @@ public static FluentFilter where(String field) { /** * Creates an equality filter which matches documents where the value * of a field equals the specified value. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value as 30 - * collection.find(where("age").eq(30)); - * -- + * * * @param value the value * @return the equality filter. */ - public Filter eq(Object value) { + public NitriteFilter eq(Object value) { return new EqualsFilter(field, value); } - public Filter notEq(Object value) { + /** + * Creates an equality filter which matches documents where the value + * of a field not equals the specified value. + * + * @param value the value + * @return the filter + */ + public NitriteFilter notEq(Object value) { return new NotEqualsFilter(field, value); } /** * Creates a greater than filter which matches those documents where the value * of the field is greater than (i.e. >) the specified value. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value greater than 30 - * collection.find(where("age").gt(30)); - * -- * * @param value the value * @return the greater than filter */ - public Filter gt(Comparable value) { + public NitriteFilter gt(Comparable value) { return new GreaterThanFilter(field, value); } /** * Creates a greater equal filter which matches those documents where the value * of the field is greater than or equals to (i.e. ≥) the specified value. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value greater than or equal to 30 - * collection.find(where("age").gte(30)); - * -- * * @param value the value * @return the greater or equal filter */ - public Filter gte(Comparable value) { + public NitriteFilter gte(Comparable value) { return new GreaterEqualFilter(field, value); } /** * Creates a lesser than filter which matches those documents where the value * of the field is less than (i.e. <) the specified value. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value less than 30 - * collection.find(where("age").lt(30)); - * -- * * @param value the value * @return the lesser than filter */ - public Filter lt(Comparable value) { + public NitriteFilter lt(Comparable value) { return new LesserThanFilter(field, value); } /** * Creates a lesser equal filter which matches those documents where the value * of the field is lesser than or equals to (i.e. ≤) the specified value. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value lesser than or equal to 30 - * collection.find(where("age").lte(30)); - * -- * * @param value the value * @return the lesser equal filter */ - public Filter lte(Comparable value) { + public NitriteFilter lte(Comparable value) { return new LesserEqualFilter(field, value); } @@ -139,14 +118,14 @@ public Filter lte(Comparable value) { *

     {@code
          * // matches all documents where 'age' field is between 30 and 40
          * collection.find(where("age").between(40, 30));
    -     * }
    +     * }*
          * 
    * * @param lowerBound the lower value * @param upperBound the upper value * @return the between filter */ - public Filter between(Comparable lowerBound, Comparable upperBound) { + public NitriteFilter between(Comparable lowerBound, Comparable upperBound) { return new BetweenFilter<>(field, new BetweenFilter.Bound<>(lowerBound, upperBound)); } @@ -157,15 +136,15 @@ public Filter between(Comparable lowerBound, Comparable upperBound) { * // matches all documents where 'age' field is * // between 30 and 40, excluding 30 and 40 * collection.find(where("age").between(40, 30, false)); - * } + * }* * * * @param lowerBound the lower value * @param upperBound the upper value - * @param inclusive indicates whether to include end values + * @param inclusive indicates whether to include end values * @return the between filter */ - public Filter between(Comparable lowerBound, Comparable upperBound, boolean inclusive) { + public NitriteFilter between(Comparable lowerBound, Comparable upperBound, boolean inclusive) { return new BetweenFilter<>(field, new BetweenFilter.Bound<>(lowerBound, upperBound, inclusive)); } @@ -176,115 +155,75 @@ public Filter between(Comparable lowerBound, Comparable upperBound, boolea * // matches all documents where 'age' field is * // between 30 and 40, including 40 and excluding 30 * collection.find(where("age").between(40, 30, true, false)); - * } + * }* * * - * @param lowerBound the lower value - * @param upperBound the upper value + * @param lowerBound the lower value + * @param upperBound the upper value * @param lowerInclusive indicates whether to include lower end value * @param upperInclusive indicates whether to include upper end value * @return the between filter */ - public Filter between(Comparable lowerBound, Comparable upperBound, boolean lowerInclusive, boolean upperInclusive) { - return new BetweenFilter<>(field, new BetweenFilter.Bound<>(lowerBound, upperBound, lowerInclusive, upperInclusive + public NitriteFilter between(Comparable lowerBound, Comparable upperBound, + boolean lowerInclusive, boolean upperInclusive) { + return new BetweenFilter<>(field, + new BetweenFilter.Bound<>(lowerBound, upperBound, lowerInclusive, upperInclusive )); } /** * Creates a text filter which performs a text search on the content of the fields * indexed with a full-text index. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'address' field has value 'roads'. - * collection.find(where("address").text("roads")); - * -- * * @param value the text value * @return the text filter - * @see TextIndexer * @see org.dizitart.no2.index.fulltext.TextTokenizer */ - public Filter text(String value) { + public NitriteFilter text(String value) { return new TextFilter(field, value); } /** * Creates a string filter which provides regular expression capabilities * for pattern matching strings in documents. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'name' value starts with 'jim' or 'joe'. - * collection.find(where("address").regex("^(jim|joe).*")); - * -- * * @param value the regular expression * @return the regex filter */ - public Filter regex(String value) { + public NitriteFilter regex(String value) { return new RegexFilter(field, value); } /** * Creates an in filter which matches the documents where * the value of a field equals any value in the specified array. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value in [20, 30, 40] - * collection.find(where("age").in(20, 30, 40)); - * -- * * @param values the range values * @return the in filter */ - public Filter in(Comparable... values) { + public NitriteFilter in(Comparable... values) { return new InFilter(field, values); } /** * Creates a notIn filter which matches the documents where * the value of a field not equals any value in the specified array. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents where 'age' field has value not in [20, 30, 40] - * collection.find(where("age").notIn(20, 30, 40)); - * -- * * @param values the range values * @return the notIn filter */ - public Filter notIn(Comparable... values) { + public NitriteFilter notIn(Comparable... values) { return new NotInFilter(field, values); } /** * Creates an element match filter that matches documents that contain an array - * value with at least one element that matches the specified `filter`. - *

    - * [[app-listing]] - * [source,java] - * .Example - * -- - * // matches all documents which has an array field - 'color' and the array - * // contains a value - 'red'. - * collection.find(where("age").elemMatch($.eq("red"))); - * -- + * value with at least one element that matches the specified filter. * * @param filter the filter to satisfy * @return the element match filter */ - public Filter elemMatch(Filter filter) { + public NitriteFilter elemMatch(Filter filter) { return new ElementMatchFilter(field, filter); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java index ab58d2440..dfc7c2776 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java @@ -20,47 +20,23 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; /** * @author Anindya Chatterjee */ -class GreaterEqualFilter extends ComparisonFilter { +class GreaterEqualFilter extends ComparableFilter { GreaterEqualFilter(String field, Comparable value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findGreaterEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else { - if (getValue() instanceof Comparable) { - throw new FilterException("gte filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("gte filter cannot be applied on _id field"); - } - @Override @SuppressWarnings({"unchecked", "rawtypes"}) public boolean apply(Pair element) { @@ -80,4 +56,33 @@ public boolean apply(Pair element) { return false; } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object applyOnIndex(IndexScanner indexScanner) { + Comparable comparable = getComparable(); + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + + // maintain the find sorting order + List nitriteIds = new ArrayList<>(); + + Comparable ceilingKey = indexScanner.ceilingKey(comparable); + while (ceilingKey != null) { + // get the starting value, it can be a navigable-map (compound index) + // or list (single field index) + Object value = indexScanner.get(ceilingKey); + processIndexValue(value, subMap, nitriteIds); + + ceilingKey = indexScanner.higherKey(ceilingKey); + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java index f4b4e5ff3..712effe28 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java @@ -20,46 +20,21 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; /** * @author Anindya Chatterjee */ -class GreaterThanFilter extends ComparisonFilter { +class GreaterThanFilter extends ComparableFilter { protected GreaterThanFilter(String field, Comparable value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findGreaterThan(getCollectionName(), getField(), (Comparable) getValue()); - } else { - if (getValue() instanceof Comparable) { - throw new FilterException("gt filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("gt filter cannot be applied on _id field"); - } @Override @SuppressWarnings({"unchecked", "rawtypes"}) @@ -80,4 +55,31 @@ public boolean apply(Pair element) { return false; } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object applyOnIndex(IndexScanner indexScanner) { + Comparable comparable = getComparable(); + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + Comparable ceilingKey = indexScanner.higherKey(comparable); + while (ceilingKey != null) { + // get the starting value, it can be a navigable-map (compound index) + // or list (single field index) + Object value = indexScanner.get(ceilingKey); + processIndexValue(value, subMap, nitriteIds); + + ceilingKey = indexScanner.higherKey(ceilingKey); + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java index a46cdd211..6b97a45d6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java @@ -20,21 +20,17 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; import java.util.*; - -import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import java.util.concurrent.ConcurrentSkipListMap; /** * @author Anindya Chatterjee */ -class InFilter extends IndexAwareFilter { +class InFilter extends ComparableFilter { @Getter - private Set> comparableSet; + private final Set> comparableSet; InFilter(String field, Comparable... values) { super(field, values); @@ -42,43 +38,6 @@ class InFilter extends IndexAwareFilter { Collections.addAll(this.comparableSet, values); } - @Override - protected Set findIndexedIdSet() { - validateInFilterValue(getField(), comparableSet); - this.comparableSet = convertValues(this.comparableSet); - - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && comparableSet != null) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findIn(getCollectionName(), getField(), comparableSet); - } else { - if (comparableSet != null && !comparableSet.isEmpty()) { - throw new FilterException("in filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException("invalid in filter"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - Set idSet = new LinkedHashSet<>(); - if (getOnIdField()) { - for (Comparable comparable : comparableSet) { - if (comparable instanceof String) { - NitriteId nitriteId = NitriteId.createId((String) comparable); - if (collection.containsKey(nitriteId)) { - idSet.add(nitriteId); - } - } - } - } - return idSet; - } @Override public boolean apply(Pair element) { @@ -92,11 +51,23 @@ public boolean apply(Pair element) { return false; } - private void validateInFilterValue(String field, Collection> values) { - notNull(field, "field cannot be null"); - notNull(values, "values cannot be null"); - if (values.size() == 0) { - throw new ValidationException("values cannot be empty"); + public Object applyOnIndex(IndexScanner indexScanner) { + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + for (Pair, ?> entry : indexScanner.entries()) { + if (comparableSet.contains(entry.getFirst())) { + processIndexValue(entry.getSecond(), subMap, nitriteIds); + } + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java deleted file mode 100644 index c7f051ba2..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/IndexAwareFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.filters; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.store.NitriteMap; - -import java.util.Set; - -/** - * @author Anindya Chatterjee - */ -@ToString(exclude = "indexedIdSet") -@EqualsAndHashCode(callSuper = true) -public abstract class IndexAwareFilter extends FieldBasedFilter { - @Getter @Setter - private Boolean isFieldIndexed = false; - - @Getter @Setter - private Boolean onIdField = false; - - @Getter @Setter - private NitriteIndexer nitriteIndexer; - - private Set indexedIdSet; - private Set idSet; - - protected IndexAwareFilter(String field, Object value) { - super(field, value); - } - - protected abstract Set findIndexedIdSet(); - protected abstract Set findIdSet(NitriteMap collection); - - public Set cachedIndexedIds() { - if (indexedIdSet == null || indexedIdSet.isEmpty()) { - indexedIdSet = findIndexedIdSet(); - } - return indexedIdSet; - } - - public Set cachedIds(NitriteMap collection) { - if (idSet == null) { - idSet = findIdSet(collection); - } - return idSet; - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java new file mode 100644 index 000000000..94aef5b5c --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import lombok.Getter; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.InvalidOperationException; + +import java.util.List; + +/** + * Represents a set of filter which can be applied on an index. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class IndexScanFilter implements Filter { + @Getter + private final List filters; + + /** + * Instantiates a new Index scan filter. + * + * @param filters the filters + */ + public IndexScanFilter(List filters) { + this.filters = filters; + } + + @Override + public boolean apply(Pair element) { + throw new InvalidOperationException("index scan filter cannot be applied on collection"); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java deleted file mode 100644 index 75f9c97a2..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/IndexedQuerySupport.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.dizitart.no2.filters; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.FieldValues; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; - -/** - * @author Anindya Chatterjee - */ -public class IndexedQuerySupport { - private ComparableIndexer comparableIndexer; - - public IndexedQuerySupport(ComparableIndexer comparableIndexer) { - this.comparableIndexer = comparableIndexer; - } - - public RecordStream findByFilter(NitriteMap indexMap, NitriteFilter filter, NitriteConfig nitriteConfig) { - - return null; - } - - public FieldValues calculateFieldValues(NitriteFilter filter) { - - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java index 7b5af2aa6..be08e7171 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java @@ -20,47 +20,23 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; /** * @author Anindya Chatterjee */ -class LesserEqualFilter extends ComparisonFilter { +class LesserEqualFilter extends ComparableFilter { LesserEqualFilter(String field, Comparable value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findLesserEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else { - if (getValue() instanceof Comparable) { - throw new FilterException("lte filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("lte filter cannot be applied on _id field"); - } - @Override @SuppressWarnings({"unchecked", "rawtypes"}) public boolean apply(Pair element) { @@ -80,4 +56,31 @@ public boolean apply(Pair element) { return false; } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object applyOnIndex(IndexScanner indexScanner) { + Comparable comparable = getComparable(); + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + Comparable ceilingKey = indexScanner.floorKey(comparable); + while (ceilingKey != null) { + // get the starting value, it can be a navigable-map (compound index) + // or list (single field index) + Object value = indexScanner.get(ceilingKey); + processIndexValue(value, subMap, nitriteIds); + + ceilingKey = indexScanner.lowerKey(ceilingKey); + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java index f99397e92..21cced2f3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java @@ -20,47 +20,21 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; /** * @author Anindya Chatterjee */ -class LesserThanFilter extends ComparisonFilter { +class LesserThanFilter extends ComparableFilter { LesserThanFilter(String field, Comparable value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && getValue() instanceof Comparable) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findLesserThan(getCollectionName(), getField(), (Comparable) getValue()); - } else { - if (getValue() instanceof Comparable) { - throw new FilterException("lt filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("lt filter cannot be applied on _id field"); - } - @Override @SuppressWarnings({"unchecked", "rawtypes"}) public boolean apply(Pair element) { @@ -80,4 +54,31 @@ public boolean apply(Pair element) { return false; } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object applyOnIndex(IndexScanner indexScanner) { + Comparable comparable = getComparable(); + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + Comparable ceilingKey = indexScanner.lowerKey(comparable); + while (ceilingKey != null) { + // get the starting value, it can be a navigable-map (compound index) + // or list (single field index) + Object value = indexScanner.get(ceilingKey); + processIndexValue(value, subMap, nitriteIds); + + ceilingKey = indexScanner.lowerKey(ceilingKey); + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java index 7cb47cc3e..1ba4abe58 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LogicalFilter.java @@ -22,12 +22,21 @@ import java.util.List; /** + * Represents a filter which does a logical operation (AND, OR) + * between a set of filters. + * * @author Anindya Chatterjee. + * @since 1.0 */ @Getter public abstract class LogicalFilter extends NitriteFilter { private final List filters; + /** + * Instantiates a new Logical filter. + * + * @param filters the filters + */ public LogicalFilter(Filter... filters) { this.filters = Arrays.asList(filters); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java index c15e10503..ebf31b58f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java @@ -21,7 +21,10 @@ import org.dizitart.no2.NitriteConfig; /** + * Represents a nitrite filter. + * * @author Anindya Chatterjee. + * @since 4.0 */ @Getter @Setter @@ -29,4 +32,28 @@ public abstract class NitriteFilter implements Filter { private NitriteConfig nitriteConfig; private String collectionName; private Boolean objectFilter = false; + + /** + * Creates an and filter which performs a logical AND operation on two filters and selects + * the documents that satisfy both filters. + *

    + * + * @param filter other filter + * @return the and filter + */ + public Filter and(Filter filter) { + return new AndFilter(this, filter); + } + + /** + * Creates an or filter which performs a logical OR operation on two filters and selects + * the documents that satisfy at least one of the filter. + *

    + * + * @param filter other filter + * @return the or filter + */ + public Filter or(Filter filter) { + return new OrFilter(this, filter); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java index a5d57ab77..4244a140e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java @@ -4,13 +4,10 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.index.TextIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; @@ -18,46 +15,11 @@ * @author Anindya Chatterjee */ @ToString -class NotEqualsFilter extends IndexAwareFilter { +class NotEqualsFilter extends ComparableFilter { protected NotEqualsFilter(String field, Object value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getValue() == null || getValue() instanceof Comparable) { - if (getNitriteIndexer() instanceof ComparableIndexer) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findNotEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else if (getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String) { - // notEq filter is not compatible with TextIndexer - setIsFieldIndexed(false); - } else { - throw new FilterException("notEq filter is not supported on indexed field " - + getField()); - } - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - Set idSet = new LinkedHashSet<>(); - if (getOnIdField() && getValue() instanceof String) { - NitriteId nitriteId = NitriteId.createId((String) getValue()); - if (!collection.containsKey(nitriteId)) { - idSet.add(nitriteId); - } - } - return idSet; - } - @Override public boolean apply(Pair element) { Document document = element.getSecond(); @@ -65,10 +27,23 @@ public boolean apply(Pair element) { return !deepEquals(fieldValue, getValue()); } - @Override - public void setIsFieldIndexed(Boolean isFieldIndexed) { - if (!(getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String)) { - super.setIsFieldIndexed(isFieldIndexed); + public Object applyOnIndex(IndexScanner indexScanner) { + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + for (Pair, ?> entry : indexScanner.entries()) { + if (!deepEquals(getValue(), entry.getFirst())) { + processIndexValue(entry.getSecond(), subMap, nitriteIds); + } + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java index 1c80c7eb7..68f3a66c9 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java @@ -20,21 +20,17 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.index.IndexScanner; import java.util.*; - -import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import java.util.concurrent.ConcurrentSkipListMap; /** * @author Anindya Chatterjee */ -class NotInFilter extends IndexAwareFilter { +class NotInFilter extends ComparableFilter { @Getter - private Set> comparableSet; + private final Set> comparableSet; NotInFilter(String field, Comparable... values) { super(field, values); @@ -42,49 +38,6 @@ class NotInFilter extends IndexAwareFilter { Collections.addAll(this.comparableSet, values); } - @Override - protected Set findIndexedIdSet() { - validateNotInFilterValue(getField(), comparableSet); - this.comparableSet = convertValues(this.comparableSet); - - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof ComparableIndexer && comparableSet != null) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findNotIn(getCollectionName(), getField(), comparableSet); - } else { - if (comparableSet != null && !comparableSet.isEmpty()) { - throw new FilterException("notIn filter is not supported on indexed field " - + getField()); - } else { - throw new FilterException("invalid notIn filter"); - } - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - Set idSet = new LinkedHashSet<>(); - if (getOnIdField()) { - Set notInSet = new LinkedHashSet<>(); - for (Comparable comparable : comparableSet) { - if (comparable instanceof String) { - NitriteId nitriteId = NitriteId.createId((String) comparable); - notInSet.add(nitriteId); - } - } - - for (NitriteId nitriteId : collection.keySet()) { - if (!notInSet.contains(nitriteId)) { - idSet.add(nitriteId); - } - } - } - return idSet; - } - @Override public boolean apply(Pair element) { Document document = element.getSecond(); @@ -97,11 +50,23 @@ public boolean apply(Pair element) { return true; } - private void validateNotInFilterValue(String field, Collection> values) { - notNull(field, "field cannot be null"); - notNull(values, "values cannot be null"); - if (values.size() == 0) { - throw new ValidationException("values cannot be empty"); + public Object applyOnIndex(IndexScanner indexScanner) { + NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List nitriteIds = new ArrayList<>(); + + for (Pair, ?> entry : indexScanner.entries()) { + if (!comparableSet.contains(entry.getFirst())) { + processIndexValue(entry.getSecond(), subMap, nitriteIds); + } + } + + if (!subMap.isEmpty()) { + // if sub-map is populated then filtering on compound index, return sub-map + return subMap; + } else { + // else it is filtering on either single field index, + // or it is a terminal filter on compound index, return only nitrite-ids + return nitriteIds; } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java index c5fcd3331..d6b7b0631 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java @@ -22,10 +22,18 @@ import org.dizitart.no2.common.tuples.Pair; /** + * Represents an OR filter. + * * @author Anindya Chatterjee + * @since 1.0 */ @Getter public class OrFilter extends LogicalFilter { + /** + * Instantiates a new Or filter. + * + * @param filters the filters + */ OrFilter(Filter... filters) { super(filters); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java deleted file mode 100644 index 1e8c1aafa..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryOptimizer.java +++ /dev/null @@ -1,248 +0,0 @@ -package org.dizitart.no2.filters; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.collection.operation.FindOptions; -import org.dizitart.no2.common.*; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.store.IndexCatalog; -import org.dizitart.no2.store.NitriteMap; - -import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.ConcurrentSkipListSet; - - -/** - * @author Anindya Chatterjee - */ -public class QueryOptimizer { - private final NitriteConfig nitriteConfig; - - /* - * 1. If And filter - * 1.1 flatten the filter using depth first traversal - * 1.2 check each filter, group OR & AND, single field filters - * 1.3 scan through single field filter or and filter if there is any match for composite index - * 1.3.1 if matching composite index found, get index stream - * 1.3.2 group remaining filters as a new and filter and apply on indexed stream from 1.3.1 - * 1.4 if no matching composite index found, scan for simple index - * 1.4.1 if found, get indexed stream - * 1.4.2 group remaining filter as a new and filter and apply on index stream from 1.4.1 - * 1.5 if no matching index found, collscan and apply filter - * - * 2. If OR filter - * 1.1 If every simple field is indexed or and filter composite indexed - * 1.1.1 - * 1.2 If one of the fields is not indexed, get collscan and apply filter - * - * 3. If simple filter - * 3.1 Check if index exists, send indexed stream - * 3.2 If no index found, collscan - * - * */ - - public QueryOptimizer(NitriteConfig nitriteConfig) { - this.nitriteConfig = nitriteConfig; - } - - public FilterStep optimizeFilter(NitriteMap primaryCollection, - Filter filter, - FindOptions findOptions) { - List flattenedFilters = new ArrayList<>(); - if (filter instanceof AndFilter) { - List filters = flattenAndFilter((AndFilter) filter); - flattenedFilters.addAll(filters); - } else { - flattenedFilters.add(filter); - } - - return null; - } - - private List flattenAndFilter(AndFilter andFilter) { - List flattenedFilters = new ArrayList<>(); - if (andFilter != null) { - for (Filter filter : andFilter.getFilters()) { - if (filter instanceof AndFilter) { - List filters = flattenAndFilter((AndFilter) filter); - flattenedFilters.addAll(filters); - } else { - flattenedFilters.add(filter); - } - } - } - return flattenedFilters; - } - - private Pair optimizeAnd(String collectionName, List flattenedFilter) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - Set indexedFieldNames = indexCatalog.findIndexSupportedFields(collectionName); - Set filterFieldNames = getFieldNames(flattenedFilter); - - - return null; - } - - private Set getFieldNames(List filters) { - // send only eligible field names, ignore OR filers as they can't be used for composite index - return null; - } - - - - - - - - - - - - - - - - - - - - - - @SuppressWarnings("unchecked") - public RecordStream> findOptimizedStream(NitriteMap primaryCollection, - Filter filter, - FindOptions findOptions) { - if (filter == null) { - return optimizedStream(null, findOptions, primaryCollection); - } - - if (filter instanceof AndFilter) { - AndFilter andFilter = (AndFilter) filter; - FieldValues fieldValues = decomposeAnd(andFilter); - NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); - return optimizedStream(filter, findOptions, primaryCollection, indexMap); - } else if (filter instanceof OrFilter) { - OrFilter orFilter = (OrFilter) filter; - List fieldValuesList = decomposeOr(orFilter); - List> indexedMaps = new ArrayList<>(); - - for (FieldValues fieldValues : fieldValuesList) { - NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); - if (indexMap != null) { - indexedMaps.add(indexMap); - } - } - - return optimizedStream(filter, findOptions, primaryCollection, indexedMaps.toArray(new NitriteMap[0])); - } else if (filter instanceof IndexAwareFilter) { - FieldValues fieldValues = decomposeFilter(filter); - NitriteMap, ?> indexMap = findSuitableIndexMap(primaryCollection.getName(), fieldValues); - return optimizedStream(filter, findOptions, primaryCollection, indexMap); - } else { - return optimizedStream(filter, findOptions, primaryCollection); - } - } - - private FieldValues decomposeFilter(Filter filter) { - FieldValues fieldValues = new FieldValues(); - if (filter instanceof ComparisonFilter) { - ComparisonFilter comparisonFilter = (ComparisonFilter) filter; - fieldValues.getValues().add(new Pair<>(comparisonFilter.getField(), comparisonFilter.getComparable())); - } else if (filter instanceof AndFilter) { - AndFilter andFilter = (AndFilter) filter; - FieldValues fv = decomposeAnd(andFilter); - fieldValues.getValues().addAll(fv.getValues()); - } - return fieldValues; - } - - private FieldValues decomposeAnd(AndFilter filter) { - FieldValues fieldValues = new FieldValues(); - - Filter lhs = filter.getLhs(); - Filter rhs = filter.getRhs(); - - // if there are any OR filter in any of the arms, nitrite will not consider it - FieldValues lhsFieldValues = decomposeFilter(lhs); - FieldValues rhsFieldValues = decomposeFilter(rhs); - fieldValues.getValues().addAll(lhsFieldValues.getValues()); - fieldValues.getValues().addAll(rhsFieldValues.getValues()); - return fieldValues; - } - - private List decomposeOr(OrFilter filter) { - List fieldValues = new ArrayList<>(); - - Filter lhs = filter.getLhs(); - Filter rhs = filter.getRhs(); - - if (lhs instanceof OrFilter) { - fieldValues.addAll(decomposeOr((OrFilter) lhs)); - } else { - fieldValues.add(decomposeFilter(lhs)); - } - - if (rhs instanceof OrFilter) { - fieldValues.addAll(decomposeOr((OrFilter) rhs)); - } else { - fieldValues.add(decomposeFilter(rhs)); - } - - return fieldValues; - } - - private NitriteMap, ?> findSuitableIndexMap(String collectionName, FieldValues fieldValues) { - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - IndexDescriptor descriptor = null; - - if (indexCatalog != null) { - NavigableMap indexScore = new TreeMap<>(Collections.reverseOrder()); - - Fields fields = fieldValues.getFields(); - Collection indexDescriptors = indexCatalog.listIndexDescriptors(collectionName); - for (IndexDescriptor indexDescriptor : indexDescriptors) { - Fields indexFields = indexDescriptor.getIndexFields(); - if (indexFields.isPrefix(fields)) { - int keySize = indexFields.getFieldNames().size(); - int score = IndexType.Unique.equals(indexDescriptor.getIndexType()) ? keySize + 10 : keySize; - indexScore.put(score, indexDescriptor); - } - } - - if (!indexScore.isEmpty()) { - descriptor = indexScore.firstEntry().getValue(); - } - } - - return getIndexMap(descriptor, fieldValues); - } - - private NitriteMap, ?> getIndexMap(IndexDescriptor indexDescriptor, FieldValues fieldValues) { - if (indexDescriptor == null) return null; - - String indexMapName = nitriteConfig.getNitriteStore().getIndexCatalog().getIndexMapName(indexDescriptor); - Class keyType = fieldValues.getFirstValue() == null ? Comparable.class - : fieldValues.getFirstValue().getClass(); - Class valueType = indexDescriptor.isCompoundIndex() ? ConcurrentSkipListMap.class - : ConcurrentSkipListSet.class; - - return nitriteConfig.getNitriteStore().openMap(indexMapName, keyType, valueType); - } - - - @SafeVarargs - private final RecordStream> optimizedStream(Filter filter, - FindOptions findOptions, - NitriteMap primaryCollection, - NitriteMap, ?>... indexMaps) { - if (filter == null) { - return primaryCollection.entries(); - } - - - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java b/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java deleted file mode 100644 index 4e11fd711..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/QueryPlan.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.dizitart.no2.filters; - -import lombok.Data; - -/** - * @author Anindya Chatterjee - */ -@Data -public class QueryPlan { - private Filter indexedFilter; - private Filter nonIndexedFilter; -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java index 1e6f8e622..380be384e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java @@ -17,13 +17,27 @@ package org.dizitart.no2.filters; /** + * Represents a filter on string values. + * * @author Anindya Chatterjee + * @since 1.0 */ -public abstract class StringFilter extends IndexAwareFilter { +public abstract class StringFilter extends FieldBasedFilter { + /** + * Instantiates a new String filter. + * + * @param field the field + * @param value the value + */ protected StringFilter(String field, String value) { super(field, value); } + /** + * Gets string value. + * + * @return the string value + */ public String getStringValue() { return (String) getValue(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java index bc5186bd3..1d4d568ea 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java @@ -16,45 +16,162 @@ package org.dizitart.no2.filters; +import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.TextIndexer; +import org.dizitart.no2.index.fulltext.TextTokenizer; import org.dizitart.no2.store.NitriteMap; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; + +import static org.dizitart.no2.common.util.StringUtils.stringTokenizer; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** + * Represents a nitrite full-text search filter. + * * @author Anindya Chatterjee + * @since 1.0 */ -class TextFilter extends StringFilter { +public class TextFilter extends StringFilter { + @Setter + private TextTokenizer textTokenizer; + + /** + * Instantiates a new Text filter. + * + * @param field the field + * @param value the value + */ TextFilter(String field, String value) { super(field, value); } @Override - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getNitriteIndexer() instanceof TextIndexer) { - TextIndexer textIndexer = (TextIndexer) getNitriteIndexer(); - idSet = textIndexer.findText(getCollectionName(), getField(), getStringValue()); - } else { - throw new FilterException(getField() + " is not full-text indexed"); + public boolean apply(Pair element) { + throw new FilterException(getField() + " is not full-text indexed"); + } + + /** + * Apply on index linked hash set. + * + * @param indexMap the index map + * @return the linked hash set + */ + public LinkedHashSet applyOnIndex(NitriteMap> indexMap) { + notNull(getField(), "field cannot be null"); + notNull(getStringValue(), "search term cannot be null"); + String searchString = getStringValue(); + + if (searchString.startsWith("*") || searchString.endsWith("*")) { + return searchByWildCard(indexMap, searchString); + } else { + return searchExactByIndex(indexMap, searchString); + } + } + + @SuppressWarnings("unchecked") + private LinkedHashSet searchExactByIndex(NitriteMap> indexMap, String searchString) { + + Set words = textTokenizer.tokenize(searchString); + Map scoreMap = new HashMap<>(); + for (String word : words) { + List nitriteIds = (List) indexMap.get(word); + if (nitriteIds != null) { + for (NitriteId id : nitriteIds) { + Integer score = scoreMap.get(id); + if (score == null) { + scoreMap.put(id, 1); + } else { + scoreMap.put(id, score + 1); + } + } + } + } + + return sortedIdsByScore(scoreMap); + } + + private LinkedHashSet searchByWildCard(NitriteMap> indexMap, String searchString) { + if (searchString.contentEquals("*")) { + throw new FilterException("* is not a valid search string"); + } + + StringTokenizer stringTokenizer = stringTokenizer(searchString); + if (stringTokenizer.countTokens() > 1) { + throw new FilterException("multiple words with wildcard is not supported"); + } + + if (searchString.startsWith("*") && !searchString.endsWith("*")) { + return searchByLeadingWildCard(indexMap, searchString); + } else if (searchString.endsWith("*") && !searchString.startsWith("*")) { + return searchByTrailingWildCard(indexMap, searchString); + } else { + String term = searchString.substring(1, searchString.length() - 1); + return searchContains(indexMap, term); + } + } + + @SuppressWarnings("unchecked") + private LinkedHashSet searchByLeadingWildCard(NitriteMap> indexMap, String searchString) { + if (searchString.equalsIgnoreCase("*")) { + throw new FilterException("invalid search term '*'"); + } + + LinkedHashSet idSet = new LinkedHashSet<>(); + String term = searchString.substring(1); + + for (Pair> entry : indexMap.entries()) { + String key = entry.getFirst(); + if (key.endsWith(term.toLowerCase())) { + idSet.addAll((List) entry.getSecond()); } } return idSet; } - @Override - protected Set findIdSet(NitriteMap collection) { - throw new FilterException("text filter cannot be applied on _id field"); + @SuppressWarnings("unchecked") + private LinkedHashSet searchByTrailingWildCard(NitriteMap> indexMap, String searchString) { + if (searchString.equalsIgnoreCase("*")) { + throw new FilterException("invalid search term '*'"); + } + + LinkedHashSet idSet = new LinkedHashSet<>(); + String term = searchString.substring(0, searchString.length() - 1); + + for (Pair> entry : indexMap.entries()) { + String key = entry.getFirst(); + if (key.startsWith(term.toLowerCase())) { + idSet.addAll((List) entry.getSecond()); + } + } + return idSet; } - @Override - public boolean apply(Pair element) { - throw new FilterException(getField() + " is not full-text indexed"); + @SuppressWarnings("unchecked") + private LinkedHashSet searchContains(NitriteMap> indexMap, String term) { + LinkedHashSet idSet = new LinkedHashSet<>(); + + for (Pair> entry : indexMap.entries()) { + String key = entry.getFirst(); + if (key.contains(term.toLowerCase())) { + idSet.addAll((List) entry.getSecond()); + } + } + return idSet; + } + + private LinkedHashSet sortedIdsByScore(Map unsortedMap) { + List> list = new LinkedList<>(unsortedMap.entrySet()); + Collections.sort(list, (e1, e2) -> (e2.getValue()).compareTo(e1.getValue())); + + LinkedHashSet result = new LinkedHashSet<>(); + for (Map.Entry entry : list) { + result.add(entry.getKey()); + } + + return result; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java deleted file mode 100644 index d04863de1..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/index/BaseNitriteIndexer.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dizitart.no2.index; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.common.UnknownType; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; - -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.ConcurrentSkipListSet; - -/** - * @author Anindya Chatterjee - */ -public abstract class BaseNitriteIndexer implements NitriteIndexer { - - @Override - public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - NitriteMap indexMap; - if (indexDescriptor.isCompoundIndex()) { - indexMap = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - } else { - indexMap = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - } - indexMap.clear(); - indexMap.drop(); - } - - @SuppressWarnings("rawtypes") - public NitriteMap> getSimpleIndexMap(IndexDescriptor indexDescriptor, - NitriteStore nitriteStore, - Class keyType) { - String mapName = getIndexMapName(indexDescriptor, nitriteStore); - return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListSet.class); - } - - @SuppressWarnings("rawtypes") - public NitriteMap> getCompoundIndexMap(IndexDescriptor indexDescriptor, - NitriteStore nitriteStore, - Class keyType) { - String mapName = getIndexMapName(indexDescriptor, nitriteStore); - return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListMap.class); - } - - protected String getIndexMapName(IndexDescriptor indexDescriptor, NitriteStore nitriteStore) { - return nitriteStore.getIndexCatalog().getIndexMapName(indexDescriptor); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/BoundingBox.java b/nitrite/src/main/java/org/dizitart/no2/index/BoundingBox.java index 0414451e7..2d30d8984 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/BoundingBox.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/BoundingBox.java @@ -19,14 +19,36 @@ import java.io.Serializable; /** + * Represents a bounding box for spatial indexing. + * * @author Anindya Chatterjee */ public interface BoundingBox extends Serializable { + /** + * Gets min x. + * + * @return the min x + */ float getMinX(); + /** + * Gets max x. + * + * @return the max x + */ float getMaxX(); + /** + * Gets min y. + * + * @return the min y + */ float getMinY(); + /** + * Gets max y. + * + * @return the max y + */ float getMaxY(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java index 59fee6bf0..0064753be 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/ComparableIndexer.java @@ -17,40 +17,36 @@ package org.dizitart.no2.index; import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.*; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.filters.IndexedQuerySupport; -import org.dizitart.no2.filters.NitriteFilter; -import org.dizitart.no2.store.IndexCatalog; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.ConcurrentSkipListSet; - -import static org.dizitart.no2.common.util.Iterables.getElementType; -import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; -import static org.dizitart.no2.common.util.ValidationUtils.validateArrayIndexField; -import static org.dizitart.no2.common.util.ValidationUtils.validateIterableIndexField; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** + * Represents an indexer for {@link Comparable} values. + * * @author Anindya Chatterjee + * @since 4.0 */ -@SuppressWarnings("rawtypes") -public abstract class ComparableIndexer extends BaseNitriteIndexer { - protected IndexedQuerySupport querySupport; +public abstract class ComparableIndexer implements NitriteIndexer { + private final Map indexRegistry; + /** + * Instantiates a new Comparable indexer. + */ public ComparableIndexer() { - querySupport = new IndexedQuerySupport(this); + this.indexRegistry = new ConcurrentHashMap<>(); } + /** + * Indicates if it is an unique index. + * + * @return the boolean + */ abstract boolean isUnique(); @Override @@ -58,360 +54,48 @@ public void initialize(NitriteConfig nitriteConfig) { } @Override - public RecordStream findByFilter(String collectionName, Filter filter, NitriteConfig nitriteConfig) { - if (filter instanceof NitriteFilter) { - NitriteFilter nitriteFilter = (NitriteFilter) filter; - IndexCatalog indexCatalog = nitriteConfig.getNitriteStore().getIndexCatalog(); - Collection descriptors = indexCatalog.listIndexDescriptors(collectionName); - - - FieldValues fieldValues = querySupport.calculateFieldValues(nitriteFilter); - IndexDescriptor descriptor = new IndexDescriptor(getIndexType(), fieldValues.getFields(), collectionName); - - NitriteMap indexMap = findSuitableIndexMap(descriptor, fieldValues, nitriteConfig.getNitriteStore()); - - - return querySupport.findByFilter(indexMap, nitriteFilter, nitriteConfig); - } else { - throw new FilterException(filter.getClass().getName() + " is not supported"); - } + public void validateIndex(Fields fields) { + // nothing to validate } - //region Write Index + @Override + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { + NitriteIndex nitriteIndex = findNitriteIndex(findPlan.getIndexDescriptor(), nitriteConfig); + return nitriteIndex.findNitriteIds(findPlan); + } @Override - public void writeIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - if (indexDescriptor.isCompoundIndex()) { - writeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); - } else { - writeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); - } + NitriteIndex nitriteIndex = findNitriteIndex(indexDescriptor, nitriteConfig); + nitriteIndex.write(fieldValues); } @Override - public void removeIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - if (indexDescriptor.isCompoundIndex()) { - removeCompoundIndexEntry(indexDescriptor, fieldValues, nitriteConfig); - } else { - removeSimpleIndexEntry(indexDescriptor, fieldValues, nitriteConfig); - } + NitriteIndex nitriteIndex = findNitriteIndex(indexDescriptor, nitriteConfig); + nitriteIndex.remove(fieldValues); } - private void writeCompoundIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, - NitriteConfig nitriteConfig) { - Fields fields = fieldValues.getFields(); - FieldNames fieldNames = fields.getFieldNames(); - - String firstField = fieldNames.get(0); - Object firstValue = fieldValues.get(firstField); - - // NOTE: only first field can have array or iterable value, subsequent fields can not - validateIndexField(firstValue, firstField); - - if (firstValue == null) { - NitriteMap> indexMap - = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - - addCompoundIndexElement(indexMap, fieldValues, null); - } else if (firstValue instanceof Comparable) { - NitriteMap> indexMap - = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), firstValue.getClass()); - - addCompoundIndexElement(indexMap, fieldValues, (Comparable) firstValue); - } else if (firstValue.getClass().isArray()) { - Object[] array = convertToObjectArray(firstValue); - NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - - for (Object item : array) { - addCompoundIndexElement(indexMap, fieldValues, (Comparable) item); - } - } else if (firstValue instanceof Iterable) { - Iterable iterable = (Iterable) firstValue; - NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), getElementType(iterable)); - - for (Object item : iterable) { - addCompoundIndexElement(indexMap, fieldValues, (Comparable) item); - } - } - } - - private void writeSimpleIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, - NitriteConfig nitriteConfig) { - Fields fields = fieldValues.getFields(); - FieldNames fieldNames = fields.getFieldNames(); - - String firstField = fieldNames.get(0); - Object element = fieldValues.get(firstField); - - if (element == null) { - NitriteMap> indexMap - = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - - addSimpleIndexElement(indexMap, fieldValues, null); - } else if (element instanceof Comparable) { - NitriteMap> indexMap - = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), element.getClass()); - - addSimpleIndexElement(indexMap, fieldValues, (Comparable) element); - } else if (element.getClass().isArray()) { - Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - - for (Object item : array) { - addSimpleIndexElement(indexMap, fieldValues, (Comparable) item); - } - } else if (element instanceof Iterable) { - Iterable iterable = (Iterable) element; - NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), getElementType(iterable)); - - for (Object item : iterable) { - addSimpleIndexElement(indexMap, fieldValues, (Comparable) item); - } - } - } - - private void addCompoundIndexElement(NitriteMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableMap subMap = indexMap.get(element); - if (subMap == null) { - SortOrder sortOrder = fieldValues.getFields().getFirstKey().getSecond(); - subMap = sortOrder == SortOrder.Ascending ? new ConcurrentSkipListMap<>() - : new ConcurrentSkipListMap<>(Collections.reverseOrder()); - } - - populateSubMap(subMap, fieldValues, 1); - indexMap.put(element, subMap); - } - - @SuppressWarnings("unchecked") - private void populateSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { - for (int i = startIndex; i < fieldValues.getValues().size(); i++) { - Pair pair = fieldValues.getValues().get(i); - Object value = pair.getSecond(); - if (value == null) { - value = DBNull.getInstance(); - } - - if (!(value instanceof Comparable)) { - throw new IndexingException(value + " is not comparable"); - } - - if (i == fieldValues.getValues().size() - 1) { - NavigableSet nitriteIds = (NavigableSet) subMap.get(value); - nitriteIds = addNitriteIds(nitriteIds, fieldValues); - subMap.put(value, nitriteIds); - } else { - NavigableMap subMap2 = (NavigableMap) subMap.get(value); - if (subMap2 == null) { - SortOrder sortOrder = fieldValues.getFields().getSortOrder(pair.getFirst()); - subMap2 = sortOrder == SortOrder.Ascending ? new ConcurrentSkipListMap<>() - : new ConcurrentSkipListMap<>(Collections.reverseOrder()); - } - - populateSubMap(subMap2, fieldValues, startIndex + 1); - subMap.put(value, subMap2); - } - } - } - - @SuppressWarnings("unchecked") - private void addSimpleIndexElement(NitriteMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableSet nitriteIds = (NavigableSet) indexMap.get(element); - nitriteIds = addNitriteIds(nitriteIds, fieldValues); - indexMap.put(element, nitriteIds); - } - - private NavigableSet addNitriteIds(NavigableSet nitriteIds, FieldValues fieldValues) { - if (nitriteIds == null) { - nitriteIds = new ConcurrentSkipListSet<>(); - } - - if (isUnique() && nitriteIds.size() == 1 - && !nitriteIds.contains(fieldValues.getNitriteId())) { - // if key is already exists for unique type, throw error - throw new UniqueConstraintException("unique key constraint violation for " + fieldValues.getFields()); - } - - nitriteIds.add(fieldValues.getNitriteId()); - return nitriteIds; - } - - private void removeCompoundIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, - NitriteConfig nitriteConfig) { - Fields fields = fieldValues.getFields(); - FieldNames fieldNames = fields.getFieldNames(); - - String firstField = fieldNames.get(0); - Object firstValue = fieldValues.get(firstField); - - // NOTE: only first field can have array or iterable value, subsequent fields can not - validateIndexField(firstValue, firstField); - - if (firstValue == null) { - NitriteMap> indexMap - = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - - removeCompoundIndexElement(indexMap, fieldValues, null); - } else if (firstValue instanceof Comparable) { - NitriteMap> indexMap - = getCompoundIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), firstValue.getClass()); - - removeCompoundIndexElement(indexMap, fieldValues, (Comparable) firstValue); - } else if (firstValue.getClass().isArray()) { - Object[] array = convertToObjectArray(firstValue); - NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - - for (Object item : array) { - removeCompoundIndexElement(indexMap, fieldValues, (Comparable) item); - } - } else if (firstValue instanceof Iterable) { - Iterable iterable = (Iterable) firstValue; - NitriteMap> indexMap = getCompoundIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), getElementType(iterable)); - - for (Object item : iterable) { - removeCompoundIndexElement(indexMap, fieldValues, (Comparable) item); - } - } - } - - private void removeSimpleIndexEntry(IndexDescriptor indexDescriptor, - FieldValues fieldValues, - NitriteConfig nitriteConfig) { - Fields fields = fieldValues.getFields(); - FieldNames fieldNames = fields.getFieldNames(); - - String firstField = fieldNames.get(0); - Object element = fieldValues.get(firstField); - - if (element == null) { - NitriteMap> indexMap - = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), UnknownType.class); - - removeSimpleIndexElement(indexMap, fieldValues, null); - } else if (element instanceof Comparable) { - NitriteMap> indexMap - = getSimpleIndexMap(indexDescriptor, nitriteConfig.getNitriteStore(), element.getClass()); - - removeSimpleIndexElement(indexMap, fieldValues, (Comparable) element); - } else if (element.getClass().isArray()) { - Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), array.getClass().getComponentType()); - - for (Object item : array) { - removeSimpleIndexElement(indexMap, fieldValues, (Comparable) item); - } - } else if (element instanceof Iterable) { - Iterable iterable = (Iterable) element; - NitriteMap> indexMap = getSimpleIndexMap(indexDescriptor, - nitriteConfig.getNitriteStore(), getElementType(iterable)); - - for (Object item : iterable) { - removeSimpleIndexElement(indexMap, fieldValues, (Comparable) item); - } - } - } - - @SuppressWarnings("unchecked") - private void removeSimpleIndexElement(NitriteMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableSet nitriteIds = (NavigableSet) indexMap.get(element); - if (nitriteIds != null && !nitriteIds.isEmpty()) { - nitriteIds.remove(fieldValues.getNitriteId()); - if (nitriteIds.size() == 0) { - indexMap.remove(element); - } else { - indexMap.put(element, nitriteIds); - } - } - } - - private void removeCompoundIndexElement(NitriteMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableMap subMap = indexMap.get(element); - if (subMap != null && !subMap.isEmpty()) { - deleteFromSubMap(subMap, fieldValues, 1); - indexMap.put(element, subMap); - } - } - - @SuppressWarnings("unchecked") - private void deleteFromSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { - for (int i = startIndex; i < fieldValues.getValues().size(); i++) { - Pair pair = fieldValues.getValues().get(i); - Object value = pair.getSecond(); - if (value == null) { - value = DBNull.getInstance(); - } - - if (!(value instanceof Comparable)) { - continue; - } - - if (i == fieldValues.getValues().size() - 1) { - NavigableSet nitriteIds = (NavigableSet) subMap.get(value); - nitriteIds = removeNitriteIds(nitriteIds, fieldValues); - if (nitriteIds == null || nitriteIds.isEmpty()) { - subMap.remove(value); - } else { - subMap.put(value, nitriteIds); - } - } else { - NavigableMap subMap2 = (NavigableMap) subMap.get(value); - if (subMap2 == null) { - continue; - } - - deleteFromSubMap(subMap2, fieldValues, startIndex + 1); - subMap.put(value, subMap2); - } - } + @Override + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + NitriteIndex nitriteIndex = findNitriteIndex(indexDescriptor, nitriteConfig); + nitriteIndex.drop(); } - private NavigableSet removeNitriteIds(NavigableSet nitriteIds, FieldValues fieldValues) { - if (nitriteIds != null && !nitriteIds.isEmpty()) { - nitriteIds.remove(fieldValues.getNitriteId()); + private NitriteIndex findNitriteIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + if (indexRegistry.containsKey(indexDescriptor)) { + return indexRegistry.get(indexDescriptor); } - return nitriteIds; - } - private void validateIndexField(Object value, String field) { - if (value == null) return; - if (value instanceof Iterable) { - validateIterableIndexField((Iterable) value, field); - } else if (value.getClass().isArray()) { - validateArrayIndexField(value, field); + NitriteIndex nitriteIndex; + if (indexDescriptor.isCompoundIndex()) { + nitriteIndex = new CompoundIndex(indexDescriptor, nitriteConfig.getNitriteStore()); } else { - if (!(value instanceof Comparable)) { - throw new ValidationException(value + " is not comparable"); - } + nitriteIndex = new SingleFieldIndex(indexDescriptor, nitriteConfig.getNitriteStore()); } - } - - //endregion - - private NitriteMap findSuitableIndexMap(IndexDescriptor descriptor, - FieldValues fieldValues, - NitriteStore nitriteStore) { - // get all indices of a collection - // find the suitable index (prefix included) - // find the index map - // get value by prefix using filter (if compound) - // get value by filter (if simple) - return null; + indexRegistry.put(indexDescriptor, nitriteIndex); + return nitriteIndex; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java new file mode 100644 index 000000000..a3b0e6a77 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.Getter; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.*; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.filters.ComparableFilter; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; + +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; +import static org.dizitart.no2.common.util.Iterables.getElementType; +import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; + +/** + * Represents a nitrite compound index. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class CompoundIndex implements NitriteIndex { + @Getter + private final IndexDescriptor indexDescriptor; + private final NitriteStore nitriteStore; + + /** + * Instantiates a new Compound index. + * + * @param indexDescriptor the index descriptor + * @param nitriteStore the nitrite store + */ + public CompoundIndex(IndexDescriptor indexDescriptor, NitriteStore nitriteStore) { + this.indexDescriptor = indexDescriptor; + this.nitriteStore = nitriteStore; + } + + public void write(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object firstValue = fieldValues.get(firstField); + + // NOTE: only first field can have array or iterable value, subsequent fields can not + validateIndexField(firstValue, firstField); + + if (firstValue == null) { + NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + + addIndexElement(indexMap, fieldValues, null); + } else if (firstValue instanceof Comparable) { + NitriteMap, NavigableMap> indexMap = findIndexMap(firstValue.getClass()); + + addIndexElement(indexMap, fieldValues, (Comparable) firstValue); + } else if (firstValue.getClass().isArray()) { + Object[] array = convertToObjectArray(firstValue); + NitriteMap, NavigableMap> indexMap = findIndexMap(array.getClass().getComponentType()); + + for (Object item : array) { + addIndexElement(indexMap, fieldValues, (Comparable) item); + } + } else if (firstValue instanceof Iterable) { + Iterable iterable = (Iterable) firstValue; + NitriteMap, NavigableMap> indexMap = findIndexMap(getElementType(iterable)); + + for (Object item : iterable) { + addIndexElement(indexMap, fieldValues, (Comparable) item); + } + } + } + + @Override + public void remove(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object firstValue = fieldValues.get(firstField); + + // NOTE: only first field can have array or iterable value, subsequent fields can not + validateIndexField(firstValue, firstField); + + if (firstValue == null) { + NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + + removeIndexElement(indexMap, fieldValues, null); + } else if (firstValue instanceof Comparable) { + NitriteMap, NavigableMap> indexMap = findIndexMap(firstValue.getClass()); + + removeIndexElement(indexMap, fieldValues, (Comparable) firstValue); + } else if (firstValue.getClass().isArray()) { + Object[] array = convertToObjectArray(firstValue); + NitriteMap, NavigableMap> indexMap = findIndexMap(array.getClass().getComponentType()); + + for (Object item : array) { + removeIndexElement(indexMap, fieldValues, (Comparable) item); + } + } else if (firstValue instanceof Iterable) { + Iterable iterable = (Iterable) firstValue; + NitriteMap, NavigableMap> indexMap = findIndexMap(getElementType(iterable)); + + for (Object item : iterable) { + removeIndexElement(indexMap, fieldValues, (Comparable) item); + } + } + } + + @Override + public void drop() { + NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + indexMap.clear(); + indexMap.drop(); + } + + @Override + public LinkedHashSet findNitriteIds(FindPlan findPlan) { + if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); + + NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + return scanIndex(findPlan, indexMap); + } + + private void addIndexElement(NitriteMap, NavigableMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableMap subMap = indexMap.get(element); + if (subMap == null) { + // index are always in ascending order + subMap = new ConcurrentSkipListMap<>(); + } + + populateSubMap(subMap, fieldValues, 1); + indexMap.put(element, subMap); + } + + private void removeIndexElement(NitriteMap, NavigableMap> indexMap, + FieldValues fieldValues, Comparable element) { + NavigableMap subMap = indexMap.get(element); + if (subMap != null && !subMap.isEmpty()) { + deleteFromSubMap(subMap, fieldValues, 1); + indexMap.put(element, subMap); + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private void populateSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { + for (int i = startIndex; i < fieldValues.getValues().size(); i++) { + Pair pair = fieldValues.getValues().get(i); + Object value = pair.getSecond(); + if (value == null) { + value = DBNull.getInstance(); + } + + if (!(value instanceof Comparable)) { + throw new IndexingException(value + " is not comparable"); + } + + if (i == fieldValues.getValues().size() - 1) { + List nitriteIds = (List) subMap.get(value); + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + subMap.put(value, nitriteIds); + } else { + NavigableMap subMap2 = (NavigableMap) subMap.get(value); + if (subMap2 == null) { + // index are always in ascending order + subMap2 = new ConcurrentSkipListMap<>(); + } + + populateSubMap(subMap2, fieldValues, startIndex + 1); + subMap.put(value, subMap2); + } + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private void deleteFromSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { + for (int i = startIndex; i < fieldValues.getValues().size(); i++) { + Pair pair = fieldValues.getValues().get(i); + Object value = pair.getSecond(); + if (value == null) { + value = DBNull.getInstance(); + } + + if (!(value instanceof Comparable)) { + continue; + } + + if (i == fieldValues.getValues().size() - 1) { + List nitriteIds = (List) subMap.get(value); + nitriteIds = removeNitriteIds(nitriteIds, fieldValues); + if (nitriteIds == null || nitriteIds.isEmpty()) { + subMap.remove(value); + } else { + subMap.put(value, nitriteIds); + } + } else { + NavigableMap subMap2 = (NavigableMap) subMap.get(value); + if (subMap2 == null) { + continue; + } + + deleteFromSubMap(subMap2, fieldValues, startIndex + 1); + subMap.put(value, subMap2); + } + } + } + + private NitriteMap, NavigableMap> findIndexMap(Class keyType) { + String mapName = deriveIndexMapName(indexDescriptor); + return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListMap.class); + } + + @SuppressWarnings("unchecked") + private LinkedHashSet scanIndex(FindPlan findPlan, + NitriteMap, NavigableMap> indexMap) { + // linked-hash-set to return only unique ids preserving the order in index + LinkedHashSet nitriteIds = new LinkedHashSet<>(); + List filters = findPlan.getIndexScanFilter().getFilters(); + + if (filters != null && !filters.isEmpty()) { + Object scanResult = indexMap; + for (Filter filter : filters) { + if (scanResult == null) { + // invalid scanning state + break; + } + + if (filter instanceof ComparableFilter) { + ComparableFilter comparableFilter = (ComparableFilter) filter; + // filter can consume nitrite-map or sub-map + // filter can return list of nitrite-id or sub-map + + IndexScanner indexScanner = null; + boolean reverseScan = findPlan.getIndexScanOrder().get(comparableFilter.getField()); + if (scanResult instanceof NitriteMap) { + indexScanner = new IndexScanner((NitriteMap, ?>) scanResult); + } else if (scanResult instanceof NavigableMap) { + indexScanner = new IndexScanner((NavigableMap, ?>) scanResult); + } + + if (indexScanner != null) { + indexScanner.setReverseScan(reverseScan); + scanResult = comparableFilter.applyOnIndex(indexScanner); + } + } else { + throw new FilterException("index scan is not supported for " + filter.getClass().getName()); + } + } + + // final result of last filter can be a navigable map or list + if (scanResult instanceof List) { + // for linked list take the nitrite-ids maintaining the insertion order + List terminalResult = (List) scanResult; + nitriteIds.addAll(terminalResult); + } else if (scanResult instanceof NavigableMap) { + // if filter is a covered query but index still have some extra field, + // then the return type of last filter will be a navigable-map + // we need to traverse the rest of the data and collect all + // terminal nitrite-ids preserving the insertion order + NavigableMap subMap = (NavigableMap) scanResult; + + // collection all terminal nitrite-ids + List terminalResult = getTerminalNitriteIds(subMap); + nitriteIds.addAll(terminalResult); + } else { + throw new FilterException("invalid result state after index scan"); + } + } + return nitriteIds; + } + + + @SuppressWarnings("unchecked") + private List getTerminalNitriteIds(NavigableMap navigableMap) { + List terminalResult = new ArrayList<>(); + + // scan each entry of th navigable map and collect all terminal nitrite-ids + for (Map.Entry entry : navigableMap.entrySet()) { + // if the value is terminal, collect all nitrite-ids + if (entry.getValue() instanceof List) { + List nitriteIds = (List) entry.getValue(); + terminalResult.addAll(nitriteIds); + } + + // if the value is not terminal, scan recursively + if (entry.getValue() instanceof NavigableMap) { + NavigableMap subMap = (NavigableMap) entry.getValue(); + List nitriteIds = getTerminalNitriteIds(subMap); + terminalResult.addAll(nitriteIds); + } + } + return terminalResult; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index 2c2eb368f..8bf655375 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -16,8 +16,10 @@ package org.dizitart.no2.index; -import lombok.*; -import org.dizitart.no2.collection.NitriteCollection; +import lombok.AccessLevel; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; import org.dizitart.no2.common.Fields; import java.io.IOException; @@ -32,8 +34,6 @@ * Represents a nitrite database index. * * @author Anindya Chatterjee - * @see NitriteCollection#createIndex(String, IndexOptions) - * @see NitriteCollection#createIndex(Fields, IndexOptions) * @since 1.0 */ @Data diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexOptions.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexOptions.java index a0201c0d5..75bf1d6b6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexOptions.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexOptions.java @@ -19,13 +19,11 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; -import org.dizitart.no2.collection.NitriteCollection; /** * Represents options to apply while creating an index. * * @author Anindya Chatterjee - * @see NitriteCollection#createIndex(String, IndexOptions) * @since 1.0 */ @EqualsAndHashCode @@ -41,20 +39,6 @@ public class IndexOptions { @Setter private String indexType; - /** - * Indicates whether an index to be created in a non-blocking - * way. - * - * @param async if set to `true` then the index will be created asynchronously; - * otherwise create index operation will wait until all existing - * documents are indexed. - * @return `true` if index is to be created asynchronously; otherwise `false`. - * @see NitriteCollection#createIndex(String, IndexOptions) - */ - @Getter - @Setter - private boolean async = false; - /** * Creates an {@link IndexOptions} with the specified `indexType`. Index creation * will be synchronous with this option. @@ -63,21 +47,8 @@ public class IndexOptions { * @return a new synchronous index creation option. */ public static IndexOptions indexOptions(String indexType) { - return indexOptions(indexType, false); - } - - /** - * Creates an {@link IndexOptions} with the specified `indexType` and `async` flag. - * - * @param indexType the type of index to be created. - * @param async if set to `true` then the index would be created asynchronously; - * otherwise synchronously. - * @return a new index creation option. - */ - public static IndexOptions indexOptions(String indexType, boolean async) { IndexOptions options = new IndexOptions(); options.setIndexType(indexType); - options.setAsync(async); return options; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java new file mode 100644 index 000000000..59271daee --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.Getter; +import lombok.Setter; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.store.NitriteMap; + +import java.util.Iterator; +import java.util.Map; +import java.util.NavigableMap; + +/** + * Represents an index scanner during find operation. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +@SuppressWarnings("unchecked") +public class IndexScanner { + private NitriteMap, ?> nitriteMap; + private NavigableMap, ?> navigableMap; + + @Getter + @Setter + private boolean reverseScan; + + /** + * Instantiates a new Index scanner. + * + * @param nitriteMap the nitrite map + */ + public IndexScanner(NitriteMap, ?> nitriteMap) { + this.nitriteMap = nitriteMap; + } + + /** + * Instantiates a new Index scanner. + * + * @param navigableMap the navigable map + */ + public IndexScanner(NavigableMap, ?> navigableMap) { + this.navigableMap = navigableMap; + } + + /** + * Get the largest key that is smaller than the given key, or null if no + * such key exists. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T lowerKey(T key) { + if (!reverseScan) { + if (nitriteMap != null) { + return (T) nitriteMap.lowerKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.lowerKey(key); + } + } else { + if (nitriteMap != null) { + return (T) nitriteMap.higherKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.higherKey(key); + } + } + return null; + } + + /** + * Get the smallest key that is larger than the given key, or null if no + * such key exists. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T higherKey(T key) { + if (!reverseScan) { + if (nitriteMap != null) { + return (T) nitriteMap.higherKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.higherKey(key); + } + } else { + if (nitriteMap != null) { + return (T) nitriteMap.lowerKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.lowerKey(key); + } + } + return null; + } + + /** + * Get the smallest key that is larger or equal to this key. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T ceilingKey(T key) { + if (!reverseScan) { + if (nitriteMap != null) { + return (T) nitriteMap.ceilingKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.ceilingKey(key); + } + } else { + if (nitriteMap != null) { + return (T) nitriteMap.floorKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.floorKey(key); + } + } + return null; + } + + /** + * Get the largest key that is smaller or equal to this key. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T floorKey(T key) { + if (!reverseScan) { + if (nitriteMap != null) { + return (T) nitriteMap.floorKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.floorKey(key); + } + } else { + if (nitriteMap != null) { + return (T) nitriteMap.ceilingKey(key); + } else if (navigableMap != null) { + return (T) navigableMap.ceilingKey(key); + } + } + return null; + } + + /** + * Gets the value mapped with the specified key or null otherwise. + * + * @param comparable the comparable + * @return the object + */ + public Object get(Comparable comparable) { + if (nitriteMap != null) { + return nitriteMap.get(comparable); + } else if (navigableMap != null) { + return navigableMap.get(comparable); + } + return null; + } + + /** + * Returns the iterable entries of the indexed items. + * + * @return the iterable + */ + public Iterable, ?>> entries() { + if (nitriteMap != null) { + if (!reverseScan) { + return nitriteMap.entries(); + } else { + return nitriteMap.reversedEntries(); + } + } else if (navigableMap != null) { + Iterator, ?>> entryIterator; + if (reverseScan) { + entryIterator = navigableMap.descendingMap().entrySet().iterator(); + } else { + entryIterator = navigableMap.entrySet().iterator(); + } + + return (Iterable, ?>>) () -> new Iterator, ?>>() { + @Override + public boolean hasNext() { + return entryIterator.hasNext(); + } + + @Override + public Pair, ?> next() { + Map.Entry, ?> entry = entryIterator.next(); + return Pair.pair(entry.getKey(), entry.getValue()); + } + }; + } + return null; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexType.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexType.java index bd6431854..3b684efa5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexType.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexType.java @@ -17,10 +17,24 @@ package org.dizitart.no2.index; /** + * Represents a type of nitrite index. + * * @author Anindya Chatterjee + * @since 4.0 */ public interface IndexType { + /** + * A unique index. + */ String Unique = "Unique"; + + /** + * A non-unique index. + */ String NonUnique = "NonUnique"; + + /** + * A nitrite full-text index. + */ String Fulltext = "Fulltext"; } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndex.java new file mode 100644 index 000000000..de0557be1 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndex.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.exceptions.ValidationException; + +import java.util.*; + +import static org.dizitart.no2.common.util.ValidationUtils.validateArrayIndexField; +import static org.dizitart.no2.common.util.ValidationUtils.validateIterableIndexField; + +/** + * Represents a nitrite index. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public interface NitriteIndex { + /** + * Gets index descriptor. + * + * @return the index descriptor + */ + IndexDescriptor getIndexDescriptor(); + + /** + * Writes a {@link FieldValues} in the index. + * + * @param fieldValues the field values + */ + void write(FieldValues fieldValues); + + /** + * Removes a {@link FieldValues} from the index. + * + * @param fieldValues the field values + */ + void remove(FieldValues fieldValues); + + /** + * Drops this index. + */ + void drop(); + + /** + * Finds a set of {@link NitriteId}s from the index after executing the {@link FindPlan}. + * + * @param findPlan the find plan + * @return the linked hash set + */ + LinkedHashSet findNitriteIds(FindPlan findPlan); + + /** + * Indicates if this is an unique index. + * + * @return the boolean + */ + default boolean isUnique() { + return getIndexDescriptor().getIndexType().equalsIgnoreCase(IndexType.Unique); + } + + /** + * Validates the index field. + * + * @param value the value + * @param field the field + */ + default void validateIndexField(Object value, String field) { + if (value == null) return; + if (value instanceof Iterable) { + validateIterableIndexField((Iterable) value, field); + } else if (value.getClass().isArray()) { + validateArrayIndexField(value, field); + } else { + if (!(value instanceof Comparable)) { + throw new ValidationException(value + " is not comparable"); + } + } + } + + /** + * Adds a {@link NitriteId} of the {@link FieldValues} to the existing indexed list of {@link NitriteId}s. + * + * @param nitriteIds the nitrite ids + * @param fieldValues the field values + * @return the list + */ + default List addNitriteIds(List nitriteIds, FieldValues fieldValues) { + if (nitriteIds == null) { + nitriteIds = new ArrayList<>(); + } + + if (isUnique() && nitriteIds.size() == 1 + && !nitriteIds.contains(fieldValues.getNitriteId())) { + // if key is already exists for unique type, throw error + throw new UniqueConstraintException("unique key constraint violation for " + fieldValues.getFields()); + } + + // index always are in ascending format + nitriteIds.add(fieldValues.getNitriteId()); + return nitriteIds; + } + + /** + * Removes a {@link NitriteId} of the {@link FieldValues} from the existing indexed list of {@link NitriteId}s. + * + * @param nitriteIds the nitrite ids + * @param fieldValues the field values + * @return the list + */ + default List removeNitriteIds(List nitriteIds, FieldValues fieldValues) { + if (nitriteIds != null && !nitriteIds.isEmpty()) { + nitriteIds.remove(fieldValues.getNitriteId()); + } + return nitriteIds; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java index d77b279ac..607906a82 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java @@ -17,23 +17,67 @@ package org.dizitart.no2.index; import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.module.NitritePlugin; +import java.util.LinkedHashSet; + /** + * Represents an indexer for creating a nitrite index. + * * @author Anindya Chatterjee. + * @since 4.0 */ public interface NitriteIndexer extends NitritePlugin { + /** + * Gets the index type. + * + * @return the index type + */ String getIndexType(); + /** + * Validates an index on the fields. + * + * @param fields the fields + */ + void validateIndex(Fields fields); + + /** + * Drops the index specified by the index descriptor. + * + * @param indexDescriptor the index descriptor + * @param nitriteConfig the nitrite config + */ void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig); - void writeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig); + /** + * Writes an index entry. + * + * @param fieldValues the field values + * @param indexDescriptor the index descriptor + * @param nitriteConfig the nitrite config + */ + void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig); - void removeIndexEntry(IndexDescriptor indexDescriptor, FieldValues fieldValues, NitriteConfig nitriteConfig); + /** + * Removes an index entry. + * + * @param fieldValues the field values + * @param indexDescriptor the index descriptor + * @param nitriteConfig the nitrite config + */ + void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig); - RecordStream findByFilter(String collectionName, Filter filter, NitriteConfig nitriteConfig); + /** + * Finds a list of {@link NitriteId} after executing the {@link FindPlan} on the index. + * + * @param findPlan the find plan + * @param nitriteConfig the nitrite config + * @return the linked hash set + */ + LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig); } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java index 99808fe90..de5a66a18 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java @@ -17,44 +17,48 @@ package org.dizitart.no2.index; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.fulltext.EnglishTextTokenizer; import org.dizitart.no2.index.fulltext.TextTokenizer; -import org.dizitart.no2.store.IndexCatalog; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListSet; - -import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; -import static org.dizitart.no2.common.util.StringUtils.stringTokenizer; -import static org.dizitart.no2.common.util.ValidationUtils.*; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** + * Represents a nitrite text indexer. + * * @author Anindya Chatterjee + * @since 4.0 */ -@SuppressWarnings("rawtypes") -public class NitriteTextIndexer implements TextIndexer { +public class NitriteTextIndexer implements NitriteIndexer { private final TextTokenizer textTokenizer; - private NitriteStore nitriteStore; + private final Map indexRegistry; + /** + * Instantiates a new {@link NitriteTextIndexer}. + */ public NitriteTextIndexer() { this.textTokenizer = new EnglishTextTokenizer(); + this.indexRegistry = new ConcurrentHashMap<>(); } + /** + * Instantiates a new {@link NitriteTextIndexer}. + * + * @param textTokenizer the text tokenizer + */ public NitriteTextIndexer(TextTokenizer textTokenizer) { this.textTokenizer = textTokenizer; + this.indexRegistry = new ConcurrentHashMap<>(); } - public NitriteTextIndexer clone() throws CloneNotSupportedException { - return (NitriteTextIndexer) super.clone(); + @Override + public void initialize(NitriteConfig nitriteConfig) { } @Override @@ -63,246 +67,43 @@ public String getIndexType() { } @Override - public Set findText(String collectionName, String field, String searchString) { - notNull(field, "field cannot be null"); - notNull(searchString, "search term cannot be null"); - - try { - if (searchString.startsWith("*") || searchString.endsWith("*")) { - return searchByWildCard(collectionName, field, searchString); - } else { - return searchExactByIndex(collectionName, field, searchString); - } - } catch (IOException ioe) { - throw new IndexingException("could not search on full-text index", ioe); + public void validateIndex(Fields fields) { + if (fields.getFieldNames().size() > 1) { + throw new IndexingException("text index can only be created on a single field"); } } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - createOrUpdate(collection, nitriteId, field, fieldValue); + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + TextIndex textIndex = findTextIndex(indexDescriptor, nitriteConfig); + textIndex.drop(); } @Override - @SuppressWarnings("unchecked") - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - try { - validateStringValue(fieldValue, field); - Set words = decompose(fieldValue); - - NitriteMap indexMap - = getIndexMap(collection.getName(), field); - - for (String word : words) { - ConcurrentSkipListSet nitriteIds = (ConcurrentSkipListSet) indexMap.get(word); - if (nitriteIds != null) { - nitriteIds.remove(nitriteId); - - if (nitriteIds.isEmpty()) { - indexMap.remove(word); - } else { - indexMap.put(word, nitriteIds); - } - } - } - } catch (IOException ioe) { - throw new IndexingException("failed to remove full-text index data for " + field + " with id " + nitriteId); - } - } - - @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { - removeIndex(collection, nitriteId, field, oldValue); - createOrUpdate(collection, nitriteId, field, newValue); + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + TextIndex textIndex = findTextIndex(indexDescriptor, nitriteConfig); + textIndex.write(fieldValues); } @Override - public void dropIndex(NitriteMap collection, Fields field) { - indexCatalog.dropIndexDescriptor(collection.getName(), field); + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + TextIndex textIndex = findTextIndex(indexDescriptor, nitriteConfig); + textIndex.remove(fieldValues); } @Override - public void initialize(NitriteConfig nitriteConfig) { - this.nitriteStore = nitriteConfig.getNitriteStore(); - this.indexCatalog = this.nitriteStore.getIndexCatalog(); - } - - @SuppressWarnings("rawtypes") - private NitriteMap getIndexMap(String collectionName, String field) { - String mapName = getIndexMapName(collectionName, field); - return nitriteStore.openMap(mapName, String.class, ConcurrentSkipListSet.class); - } - - private void validateStringValue(Object value, String field) { - if (value == null || value instanceof String) return; - - if (value instanceof Iterable) { - validateStringIterableIndexField((Iterable) value, field); - } else if (value.getClass().isArray()) { - validateStringArrayIndexField(value, field); - } else { - throw new IndexingException("string data is expected"); - } - } - - @SuppressWarnings("unchecked") - private void createOrUpdate(NitriteMap collection, NitriteId id, String field, Object fieldValue) { - try { - validateStringValue(fieldValue, field); - Set words = decompose(fieldValue); - - NitriteMap indexMap - = getIndexMap(collection.getName(), field); - - for (String word : words) { - ConcurrentSkipListSet nitriteIds = (ConcurrentSkipListSet) indexMap.get(word); - - if (nitriteIds == null) { - nitriteIds = new ConcurrentSkipListSet<>(); - } - nitriteIds.add(id); - indexMap.put(word, nitriteIds); - } - } catch (IOException ioe) { - throw new IndexingException("could not write full-text index data for " + fieldValue, ioe); - } - } - - private Set decompose(Object fieldValue) throws IOException { - Set result = new HashSet<>(); - if (fieldValue == null) { - result.add(null); - } else if (fieldValue instanceof String) { - result.add((String) fieldValue); - } else if (fieldValue instanceof Iterable) { - Iterable iterable = (Iterable) fieldValue; - for (Object item : iterable) { - result.addAll(decompose(item)); - } - } else if (fieldValue.getClass().isArray()) { - Object[] array = convertToObjectArray(fieldValue); - for (Object item : array) { - result.addAll(decompose(item)); - } - } - - Set words = new HashSet<>(); - for (String item : result) { - words.addAll(textTokenizer.tokenize(item)); - } - - return words; - } - - private Set searchByWildCard(String collectionName, String field, String searchString) { - if (searchString.contentEquals("*")) { - throw new FilterException("* is not a valid search string"); - } - - StringTokenizer stringTokenizer = stringTokenizer(searchString); - if (stringTokenizer.countTokens() > 1) { - throw new FilterException("multiple words with wildcard is not supported"); - } - - if (searchString.startsWith("*") && !searchString.endsWith("*")) { - return searchByLeadingWildCard(collectionName, field, searchString); - } else if (searchString.endsWith("*") && !searchString.startsWith("*")) { - return searchByTrailingWildCard(collectionName, field, searchString); - } else { - String term = searchString.substring(1, searchString.length() - 1); - return searchContains(collectionName, field, term); - } - } - - @SuppressWarnings("unchecked") - private Set searchByTrailingWildCard(String collectionName, String field, String searchString) { - if (searchString.equalsIgnoreCase("*")) { - throw new FilterException("invalid search term '*'"); - } - - NitriteMap indexMap - = getIndexMap(collectionName, field); - Set idSet = new LinkedHashSet<>(); - String term = searchString.substring(0, searchString.length() - 1); - - for (Pair entry : indexMap.entries()) { - String key = (String) entry.getFirst(); - if (key.startsWith(term.toLowerCase())) { - idSet.addAll((ConcurrentSkipListSet) entry.getSecond()); - } - } - return idSet; - } - - @SuppressWarnings("unchecked") - private Set searchContains(String collectionName, String field, String term) { - NitriteMap indexMap - = getIndexMap(collectionName, field); - Set idSet = new LinkedHashSet<>(); - - for (Pair entry : indexMap.entries()) { - String key = (String) entry.getFirst(); - if (key.contains(term.toLowerCase())) { - idSet.addAll((ConcurrentSkipListSet) entry.getSecond()); - } - } - return idSet; + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { + TextIndex textIndex = findTextIndex(findPlan.getIndexDescriptor(), nitriteConfig); + return textIndex.findNitriteIds(findPlan); } - @SuppressWarnings("unchecked") - private Set searchByLeadingWildCard(String collectionName, String field, String searchString) { - if (searchString.equalsIgnoreCase("*")) { - throw new FilterException("invalid search term '*'"); - } - - NitriteMap indexMap - = getIndexMap(collectionName, field); - Set idSet = new LinkedHashSet<>(); - String term = searchString.substring(1); - - for (Pair entry : indexMap.entries()) { - String key = (String) entry.getFirst(); - if (key.endsWith(term.toLowerCase())) { - idSet.addAll((ConcurrentSkipListSet) entry.getSecond()); - } - } - return idSet; - } - - @SuppressWarnings("unchecked") - private Set searchExactByIndex(String collectionName, String field, String searchString) throws IOException { - NitriteMap indexMap - = getIndexMap(collectionName, field); - - Set words = textTokenizer.tokenize(searchString); - Map scoreMap = new HashMap<>(); - for (String word : words) { - ConcurrentSkipListSet nitriteIds = (ConcurrentSkipListSet) indexMap.get(word); - if (nitriteIds != null) { - for (NitriteId id : nitriteIds) { - Integer score = scoreMap.get(id); - if (score == null) { - scoreMap.put(id, 1); - } else { - scoreMap.put(id, score + 1); - } - } - } - } - - Map sortedScoreMap = sortByScore(scoreMap); - return sortedScoreMap.keySet(); - } - - private > Map sortByScore(Map unsortedMap) { - List> list = new LinkedList<>(unsortedMap.entrySet()); - Collections.sort(list, (e1, e2) -> (e2.getValue()).compareTo(e1.getValue())); - - Map result = new LinkedHashMap<>(); - for (Map.Entry entry : list) { - result.put(entry.getKey(), entry.getValue()); + private TextIndex findTextIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + if (indexRegistry.containsKey(indexDescriptor)) { + return indexRegistry.get(indexDescriptor); } - return result; + TextIndex textIndex = new TextIndex(textTokenizer, indexDescriptor, nitriteConfig.getNitriteStore()); + indexRegistry.put(indexDescriptor, textIndex); + return textIndex; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java index d4d171dd6..f5bd096ed 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java @@ -17,7 +17,10 @@ package org.dizitart.no2.index; /** + * Represents a non unique indexer. + * * @author Anindya Chatterjee + * @since 4.0 */ public final class NonUniqueIndexer extends ComparableIndexer { diff --git a/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java new file mode 100644 index 000000000..47748b6f1 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.Getter; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.UnknownType; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.filters.ComparableFilter; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; + +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; +import static org.dizitart.no2.common.util.Iterables.getElementType; +import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; + +/** + * Represents a nitrite index on a single field. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class SingleFieldIndex implements NitriteIndex { + @Getter + private final IndexDescriptor indexDescriptor; + private final NitriteStore nitriteStore; + + /** + * Instantiates a new {@link SingleFieldIndex}. + * + * @param indexDescriptor the index descriptor + * @param nitriteStore the nitrite store + */ + public SingleFieldIndex(IndexDescriptor indexDescriptor, NitriteStore nitriteStore) { + this.indexDescriptor = indexDescriptor; + this.nitriteStore = nitriteStore; + } + + @Override + public void write(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + if (element == null) { + NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + + addIndexElement(indexMap, fieldValues, null); + } else if (element instanceof Comparable) { + NitriteMap, List> indexMap = findIndexMap(element.getClass()); + + addIndexElement(indexMap, fieldValues, (Comparable) element); + } else if (element.getClass().isArray()) { + Object[] array = convertToObjectArray(element); + NitriteMap, List> indexMap = findIndexMap(array.getClass().getComponentType()); + + for (Object item : array) { + addIndexElement(indexMap, fieldValues, (Comparable) item); + } + } else if (element instanceof Iterable) { + Iterable iterable = (Iterable) element; + NitriteMap, List> indexMap = findIndexMap(getElementType(iterable)); + + for (Object item : iterable) { + addIndexElement(indexMap, fieldValues, (Comparable) item); + } + } + } + + @Override + public void remove(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + if (element == null) { + NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + + removeIndexElement(indexMap, fieldValues, null); + } else if (element instanceof Comparable) { + NitriteMap, List> indexMap = findIndexMap(element.getClass()); + + removeIndexElement(indexMap, fieldValues, (Comparable) element); + } else if (element.getClass().isArray()) { + Object[] array = convertToObjectArray(element); + NitriteMap, List> indexMap = findIndexMap(array.getClass().getComponentType()); + + for (Object item : array) { + removeIndexElement(indexMap, fieldValues, (Comparable) item); + } + } else if (element instanceof Iterable) { + Iterable iterable = (Iterable) element; + NitriteMap, List> indexMap = findIndexMap(getElementType(iterable)); + + for (Object item : iterable) { + removeIndexElement(indexMap, fieldValues, (Comparable) item); + } + } + } + + @Override + public void drop() { + NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + indexMap.clear(); + indexMap.drop(); + } + + @Override + public LinkedHashSet findNitriteIds(FindPlan findPlan) { + if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); + + NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + return scanIndex(findPlan, indexMap); + } + + @SuppressWarnings("unchecked") + private void addIndexElement(NitriteMap, List> indexMap, + FieldValues fieldValues, Comparable element) { + List nitriteIds = (List) indexMap.get(element); + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + indexMap.put(element, nitriteIds); + } + + @SuppressWarnings("unchecked") + private void removeIndexElement(NitriteMap, List> indexMap, + FieldValues fieldValues, Comparable element) { + List nitriteIds = (List) indexMap.get(element); + if (nitriteIds != null && !nitriteIds.isEmpty()) { + nitriteIds.remove(fieldValues.getNitriteId()); + if (nitriteIds.size() == 0) { + indexMap.remove(element); + } else { + indexMap.put(element, nitriteIds); + } + } + } + + private NitriteMap, List> findIndexMap(Class keyType) { + String mapName = deriveIndexMapName(indexDescriptor); + return nitriteStore.openMap(mapName, keyType, ArrayList.class); + } + + @SuppressWarnings("unchecked") + private LinkedHashSet scanIndex(FindPlan findPlan, + NitriteMap, List> indexMap) { + // linked-hash-set to return only unique ids preserving the order in index + LinkedHashSet nitriteIds = new LinkedHashSet<>(); + List filters = findPlan.getIndexScanFilter().getFilters(); + + if (filters != null && filters.size() == 1) { + Filter filter = filters.get(0); + if (filter instanceof ComparableFilter) { + ComparableFilter comparableFilter = (ComparableFilter) filter; + // filter will return a list of nitrite-ids + + IndexScanner indexScanner = new IndexScanner(indexMap); + boolean reverseScan = findPlan.getIndexScanOrder().get(comparableFilter.getField()); + indexScanner.setReverseScan(reverseScan); + + Object scanResult = comparableFilter.applyOnIndex(indexScanner); + + if (scanResult instanceof List) { + // for list take the nitrite-ids maintaining the insertion order + List terminalResult = (List) scanResult; + nitriteIds.addAll(terminalResult); + return nitriteIds; + } + } + } + + throw new FilterException("invalid result state after index scan"); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java new file mode 100644 index 000000000..93a9e5021 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.Getter; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.TextFilter; +import org.dizitart.no2.index.fulltext.TextTokenizer; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.NitriteStore; + +import java.util.*; + +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; +import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; +import static org.dizitart.no2.common.util.ValidationUtils.validateStringArrayIndexField; +import static org.dizitart.no2.common.util.ValidationUtils.validateStringIterableIndexField; + +/** + * Represents a nitrite full-text index. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class TextIndex implements NitriteIndex { + @Getter + private final IndexDescriptor indexDescriptor; + private final NitriteStore nitriteStore; + private final TextTokenizer textTokenizer; + + /** + * Instantiates a new {@link TextIndex}. + * + * @param textTokenizer the text tokenizer + * @param indexDescriptor the index descriptor + * @param nitriteStore the nitrite store + */ + public TextIndex(TextTokenizer textTokenizer, + IndexDescriptor indexDescriptor, + NitriteStore nitriteStore) { + this.textTokenizer = textTokenizer; + this.indexDescriptor = indexDescriptor; + this.nitriteStore = nitriteStore; + } + + @Override + public void write(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + if (element == null) { + NitriteMap> indexMap = findIndexMap(); + + addIndexElement(indexMap, fieldValues, null); + } else if (element instanceof String) { + NitriteMap> indexMap = findIndexMap(); + + addIndexElement(indexMap, fieldValues, (String) element); + } else if (element.getClass().isArray()) { + validateStringArrayIndexField(element, firstField); + + Object[] array = convertToObjectArray(element); + NitriteMap> indexMap = findIndexMap(); + + for (Object item : array) { + addIndexElement(indexMap, fieldValues, (String) item); + } + } else if (element instanceof Iterable) { + validateStringIterableIndexField((Iterable) element, firstField); + + Iterable iterable = (Iterable) element; + NitriteMap> indexMap = findIndexMap(); + + for (Object item : iterable) { + addIndexElement(indexMap, fieldValues, (String) item); + } + } else { + throw new IndexingException("string data is expected"); + } + } + + @Override + public void remove(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + if (element == null) { + NitriteMap> indexMap = findIndexMap(); + + removeIndexElement(indexMap, fieldValues, null); + } else if (element instanceof String) { + NitriteMap> indexMap = findIndexMap(); + + removeIndexElement(indexMap, fieldValues, (String) element); + } else if (element.getClass().isArray()) { + validateStringArrayIndexField(element, firstField); + + Object[] array = convertToObjectArray(element); + NitriteMap> indexMap = findIndexMap(); + + for (Object item : array) { + removeIndexElement(indexMap, fieldValues, (String) item); + } + } else if (element instanceof Iterable) { + validateStringIterableIndexField((Iterable) element, firstField); + + Iterable iterable = (Iterable) element; + NitriteMap> indexMap = findIndexMap(); + + for (Object item : iterable) { + removeIndexElement(indexMap, fieldValues, (String) item); + } + } else { + throw new IndexingException("string data is expected"); + } + } + + @Override + public void drop() { + NitriteMap> indexMap = findIndexMap(); + indexMap.clear(); + indexMap.drop(); + } + + @Override + public LinkedHashSet findNitriteIds(FindPlan findPlan) { + if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); + + NitriteMap> indexMap = findIndexMap(); + List filters = findPlan.getIndexScanFilter().getFilters(); + + if (filters.size() == 1 && filters.get(0) instanceof TextFilter) { + TextFilter textFilter = (TextFilter) filters.get(0); + textFilter.setTextTokenizer(textTokenizer); + return textFilter.applyOnIndex(indexMap); + } + throw new FilterException("invalid filter found for full-text index"); + } + + private NitriteMap> findIndexMap() { + String mapName = deriveIndexMapName(indexDescriptor); + return nitriteStore.openMap(mapName, String.class, ArrayList.class); + } + + @SuppressWarnings("unchecked") + private void addIndexElement(NitriteMap> indexMap, FieldValues fieldValues, String value) { + Set words = decompose(value); + + for (String word : words) { + List nitriteIds = (List) indexMap.get(word); + + if (nitriteIds == null) { + nitriteIds = new ArrayList<>(); + } + + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + indexMap.put(value, nitriteIds); + } + } + + @SuppressWarnings("unchecked") + private void removeIndexElement(NitriteMap> indexMap, FieldValues fieldValues, String value) { + Set words = decompose(value); + for (String word : words) { + List nitriteIds = (List) indexMap.get(word); + if (nitriteIds != null && !nitriteIds.isEmpty()) { + nitriteIds.remove(fieldValues.getNitriteId()); + if (nitriteIds.isEmpty()) { + indexMap.remove(word); + } else { + indexMap.put(word, nitriteIds); + } + } + } + } + + private Set decompose(Object fieldValue) { + Set result = new HashSet<>(); + if (fieldValue == null) { + result.add(null); + } else if (fieldValue instanceof String) { + result.add((String) fieldValue); + } else if (fieldValue instanceof Iterable) { + Iterable iterable = (Iterable) fieldValue; + for (Object item : iterable) { + result.addAll(decompose(item)); + } + } else if (fieldValue.getClass().isArray()) { + Object[] array = convertToObjectArray(fieldValue); + for (Object item : array) { + result.addAll(decompose(item)); + } + } + + Set words = new HashSet<>(); + for (String item : result) { + words.addAll(textTokenizer.tokenize(item)); + } + + return words; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java deleted file mode 100644 index a7ba89d43..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/index/TextIndexer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.index; - -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.filters.FluentFilter; - -import java.util.Set; - -/** - * Represents a full-text indexing engine. It scans a document - * and modifies full-text index entries by decomposing texts of - * an indexed field, into a set of string tokens. It uses the - * full-text index to search for a specific text. - * - * @author Anindya Chatterjee - * @see FluentFilter#text(String) - * @since 1.0 - */ -public interface TextIndexer extends NitriteIndexer { - /** - * Finds matching text using full-text index. - * - * @param collectionName collection name - * @param field the value - * @param value the value - * @return the result set - */ - Set findText(String collectionName, String field, String value); -} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java index 6d3d3e9b1..c576b943b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java @@ -17,7 +17,10 @@ package org.dizitart.no2.index; /** + * Represents a nitrite unique indexer. + * * @author Anindya Chatterjee. + * @since 4.0 */ public final class UniqueIndexer extends ComparableIndexer { @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/index/fulltext/TextTokenizer.java b/nitrite/src/main/java/org/dizitart/no2/index/fulltext/TextTokenizer.java index 3610d2cc4..5b7876d5f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/fulltext/TextTokenizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/fulltext/TextTokenizer.java @@ -16,16 +16,12 @@ package org.dizitart.no2.index.fulltext; -import org.dizitart.no2.index.TextIndexer; - -import java.io.IOException; import java.util.Set; /** * A stop-word based string tokenizer. * * @author Anindya Chatterjee. - * @see TextIndexer * @see EnglishTextTokenizer * @since 1.0 */ @@ -43,9 +39,8 @@ public interface TextTokenizer { * * @param text the text to tokenize * @return the set of tokens. - * @throws IOException if a low-level I/O error occurs. */ - Set tokenize(String text) throws IOException; + Set tokenize(String text); /** * Gets all stop-words for a language. diff --git a/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java b/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java index e196bae5a..e0721a290 100644 --- a/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java +++ b/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java @@ -27,36 +27,32 @@ import static org.dizitart.no2.common.util.ObjectUtils.newInstance; /** + * A {@link NitriteMapper} based on {@link Mappable} implementation. + * * @author Anindya Chatterjee. + * @since 4.0 */ public class MappableMapper implements NitriteMapper { private final Set> valueTypes; + /** + * Instantiates a new {@link MappableMapper}. + * + * @param valueTypes the value types + */ public MappableMapper(Class... valueTypes) { this.valueTypes = new HashSet<>(); init(listOf(valueTypes)); } - @Override - @SuppressWarnings("unchecked") - public Target convert(Source source, Class type) { - if (source == null) { - return null; - } - - if (isValue(source)) { - return (Target) source; - } else { - if (Document.class.isAssignableFrom(type)) { - return (Target) convertToDocument(source); - } else if (source instanceof Document) { - return convertFromDocument((Document) source, type); - } - } - - throw new ObjectMappingException("object must implements Mappable"); - } - + /** + * Converts a document to a target object of type Target. + * + * @param the type parameter + * @param source the source + * @param type the type + * @return the target + */ protected Target convertFromDocument(Document source, Class type) { if (source == null) { return null; @@ -73,6 +69,13 @@ protected Target convertFromDocument(Document source, Class typ throw new ObjectMappingException("object must implements Mappable"); } + /** + * Converts an object of type Source to a document. + * + * @param the type parameter + * @param source the source + * @return the document + */ protected Document convertToDocument(Source source) { if (source instanceof Mappable) { Mappable mappable = (Mappable) source; @@ -82,6 +85,35 @@ protected Document convertToDocument(Source source) { throw new ObjectMappingException("object must implements Mappable"); } + /** + * Adds a value type to ignore during mapping. + * + * @param valueType the value type + */ + protected void addValueType(Class valueType) { + this.valueTypes.add(valueType); + } + + @Override + @SuppressWarnings("unchecked") + public Target convert(Source source, Class type) { + if (source == null) { + return null; + } + + if (isValue(source)) { + return (Target) source; + } else { + if (Document.class.isAssignableFrom(type)) { + return (Target) convertToDocument(source); + } else if (source instanceof Document) { + return convertFromDocument((Document) source, type); + } + } + + throw new ObjectMappingException("object must implements Mappable"); + } + @Override public boolean isValueType(Class type) { if (type.isPrimitive() && type != void.class) return true; @@ -102,10 +134,6 @@ public void initialize(NitriteConfig nitriteConfig) { } - protected void addValueType(Class valueType) { - this.valueTypes.add(valueType); - } - private void init(List> valueTypes) { this.valueTypes.add(Number.class); this.valueTypes.add(Boolean.class); diff --git a/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java b/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java index 2a2864c43..8bec0e1d9 100644 --- a/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java +++ b/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java @@ -19,12 +19,36 @@ import org.dizitart.no2.module.NitritePlugin; /** + * Represents a mapper which will convert a object of one type to an object of another type. + * * @author Anindya Chatterjee. + * @since 4.0 */ public interface NitriteMapper extends NitritePlugin { + /** + * Converts an object of type Source to an object of type Target. + * + * @param the type parameter + * @param the type parameter + * @param source the source + * @param type the type + * @return the target + */ Target convert(Source source, Class type); + /** + * Checks if the provided type is registered as a value type. + * + * @param type the type + * @return the boolean + */ boolean isValueType(Class type); + /** + * Checks if an object is of a value type. + * + * @param object the object + * @return the boolean + */ boolean isValue(Object object); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/CollectionInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/CollectionInstruction.java index fbbe24056..edc12009c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/CollectionInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/CollectionInstruction.java @@ -1,12 +1,22 @@ package org.dizitart.no2.migration; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.tuples.Triplet; /** + * Represents a migration instruction set for {@link org.dizitart.no2.collection.NitriteCollection}. + * * @author Anindya Chatterjee + * @since 4.0 */ -public interface CollectionInstruction extends Composable { +public interface CollectionInstruction extends Instruction { + /** + * Adds an instruction to rename a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param name the name + * @return the instruction + */ default CollectionInstruction rename(String name) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionRename); @@ -27,10 +37,25 @@ public void addStep(MigrationStep step) { }; } + /** + * Adds an instruction to add new field to the documents of + * a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param fieldName the field name + * @return the collection instruction + */ default CollectionInstruction addField(String fieldName) { return addField(fieldName, null); } + /** + * Adds an instruction to add new field with a default value, into the documents of + * a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param fieldName the field name + * @param defaultValue the default value + * @return the collection instruction + */ default CollectionInstruction addField(String fieldName, Object defaultValue) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionAddField); @@ -39,6 +64,14 @@ default CollectionInstruction addField(String fieldName, Object defaultValue) { return this; } + /** + * Adds an instruction to add new field with value generator, into the document of + * a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param fieldName the field name + * @param generator the generator + * @return the collection instruction + */ default CollectionInstruction addField(String fieldName, Generator generator) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionAddField); @@ -47,6 +80,14 @@ default CollectionInstruction addField(String fieldName, Generator generator) return this; } + /** + * Adds an instruction to rename a field to the document of + * a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param oldName the old name + * @param newName the new name + * @return the collection instruction + */ default CollectionInstruction renameField(String oldName, String newName) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionRenameField); @@ -55,6 +96,13 @@ default CollectionInstruction renameField(String oldName, String newName) { return this; } + /** + * Adds an instruction to delete a field from the document of + * a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param fieldName the field name + * @return the collection instruction + */ default CollectionInstruction deleteField(String fieldName) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionDeleteField); @@ -63,14 +111,26 @@ default CollectionInstruction deleteField(String fieldName) { return this; } - default CollectionInstruction dropIndex(String indexedFieldName) { + /** + * Adds an instruction to drop an index from a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param indexedFieldNames the indexed field names + * @return the collection instruction + */ + default CollectionInstruction dropIndex(String... indexedFieldNames) { + Fields indexedFields = Fields.withNames(indexedFieldNames); MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionDropIndex); - migrationStep.setArguments(new Pair<>(collectionName(), indexedFieldName)); + migrationStep.setArguments(new Pair<>(collectionName(), indexedFields)); addStep(migrationStep); return this; } + /** + * Adds an instruction to drop all indices from a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @return the collection instruction + */ default CollectionInstruction dropAllIndices() { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionDropIndices); @@ -79,13 +139,26 @@ default CollectionInstruction dropAllIndices() { return this; } - default CollectionInstruction createIndex(String fieldName, String indexType) { + /** + * Adds an instruction to create an index in a {@link org.dizitart.no2.collection.NitriteCollection}. + * + * @param fieldNames the field names + * @param indexType the index type + * @return the collection instruction + */ + default CollectionInstruction createIndex(String indexType, String... fieldNames) { + Fields indexedFields = Fields.withNames(fieldNames); MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.CollectionCreateIndex); - migrationStep.setArguments(new Triplet<>(collectionName(), fieldName, indexType)); + migrationStep.setArguments(new Triplet<>(collectionName(), indexedFields, indexType)); addStep(migrationStep); return this; } + /** + * The name of the collection for this instruction. + * + * @return the name + */ String collectionName(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/Composable.java b/nitrite/src/main/java/org/dizitart/no2/migration/Composable.java deleted file mode 100644 index 74d49c7a9..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/migration/Composable.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.dizitart.no2.migration; - -/** - * @author Anindya Chatterjee - */ -interface Composable { - void addStep(MigrationStep step); -} diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/CustomInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/CustomInstruction.java index 637a7bc1d..5995afc94 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/CustomInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/CustomInstruction.java @@ -3,8 +3,16 @@ import org.dizitart.no2.Nitrite; /** + * Represents a custom instruction for database migration. + * * @author Anindya Chatterjee + * @since 4.0 */ public interface CustomInstruction { + /** + * Performs the instruction on the nitrite database. + * + * @param nitrite the nitrite database + */ void perform(Nitrite nitrite); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/DatabaseInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/DatabaseInstruction.java index 9373308f2..3f6f919e4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/DatabaseInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/DatabaseInstruction.java @@ -5,10 +5,20 @@ import org.dizitart.no2.common.util.SecureString; /** + * Represents a migration instruction set for the nitrite database. + * * @author Anindya Chatterjee + * @since 4.0 */ -public interface DatabaseInstruction extends Composable { +public interface DatabaseInstruction extends Instruction { + /** + * Adds an instruction to set an user authentication to the database. + * + * @param username the username + * @param password the password + * @return the database instruction + */ default DatabaseInstruction addPassword(String username, String password) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.AddPassword); @@ -17,6 +27,14 @@ default DatabaseInstruction addPassword(String username, String password) { return this; } + /** + * Adds an instruction to change the password for the user authentication to the database. + * + * @param username the username + * @param oldPassword the old password + * @param newPassword the new password + * @return the database instruction + */ default DatabaseInstruction changePassword(String username, String oldPassword, String newPassword) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.ChangePassword); @@ -25,6 +43,12 @@ default DatabaseInstruction changePassword(String username, String oldPassword, return this; } + /** + * Adds an instruction to drop a {@link org.dizitart.no2.collection.NitriteCollection} from the database. + * + * @param collectionName the collection name + * @return the database instruction + */ default DatabaseInstruction dropCollection(String collectionName) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.DropCollection); @@ -33,18 +57,44 @@ default DatabaseInstruction dropCollection(String collectionName) { return this; } + /** + * Adds an instruction to drop an {@link org.dizitart.no2.repository.ObjectRepository} from the database. + * + * @param type the type + * @return the database instruction + */ default DatabaseInstruction dropRepository(Class type) { return dropRepository(type.getName()); } + /** + * Adds an instruction to drop an {@link org.dizitart.no2.repository.ObjectRepository} from the database. + * + * @param typeName the type name + * @return the database instruction + */ default DatabaseInstruction dropRepository(String typeName) { return dropRepository(typeName, null); } + /** + * Adds an instruction to drop a keyed {@link org.dizitart.no2.repository.ObjectRepository} from the database. + * + * @param type the type + * @param key the key + * @return the database instruction + */ default DatabaseInstruction dropRepository(Class type, String key) { return dropRepository(type.getName(), key); } + /** + * Adds an instruction to drop a keyed {@link org.dizitart.no2.repository.ObjectRepository} from the database. + * + * @param typeName the type name + * @param key the key + * @return the database instruction + */ default DatabaseInstruction dropRepository(String typeName, String key) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.DropRepository); @@ -53,6 +103,12 @@ default DatabaseInstruction dropRepository(String typeName, String key) { return this; } + /** + * Adds a custom instruction to perform a user defined operation on the database. + * + * @param instruction the instruction + * @return the database instruction + */ default DatabaseInstruction customInstruction(CustomInstruction instruction) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.Custom); diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/Generator.java b/nitrite/src/main/java/org/dizitart/no2/migration/Generator.java index 039fde65a..66fff74e0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/Generator.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/Generator.java @@ -3,8 +3,18 @@ import org.dizitart.no2.collection.Document; /** + * Represents a default value generator for the document fields during field manipulation instruction. + * + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ public interface Generator { + /** + * Generates a new value for a field in the document. + * + * @param document the document + * @return the value + */ T generate(Document document); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/Instruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/Instruction.java index 821055bcf..f9af0e355 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/Instruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/Instruction.java @@ -1,26 +1,16 @@ package org.dizitart.no2.migration; -import static org.dizitart.no2.common.util.ObjectUtils.getEntityName; - /** + * Represents a collection of database migration steps. + * * @author Anindya Chatterjee + * @since 4.0 */ -public interface Instruction { - DatabaseInstruction forDatabase(); - - default RepositoryInstruction forRepository(String typeName) { - return forRepository(typeName, null); - } - - default RepositoryInstruction forRepository(Class type) { - return forRepository(getEntityName(type), null); - } - - default RepositoryInstruction forRepository(Class type, String key) { - return forRepository(getEntityName(type), key); - } - - RepositoryInstruction forRepository(String typeName, String key); - - CollectionInstruction forCollection(String collectionName); +interface Instruction { + /** + * Adds a migration step to the instruction set. + * + * @param step the step + */ + void addStep(MigrationStep step); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/InstructionType.java b/nitrite/src/main/java/org/dizitart/no2/migration/InstructionType.java index 0489b514a..3fc8a927e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/InstructionType.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/InstructionType.java @@ -1,33 +1,101 @@ package org.dizitart.no2.migration; /** + * Represents an instruction type. + * * @author Anindya Chatterjee + * @since 4.0 */ public enum InstructionType { // db related statements + /** + * The add password instruction. + */ AddPassword, + /** + * The change password instruction. + */ ChangePassword, + /** + * The drop collection instruction. + */ DropCollection, + /** + * The drop repository instruction. + */ DropRepository, + /** + * The custom instruction. + */ Custom, + // collection related statements + /** + * The collection rename instruction. + */ CollectionRename, + /** + * The collection add field instruction. + */ CollectionAddField, + /** + * The collection rename field instruction. + */ CollectionRenameField, + /** + * The collection delete field instruction. + */ CollectionDeleteField, + /** + * The collection drop index instruction. + */ CollectionDropIndex, + /** + * The collection drop all indices instruction. + */ CollectionDropIndices, + /** + * The collection create index instruction. + */ CollectionCreateIndex, + // repository related statements + /** + * The rename repository instruction. + */ RenameRepository, + /** + * The repository add field instruction. + */ RepositoryAddField, + /** + * The repository rename field instruction. + */ RepositoryRenameField, + /** + * The repository delete field instruction. + */ RepositoryDeleteField, + /** + * The repository change data type instruction. + */ RepositoryChangeDataType, + /** + * The repository change id field instruction. + */ RepositoryChangeIdField, + /** + * The repository drop index instruction. + */ RepositoryDropIndex, + /** + * The repository drop indices instruction. + */ RepositoryDropIndices, + /** + * The repository create index instruction. + */ RepositoryCreateIndex } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/Instructions.java b/nitrite/src/main/java/org/dizitart/no2/migration/Instructions.java new file mode 100644 index 000000000..5f98c267e --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/migration/Instructions.java @@ -0,0 +1,66 @@ +package org.dizitart.no2.migration; + +import static org.dizitart.no2.common.util.ObjectUtils.getEntityName; + +/** + * Represents a set of instruction to perform during database migration. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public interface Instructions { + /** + * Creates a {@link DatabaseInstruction}. + * + * @return the database instruction + */ + DatabaseInstruction forDatabase(); + + /** + * Creates a {@link RepositoryInstruction}. + * + * @param typeName the type name + * @return the repository instruction + */ + default RepositoryInstruction forRepository(String typeName) { + return forRepository(typeName, null); + } + + /** + * Creates a {@link RepositoryInstruction}. + * + * @param type the type + * @return the repository instruction + */ + default RepositoryInstruction forRepository(Class type) { + return forRepository(getEntityName(type), null); + } + + /** + * Creates a {@link RepositoryInstruction}. + * + * @param type the type + * @param key the key + * @return the repository instruction + */ + default RepositoryInstruction forRepository(Class type, String key) { + return forRepository(getEntityName(type), key); + } + + /** + * Creates a {@link RepositoryInstruction}. + * + * @param typeName the type name + * @param key the key + * @return the repository instruction + */ + RepositoryInstruction forRepository(String typeName, String key); + + /** + * Creates a {@link CollectionInstruction}. + * + * @param collectionName the collection name + * @return the collection instruction + */ + CollectionInstruction forCollection(String collectionName); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/Migration.java b/nitrite/src/main/java/org/dizitart/no2/migration/Migration.java index 3c9cd7333..92af007be 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/Migration.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/Migration.java @@ -6,7 +6,10 @@ import java.util.Queue; /** + * Represents the database migration operation. + * * @author Anindya Chatterjee + * @since 4.0 */ public abstract class Migration { private final Queue migrationSteps; @@ -19,14 +22,30 @@ public abstract class Migration { private boolean executed = false; + /** + * Instantiates a new {@link Migration}. + * + * @param startVersion the start version + * @param endVersion the end version + */ public Migration(Integer startVersion, Integer endVersion) { this.startVersion = startVersion; this.endVersion = endVersion; this.migrationSteps = new LinkedList<>(); } - public abstract void migrate(Instruction instruction); - + /** + * Migrates the database using the instructions. + * + * @param instructions the instructions + */ + public abstract void migrate(Instructions instructions); + + /** + * Returns the {@link MigrationStep}s as a queue for execution. + * + * @return the queue + */ public Queue steps() { if (!executed) { execute(); @@ -35,7 +54,7 @@ public Queue steps() { } private void execute() { - NitriteInstruction instruction = new NitriteInstruction(migrationSteps); + NitriteInstructions instruction = new NitriteInstructions(migrationSteps); migrate(instruction); this.executed = true; } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java index 9cbcd97fa..150460d44 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java @@ -3,15 +3,17 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.tuples.Quartet; import org.dizitart.no2.common.tuples.Triplet; import org.dizitart.no2.common.util.SecureString; import org.dizitart.no2.exceptions.MigrationException; +import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.migration.commands.*; import org.dizitart.no2.store.DatabaseMetaData; import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.StoreSecurity; +import org.dizitart.no2.store.UserAuthenticationService; import java.util.LinkedList; import java.util.Queue; @@ -22,19 +24,30 @@ import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; /** + * The database migration manager. + * * @author Anindya Chatterjee + * @since 4.0 */ public class MigrationManager { private final NitriteConfig nitriteConfig; private final DatabaseMetaData databaseMetadata; private final Nitrite database; + /** + * Instantiates a new {@link MigrationManager}. + * + * @param nitrite the nitrite database + */ public MigrationManager(Nitrite nitrite) { this.database = nitrite; this.nitriteConfig = nitrite.getConfig(); this.databaseMetadata = nitrite.getDatabaseMetaData(); } + /** + * Performs the migration on the database. + */ public void doMigrate() { if (isMigrationNeeded()) { Integer existingVersion = databaseMetadata.getSchemaVersion(); @@ -43,7 +56,11 @@ public void doMigrate() { Queue migrationPath = findMigrationPath(existingVersion, incomingVersion); if (migrationPath == null || migrationPath.isEmpty()) { // close the database - database.close(); + try { + database.close(); + } catch (Exception e) { + throw new NitriteIOException("failed to close the database", e); + } throw new MigrationException("schema version mismatch, as no migration path found from version " + databaseMetadata.getSchemaVersion() + " to " + nitriteConfig.getSchemaVersion()); @@ -145,15 +162,20 @@ private void executeStep(MigrationStep step) { case AddPassword: Pair arg1 = (Pair) step.getArguments(); - command = nitrite -> StoreSecurity.addOrUpdatePassword(nitrite.getStore(), - false, arg1.getFirst(), null, arg1.getSecond()); + command = nitrite -> { + UserAuthenticationService authService = new UserAuthenticationService(nitrite.getStore()); + authService.addOrUpdatePassword(false, arg1.getFirst(), + null, arg1.getSecond()); + }; break; case ChangePassword: Triplet arg2 = (Triplet) step.getArguments(); - command = nitrite -> StoreSecurity.addOrUpdatePassword(nitrite.getStore(), - true, arg2.getFirst(), arg2.getSecond(), arg2.getThird()); + command = nitrite -> { + UserAuthenticationService authService = new UserAuthenticationService(nitrite.getStore()); + authService.addOrUpdatePassword(true, arg2.getFirst(), arg2.getSecond(), arg2.getThird()); + }; break; case DropCollection: @@ -192,7 +214,7 @@ private void executeStep(MigrationStep step) { break; case CollectionDropIndex: - Pair arg9 = (Pair) step.getArguments(); + Pair arg9 = (Pair) step.getArguments(); command = new DropIndex(arg9.getFirst(), arg9.getSecond()); break; @@ -202,7 +224,7 @@ private void executeStep(MigrationStep step) { break; case CollectionCreateIndex: - Triplet arg10 = (Triplet) step.getArguments(); + Triplet arg10 = (Triplet) step.getArguments(); command = new CreateIndex(arg10.getFirst(), arg10.getSecond(), arg10.getThird()); break; @@ -241,14 +263,14 @@ private void executeStep(MigrationStep step) { break; case RepositoryChangeIdField: - Quartet arg17 = - (Quartet) step.getArguments(); + Quartet arg17 = + (Quartet) step.getArguments(); command = new ChangeIdField(findRepositoryName(arg17.getFirst(), arg17.getSecond()), arg17.getThird(), arg17.getFourth()); break; case RepositoryDropIndex: - Triplet arg18 = (Triplet) step.getArguments(); + Triplet arg18 = (Triplet) step.getArguments(); command = new DropIndex(findRepositoryName(arg18.getFirst(), arg18.getSecond()), arg18.getThird()); break; @@ -258,8 +280,8 @@ private void executeStep(MigrationStep step) { break; case RepositoryCreateIndex: - Quartet arg20 = - (Quartet) step.getArguments(); + Quartet arg20 = + (Quartet) step.getArguments(); command = new CreateIndex(findRepositoryName(arg20.getFirst(), arg20.getSecond()), arg20.getThird(), arg20.getFourth()); break; diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationStep.java b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationStep.java index ccabc1459..0d9c059ff 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationStep.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationStep.java @@ -6,7 +6,10 @@ import lombok.Setter; /** + * Represents a migration step. + * * @author Anindya Chatterjee + * @since 4.0 */ @Getter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE) diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstructions.java similarity index 87% rename from nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstruction.java rename to nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstructions.java index e49d0d91b..3dade87ec 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/NitriteInstructions.java @@ -6,13 +6,16 @@ import java.util.Queue; /** + * Default implementation of {@link Instructions}. + * * @author Anindya Chatterjee + * @since 4.0 */ -class NitriteInstruction implements Instruction { +class NitriteInstructions implements Instructions { @Getter(AccessLevel.PACKAGE) private final Queue migrationSteps; - NitriteInstruction(Queue migrationSteps) { + NitriteInstructions(Queue migrationSteps) { this.migrationSteps = migrationSteps; } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java index a4f3ffad7..b288aec54 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java @@ -1,14 +1,27 @@ package org.dizitart.no2.migration; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.tuples.Quartet; import org.dizitart.no2.common.tuples.Triplet; +import java.util.List; + /** + * Represents a migration instruction set for {@link org.dizitart.no2.repository.ObjectRepository}. + * * @author Anindya Chatterjee + * @since 4.0 */ -public interface RepositoryInstruction extends Composable { - +public interface RepositoryInstruction extends Instruction { + + /** + * Adds an instruction to rename the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param entityName the entity name + * @param key the key + * @return the repository instruction + */ default RepositoryInstruction renameRepository(String entityName, String key) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RenameRepository); @@ -34,10 +47,27 @@ public void addStep(MigrationStep step) { }; } + /** + * Adds an instruction to add new field to the entity in + * the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param the type parameter + * @param fieldName the field name + * @return the repository instruction + */ default RepositoryInstruction addField(String fieldName) { return addField(fieldName, null); } + /** + * Adds an instruction to add new field with a default value, into the entity in the + * {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param the type parameter + * @param fieldName the field name + * @param defaultValue the default value + * @return the repository instruction + */ default RepositoryInstruction addField(String fieldName, T defaultValue) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryAddField); @@ -46,6 +76,15 @@ default RepositoryInstruction addField(String fieldName, T defaultValue) { return this; } + /** + * Adds an instruction to add new field with value generator, into the entity in + * the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param the type parameter + * @param fieldName the field name + * @param generator the generator + * @return the repository instruction + */ default RepositoryInstruction addField(String fieldName, Generator generator) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryAddField); @@ -54,6 +93,14 @@ default RepositoryInstruction addField(String fieldName, Generator genera return this; } + /** + * Adds an instruction to rename a field to the entity in the + * {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param oldName the old name + * @param newName the new name + * @return the repository instruction + */ default RepositoryInstruction renameField(String oldName, String newName) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryRenameField); @@ -62,6 +109,13 @@ default RepositoryInstruction renameField(String oldName, String newName) { return this; } + /** + * Adds an instruction to delete a field from the entity in + * the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param fieldName the field name + * @return the repository instruction + */ default RepositoryInstruction deleteField(String fieldName) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryDeleteField); @@ -70,7 +124,15 @@ default RepositoryInstruction deleteField(String fieldName) { return this; } - default RepositoryInstruction changeDataType(String fieldName, TypeConverter converter) { + /** + * Adds an instruction to change the datatype of a field of the entity in + * the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param fieldName the field name + * @param converter the converter + * @return the repository instruction + */ + default RepositoryInstruction changeDataType(String fieldName, TypeConverter converter) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryChangeDataType); migrationStep.setArguments(new Quartet<>(entityName(), key(), fieldName, converter)); @@ -78,22 +140,45 @@ default RepositoryInstruction changeDataType(String fieldName, TypeConverter return this; } - default RepositoryInstruction changeIdField(String oldFieldName, String newFieldName) { + /** + * Adds an instruction to change the id field of an entity in the + * {@link org.dizitart.no2.repository.ObjectRepository} + * + * @param oldFieldNames the old field names + * @param newFieldNames the new field names + * @return the repository instruction + */ + default RepositoryInstruction changeIdField(List oldFieldNames, List newFieldNames) { + Fields oldFields = Fields.withNames(oldFieldNames.toArray(new String[0])); + Fields newFields = Fields.withNames(newFieldNames.toArray(new String[0])); + MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryChangeIdField); - migrationStep.setArguments(new Quartet<>(entityName(), key(), oldFieldName, newFieldName)); + migrationStep.setArguments(new Quartet<>(entityName(), key(), oldFields, newFields)); addStep(migrationStep); return this; } - default RepositoryInstruction dropIndex(String field) { + /** + * Adds an instruction to drop an index from the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param fieldNames the field names + * @return the repository instruction + */ + default RepositoryInstruction dropIndex(String... fieldNames) { + Fields fields = Fields.withNames(fieldNames); MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryDropIndex); - migrationStep.setArguments(new Triplet<>(entityName(), key(), field)); + migrationStep.setArguments(new Triplet<>(entityName(), key(), fields)); addStep(migrationStep); return this; } + /** + * Adds an instruction to drop all indices from the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @return the repository instruction + */ default RepositoryInstruction dropAllIndices() { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryDropIndices); @@ -102,15 +187,33 @@ default RepositoryInstruction dropAllIndices() { return this; } - default RepositoryInstruction createIndex(String field, String indexType) { + /** + * Adds an instruction to create an index in the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @param indexType the index type + * @param fieldNames the field names + * @return the repository instruction + */ + default RepositoryInstruction createIndex(String indexType, String... fieldNames) { + Fields fields = Fields.withNames(fieldNames); MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryCreateIndex); - migrationStep.setArguments(new Quartet<>(entityName(), key(), field, indexType)); + migrationStep.setArguments(new Quartet<>(entityName(), key(), fields, indexType)); addStep(migrationStep); return this; } + /** + * The entity name of the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @return the string + */ String entityName(); + /** + * The key of the {@link org.dizitart.no2.repository.ObjectRepository}. + * + * @return the string + */ String key(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/TypeConverter.java b/nitrite/src/main/java/org/dizitart/no2/migration/TypeConverter.java index 74b8bbbfb..d52d36162 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/TypeConverter.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/TypeConverter.java @@ -1,8 +1,19 @@ package org.dizitart.no2.migration; /** + * Represents a type converter. + * + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ public interface TypeConverter { + /** + * Converts an object of type S to an object of type T. + * + * @param source the source + * @return the target object + */ T convert(S source); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java index f18d9d826..b9c6fe4c2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/AddField.java @@ -4,12 +4,11 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.Generator; -import static org.dizitart.no2.common.Fields.single; - /** * @author Anindya Chatterjee */ @@ -23,7 +22,7 @@ public class AddField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); + IndexDescriptor indexDescriptor = operations.findIndex(Fields.withNames(fieldName)); for (Pair pair : nitriteMap.entries()) { Document document = pair.getSecond(); @@ -37,7 +36,7 @@ public void execute(Nitrite nitrite) { } if (indexDescriptor != null) { - operations.createIndex(single(fieldName), indexDescriptor.getIndexType(), false); + operations.createIndex(Fields.withNames(fieldName), indexDescriptor.getIndexType()); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java index 4de2f75f3..db6cade49 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/BaseCommand.java @@ -8,13 +8,34 @@ import org.dizitart.no2.store.NitriteStore; /** + * Represents a base command for database migration. It initializes + * different components necessary to execute the migration steps + * * @author Anindya Chatterjee + * @since 4.0 */ abstract class BaseCommand implements Command { + /** + * The nitrite store. + */ protected NitriteStore nitriteStore; + + /** + * The nitrite map. + */ protected NitriteMap nitriteMap; + + /** + * The collection operations. + */ protected CollectionOperations operations; + /** + * Initializes the database for migration. + * + * @param nitrite the nitrite + * @param collectionName the collection name + */ void initialize(Nitrite nitrite, String collectionName) { nitriteStore = nitrite.getStore(); diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java index 423974b57..ec0685aa7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeDataType.java @@ -4,14 +4,17 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.migration.TypeConverter; -import static org.dizitart.no2.common.Fields.single; - /** + * A migration command to change the datatype of a document field + * in a collection. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor @SuppressWarnings({"unchecked", "rawtypes"}) @@ -33,9 +36,9 @@ public void execute(Nitrite nitrite) { nitriteMap.put(entry.getFirst(), document); } - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); + IndexDescriptor indexDescriptor = operations.findIndex(Fields.withNames(fieldName)); if (indexDescriptor != null) { - operations.rebuildIndex(indexDescriptor, false); + operations.rebuildIndex(indexDescriptor); } } } \ No newline at end of file diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java index 18bfbc4f9..318e6c6a2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java @@ -2,26 +2,31 @@ import lombok.AllArgsConstructor; import org.dizitart.no2.Nitrite; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.index.IndexType; /** + * A command to change the id fields of an entity in + * an {@link org.dizitart.no2.repository.ObjectRepository}. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class ChangeIdField extends BaseCommand implements Command { private final String collectionName; - private final String oldFieldName; - private final String newFieldName; + private final Fields oldFields; + private final Fields newFields; @Override public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - boolean hasIndex = operations.hasIndex(oldFieldName); + boolean hasIndex = operations.hasIndex(oldFields); if (hasIndex) { - operations.dropIndex(oldFieldName); + operations.dropIndex(oldFields); } - operations.createIndex(newFieldName, IndexType.Unique, false); + operations.createIndex(newFields, IndexType.Unique); } } \ No newline at end of file diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Command.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Command.java index bc9e5788c..7d3c7b0db 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Command.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Command.java @@ -3,8 +3,16 @@ import org.dizitart.no2.Nitrite; /** + * Represents a database migration command. + * * @author Anindya Chatterjee + * @since 4.0 */ public interface Command { + /** + * Executes a migration step on the database. + * + * @param nitrite the nitrite database instance + */ void execute(Nitrite nitrite); } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/CreateIndex.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/CreateIndex.java index 3d6772979..3081a613a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/CreateIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/CreateIndex.java @@ -2,20 +2,24 @@ import lombok.AllArgsConstructor; import org.dizitart.no2.Nitrite; +import org.dizitart.no2.common.Fields; /** + * A command to create an index. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class CreateIndex extends BaseCommand implements Command { private final String collectionName; - private final String fieldName; + private final Fields fields; private final String indexType; @Override public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - operations.createIndex(fieldName, indexType, false); + operations.createIndex(fields, indexType); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java index 2f295c059..9826e7d38 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DeleteField.java @@ -4,13 +4,16 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; -import static org.dizitart.no2.common.Fields.single; - /** + * A command to delete a field from the document of + * a collection. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class DeleteField extends BaseCommand implements Command { @@ -21,7 +24,7 @@ public class DeleteField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(fieldName)); + IndexDescriptor indexDescriptor = operations.findIndex(Fields.withNames(fieldName)); for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); document.remove(fieldName); @@ -29,7 +32,7 @@ public void execute(Nitrite nitrite) { } if (indexDescriptor != null) { - operations.dropIndex(single(fieldName)); + operations.dropIndex(Fields.withNames(fieldName)); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Drop.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Drop.java index 4f7e6f1ab..c8bf6cc42 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Drop.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Drop.java @@ -4,7 +4,10 @@ import org.dizitart.no2.Nitrite; /** + * A command to drop a nitrite collection. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class Drop extends BaseCommand implements Command { diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DropIndex.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DropIndex.java index 761d07c42..ca242840a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/DropIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/DropIndex.java @@ -2,25 +2,27 @@ import lombok.AllArgsConstructor; import org.dizitart.no2.Nitrite; - -import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; +import org.dizitart.no2.common.Fields; /** + * A command to drop an index. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class DropIndex extends BaseCommand implements Command { private final String collectionName; - private final String fieldName; + private final Fields fields; @Override public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - if (isNullOrEmpty(fieldName)) { + if (fields == null) { operations.dropAllIndices(); } else { - operations.dropIndex(fieldName); + operations.dropIndex(fields); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java index c641a74b6..5839867c0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/Rename.java @@ -5,16 +5,19 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.operation.CollectionOperations; +import org.dizitart.no2.collection.operation.IndexManager; import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.store.IndexCatalog; import org.dizitart.no2.store.NitriteMap; import java.util.Collection; /** + * A command to rename a {@link org.dizitart.no2.collection.NitriteCollection}. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class Rename extends BaseCommand implements Command { @@ -32,12 +35,12 @@ public void execute(Nitrite nitrite) { newMap.put(entry.getFirst(), entry.getSecond()); } - IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); - Collection indexEntries = indexCatalog.listIndexDescriptors(oldName); + IndexManager indexManager = new IndexManager(oldName, nitrite.getConfig()); + Collection indexEntries = indexManager.getIndexDescriptors(); for (IndexDescriptor indexDescriptor : indexEntries) { Fields field = indexDescriptor.getIndexFields(); String indexType = indexDescriptor.getIndexType(); - newOperations.createIndex(field, indexType, false); + newOperations.createIndex(field, indexType); } operations.dropCollection(); diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java index cdc867abc..7475c5599 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/RenameField.java @@ -4,14 +4,18 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.collection.operation.IndexManager; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.store.IndexCatalog; -import static org.dizitart.no2.common.Fields.single; +import java.util.Collection; /** + * A command to rename a document field. + * * @author Anindya Chatterjee + * @since 4.0 */ @AllArgsConstructor public class RenameField extends BaseCommand implements Command { @@ -23,8 +27,10 @@ public class RenameField extends BaseCommand implements Command { public void execute(Nitrite nitrite) { initialize(nitrite, collectionName); - IndexCatalog indexCatalog = nitrite.getStore().getIndexCatalog(); - boolean indexExists = indexCatalog.hasIndexDescriptor(collectionName, single(oldName)); + IndexManager indexManager = new IndexManager(oldName, nitrite.getConfig()); + Fields oldField = Fields.withNames(oldName); + Collection matchingIndexDescriptors = indexManager.findMatchingIndexDescriptors(oldField); + for (Pair entry : nitriteMap.entries()) { Document document = entry.getSecond(); if (document.containsKey(oldName)) { @@ -36,12 +42,27 @@ public void execute(Nitrite nitrite) { } } - if (indexExists) { - IndexDescriptor indexDescriptor = indexCatalog.findIndexDescriptorExact(collectionName, single(oldName)); - String indexType = indexDescriptor.getIndexType(); + if (!matchingIndexDescriptors.isEmpty()) { + for (IndexDescriptor matchingIndexDescriptor : matchingIndexDescriptors) { + String indexType = matchingIndexDescriptor.getIndexType(); + + Fields oldIndexFields = matchingIndexDescriptor.getIndexFields(); + Fields newIndexFields = getNewIndexFields(oldIndexFields, oldName, newName); + operations.dropIndex(matchingIndexDescriptor.getIndexFields()); + operations.createIndex(newIndexFields, indexType); + } + } + } - operations.dropIndex(single(oldName)); - operations.createIndex(single(newName), indexType, false); + private Fields getNewIndexFields(Fields oldIndexFields, String oldName, String newName) { + Fields newIndexFields = new Fields(); + for (String fieldName : oldIndexFields.getFieldNames()) { + if (fieldName.equals(oldName)) { + newIndexFields.addField(newName); + } else { + newIndexFields.addField(fieldName); + } } + return newIndexFields; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java b/nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java new file mode 100644 index 000000000..49537b414 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.module; + +/** + * Represents a {@link NitriteModule} configurator. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public interface ModuleConfig { + /** + * Builds a {@link NitriteModule} form this configuration. + * + * @return the nitrite module + */ + NitriteModule build(); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java b/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java index 64e2b52d2..d7b3f580c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java @@ -16,39 +16,43 @@ package org.dizitart.no2.module; -import java.util.Arrays; -import java.util.HashSet; import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** + * Represents a nitrite plugin modules which may contains + * one or more nitrite plugins. + * * @author Anindya Chatterjee + * @since 4.0 */ public interface NitriteModule { + /** + * Creates a {@link NitriteModule} from a set of {@link NitritePlugin}s. + * + * @param plugins the plugins + * @return the nitrite module + */ static NitriteModule module(NitritePlugin... plugins) { - return new NitriteModule() { - @Override - public Set plugins() { - return setOf(plugins); - } - }; + return () -> setOf(plugins); } + /** + * Returns the set of {@link NitritePlugin} encapsulated by this module. + * + * @return the set + */ Set plugins(); - @SuppressWarnings("unchecked") - default Set setOf(T... items) { - Set set = new HashSet<>(); - if (items != null) { - set.addAll(Arrays.asList(items)); - } - return set; - } - + /** + * Creates a {@link ModuleConfig} to configure a {@link NitriteModule}. + * + * @param the type parameter + * @return the module config + */ static T withConfig() { return null; } - interface ModuleConfig { - NitriteModule build(); - } } diff --git a/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java b/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java index 0f08d5f0c..7f182f892 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java +++ b/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java @@ -19,8 +19,16 @@ import org.dizitart.no2.NitriteConfig; /** + * Represents a nitrite database plugin component. + * * @author Anindya Chatterjee. + * @since 4.0 */ public interface NitritePlugin { + /** + * Initializes the plugin instance. + * + * @param nitriteConfig the nitrite config + */ void initialize(NitriteConfig nitriteConfig); } diff --git a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java b/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java index ffb7f011b..433ec1c68 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java @@ -31,7 +31,13 @@ import java.util.Map; /** + * The nitrite database plugin manager. It loads the nitrite plugins + * before opening the database. + * + * @see NitriteModule + * @see NitritePlugin * @author Anindya Chatterjee. + * @since 4.0 */ @Slf4j @Getter @@ -41,11 +47,21 @@ public class PluginManager { private NitriteStore nitriteStore; private final NitriteConfig nitriteConfig; + /** + * Instantiates a new {@link PluginManager}. + * + * @param nitriteConfig the nitrite config + */ public PluginManager(NitriteConfig nitriteConfig) { this.indexerMap = new HashMap<>(); this.nitriteConfig = nitriteConfig; } + /** + * Loads a {@link NitriteModule} instance. + * + * @param module the module + */ public void loadModule(NitriteModule module) { if (module != null && module.plugins() != null) { for (NitritePlugin plugin : module.plugins()) { @@ -54,6 +70,9 @@ public void loadModule(NitriteModule module) { } } + /** + * Find and loads all nitrite plugins configured. + */ public void findAndLoadPlugins() { try { loadInternalPlugins(); @@ -63,6 +82,9 @@ public void findAndLoadPlugins() { } } + /** + * Initializes all plugins instances. + */ public void initializePlugins() { if (nitriteStore != null) { initializePlugin(nitriteStore); diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/Processor.java b/nitrite/src/main/java/org/dizitart/no2/processors/Processor.java new file mode 100644 index 000000000..06496f0c0 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/processors/Processor.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.processors; + +import org.dizitart.no2.collection.Document; + +/** + * Represents a document processor. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public interface Processor { + /** + * Processes a document before writing it into database. + * + * @param document the document + * @return the document + */ + Document processBeforeWrite(Document document); + + /** + * Processes a document after reading from the database. + * + * @param document the document + * @return the document + */ + Document processAfterRead(Document document); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java b/nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java new file mode 100644 index 000000000..07c049b71 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.processors; + +import org.dizitart.no2.collection.Document; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a {@link Processor} chain. It executes a + * list of processor on a document. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class ProcessorChain implements Processor { + private final List processors; + + /** + * Instantiates a new Processor chain. + */ + public ProcessorChain() { + processors = new ArrayList<>(); + } + + /** + * Adds a processor to the chain. + * + * @param processor the processor + */ + public void add(Processor processor) { + processors.add(processor); + } + + /** + * Removes a processor from the chain. + * + * @param processor the processor + */ + public void remove(Processor processor) { + processors.remove(processor); + } + + @Override + public Document processBeforeWrite(Document document) { + Document processed = document; + for (Processor processor : processors) { + processed = processor.processBeforeWrite(processed); + } + return processed; + } + + @Override + public Document processAfterRead(Document document) { + Document processed = document; + for (Processor processor : processors) { + processed = processor.processAfterRead(processed); + } + return processed; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java b/nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java new file mode 100644 index 000000000..3808d6de8 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.processors; + +import lombok.extern.slf4j.Slf4j; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.util.StringUtils; +import org.dizitart.no2.exceptions.NitriteIOException; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A string field encryption processor. It encrypts the field value + * of type {@link String} in a nitrite document using the provided {@link Encryptor}. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +@Slf4j +public class StringFieldEncryptionProcessor implements Processor { + private final Encryptor encryptor; + private final List fields; + + /** + * Instantiates a new {@link StringFieldEncryptionProcessor}. + * + * @param password the password + */ + public StringFieldEncryptionProcessor(String password) { + this(new AESEncryptor(password)); + } + + /** + * Instantiates a new {@link StringFieldEncryptionProcessor}. + * + * @param encryptor the encryptor + */ + public StringFieldEncryptionProcessor(Encryptor encryptor) { + this.encryptor = encryptor; + this.fields = new ArrayList<>(); + } + + /** + * Adds fields for encryption. + * + * @param fields the fields + */ + public void addFields(String... fields){ + this.fields.addAll(Arrays.asList(fields)); + } + + + @Override + public Document processBeforeWrite(Document document) { + try { + Document copy = document.clone(); + if (!fields.isEmpty()) { + for (String field : fields) { + String value = copy.get(field, String.class); + if (!StringUtils.isNullOrEmpty(value)) { + // encrypt + value = encryptor.encrypt(value.getBytes(StandardCharsets.UTF_8)); + + // set the value + copy.put(field, value); + } + } + } + return copy; + } catch (Exception e) { + log.error("Error while processing document before write", e); + throw new NitriteIOException("failed to process document before write", e); + } + } + + @Override + public Document processAfterRead(Document document) { + try { + Document copy = document.clone(); + if (!fields.isEmpty()) { + for (String field : fields) { + String value = copy.get(field, String.class); + if (!StringUtils.isNullOrEmpty(value)) { + // decrypt + value = encryptor.decrypt(value); + + // set the value + copy.put(field, value); + } + } + } + return copy; + } catch (Exception e) { + log.error("Error while processing document after read", e); + throw new NitriteIOException("failed to process document after read", e); + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/Cursor.java b/nitrite/src/main/java/org/dizitart/no2/repository/Cursor.java index 06bd030c6..5d6049923 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/Cursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/Cursor.java @@ -16,35 +16,32 @@ package org.dizitart.no2.repository; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.filters.Filter; - -import java.text.Collator; /** * A collection of {@link NitriteId}s of the database records, * as a result of a find operation. * * @author Anindya Chatterjee - * @see ObjectRepository#find(Filter) - * @see ObjectRepository#find() * @since 1.0 */ public interface Cursor extends RecordStream { - Cursor sort(String field, SortOrder sortOrder, Collator collator, NullOrder nullOrder); - - Cursor skipLimit(long skip, long size); + /** + * Gets a filter plan for the query. + * + * @return the filter plan + */ + FindPlan getFindPlan(); /** * Projects the result of one type into an {@link Iterable} of other type. * * @param

    the type of the target objects. * @param projectionType the projection type. - * @return `Iterable` of projected objects. + * @return java.lang.Iterable of projected objects. */

    RecordStream

    project(Class

    projectionType); @@ -52,7 +49,7 @@ public interface Cursor extends RecordStream { * Performs a left outer join with a foreign cursor with the specified lookup parameters. *

    * It performs an equality match on the localString to the foreignString from the objects of the foreign cursor. - * If an input object does not contain the localString, the join treats the field as having a value of `null` + * If an input object does not contain the localString, the join treats the field as having a value of null * for matching purposes. * * @param the type of the foreign object. @@ -64,28 +61,4 @@ public interface Cursor extends RecordStream { * @since 2.1.0 */ RecordStream join(Cursor foreignCursor, Lookup lookup, Class type); - - default Cursor sort(String field) { - return sort(field, SortOrder.Ascending); - } - - default Cursor sort(String field, SortOrder sortOrder) { - return sort(field, sortOrder, NullOrder.Default); - } - - default Cursor sort(String field, SortOrder sortOrder, Collator collator) { - return sort(field, sortOrder, collator, NullOrder.Default); - } - - default Cursor sort(String field, SortOrder sortOrder, NullOrder nullOrder) { - return sort(field, sortOrder, null, nullOrder); - } - - default Cursor skip(long skip) { - return skipLimit(skip, size()); - } - - default Cursor limit(long limit) { - return skipLimit(0, limit); - } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java index e8ae27347..85385620f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java @@ -18,15 +18,16 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.store.NitriteStore; import java.util.Collection; @@ -54,13 +55,25 @@ class DefaultObjectRepository implements ObjectRepository { } @Override - public void createIndex(Fields fields, IndexOptions indexOptions) { - collection.createIndex(fields, indexOptions); + public void addProcessor(Processor processor) { + notNull(processor, "a null processor cannot be added"); + collection.addProcessor(processor); } @Override - public void rebuildIndex(Fields fields, boolean isAsync) { - collection.rebuildIndex(fields, isAsync); + public void removeProcessor(Processor processor) { + notNull(processor, "a null processor cannot be removed"); + collection.removeProcessor(processor); + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fields) { + collection.createIndex(indexOptions, fields); + } + + @Override + public void rebuildIndex(String... fields) { + collection.rebuildIndex(fields); } @Override @@ -69,17 +82,17 @@ public Collection listIndices() { } @Override - public boolean hasIndex(Fields fields) { + public boolean hasIndex(String... fields) { return collection.hasIndex(fields); } @Override - public boolean isIndexing(Fields fields) { + public boolean isIndexing(String... fields) { return collection.isIndexing(fields); } @Override - public void dropIndex(Fields fields) { + public void dropIndex(String... fields) { collection.dropIndex(fields); } @@ -135,14 +148,10 @@ public void clear() { collection.clear(); } - @Override - public Cursor find() { - return operations.find(type); - } @Override - public Cursor find(Filter filter) { - return operations.find(filter, type); + public Cursor find(Filter filter, FindOptions findOptions) { + return operations.find(filter, findOptions, type); } @Override @@ -167,7 +176,7 @@ public boolean isOpen() { } @Override - public void close() { + public void close() throws Exception { collection.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java index 3f13ef02c..1c902a3c0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java @@ -18,16 +18,14 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.mapper.NitriteMapper; import java.lang.reflect.Modifier; -import java.text.Collator; import java.util.Iterator; import static org.dizitart.no2.common.util.DocumentUtils.skeletonDocument; @@ -52,6 +50,11 @@ public long size() { return cursor.size(); } + @Override + public FindPlan getFindPlan() { + return cursor.getFindPlan(); + } + @Override public

    RecordStream

    project(Class

    projectionType) { notNull(projectionType, "projection cannot be null"); @@ -65,16 +68,6 @@ public RecordStream join(Cursor foreignCursor return new MutatedObjectStream<>(nitriteMapper, cursor.join(foreignObjectCursor.cursor, lookup), type); } - @Override - public Cursor sort(String field, SortOrder sortOrder, Collator collator, NullOrder nullOrder) { - return new ObjectCursor<>(nitriteMapper, cursor.sort(field, sortOrder, collator, nullOrder), type); - } - - @Override - public Cursor skipLimit(long skip, long size) { - return new ObjectCursor<>(nitriteMapper, cursor.skipLimit(skip, size), type); - } - @Override public Iterator iterator() { return new ObjectCursorIterator(cursor.iterator()); diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java index ec6997f10..05efdae31 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectRepository.java @@ -17,6 +17,7 @@ package org.dizitart.no2.repository; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.events.CollectionEventListener; @@ -257,7 +258,9 @@ default WriteResult remove(Filter filter) { * * @return a cursor to all objects in the collection. */ - Cursor find(); + default Cursor find() { + return find(Filter.ALL, null); + } /** * Applies a filter on the collection and returns a cursor to the @@ -271,11 +274,37 @@ default WriteResult remove(Filter filter) { * * @param filter the filter to apply to select objects from collection. * @return a cursor to all selected objects. - * @throws ValidationException if {@code filter} is null. * @see Filter * @see Cursor#project(Class) */ - Cursor find(Filter filter); + default Cursor find(Filter filter) { + return find(filter, null); + } + + /** + * Returns a customized cursor to all objects in the collection. + * + * @param findOptions specifies pagination, sort options for the cursor. + * @return a cursor to all selected objects. + */ + default Cursor find(FindOptions findOptions) { + return find(Filter.ALL, findOptions); + } + + /** + * Applies a filter on the collection and returns a customized cursor to the + * selected objects. + * + *

    + * NOTE: If there is an index on the value specified in the filter, this operation + * will take advantage of the index. + *

    + * + * @param filter the filter to apply to select objects from collection. + * @param findOptions specifies pagination, sort options for the cursor. + * @return a cursor to all selected objects. + */ + Cursor find(Filter filter, FindOptions findOptions); /** * Gets a single element from the repository by its id. If no element @@ -285,7 +314,7 @@ default WriteResult remove(Filter filter) { * @param the type parameter * @param id the id value * @return the unique object associated with the id. - * @throws ValidationException if `id` is {@code null}. + * @throws ValidationException if id is {@code null}. * @throws InvalidIdException if the id value is {@code null}, or the type is not compatible. * @throws NotIdentifiableException if the object has no field marked with {@link Id}. */ diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java index 1a928a2c1..9ff2624ce 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java @@ -18,39 +18,63 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.CollectionFactory; -import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.util.StringUtils; +import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.StoreCatalog; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; -import static org.dizitart.no2.common.Constants.*; import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; /** + * The {@link ObjectRepository} factory. + * * @author Anindya Chatterjee + * @since 1.0 */ public class RepositoryFactory { private final Map> repositoryMap; private final CollectionFactory collectionFactory; private final ReentrantLock lock; + /** + * Instantiates a new {@link RepositoryFactory}. + * + * @param collectionFactory the collection factory + */ public RepositoryFactory(CollectionFactory collectionFactory) { this.collectionFactory = collectionFactory; this.repositoryMap = new HashMap<>(); this.lock = new ReentrantLock(); } + /** + * Gets an {@link ObjectRepository} by type. + * + * @param the type parameter + * @param nitriteConfig the nitrite config + * @param type the type + * @return the repository + */ public ObjectRepository getRepository(NitriteConfig nitriteConfig, Class type) { return getRepository(nitriteConfig, type, null); } + /** + * Gets an {@link ObjectRepository} by type and a key. + * + * @param the type parameter + * @param nitriteConfig the nitrite config + * @param type the type + * @param key the key + * @return the repository + */ @SuppressWarnings("unchecked") public ObjectRepository getRepository(NitriteConfig nitriteConfig, Class type, String key) { if (type == null) { @@ -81,6 +105,9 @@ public ObjectRepository getRepository(NitriteConfig nitriteConfig, Class< } } + /** + * Closes all opened {@link ObjectRepository}s and clear internal data from this class. + */ public void clear() { try { lock.lock(); @@ -88,6 +115,8 @@ public void clear() { repository.close(); } repositoryMap.clear(); + } catch (Exception e) { + throw new NitriteIOException("failed to close an object repository", e); } finally { lock.unlock(); } @@ -115,16 +144,11 @@ private ObjectRepository createRepository(NitriteConfig nitriteConfig, Cl } private void writeCatalog(NitriteStore store, String name, String key) { - NitriteMap catalogMap = store.openMap(COLLECTION_CATALOG, String.class, Document.class); - Document document = StringUtils.isNullOrEmpty(key) ? catalogMap.get(TAG_REPOSITORIES) - : catalogMap.get(TAG_KEYED_REPOSITORIES); - if (document == null) document = Document.createDocument(); - - document.put(name, true); + StoreCatalog storeCatalog = store.getCatalog(); if (StringUtils.isNullOrEmpty(key)) { - catalogMap.put(TAG_REPOSITORIES, document); + storeCatalog.writeRepositoryEntry(name); } else { - catalogMap.put(TAG_KEYED_REPOSITORIES, document); + storeCatalog.writeKeyedRepositoryEntries(name); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java index fcada797a..3dc7a299b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java @@ -17,9 +17,7 @@ package org.dizitart.no2.repository; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.collection.*; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.*; import org.dizitart.no2.filters.Filter; @@ -43,7 +41,13 @@ import static org.dizitart.no2.index.IndexOptions.indexOptions; /** + * The {@link ObjectRepository} operations. + *

    + * This class is for internal use only. + *

    + * * @author Anindya Chatterjee + * @since 4.0 */ public class RepositoryOperations { private final NitriteMapper nitriteMapper; @@ -51,6 +55,13 @@ public class RepositoryOperations { private final NitriteCollection collection; private Field idField; + /** + * Instantiates a new {@link RepositoryOperations}. + * + * @param type the type + * @param nitriteMapper the nitrite mapper + * @param collection the collection + */ public RepositoryOperations(Class type, NitriteMapper nitriteMapper, NitriteCollection collection) { @@ -63,9 +74,9 @@ public RepositoryOperations(Class type, public void createIndexes() { Set indexes = extractIndices(type); for (Index idx : indexes) { - String field = idx.value(); - if (!collection.hasIndex(field)) { - collection.createIndex(idx.value(), indexOptions(idx.type(), false)); + String[] fields = idx.value(); + if (!collection.hasIndex(fields)) { + collection.createIndex(indexOptions(idx.type()), fields); } } @@ -73,7 +84,7 @@ public void createIndexes() { if (idField != null) { String field = idField.getName(); if (!collection.hasIndex(field)) { - collection.createIndex(field, indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.Unique), field); } } } @@ -337,10 +348,19 @@ private Field getEmbeddedField(Class startingClass, String embeddedField) private void populateIndex(NitriteMapper nitriteMapper, Class type, List indexList, Set indexSet) { for (Index index : indexList) { - String name = index.value(); - Field field = getField(type, name); - if (field != null) { - validateObjectIndexField(nitriteMapper, field.getType(), field.getName()); + String[] names = index.value(); + List entityFields = new ArrayList<>(); + + for (String name : names) { + Field field = getField(type, name); + if (field != null) { + entityFields.add(field); + validateObjectIndexField(nitriteMapper, field.getType(), field.getName()); + } + } + + if (entityFields.size() == names.length) { + // validation for all field are success indexSet.add(index); } } @@ -368,12 +388,11 @@ private void validateObjectIndexField(NitriteMapper nitriteMapper, Class fiel Document document; try { document = skeletonDocument(nitriteMapper, fieldType); + if (document == null || document.size() > 0) { + throw new InvalidOperationException("invalid type specified " + fieldType.getName() + " for indexing"); + } } catch (Throwable e) { - throw new IndexingException("invalid type specified " + fieldType.getName() + " for indexing", e); - } - - if (document == null || document.size() > 0) { - throw new InvalidOperationException("compound index on field " + field + " is not supported"); + throw new IndexingException("failed to index field " + fieldType.getName(), e); } } @@ -401,11 +420,17 @@ private List findAnnotations(Class annotation, Clas return annotations; } - public Cursor find(Class type) { - return new ObjectCursor<>(nitriteMapper, collection.find(), type); - } - - public Cursor find(Filter filter, Class type) { - return new ObjectCursor<>(nitriteMapper, collection.find(asObjectFilter(filter)), type); + /** + * Find cursor. + * + * @param the type parameter + * @param filter the filter + * @param findOptions the find options + * @param type the type + * @return the cursor + */ + public Cursor find(Filter filter, FindOptions findOptions, Class type) { + DocumentCursor documentCursor = collection.find(asObjectFilter(filter), findOptions); + return new ObjectCursor<>(nitriteMapper, documentCursor, type); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Entity.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Entity.java index 0a618ecf9..92822a3d2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Entity.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Entity.java @@ -22,11 +22,26 @@ import java.lang.annotation.Target; /** + * Represents an entity for an {@link org.dizitart.no2.repository.ObjectRepository}. + * * @author Anindya Chatterjee + * @since 4.0 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Entity { + /** + * Name of the {@link org.dizitart.no2.repository.ObjectRepository}. By default, + * the name would be the class name of the entity. + * + * @return the name + */ String value() default ""; + + /** + * Index definitions of the entity. + * + * @return the index definitions + */ Index[] indices() default {}; } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java index 150a9b34f..143620032 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java @@ -16,22 +16,14 @@ package org.dizitart.no2.repository.annotations; -import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.ObjectRepository; import java.lang.annotation.*; /** * Specifies a field to be indexed. - *

    - * [[app-listing]] - * [source,java] - * .Example of Index annotation - * -- * * @author Anindya Chatterjee. - * @see ObjectRepository#createIndex(String, IndexOptions) * @since 1.0 */ @Retention(RetentionPolicy.RUNTIME) @@ -43,7 +35,7 @@ * * @return the field name */ - String value(); + String[] value(); /** * Type of the index. diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Indices.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Indices.java index e43626523..836fc5a93 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Indices.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Indices.java @@ -23,15 +23,8 @@ /** * Specifies multiple indexed fields for a class. - *

    - * [[app-listing]] - * [source,java] - * .Example of Indices annotation - * -- - * + * @author Anindya Chatterjee. - * - * * @see Index * @since 1.0 */ diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java index 405f0b5ac..9ef47c0b0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java @@ -20,7 +20,8 @@ /** * Indicates that a class should consider all index related - * annotations - `@Id`, `@Index`, `@Indices` from its superclass. + * annotations - @Id@Id, @Index, + * @Indices from its superclass. * * @author Anindya Chatterjee * @since 2.1.0 diff --git a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java index f235fdc5d..3093f3edf 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java @@ -4,22 +4,22 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.event.NitriteEventBus; import org.dizitart.no2.store.events.EventInfo; import org.dizitart.no2.store.events.StoreEventBus; import org.dizitart.no2.store.events.StoreEventListener; import org.dizitart.no2.store.events.StoreEvents; -import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; -import static org.dizitart.no2.common.Constants.*; -import static org.dizitart.no2.common.util.ObjectUtils.getKeyName; -import static org.dizitart.no2.common.util.ObjectUtils.getKeyedRepositoryType; - +/** + * An abstract {@link NitriteStore} implementation. + * + * @param the type parameter + * @author Anindya Chatterjee + * @since 4.0 + */ @Slf4j public abstract class AbstractNitriteStore implements NitriteStore { @@ -27,14 +27,30 @@ public abstract class AbstractNitriteStore @Getter @Setter private Config storeConfig; + /** + * The {@link NitriteEventBus} for the database. + */ protected final NitriteEventBus eventBus; + + /** + * The {@link NitriteConfig} for this store. + */ protected NitriteConfig nitriteConfig; - private IndexCatalog indexCatalog; + private StoreCatalog storeCatalog; + + /** + * Instantiates a new {@link AbstractNitriteStore}. + */ protected AbstractNitriteStore() { eventBus = new StoreEventBus(); } + /** + * Alerts about an {@link StoreEvents} to all subscribed {@link StoreEventListener}s. + * + * @param eventType the event type + */ protected void alert(StoreEvents eventType) { EventInfo event = new EventInfo(eventType, nitriteConfig); eventBus.post(event); @@ -42,43 +58,17 @@ protected void alert(StoreEvents eventType) { @Override public Set getCollectionNames() { - NitriteMap catalogMap = openMap(COLLECTION_CATALOG, String.class, Document.class); - Document document = catalogMap.get(TAG_COLLECTIONS); - if (document == null) return new HashSet<>(); - - return document.getFields(); + return getCatalog().getCollectionNames(); } @Override public Set getRepositoryRegistry() { - NitriteMap catalogMap = openMap(COLLECTION_CATALOG, String.class, Document.class); - Document document = catalogMap.get(TAG_REPOSITORIES); - if (document == null) return new HashSet<>(); - - return document.getFields(); + return getCatalog().getRepositoryNames(); } @Override public Map> getKeyedRepositoryRegistry() { - NitriteMap catalogMap = openMap(COLLECTION_CATALOG, String.class, Document.class); - Document document = catalogMap.get(TAG_KEYED_REPOSITORIES); - if (document == null) return new HashMap<>(); - - Map> resultMap = new HashMap<>(); - for (String field : document.getFields()) { - String key = getKeyName(field); - String type = getKeyedRepositoryType(field); - - Set types; - if (resultMap.containsKey(key)) { - types = resultMap.get(key); - } else { - types = new HashSet<>(); - } - types.add(type); - resultMap.put(key, types); - } - return resultMap; + return getCatalog().getKeyedRepositoryNames(); } @Override @@ -86,15 +76,6 @@ public void beforeClose() { alert(StoreEvents.Closing); } - @Override - public IndexCatalog getIndexCatalog() { - if (indexCatalog == null) { - indexCatalog = new IndexCatalog(this); - } - - return indexCatalog; - } - @Override public void removeRTree(String mapName) { this.removeMap(mapName); @@ -113,5 +94,11 @@ public void unsubscribe(StoreEventListener listener) { @Override public void initialize(NitriteConfig nitriteConfig) { this.nitriteConfig = nitriteConfig; + this.storeCatalog = new StoreCatalog(this); + } + + @Override + public StoreCatalog getCatalog() { + return storeCatalog; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java b/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java index 4a0cf6647..8da309d87 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java @@ -21,7 +21,10 @@ import org.dizitart.no2.collection.Document; /** + * The nitrite database metadata. + * * @author Anindya Chatterjee. + * @since 4.0 */ @Data @NoArgsConstructor @@ -31,10 +34,20 @@ public class DatabaseMetaData { private String nitriteVersion; private Integer schemaVersion; + /** + * Instantiates a new {@link DatabaseMetaData}. + * + * @param document the document + */ public DatabaseMetaData(Document document) { populateInfo(document); } + /** + * Gets the database info ina document. + * + * @return the info + */ public Document getInfo() { return Document.createDocument() .put("createTime", createTime) diff --git a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java deleted file mode 100644 index 16337f8ea..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/store/IndexCatalog.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.store; - -import org.dizitart.no2.common.FieldNames; -import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.IndexedFieldNames; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexMeta; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.dizitart.no2.common.Constants.*; - -/** - * - * @since 4.0 - * @author Anindya Chatterjee - */ -public class IndexCatalog { - private final NitriteStore nitriteStore; - - public IndexCatalog(NitriteStore nitriteStore) { - this.nitriteStore = nitriteStore; - } - - public boolean hasIndexDescriptor(String collectionName, Fields fields) { - NitriteMap indexMetaMap = getIndexMetaMap(collectionName); - if (!indexMetaMap.containsKey(fields)) return false; - - IndexMeta indexMeta = indexMetaMap.get(fields); - return indexMeta != null; - } - - public IndexDescriptor createIndexDescriptor(String collectionName, Fields fields, String indexType) { - IndexDescriptor index = new IndexDescriptor(indexType, fields, collectionName); - - IndexMeta indexMeta = new IndexMeta(); - indexMeta.setIndexDescriptor(index); - indexMeta.setIsDirty(new AtomicBoolean(false)); - indexMeta.setIndexMap(getIndexMapName(index)); - - getIndexMetaMap(collectionName).put(fields, indexMeta); - - return index; - } - - public IndexDescriptor findIndexDescriptorExact(String collectionName, Fields fields) { - IndexMeta meta = getIndexMetaMap(collectionName).get(fields); - if (meta != null) { - return meta.getIndexDescriptor(); - } - return null; - } - - public Set findIndexSupportedFields(String collectionName) { - Collection indexDescriptors = listIndexDescriptors(collectionName); - Map> fieldIndexMap = new ConcurrentHashMap<>(); - - // get actual index descriptors - for (IndexDescriptor indexDescriptor : indexDescriptors) { - // create all possible combinations of fields in the same order - // if the index field is [a,b,c] then combinations would be - // like - [[a], [a,b], [a,b,c]] - List fieldsCombinations = new ArrayList<>(); - Fields indexFields = indexDescriptor.getIndexFields(); - - // create combinations of fields - for (Pair pair : indexFields.getSortSpecs()) { - FieldNames fn = new FieldNames(); - if (!fieldsCombinations.isEmpty()) { - // get the last field combination and add the current field from the pair - // [a,b] + c -> [a,b,c] - FieldNames lastFields = fieldsCombinations.get(fieldsCombinations.size() - 1); - fn.getNames().addAll(lastFields.getNames()); - } - fn.getNames().add(pair.getFirst()); - fieldsCombinations.add(fn); - } - - // for each combination, create a map with the index - // so, if the Ix1 is on fields [a,b,c], then cache would - // be like - [a] -> Ix1, [a,b] -> Ix1, [a,b,c] -> Ix1 - for (FieldNames fields : fieldsCombinations) { - Set descriptorList = fieldIndexMap.get(fields); - if (descriptorList == null) { - descriptorList = new HashSet<>(); - } - descriptorList.add(indexDescriptor); - fieldIndexMap.put(fields, descriptorList); - } - } - - Set resultSet = new HashSet<>(); - for (Map.Entry> entry : fieldIndexMap.entrySet()) { - IndexedFieldNames fieldNames = new IndexedFieldNames(); - fieldNames.setNames(entry.getKey().getNames()); - fieldNames.setSupportedIndices(entry.getValue()); - resultSet.add(fieldNames); - } - - return resultSet; - } - - public boolean isDirtyIndex(String collectionName, Fields fields) { - IndexMeta meta = getIndexMetaMap(collectionName).get(fields); - return meta != null && meta.getIsDirty().get(); - } - - public Collection listIndexDescriptors(String collectionName) { - Set indexSet = new LinkedHashSet<>(); - for (IndexMeta indexMeta : getIndexMetaMap(collectionName).values()) { - indexSet.add(indexMeta.getIndexDescriptor()); - } - return Collections.unmodifiableSet(indexSet); - } - - public void dropIndexDescriptor(String collectionName, Fields fields) { - IndexMeta meta = getIndexMetaMap(collectionName).get(fields); - if (meta != null && meta.getIndexDescriptor() != null) { - String indexMapName = meta.getIndexMap(); - nitriteStore.openMap(indexMapName, Object.class, Object.class).drop(); - } - getIndexMetaMap(collectionName).remove(fields); - } - - public void beginIndexing(String collectionName, Fields fields) { - markDirty(collectionName, fields, true); - } - - public void endIndexing(String collectionName, Fields fields) { - markDirty(collectionName, fields, false); - } - - public String getIndexMapName(IndexDescriptor descriptor) { - return INDEX_PREFIX + - INTERNAL_NAME_SEPARATOR + - descriptor.getCollectionName() + - INTERNAL_NAME_SEPARATOR + - descriptor.getIndexFields().getEncodedName() + - INTERNAL_NAME_SEPARATOR + - descriptor.getIndexType(); - } - - private NitriteMap getIndexMetaMap(String collectionName) { - String indexMetaName = getIndexMetaName(collectionName); - return nitriteStore.openMap(indexMetaName, Fields.class, IndexMeta.class); - } - - private String getIndexMetaName(String collectionName) { - return INDEX_META_PREFIX + INTERNAL_NAME_SEPARATOR + collectionName; - } - - private void markDirty(String collectionName, Fields fields, boolean dirty) { - IndexMeta meta = getIndexMetaMap(collectionName).get(fields); - if (meta != null && meta.getIndexDescriptor() != null) { - meta.getIsDirty().set(dirty); - } - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java index d2117f7e6..d8675b8f2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java @@ -18,8 +18,8 @@ import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.collection.meta.MetadataAware; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import static org.dizitart.no2.common.Constants.META_MAP_NAME; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; @@ -44,39 +44,32 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { boolean containsKey(Key key); /** - * Gets the value mapped with the specified key or `null` otherwise. + * Gets the value mapped with the specified key or null otherwise. * * @param key the key - * @return the value, or `null` if the key not found. + * @return the value, or null if the key not found. */ Value get(Key key); /** - * Gets the parent {@link NitriteStore} where this map is stored. - * - * @return the store where this map is stored. - */ - NitriteStore getStore(); - - /** - * Remove all entries in the map. + * Removes all entries in the map. */ void clear(); /** - * Gets name of this map. + * Gets a {@link RecordStream} view of the values contained in + * this map. * - * @return the name of this map. + * @return the collection view of all values in this map. */ - String getName(); + Iterable values(); /** - * Gets a {@link RecordStream} view of the values contained in - * this map. + * Gets a {@link RecordStream} view of the keys contained in this map. * - * @return the collection view of all values in this map. + * @return a set view of the keys contained in this map. */ - RecordStream values(); + Iterable keys(); /** * Removes the mapping for a key from this map if it is present. @@ -86,13 +79,6 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { */ Value remove(Key key); - /** - * Gets a {@link RecordStream} view of the keys contained in this map. - * - * @return a set view of the keys contained in this map. - */ - RecordStream keySet(); - /** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for @@ -120,16 +106,6 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { */ Value putIfAbsent(Key key, Value value); - /** - * Gets a {@link RecordStream} view of the mappings contained in this map. - * - * @return a set view of the mappings contained in this map. - */ - RecordStream> entries(); - - - RecordStream> reversedEntries(); - /** * Get the smallest key that is larger than the given key, or null if no * such key exists. @@ -171,13 +147,42 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { */ boolean isEmpty(); + /** + * Gets the parent {@link NitriteStore} where this map is stored. + * + * @return the store where this map is stored. + */ + NitriteStore getStore(); + + /** + * Gets name of this map. + * + * @return the name of this map. + */ + String getName(); + + /** + * Gets a {@link RecordStream} view of the mappings contained in this map. + * + * @return a set view of the mappings contained in this map. + */ + RecordStream> entries(); + + /** + * Gets a reversed {@link RecordStream} view of the mappings contained in this map. + * + * @return the record stream + */ + RecordStream> reversedEntries(); + /** * Deletes the map from the store. */ void drop(); - void close(); - + /** + * Gets the attributes of this map. + * */ default Attributes getAttributes() { NitriteMap metaMap = getStore().openMap(META_MAP_NAME, String.class, Attributes.class); if (metaMap != null && !getName().contentEquals(META_MAP_NAME)) { @@ -186,6 +191,9 @@ default Attributes getAttributes() { return null; } + /** + * Sets the attributes for this map. + * */ default void setAttributes(Attributes attributes) { NitriteMap metaMap = getStore().openMap(META_MAP_NAME, String.class, Attributes.class); if (metaMap != null && !getName().contentEquals(META_MAP_NAME)) { @@ -193,6 +201,9 @@ default void setAttributes(Attributes attributes) { } } + /** + * Update last modified time of the map. + */ default void updateLastModifiedTime() { if (isNullOrEmpty(getName()) || META_MAP_NAME.equals(getName())) return; diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java index a3f3a7173..f222b866a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java @@ -20,16 +20,50 @@ import org.dizitart.no2.common.RecordStream; /** + * Represents an R-Tree in the nitrite database. + * + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee. + * @since 4.0 */ -public interface NitriteRTree { +public interface NitriteRTree extends AutoCloseable { + /** + * Adds a key to the rtree. + * + * @param key the key + * @param nitriteId the nitrite id + */ void add(Key key, NitriteId nitriteId); + /** + * Removes a key from the rtree. + * + * @param key the key + * @param nitriteId the nitrite id + */ void remove(Key key, NitriteId nitriteId); + /** + * Finds the intersecting keys from the rtree. + * + * @param key the key + * @return the record stream + */ RecordStream findIntersectingKeys(Key key); + /** + * Finds the contained keys from the rtree. + * + * @param key the key + * @return the record stream + */ RecordStream findContainedKeys(Key key); + /** + * Gets the size of the rtree. + * + * @return the size + */ long size(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java index fbe528b3a..851447e69 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java @@ -26,19 +26,23 @@ import java.util.Set; /** - * Represents a persistent storage for Nitrite database. + * Represents a storage for Nitrite database. * + * @param the type parameter * @author Anindya Chatterjee * @since 1.0 */ public interface NitriteStore extends NitritePlugin, AutoCloseable { + /** + * Opens or creates this nitrite store. + */ void openOrCreate(); /** * Checks whether this store is closed for further modification. * - * @return `true` if closed; `false` otherwise. + * @return true if closed; false otherwise. */ boolean isClosed(); @@ -66,14 +70,14 @@ public interface NitriteStore extends NitritePlugin, /** * Checks whether there are any unsaved changes. * - * @return `true` if there are any changes; `false` otherwise. + * @return true if here are any changes; false otherwise. */ boolean hasUnsavedChanges(); /** * Checks whether the store is opened in readonly mode. * - * @return `true` if the store is opened in readonly mode.; `false` otherwise. + * @return true if he store is opened in readonly mode; false otherwise. */ boolean isReadOnly(); @@ -84,22 +88,10 @@ public interface NitriteStore extends NitritePlugin, void commit(); /** - * Closes the file and the store. Unsaved changes are written to disk first. - */ - void close(); - - /** - * This method runs before {@link #close()}, to run cleanup routines. + * This method runs before store {@link #close()}, to run cleanup routines. */ void beforeClose(); - /** - * Gets the {@link IndexCatalog} instances from the store. - * - * @return the IndexCatalog instance. - */ - IndexCatalog getIndexCatalog(); - /** * Checks whether a map with the name already exists in the store or not. * @@ -110,8 +102,8 @@ public interface NitriteStore extends NitritePlugin, /** * Opens a {@link NitriteMap} with the default settings. The map is - * automatically create if it does not yet exist. If a map with this - * name is already open, this map is returned. + * automatically created if it does not yet exist. If a map with this + * name is already opened, this map is returned. * * @param the key type * @param the value type @@ -131,7 +123,7 @@ public interface NitriteStore extends NitritePlugin, /** * Opens a {@link NitriteRTree} with the default settings. The RTree is - * automatically create if it does not yet exist. If a RTree with this + * automatically created if it does not yet exist. If a RTree with this * name is already open, this RTree is returned. * * @param the key type @@ -165,16 +157,24 @@ public interface NitriteStore extends NitritePlugin, void unsubscribe(StoreEventListener listener); /** - * Gets underlying store version. + * Gets the underlying store engine version. * * @return the store version */ String getStoreVersion(); /** - * Gets store config. + * Gets the store configuration. * * @return the store config */ Config getStoreConfig(); + + + /** + * Gets the store catalog. + * + * @return the catalog + */ + StoreCatalog getCatalog(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java new file mode 100644 index 000000000..24ca5105d --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.store; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.tuples.Pair; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.dizitart.no2.common.Constants.*; +import static org.dizitart.no2.common.util.ObjectUtils.getKeyName; +import static org.dizitart.no2.common.util.ObjectUtils.getKeyedRepositoryType; + +/** + * The nitrite store catalog containing the name of all collections, + * repositories and keyed-repositories. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class StoreCatalog { + private final NitriteMap catalogMap; + + /** + * Instantiates a new {@link StoreCatalog}. + * + * @param nitriteStore the nitrite store + */ + public StoreCatalog(NitriteStore nitriteStore) { + this.catalogMap = nitriteStore.openMap(COLLECTION_CATALOG, String.class, Document.class); + } + + /** + * Writes a new collection entry to the catalog. + * + * @param name the name + */ + public void writeCollectionEntry(String name) { + Document document = catalogMap.get(TAG_COLLECTIONS); + if (document == null) document = Document.createDocument(); + document.put(name, true); + catalogMap.put(TAG_COLLECTIONS, document); + } + + /** + * Writes a repository entry to the catalog. + * + * @param name the name + */ + public void writeRepositoryEntry(String name) { + Document document = catalogMap.get(TAG_REPOSITORIES); + if (document == null) document = Document.createDocument(); + document.put(name, true); + catalogMap.put(TAG_REPOSITORIES, document); + } + + /** + * Writes a keyed repository entries to the catalog + * + * @param name the name + */ + public void writeKeyedRepositoryEntries(String name) { + Document document = catalogMap.get(TAG_KEYED_REPOSITORIES); + if (document == null) document = Document.createDocument(); + document.put(name, true); + catalogMap.put(TAG_KEYED_REPOSITORIES, document); + } + + /** + * Gets all collection names. + * + * @return the collection names + */ + public Set getCollectionNames() { + Document document = catalogMap.get(TAG_COLLECTIONS); + if (document == null) return new HashSet<>(); + + return document.getFields(); + } + + /** + * Gets all repository names. + * + * @return the repository names + */ + public Set getRepositoryNames() { + Document document = catalogMap.get(TAG_REPOSITORIES); + if (document == null) return new HashSet<>(); + + return document.getFields(); + } + + /** + * Gets all keyed repository names. + * + * @return the keyed repository names + */ + public Map> getKeyedRepositoryNames() { + Document document = catalogMap.get(TAG_KEYED_REPOSITORIES); + if (document == null) return new HashMap<>(); + + Map> resultMap = new HashMap<>(); + for (String field : document.getFields()) { + String key = getKeyName(field); + String type = getKeyedRepositoryType(field); + + Set types; + if (resultMap.containsKey(key)) { + types = resultMap.get(key); + } else { + types = new HashSet<>(); + } + types.add(type); + resultMap.put(key, types); + } + return resultMap; + } + + /** + * Removes the entry from the catalog specified by name. + * + * @param name the name + */ + public void remove(String name) { + // iterate over all types of catalog and find which type contains the name + // remove the name from there + for (Pair entry : catalogMap.entries()) { + String catalogue = entry.getFirst(); + Document document = entry.getSecond(); + + if (document.containsKey(name)) { + document.remove(name); + catalogMap.put(catalogue, document); + break; + } + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreConfig.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreConfig.java index 2d3f8cd2f..9e3ea8106 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/StoreConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreConfig.java @@ -23,7 +23,7 @@ * Represents a {@link NitriteStore} configuration. * * @author Anindya Chatterjee. - * @since 4.0.0 + * @since 4.0 */ public interface StoreConfig { /** @@ -36,7 +36,7 @@ public interface StoreConfig { /** * Indicates if the {@link NitriteStore} is a readonly store. * - * @return `true`, if readonly store; otherwise `false`. + * @return true, if readonly store; otherwise false. */ Boolean isReadOnly(); @@ -50,7 +50,7 @@ public interface StoreConfig { /** * Indicates if the {@link NitriteStore} is an in-memory store. * - * @return `true`, if in-memory store; otherwise `false`. + * @return true, if in-memory store; otherwise false. */ default boolean isInMemory() { return StringUtils.isNullOrEmpty(filePath()); diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java index e04f56350..323091547 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java @@ -3,8 +3,16 @@ import org.dizitart.no2.module.NitriteModule; /** + * Represents a nitrite store module to load as a storage engine for the database. + * * @author Anindya Chatterjee + * @since 4.0 */ public interface StoreModule extends NitriteModule { + /** + * Gets the {@link NitriteStore} instance from this module. + * + * @return the store + */ NitriteStore getStore(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreSecurity.java b/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java similarity index 68% rename from nitrite/src/main/java/org/dizitart/no2/store/StoreSecurity.java rename to nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java index 1f0fa9453..bbeea1e9e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/StoreSecurity.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dizitart.no2.store; import lombok.extern.slf4j.Slf4j; @@ -10,37 +27,40 @@ import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; -import java.util.Random; import static org.dizitart.no2.common.Constants.*; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; /** + * User authentication service for nitrite. + * * @author Anindya Chatterjee + * @since 4.0 */ @Slf4j -public class StoreSecurity { - private static final Random random = new SecureRandom(); - - private StoreSecurity() {} - - public static void authenticate(NitriteStore store, String username, String password, boolean existing) { - /* - * 1. Proper user password create - * 2. Proper user password open - * 3. Blank user password for secured store - * 4. Wrong user password for secured store - * 5. User Password for un-secured store - * */ +public class UserAuthenticationService { + private final SecureRandom random; + private final NitriteStore store; + + /** + * Instantiates a new {@link UserAuthenticationService}. + * + * @param store the store + */ + public UserAuthenticationService(NitriteStore store) { + this.store = store; + this.random = new SecureRandom(); + } + /** + * Authenticates a user if the authentication data already exists in the database. + * + * @param username the username + * @param password the password + * @param existing indicates if authentication data is already existing + */ + public void authenticate(String username, String password, boolean existing) { if (!isNullOrEmpty(password) && !isNullOrEmpty(username)) { - /* - * 1. create new - * 2. open existing correct - * 3. open existing incorrect - * 4. open un-secured existing [how do I know if db already existing and user/pass not required?] - * */ - if (!existing) { byte[] salt = getNextSalt(); byte[] hash = hash(password.toCharArray(), salt); @@ -66,18 +86,22 @@ public static void authenticate(NitriteStore store, String username, String p } } } else if (existing) { - /* - * 1. create new un-secured - * 2. open un-secured - * */ if (store.hasMap(USER_MAP)) { throw new SecurityException("username or password is invalid"); } } } - public static void addOrUpdatePassword(NitriteStore store, boolean update, String username, - SecureString oldPassword, SecureString newPassword) { + /** + * Adds or updates the password for a user in the authentication data. + * + * @param update the update + * @param username the username + * @param oldPassword the old password + * @param newPassword the new password + */ + public void addOrUpdatePassword(boolean update, String username, + SecureString oldPassword, SecureString newPassword) { NitriteMap userMap = null; if (update) { @@ -111,23 +135,14 @@ public static void addOrUpdatePassword(NitriteStore store, boolean update, St userMap.put(username, userCredential); } - private static boolean notExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) { - byte[] pwdHash = hash(password, salt); - Arrays.fill(password, Character.MIN_VALUE); - if (pwdHash.length != expectedHash.length) return true; - for (int i = 0; i < pwdHash.length; i++) { - if (pwdHash[i] != expectedHash[i]) return true; - } - return false; - } - private static byte[] getNextSalt() { + private byte[] getNextSalt() { byte[] salt = new byte[16]; random.nextBytes(salt); return salt; } - private static byte[] hash(char[] password, byte[] salt) { + private byte[] hash(char[] password, byte[] salt) { PBEKeySpec spec = new PBEKeySpec(password, salt, HASH_ITERATIONS, HASH_KEY_LENGTH); Arrays.fill(password, Character.MIN_VALUE); try { @@ -141,4 +156,14 @@ private static byte[] hash(char[] password, byte[] salt) { spec.clearPassword(); } } + + private boolean notExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) { + byte[] pwdHash = hash(password, salt); + Arrays.fill(password, Character.MIN_VALUE); + if (pwdHash.length != expectedHash.length) return true; + for (int i = 0; i < pwdHash.length; i++) { + if (pwdHash[i] != expectedHash[i]) return true; + } + return false; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/UserCredential.java b/nitrite/src/main/java/org/dizitart/no2/store/UserCredential.java index e849abe92..ff25a6333 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/UserCredential.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/UserCredential.java @@ -24,8 +24,10 @@ import java.io.Serializable; /** - * @since 1.0 + * The user credential data for database authentication. + * * @author Anindya Chatterjee. + * @since 1.0 */ @Data public class UserCredential implements Serializable { diff --git a/nitrite/src/main/java/org/dizitart/no2/store/events/EventInfo.java b/nitrite/src/main/java/org/dizitart/no2/store/events/EventInfo.java index c2161ba2b..49bd27bc1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/events/EventInfo.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/events/EventInfo.java @@ -22,7 +22,10 @@ import org.dizitart.no2.NitriteConfig; /** + * The nitrite event details. + * * @author Anindya Chatterjee + * @since 4.0 */ @Data @NoArgsConstructor diff --git a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventBus.java b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventBus.java index 4e90ba489..a899b7701 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventBus.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventBus.java @@ -19,8 +19,11 @@ import org.dizitart.no2.common.event.NitriteEventBus; /** - * @since 4.0.0 + * The event bus for nitrite store events. + * + * @see StoreEvents * @author Anindya Chatterjee. + * @since 4.0.0 */ public class StoreEventBus extends NitriteEventBus { @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventListener.java b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventListener.java index 251d9b041..0e9a248ff 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventListener.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEventListener.java @@ -17,8 +17,17 @@ package org.dizitart.no2.store.events; /** + * Represents an event listener for store events. + * + * @see StoreEvents * @author Anindya Chatterjee + * @since 4.0 */ public interface StoreEventListener { + /** + * Executes when an event is fired. + * + * @param eventInfo the event info + */ void onEvent(EventInfo eventInfo); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEvents.java b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEvents.java index bd239b270..c5fbb36f5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEvents.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/events/StoreEvents.java @@ -17,11 +17,29 @@ package org.dizitart.no2.store.events; /** + * Nitrite store related events. + * * @author Anindya Chatterjee + * @since 4.0 */ public enum StoreEvents { + /** + * The store opened event. + */ Opened, + + /** + * The store commit event. + */ Commit, + + /** + * The store closing event. + */ Closing, + + /** + * The store closed event. + */ Closed } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryConfig.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryConfig.java index 76b559a17..377075e02 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryConfig.java @@ -11,7 +11,10 @@ import java.util.Set; /** + * The in-memory nitrite store config. + * * @author Anindya Chatterjee + * @since 4.0 */ @Accessors(fluent = true) public class InMemoryConfig implements StoreConfig { @@ -19,6 +22,9 @@ public class InMemoryConfig implements StoreConfig { @Setter(AccessLevel.PACKAGE) private Set eventListeners; + /** + * Instantiates a new {@link InMemoryConfig}. + */ InMemoryConfig() { this.eventListeners = new HashSet<>(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java index 92db60239..cd1d1c212 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java @@ -15,7 +15,12 @@ import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** + * The in-memory {@link NitriteMap}. + * + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ public class InMemoryMap implements NitriteMap { private final NavigableMap backingMap; @@ -23,6 +28,12 @@ public class InMemoryMap implements NitriteMap { private final NitriteStore nitriteStore; private final String mapName; + /** + * Instantiates a new {@link InMemoryMap}. + * + * @param mapName the map name + * @param nitriteStore the nitrite store + */ public InMemoryMap(String mapName, NitriteStore nitriteStore) { this.mapName = mapName; this.nitriteStore = nitriteStore; @@ -83,7 +94,7 @@ public Value remove(Key key) { } @Override - public RecordStream keySet() { + public RecordStream keys() { return RecordStream.fromIterable(() -> new Iterator() { final Iterator keyIterator = backingMap.keySet().iterator(); final Iterator nullEntryIterator = nullEntryMap.keySet().iterator(); diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryModuleBuilder.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryModuleBuilder.java index 94e352ff8..c9bfa6fb8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryModuleBuilder.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryModuleBuilder.java @@ -8,7 +8,10 @@ import java.util.Set; /** + * The in-memory store module builder. + * * @author Anindya Chatterjee + * @since 4.0 */ @Getter @Accessors(fluent = true) @@ -16,16 +19,30 @@ public class InMemoryModuleBuilder { private final Set eventListeners; private final InMemoryConfig dbConfig; + /** + * Instantiates a new {@link InMemoryModuleBuilder}. + */ InMemoryModuleBuilder() { dbConfig = new InMemoryConfig(); eventListeners = new HashSet<>(); } + /** + * Adds a {@link StoreEventListener} to the in-memory module builder. + * + * @param listener the listener + * @return the in memory module builder + */ public InMemoryModuleBuilder addStoreEventListener(StoreEventListener listener) { eventListeners.add(listener); return this; } + /** + * Builds an in-memory store module. + * + * @return the in memory store module + */ public InMemoryStoreModule build() { InMemoryStoreModule module = new InMemoryStoreModule(); dbConfig.eventListeners(eventListeners()); diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java index 3a418abad..ec54d6cb5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java @@ -12,12 +12,19 @@ import java.util.concurrent.ConcurrentHashMap; /** + * The in-memory {@link NitriteRTree}. * + * @param the type parameter + * @param the type parameter * @author Anindya Chatterjee + * @since 4.0 */ public class InMemoryRTree implements NitriteRTree { private final Map backingMap; + /** + * Instantiates a new {@link InMemoryRTree}. + */ public InMemoryRTree() { this.backingMap = new ConcurrentHashMap<>(); } @@ -100,36 +107,84 @@ private SpatialKey getKey(Key key, long id) { key.getMaxX(), key.getMinY(), key.getMaxY()); } + @Override + public void close() throws Exception { + + } + + /** + * The type Spatial key. + */ static class SpatialKey { private final long id; private final float[] minMax; + /** + * Instantiates a new Spatial key. + * + * @param id the id + * @param minMax the min max + */ public SpatialKey(long id, float... minMax) { this.id = id; this.minMax = minMax; } + /** + * Min float. + * + * @param dim the dim + * @return the float + */ public float min(int dim) { return minMax[dim + dim]; } + /** + * Sets min. + * + * @param dim the dim + * @param x the x + */ public void setMin(int dim, float x) { minMax[dim + dim] = x; } + /** + * Max float. + * + * @param dim the dim + * @return the float + */ public float max(int dim) { return minMax[dim + dim + 1]; } + /** + * Sets max. + * + * @param dim the dim + * @param x the x + */ public void setMax(int dim, float x) { minMax[dim + dim + 1] = x; } + /** + * Gets id. + * + * @return the id + */ public long getId() { return id; } + /** + * Is null boolean. + * + * @return the boolean + */ public boolean isNull() { return minMax.length == 0; } @@ -153,6 +208,12 @@ public boolean equals(Object other) { return equalsIgnoringId(o); } + /** + * Equals ignoring id boolean. + * + * @param o the o + * @return the boolean + */ public boolean equalsIgnoringId(SpatialKey o) { return Arrays.equals(minMax, o.minMax); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java index a24bd993f..66afe540a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java @@ -13,13 +13,19 @@ import static org.dizitart.no2.common.Constants.NITRITE_VERSION; /** + * The nitrite in-memory store. + * * @author Anindya Chatterjee + * @since 4.0 */ public final class InMemoryStore extends AbstractNitriteStore { private final Map> nitriteMapRegistry; private final Map> nitriteRTreeMapRegistry; private volatile boolean closed = false; + /** + * Instantiates a new {@link InMemoryStore}. + */ public InMemoryStore() { super(); this.nitriteMapRegistry = new ConcurrentHashMap<>(); @@ -53,8 +59,17 @@ public void commit() { } @Override - public void close() { + public void close() throws Exception { closed = true; + + for (NitriteMap map : nitriteMapRegistry.values()) { + map.close(); + } + + for (NitriteRTree rTree : nitriteRTreeMapRegistry.values()) { + rTree.close(); + } + alert(StoreEvents.Closed); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java index 21af18b6f..ef42e892c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java @@ -8,18 +8,31 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** + * The in-memory store module for nitrite. + * * @author Anindya Chatterjee + * @since 4.0 */ public class InMemoryStoreModule implements StoreModule { @Setter(AccessLevel.PACKAGE) private InMemoryConfig storeConfig; + /** + * Instantiates a new {@link InMemoryStoreModule}. + */ public InMemoryStoreModule() { this.storeConfig = new InMemoryConfig(); } + /** + * Creates an {@link InMemoryModuleBuilder} to configure the in-memory store. + * + * @return the in memory module builder + */ public static InMemoryModuleBuilder withConfig() { return new InMemoryModuleBuilder(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/ChangeType.java b/nitrite/src/main/java/org/dizitart/no2/transaction/ChangeType.java index 2768c6894..6c4ab7323 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/ChangeType.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/ChangeType.java @@ -1,17 +1,69 @@ package org.dizitart.no2.transaction; /** + * Represents a change type in a transaction. + * * @author Anindya Chatterjee + * @since 4.0 */ enum ChangeType { + /** + * Insert + */ Insert, + + /** + * Update. + */ Update, + + /** + * Remove. + */ Remove, + + /** + * Clear. + */ Clear, + + /** + * Create index. + */ CreateIndex, + + /** + * Rebuild index. + */ RebuildIndex, + + /** + * Drop index. + */ DropIndex, + + /** + * Drop all indices. + */ DropAllIndices, + + /** + * Drop collection. + */ DropCollection, - SetAttribute + + /** + * Set attribute. + */ + SetAttribute, + + /** + * Add processor + * */ + AddProcessor, + + /** + * Remove processor + * */ + RemoveProcessor, } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/Command.java b/nitrite/src/main/java/org/dizitart/no2/transaction/Command.java index 4335e49de..c7856c234 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/Command.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/Command.java @@ -1,8 +1,14 @@ package org.dizitart.no2.transaction; /** + * Represents an operation in a transaction. + * * @author Anindya Chatterjee + * @since 4.0 */ interface Command { + /** + * Executes the command during transaction commit or rollback. + */ void execute(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java index 015809d7c..6ad0c4c4e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java @@ -17,10 +17,12 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -35,6 +37,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ @Data class DefaultTransactionalCollection implements NitriteCollection { @@ -229,23 +232,12 @@ public WriteResult remove(Filter filter, boolean justOne) { } @Override - public DocumentCursor find() { - checkOpened(); - try { - readLock.lock(); - return collectionOperations.find(); - } finally { - readLock.unlock(); - } - } - - @Override - public DocumentCursor find(Filter filter) { + public DocumentCursor find(Filter filter, FindOptions findOptions) { checkOpened(); try { readLock.lock(); - return collectionOperations.find(filter); + return collectionOperations.find(filter, findOptions); } finally { readLock.unlock(); } @@ -270,18 +262,44 @@ public String getName() { } @Override - public void createIndex(Fields fields, IndexOptions indexOptions) { + public void addProcessor(Processor processor) { checkOpened(); - notNull(fields, "fields cannot be null"); + notNull(processor, "a null processor cannot be added"); + collectionOperations.addProcessor(processor); + + JournalEntry journalEntry = new JournalEntry(); + journalEntry.setChangeType(ChangeType.AddProcessor); + journalEntry.setCommit(() -> primary.addProcessor(processor)); + journalEntry.setRollback(() -> primary.removeProcessor(processor)); + transactionContext.getJournal().add(journalEntry); + } + + @Override + public void removeProcessor(Processor processor) { + checkOpened(); + notNull(processor, "a null processor cannot be removed"); + collectionOperations.addProcessor(processor); + + JournalEntry journalEntry = new JournalEntry(); + journalEntry.setChangeType(ChangeType.RemoveProcessor); + journalEntry.setCommit(() -> primary.removeProcessor(processor)); + journalEntry.setRollback(() -> primary.addProcessor(processor)); + transactionContext.getJournal().add(journalEntry); + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fieldNames) { + checkOpened(); + notNull(fieldNames, "fieldNames cannot be null"); // by default async is false while creating index try { + Fields fields = Fields.withNames(fieldNames); writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(fields, IndexType.Unique, false); + collectionOperations.createIndex(fields, IndexType.Unique); } else { - collectionOperations.createIndex(fields, indexOptions.getIndexType(), - indexOptions.isAsync()); + collectionOperations.createIndex(fields, indexOptions.getIndexType()); } } finally { writeLock.unlock(); @@ -289,18 +307,19 @@ public void createIndex(Fields fields, IndexOptions indexOptions) { JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.CreateIndex); - journalEntry.setCommit(() -> primary.createIndex(fields, indexOptions)); - journalEntry.setRollback(() -> primary.dropIndex(fields)); + journalEntry.setCommit(() -> primary.createIndex(indexOptions, fieldNames)); + journalEntry.setRollback(() -> primary.dropIndex(fieldNames)); transactionContext.getJournal().add(journalEntry); } @Override - public void rebuildIndex(Fields fields, boolean isAsync) { + public void rebuildIndex(String... fieldNames) { checkOpened(); - notNull(fields, "fields cannot be null"); + notNull(fieldNames, "fieldNames cannot be null"); IndexDescriptor indexDescriptor; try { + Fields fields = Fields.withNames(fieldNames); readLock.lock(); indexDescriptor = collectionOperations.findIndex(fields); } finally { @@ -312,18 +331,18 @@ public void rebuildIndex(Fields fields, boolean isAsync) { try { writeLock.lock(); - collectionOperations.rebuildIndex(indexDescriptor, isAsync); + collectionOperations.rebuildIndex(indexDescriptor); } finally { writeLock.unlock(); } } else { - throw new IndexingException(fields + " is not indexed"); + throw new IndexingException(Arrays.toString(fieldNames) + " is not indexed"); } JournalEntry journalEntry = new JournalEntry(); journalEntry.setChangeType(ChangeType.RebuildIndex); - journalEntry.setCommit(() -> primary.rebuildIndex(fields, isAsync)); - journalEntry.setRollback(() -> primary.rebuildIndex(fields, isAsync)); + journalEntry.setCommit(() -> primary.rebuildIndex(fieldNames)); + journalEntry.setRollback(() -> primary.rebuildIndex(fieldNames)); transactionContext.getJournal().add(journalEntry); } @@ -340,11 +359,12 @@ public Collection listIndices() { } @Override - public boolean hasIndex(Fields fields) { + public boolean hasIndex(String... fieldNames) { checkOpened(); - notNull(fields, "fields cannot be null"); + notNull(fieldNames, "fieldNames cannot be null"); try { + Fields fields = Fields.withNames(fieldNames); readLock.lock(); return collectionOperations.hasIndex(fields); } finally { @@ -353,11 +373,12 @@ public boolean hasIndex(Fields fields) { } @Override - public boolean isIndexing(Fields fields) { + public boolean isIndexing(String... fieldNames) { checkOpened(); - notNull(fields, "fields cannot be null"); + notNull(fieldNames, "fieldNames cannot be null"); try { + Fields fields = Fields.withNames(fieldNames); readLock.lock(); return collectionOperations.isIndexing(fields); } finally { @@ -366,10 +387,11 @@ public boolean isIndexing(Fields fields) { } @Override - public void dropIndex(Fields fields) { + public void dropIndex(String... fieldNames) { checkOpened(); - notNull(fields, "fields cannot be null"); + notNull(fieldNames, "fieldNames cannot be null"); + Fields fields = Fields.withNames(fieldNames); try { writeLock.lock(); collectionOperations.dropIndex(fields); @@ -388,12 +410,11 @@ public void dropIndex(Fields fields) { break; } } - primary.dropIndex(fields); + primary.dropIndex(fieldNames); }); journalEntry.setRollback(() -> { if (indexEntry.get() != null) { - primary.createIndex(indexEntry.get().getIndexFields(), - indexOptions(indexEntry.get().getIndexType())); + primary.createIndex(indexOptions(indexEntry.get().getIndexType()), fieldNames); } }); transactionContext.getJournal().add(journalEntry); @@ -420,8 +441,8 @@ public void dropAllIndices() { }); journalEntry.setRollback(() -> { for (IndexDescriptor indexDescriptor : indexEntries) { - primary.createIndex(indexDescriptor.getIndexFields(), - indexOptions(indexDescriptor.getIndexType())); + String[] fieldNames = indexDescriptor.getIndexFields().getFieldNames().toArray(new String[0]); + primary.createIndex(indexOptions(indexDescriptor.getIndexType()), fieldNames); } }); transactionContext.getJournal().add(journalEntry); @@ -479,8 +500,8 @@ public void drop() { NitriteCollection collection = nitrite.getCollection(collectionName); for (IndexDescriptor indexDescriptor : indexEntries) { - collection.createIndex(indexDescriptor.getIndexFields(), - indexOptions(indexDescriptor.getIndexType())); + String[] fieldNames = indexDescriptor.getIndexFields().getFieldNames().toArray(new String[0]); + collection.createIndex(indexOptions(indexDescriptor.getIndexType()), fieldNames); } for (Document document : documentList) { @@ -498,13 +519,17 @@ public boolean isDropped() { @Override public boolean isOpen() { if (nitriteStore == null || nitriteStore.isClosed() || isDropped) { - close(); + try { + close(); + } catch (Exception e) { + throw new NitriteIOException("failed to close the database", e); + } return false; } else return true; } @Override - public void close() { + public void close() throws Exception { if (collectionOperations != null) { collectionOperations.close(); } @@ -622,7 +647,7 @@ private void checkOpened() { } } - private void closeEventBus() { + private void closeEventBus() throws Exception { if (eventBus != null) { eventBus.close(); } @@ -632,7 +657,8 @@ private void closeEventBus() { private void validateRebuildIndex(IndexDescriptor indexDescriptor) { notNull(indexDescriptor, "indexEntry cannot be null"); - if (isIndexing(indexDescriptor.getIndexFields())) { + String[] fieldNames = indexDescriptor.getIndexFields().getFieldNames().toArray(new String[0]); + if (isIndexing(fieldNames)) { throw new IndexingException("indexing on value " + indexDescriptor.getIndexFields() + " is currently running"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java index b96b3af2b..6d0029e00 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java @@ -2,15 +2,16 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.RepositoryOperations; @@ -24,6 +25,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ class DefaultTransactionalRepository implements ObjectRepository { private final Class type; @@ -44,13 +46,23 @@ public DefaultTransactionalRepository(Class type, } @Override - public void createIndex(Fields fields, IndexOptions indexOptions) { - backingCollection.createIndex(fields, indexOptions); + public void addProcessor(Processor processor) { + backingCollection.addProcessor(processor); } @Override - public void rebuildIndex(Fields fields, boolean isAsync) { - backingCollection.rebuildIndex(fields, isAsync); + public void removeProcessor(Processor processor) { + backingCollection.removeProcessor(processor); + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fieldNames) { + backingCollection.createIndex(indexOptions, fieldNames); + } + + @Override + public void rebuildIndex(String... fieldNames) { + backingCollection.rebuildIndex(fieldNames); } @Override @@ -59,18 +71,18 @@ public Collection listIndices() { } @Override - public boolean hasIndex(Fields fields) { - return backingCollection.hasIndex(fields); + public boolean hasIndex(String... fieldNames) { + return backingCollection.hasIndex(fieldNames); } @Override - public boolean isIndexing(Fields fields) { - return backingCollection.isIndexing(fields); + public boolean isIndexing(String... fieldNames) { + return backingCollection.isIndexing(fieldNames); } @Override - public void dropIndex(Fields fields) { - backingCollection.dropIndex(fields); + public void dropIndex(String... fieldNames) { + backingCollection.dropIndex(fieldNames); } @Override @@ -131,13 +143,8 @@ public void clear() { } @Override - public Cursor find() { - return operations.find(type); - } - - @Override - public Cursor find(Filter filter) { - return operations.find(filter, type); + public Cursor find(Filter filter, FindOptions findOptions) { + return operations.find(filter, findOptions, type); } @Override @@ -166,7 +173,7 @@ public boolean isOpen() { } @Override - public void close() { + public void close() throws Exception { backingCollection.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/JournalEntry.java b/nitrite/src/main/java/org/dizitart/no2/transaction/JournalEntry.java index 492edf39c..73de9719a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/JournalEntry.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/JournalEntry.java @@ -5,7 +5,10 @@ import lombok.NoArgsConstructor; /** + * Represents a transaction journal entry. + * * @author Anindya Chatterjee + * @since 4.0 */ @Data @AllArgsConstructor diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java b/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java index 6f6b3549f..a24650c56 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java @@ -20,6 +20,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ @Slf4j class NitriteTransaction implements Transaction { @@ -228,16 +229,20 @@ public void rollback() { @Override public void close() { - state = State.Closed; - for (TransactionContext context : contextMap.values()) { - context.getActive().set(false); - } + try { + state = State.Closed; + for (TransactionContext context : contextMap.values()) { + context.getActive().set(false); + } - this.contextMap.clear(); - this.collectionRegistry.clear(); - this.repositoryRegistry.clear(); - this.undoRegistry.clear(); - this.transactionalStore.close(); + this.contextMap.clear(); + this.collectionRegistry.clear(); + this.repositoryRegistry.clear(); + this.undoRegistry.clear(); + this.transactionalStore.close(); + } catch (Exception e) { + throw new TransactionException("transaction failed to close", e); + } } private void prepare() { diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/Session.java b/nitrite/src/main/java/org/dizitart/no2/transaction/Session.java index 74ad2f823..7a8c0a93c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/Session.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/Session.java @@ -4,20 +4,35 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.TransactionException; -import java.io.Closeable; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; /** + * A nitrite transaction session. A session is needed to + * initiate a transaction in nitrite database. + * + *

    + * If a session is closed and the transaction is not committed, + * all opened transactions will get rolled back and all volatile + * data gets discarded for the session. + *

    + * * @author Anindya Chatterjee + * @since 4.0 */ -public class Session implements Closeable { +public class Session implements AutoCloseable { private final Nitrite nitrite; private final AtomicBoolean active; private final LockService lockService; private final Map transactionMap; + /** + * Instantiates a new Session. + * + * @param nitrite the nitrite + * @param lockService the lock service + */ public Session(Nitrite nitrite, LockService lockService) { this.nitrite = nitrite; this.active = new AtomicBoolean(true); @@ -25,6 +40,11 @@ public Session(Nitrite nitrite, LockService lockService) { this.transactionMap = new HashMap<>(); } + /** + * Begins a new transaction. + * + * @return the transaction + */ public Transaction beginTransaction() { checkState(); @@ -43,6 +63,13 @@ public void close() { } } + /** + * Checks state of the session. If the session is not active, + * it will throw a {@link TransactionException}. + * + * @throws TransactionException when the session is not active, + * and a transaction is initiated in this session. + */ public void checkState() { if (!active.get()) { throw new TransactionException("this session is not active"); diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/State.java b/nitrite/src/main/java/org/dizitart/no2/transaction/State.java index bc4a438b7..39bad9902 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/State.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/State.java @@ -1,13 +1,39 @@ package org.dizitart.no2.transaction; /** + * The transaction state. + * * @author Anindya Chatterjee + * @since 4.0 */ public enum State { + /** + * Transaction is active. + */ Active, + + /** + * Transaction is partially committed. + */ PartiallyCommitted, + + /** + * Transaction is fully committed. + */ Committed, + + /** + * Transaction is closed. + */ Closed, + + /** + * Transaction is failed. + */ Failed, + + /** + * Transaction is aborted. + */ Aborted, } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java b/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java index 77b40e922..d1c8a2d9e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java @@ -3,25 +3,64 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.repository.ObjectRepository; -import java.io.Closeable; - /** + * Represents an ACID transaction on nitrite database. + * * @author Anindya Chatterjee + * @since 4.0 */ -public interface Transaction extends Closeable { +public interface Transaction extends AutoCloseable { + /** + * Gets the transaction id. + * + * @return the id + */ String getId(); + /** + * Gets the current state of the transaction. + * + * @return the state + */ State getState(); + /** + * Gets a {@link NitriteCollection} to perform ACID operations on it. + * + * @param name the name + * @return the collection + */ NitriteCollection getCollection(String name); + /** + * Gets an {@link ObjectRepository} to perform ACID operations on it. + * + * @param the type parameter + * @param type the type + * @return the repository + */ ObjectRepository getRepository(Class type); + /** + * Gets an {@link ObjectRepository} to perform ACID operations on it. + * + * @param the type parameter + * @param type the type + * @param key the key + * @return the repository + */ ObjectRepository getRepository(Class type, String key); + /** + * Completes the transaction and commits the data to the underlying store. + */ void commit(); + /** + * Rolls back the changes. + */ void rollback(); + @Override void close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionContext.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionContext.java index b86598cbe..31ce4b7a7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionContext.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionContext.java @@ -10,6 +10,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ @Data class TransactionContext implements AutoCloseable { @@ -24,7 +25,7 @@ public TransactionContext() { } @Override - public void close() { + public void close() throws Exception { journal.clear(); nitriteMap.clear(); nitriteMap.close(); diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java index e1816adca..eafa902fc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java @@ -2,46 +2,35 @@ import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.exceptions.NitriteIOException; +import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.module.NitriteModule; import org.dizitart.no2.store.NitriteStore; -import java.util.HashMap; -import java.util.Map; - /** * @author Anindya Chatterjee + * @since 4.0 */ @Slf4j class TransactionalConfig extends NitriteConfig { private final NitriteConfig config; private final TransactionalStore transactionalStore; - private final Map indexerMap; public TransactionalConfig(NitriteConfig config, TransactionalStore transactionalStore) { + super(); this.config = config; this.transactionalStore = transactionalStore; - this.indexerMap = new HashMap<>(); } @Override public NitriteIndexer findIndexer(String indexType) { - if (indexerMap.containsKey(indexType)) { - return indexerMap.get(indexType); - } - - try { - NitriteIndexer nitriteIndexer = config.findIndexer(indexType).clone(); - if (nitriteIndexer != null) { - nitriteIndexer.initialize(this); - indexerMap.put(indexType, nitriteIndexer); - } + NitriteIndexer nitriteIndexer = pluginManager.getIndexerMap().get(indexType); + if (nitriteIndexer != null) { + nitriteIndexer.initialize(this); return nitriteIndexer; - } catch (CloneNotSupportedException e) { - log.error("Failed to clone indexer", e); - throw new NitriteIOException("error while cloning indexer", e); + } else { + throw new IndexingException("no indexer found for index type " + indexType); } } @@ -52,12 +41,13 @@ public void fieldSeparator(String separator) { @Override public NitriteConfig loadModule(NitriteModule module) { - return config.loadModule(module); + pluginManager.loadModule(module); + return this; } @Override public void autoConfigure() { - config.autoConfigure(); + pluginManager.findAndLoadPlugins(); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java index 564c64cf2..4ca11080d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java @@ -13,6 +13,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ @SuppressWarnings("SortedCollectionWithNonComparableKeys") class TransactionalMap implements NitriteMap { @@ -109,13 +110,13 @@ public V remove(K k) { } @Override - public RecordStream keySet() { + public RecordStream keys() { if (cleared) { return RecordStream.empty(); } - return RecordStream.fromCombined(RecordStream.except(primary.keySet(), tombstones), - backingMap.keySet()); + return RecordStream.fromCombined(RecordStream.except(primary.keys(), tombstones), + backingMap.keys()); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java index 63bebcc58..74c3de933 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java @@ -9,6 +9,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ class TransactionalRTree implements NitriteRTree { private final Map map; @@ -99,6 +100,11 @@ private SpatialKey getKey(Key key, long id) { key.getMaxX(), key.getMinY(), key.getMaxY()); } + @Override + public void close() throws Exception { + map.clear(); + } + /* * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (https://h2database.com/html/license.html). diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java index 3976d792a..87e151c9f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java @@ -11,6 +11,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ class TransactionalStore extends AbstractNitriteStore { private final NitriteStore primaryStore; @@ -49,8 +50,14 @@ public void commit() { } @Override - public void close() { - // nothing to do + public void close() throws Exception { + for (NitriteMap nitriteMap : mapRegistry.values()) { + nitriteMap.close(); + } + + for (NitriteRTree rTree : rTreeRegistry.values()) { + rTree.close(); + } } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/UndoEntry.java b/nitrite/src/main/java/org/dizitart/no2/transaction/UndoEntry.java index 41e9b3fe0..a75aab198 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/UndoEntry.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/UndoEntry.java @@ -4,6 +4,7 @@ /** * @author Anindya Chatterjee + * @since 4.0 */ @Data class UndoEntry { diff --git a/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java index 44ff99c11..f2796c16a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java @@ -79,9 +79,9 @@ public void testCollection() { }); NitriteCollection collection = db.getCollection("test"); - collection.createIndex("color", indexOptions(IndexType.Unique)); - collection.createIndex("books.tag", indexOptions(IndexType.NonUnique)); - collection.createIndex("books.name", indexOptions(IndexType.Fulltext)); + collection.createIndex("color"); + collection.createIndex(indexOptions(IndexType.NonUnique), "books.tag"); + collection.createIndex(indexOptions(IndexType.Fulltext), "books.name"); WriteResult writeResult = collection.insert(doc1, doc2, doc3); assertEquals(writeResult.getAffectedCount(), 3); diff --git a/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java index 518a1b56b..7ba99494f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java @@ -32,7 +32,7 @@ public class CustomFilterTest extends BaseCollectionTest { @Test public void testCustomFilter() { insert(); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); DocumentCursor cursor = collection.find(element -> element.getSecond().get("firstName", String.class) .equalsIgnoreCase("FN1")); diff --git a/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java b/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java index ef5cfd217..4bdf06148 100644 --- a/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java +++ b/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java @@ -25,13 +25,13 @@ import org.junit.Rule; import java.io.File; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import static org.dizitart.no2.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; import static org.junit.Assert.assertEquals; @@ -55,12 +55,12 @@ public static String getRandomTempDbFile() { return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; } - void createDb() { + void createDb() throws Exception { db = TestUtil.createDb(); db.close(); } - void writeCollection() { + void writeCollection() throws Exception { NitriteCollection collection; db = TestUtil.createDb(); @@ -70,20 +70,20 @@ void writeCollection() { db.close(); } - void writeIndex() { + void writeIndex() throws Exception { NitriteCollection collection; db = TestUtil.createDb(); collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); db.close(); } - void insertInCollection() throws ParseException { + void insertInCollection() throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); Document doc1 = createDocument("firstName", "fn1") @@ -116,7 +116,7 @@ void insertInCollection() throws ParseException { db.close(); } - void readCollection() throws ParseException { + void readCollection() throws Exception { NitriteCollection collection; db = TestUtil.createDb(); @@ -157,15 +157,24 @@ void readCollection() throws ParseException { cursor = collection.find(where("birthDay").lte(new Date()).or(where("firstName").eq("fn12"))); assertEquals(cursor.size(), 3); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")) - .not()); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -180,8 +189,8 @@ void readCollection() throws ParseException { cursor = collection.find(where("firstName").notIn("fn1", "fn2")); assertEquals(cursor.size(), 1); - collection.createIndex("birthDay", indexOptions(IndexType.Unique)); - cursor = collection.find().sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + collection.createIndex("birthDay"); + cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -201,7 +210,7 @@ void readCollection() throws ParseException { db.close(); } - void deleteDb() { + void deleteDb() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java b/nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java deleted file mode 100644 index a3523c032..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/IndexDescriptorTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexType; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class IndexDescriptorTest { - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testIndexEquals() { - IndexDescriptor index = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); - IndexDescriptor index2 = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); - assertEquals(index, index2); - } - - @Test - public void testIndexCompare() { - IndexDescriptor index = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); - IndexDescriptor index2 = new IndexDescriptor(IndexType.Fulltext, "test", "testColl"); - - assertEquals(index.toString(), "IndexEntry(indexType=Fulltext, field=test, collectionName=testColl)"); - assertEquals(index.compareTo(index2), 0); - } -} diff --git a/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java b/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java index 12128d8d6..bccb17eef 100644 --- a/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java @@ -60,12 +60,12 @@ public class MultiThreadedTest { public Retry retry = new Retry(3); @Test - public void testOperations() throws InterruptedException { + public void testOperations() throws Exception { db = createDb(); collection = db.getCollection("test"); collection.remove(Filter.ALL); - collection.createIndex("unixTime", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("unixTime"); db.commit(); for (int i = 0; i < threadCount; i++) { @@ -78,8 +78,8 @@ public void testOperations() throws InterruptedException { if (j == iterationCount / 2 && !collection.hasIndex("text") && !collection.hasIndex("date")) { - collection.createIndex("text", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("date", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "text"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "date"); } long unixTime = (long) document.get("unixTime"); @@ -120,7 +120,7 @@ public void testOperations() throws InterruptedException { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 8acc5b2f5..865cdd2ad 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -17,21 +17,26 @@ package org.dizitart.no2; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.NitriteMapper; import org.dizitart.no2.module.PluginManager; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreConfig; import org.junit.After; import org.junit.Rule; import org.junit.Test; +import java.util.LinkedHashSet; + import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; import static org.dizitart.no2.module.NitriteModule.module; @@ -47,7 +52,7 @@ public class NitriteBuilderTest { public Retry retry = new Retry(3); @After - public void cleanup() { + public void cleanup() throws Exception { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { @@ -56,7 +61,7 @@ public void cleanup() { } @Test - public void testConfig() { + public void testConfig() throws Exception { NitriteBuilder nitriteBuilder = Nitrite.builder(); nitriteBuilder.loadModule(module(new CustomIndexer())); @@ -70,7 +75,7 @@ public void testConfig() { } @Test - public void testConfigWithFile() { + public void testConfigWithFile() throws Exception { db = Nitrite.builder() .openOrCreate(); StoreConfig storeConfig = db.getStore().getStoreConfig(); @@ -86,7 +91,7 @@ public void testConfigWithFile() { } @Test - public void testConfigWithFileNull() { + public void testConfigWithFileNull() throws Exception { db = Nitrite.builder().openOrCreate(); StoreConfig storeConfig = db.getStore().getStoreConfig(); @@ -171,30 +176,31 @@ public String getIndexType() { } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void validateIndex(Fields fields) { } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public void dropIndex(NitriteMap collection, String field) { + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { } @Override - public NitriteIndexer clone() throws CloneNotSupportedException { + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { return null; } + @Override public void initialize(NitriteConfig nitriteConfig) { diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java index 408c171d0..4288b1def 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java @@ -72,7 +72,7 @@ public void setUp() { } @After - public void tearDown() { + public void tearDown() throws Exception { if (collection.isOpen()) { collection.remove(ALL); collection.close(); diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java index 75a1a936b..10ce57aa2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java @@ -35,7 +35,7 @@ public class NitriteSecurityTest { public Retry retry = new Retry(3); @Test - public void testInMemory() { + public void testInMemory() throws Exception { db = createDb("test-user", "test-password"); NitriteCollection dbCollection = db.getCollection("test"); dbCollection.insert(createDocument("test", "test")); @@ -50,7 +50,7 @@ public void testInMemory() { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java index 29e1dddc7..1fa0fea66 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java @@ -51,8 +51,8 @@ public class NitriteStressTest { public void stressTest() { Nitrite database = createDb(); ObjectRepository testRepository = database.getRepository(TestDto.class); - testRepository.createIndex("lastName", IndexOptions.indexOptions(IndexType.Fulltext)); - testRepository.createIndex("birthDate", IndexOptions.indexOptions(IndexType.NonUnique)); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "lastName"); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "birthDate"); int counter = 0; try { diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java index f5d18940e..aade2165f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java @@ -20,6 +20,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.UpdateOptions; import org.dizitart.no2.common.SortOrder; @@ -94,13 +95,13 @@ public void setUp() throws ParseException { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); collection.insert(doc1, doc2, doc3); } @After - public void tearDown() { + public void tearDown() throws Exception { if (collection.isOpen()) { collection.remove(ALL); collection.close(); @@ -140,7 +141,7 @@ public void testHasRepository() { } @Test - public void testClose() { + public void testClose() throws Exception { NitriteCollection testCollection = db.getCollection("test"); testCollection.insert(createDocument("a", "b")); db.close(); @@ -199,28 +200,28 @@ public void testGetRepositoryInvalid() { } @Test(expected = NitriteIOException.class) - public void testGetCollectionNullStore() { + public void testGetCollectionNullStore() throws Exception { db = Nitrite.builder().openOrCreate(); db.close(); db.getCollection("test"); } @Test(expected = NitriteIOException.class) - public void testGetRepositoryNullStore() { + public void testGetRepositoryNullStore() throws Exception { db = Nitrite.builder().openOrCreate(); db.close(); db.getRepository(NitriteTest.class); } @Test(expected = NitriteIOException.class) - public void testGetKeyedRepositoryNullStore() { + public void testGetKeyedRepositoryNullStore() throws Exception { db = Nitrite.builder().openOrCreate(); db.close(); db.getRepository(NitriteTest.class, "key"); } @Test(expected = NitriteIOException.class) - public void testCommitNullStore() { + public void testCommitNullStore() throws Exception { db = Nitrite.builder().openOrCreate(); db.close(); db.commit(); @@ -260,8 +261,8 @@ public void testIssue185() throws InterruptedException { }).start(); for (int i = 0; i < 1000; ++i) { - repository.find(where("status").eq(Receipt.Status.COMPLETED).not()) - .sort("createdTimestamp", SortOrder.Descending).toList(); + repository.find(where("status").eq(Receipt.Status.COMPLETED).not(), + FindOptions.orderBy("createdTimestamp", SortOrder.Descending)).toList(); try { Thread.sleep(5); } catch (InterruptedException ignored) { @@ -302,10 +303,10 @@ public void testIssue212() { Document doc = createDocument("fifth_key", "fifth_key"); if (!collection.hasIndex("key")) { - collection.createIndex("key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "key"); } if (!collection.hasIndex("second_key")) { - collection.createIndex("second_key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "second_key"); } collection.insert(doc1, doc2); @@ -318,7 +319,7 @@ public void testIssue212() { } @Test - public void testIssue245() throws InterruptedException { + public void testIssue245() throws Exception { class ThreadRunner implements Runnable { @Override public void run() { diff --git a/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java b/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java index 5aad73914..f38a4e27a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java @@ -46,7 +46,7 @@ public void setUp() { } @After - public void tearDown() { + public void tearDown() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/StressTest.java b/nitrite/src/test/java/org/dizitart/no2/StressTest.java index c8e1b5d1f..739b2ad05 100644 --- a/nitrite/src/test/java/org/dizitart/no2/StressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/StressTest.java @@ -64,9 +64,9 @@ public void before() { @Test public void testIssue41() { - collection.createIndex("number", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("name", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("counter", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "number"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "name"); + collection.createIndex("counter"); Random random = new Random(); AtomicLong counter = new AtomicLong(System.currentTimeMillis()); @@ -107,7 +107,7 @@ public void testIssue41() { } @After - public void clear() { + public void clear() throws Exception { if (db != null && !db.isClosed()) { long start = System.currentTimeMillis(); db.close(); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java index 32a513827..c948624db 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java @@ -72,7 +72,7 @@ public void testDeleteInEmptyCollection() { @Test public void testClear() { - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); insert(); DocumentCursor cursor = collection.find(); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java index feb80b76b..d0256f1c7 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java @@ -31,7 +31,7 @@ public class CollectionFindByIndexNegativeTest extends BaseCollectionTest { @Test(expected = FilterException.class) public void testFindTextWithWildCardMultipleWord() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); DocumentCursor cursor = collection.find(where("body").text("*ipsum dolor*")); assertEquals(cursor.size(), 1); @@ -40,7 +40,7 @@ public void testFindTextWithWildCardMultipleWord() { @Test(expected = FilterException.class) public void testFindTextWithOnlyWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); DocumentCursor cursor = collection.find(where("body").text("*")); assertEquals(cursor.size(), 1); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java index 1b1859fb1..8f6f8ee1d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java @@ -24,9 +24,15 @@ import org.junit.Test; import java.text.ParseException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; import static org.dizitart.no2.TestUtil.isSorted; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -39,14 +45,14 @@ public class CollectionFindByIndexTest extends BaseCollectionTest { @Test public void testFindByUniqueIndex() throws ParseException { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); cursor = collection.find(where("firstName").eq("fn10")); assertEquals(cursor.size(), 0); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); cursor = collection.find(where("birthDay").gt( simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); assertEquals(cursor.size(), 1); @@ -90,15 +96,23 @@ public void testFindByUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -117,8 +131,8 @@ public void testFindByUniqueIndex() throws ParseException { @Test public void testFindByNonUniqueIndex() throws ParseException { insert(); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "birthDay"); DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); assertEquals(cursor.size(), 2); @@ -169,15 +183,23 @@ public void testFindByNonUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -196,7 +218,7 @@ public void testFindByNonUniqueIndex() throws ParseException { @Test public void testFindByFullTextIndexAfterInsert() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.hasIndex("body")); DocumentCursor cursor = collection.find(where("body").text("Lorem")); @@ -218,7 +240,7 @@ public void testFindByFullTextIndexAfterInsert() { @Test public void testFindByFullTextIndexBeforeInsert() { - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.hasIndex("body")); insert(); @@ -245,9 +267,9 @@ public void testFindByFullTextIndexBeforeInsert() { @Test public void testFindByIndexSortAscending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -259,9 +281,9 @@ public void testFindByIndexSortAscending() { @Test public void testFindByIndexSortDescending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -273,10 +295,13 @@ public void testFindByIndexSortDescending() { @Test public void testFindByIndexLimitAndSort() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find( + orderBy("birthDay", SortOrder.Descending) + .skip(1) + .limit(2) + ); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -284,8 +309,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -293,8 +317,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -306,7 +329,7 @@ public void testFindByIndexLimitAndSort() { @Test public void testFindAfterDroppedIndex() { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); @@ -318,7 +341,7 @@ public void testFindAfterDroppedIndex() { @Test public void testFindTextWithWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); DocumentCursor cursor = collection.find(where("body").text("Lo")); assertEquals(cursor.size(), 0); @@ -336,7 +359,7 @@ public void testFindTextWithWildCard() { @Test public void testFindTextWithEmptyString() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); DocumentCursor cursor = collection.find(where("body").text("")); assertEquals(cursor.size(), 0); @@ -350,8 +373,8 @@ public void testFindWithOrIndexed() { Document doc3 = Document.createDocument("firstName", "Jonas").put("lastName", "Doe"); Document doc4 = Document.createDocument("firstName", "Johan").put("lastName", "Day"); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "lastName"); collection.insert(doc1, doc2, doc3, doc4); @@ -381,7 +404,7 @@ public void testIssue45() { Document doc3 = Document.createDocument("firstName", "Jonas").put("notes", list3); Document doc4 = Document.createDocument("firstName", "Johan").put("notes", list4); - collection.createIndex("notes", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "notes"); collection.insert(doc1, doc2, doc3, doc4); DocumentCursor cursor = collection.find(where("notes").text("fox")); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java index cf85610fe..953f46352 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java @@ -25,6 +25,8 @@ import java.util.List; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; @@ -41,24 +43,25 @@ public void testFindFilterInvalidIndex() { @Test(expected = ValidationException.class) public void testFindOptionsNegativeOffset() { insert(); - collection.find().skipLimit(-1, 1); + collection.find(skipBy(-1).limit(1)); } @Test(expected = ValidationException.class) public void testFindOptionsNegativeSize() { insert(); - collection.find().skipLimit(0, -1); + collection.find(skipBy(0).limit(-1)); } + @Test(expected = ValidationException.class) public void testFindOptionsInvalidOffset() { insert(); - assertEquals(collection.find().skipLimit(10, 1).size(), 0); + assertEquals(collection.find(skipBy(10).limit(1)).size(), 0); } @Test(expected = ValidationException.class) public void testFindInvalidSort() { insert(); - collection.find().sort("data", SortOrder.Descending).toList(); + collection.find(orderBy("data", SortOrder.Descending)).toList(); } @Test(expected = FilterException.class) @@ -77,8 +80,8 @@ public void testFindWithRegexInvalidValue() { @Test(expected = ValidationException.class) public void testInvalidProjection() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", "ln2"); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java index 0230aa359..78edf3a05 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java @@ -32,9 +32,10 @@ import static org.dizitart.no2.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.*; import static org.dizitart.no2.common.Constants.*; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.hamcrest.CoreMatchers.is; @@ -106,18 +107,25 @@ public void testFindWithFilter() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); - cursor = collection.find(where("data.1").eq((byte) 4)); assertEquals(cursor.size(), 2); @@ -138,16 +146,16 @@ public void testFindWithFilter() throws ParseException { public void testFindWithSkipLimit() { insert(); - DocumentCursor cursor = collection.find().skipLimit(0, 1); + DocumentCursor cursor = collection.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); - cursor = collection.find().skipLimit(1, 3); + cursor = collection.find(skipBy(1).limit(3)); assertEquals(cursor.size(), 2); - cursor = collection.find().skipLimit(0, 30); + cursor = collection.find(skipBy(0).limit(30)); assertEquals(cursor.size(), 3); - cursor = collection.find().skipLimit(2, 3); + cursor = collection.find(skipBy(2).limit(3)); assertEquals(cursor.size(), 1); } @@ -155,21 +163,21 @@ public void testFindWithSkipLimit() { public void testFindWithSkip() { insert(); - DocumentCursor cursor = collection.find().skip(0); + DocumentCursor cursor = collection.find(skipBy(0)); assertEquals(cursor.size(), 3); - cursor = collection.find().skip(1); + cursor = collection.find(skipBy(1)); assertEquals(cursor.size(), 2); - cursor = collection.find().skip(30); + cursor = collection.find(skipBy(30)); assertEquals(cursor.size(), 0); - cursor = collection.find().skip(2); + cursor = collection.find(skipBy(2)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().skip(-1); + cursor = collection.find(skipBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; @@ -181,22 +189,22 @@ public void testFindWithSkip() { public void testFindWithLimit() { insert(); - DocumentCursor cursor = collection.find().limit(0); + DocumentCursor cursor = collection.find(limitBy(0)); assertEquals(cursor.size(), 0); - cursor = collection.find().limit(1); + cursor = collection.find(limitBy(1)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().limit(-1); + cursor = collection.find(limitBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; } assertTrue(invalid); - cursor = collection.find().limit(30); + cursor = collection.find(limitBy(30)); assertEquals(cursor.size(), 3); } @@ -204,7 +212,7 @@ public void testFindWithLimit() { public void testFindSortAscending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -217,7 +225,7 @@ public void testFindSortAscending() { public void testFindSortDescending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -230,8 +238,7 @@ public void testFindSortDescending() { public void testFindLimitAndSort() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -239,8 +246,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -248,8 +254,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -261,7 +266,7 @@ public void testFindLimitAndSort() { @Test public void testFindSortOnNonExistingField() { insert(); - DocumentCursor cursor = collection.find().sort("my-value", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("my-value", SortOrder.Descending)); assertEquals(cursor.size(), 3); } @@ -282,8 +287,7 @@ public void testFindInvalidFieldWithInvalidAccessor() { @Test public void testFindLimitAndSortInvalidField() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay2", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay2", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -306,8 +310,8 @@ public void testGetById() { @Test public void testFindWithFilterAndOption() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -330,8 +334,8 @@ public void testFindTextWithRegex() { @Test public void testProject() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); int iteration = 0; for (Document document : cursor) { switch (iteration) { @@ -353,8 +357,8 @@ public void testProject() { @Test public void testProjectWithCustomDocument() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", null); @@ -614,8 +618,8 @@ public void testFilterAll() { @Test public void testIssue72() { NitriteCollection coll = db.getCollection("test"); - coll.createIndex("id", IndexOptions.indexOptions(IndexType.Unique)); - coll.createIndex("group", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.Unique), "id"); + coll.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "group"); coll.remove(ALL); @@ -625,13 +629,13 @@ public void testIssue72() { doc = createDocument().put("id", "test-2").put("group", "groupA").put("startTime", DateTime.now()); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(1).get("startTime")); assertNotNull(cursor.toList().get(0).get("startTime")); - cursor = coll.find(where("group").eq("groupA")).sort("startTime", SortOrder.Ascending); + cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Ascending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(0).get("startTime")); assertNotNull(cursor.toList().get(1).get("startTime")); @@ -649,8 +653,7 @@ public void testIssue93() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); } @@ -666,42 +669,41 @@ public void testNullOrderWithAllNull() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); - DocumentCursor cursor2 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); + DocumentCursor cursor2 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Default)); assertEquals(2, cursor2.size()); assertThat(cursor.toList(), is(cursor2.toList())); - DocumentCursor cursor3 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); + DocumentCursor cursor3 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.First)); assertEquals(2, cursor3.size()); assertThat(cursor.toList(), is(cursor3.toList())); - DocumentCursor cursor4 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); + DocumentCursor cursor4 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Last)); assertEquals(2, cursor4.size()); assertThat(cursor.toList(), is(cursor4.toList())); - DocumentCursor cursor5 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); + DocumentCursor cursor5 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Last)); assertEquals(2, cursor5.size()); assertThat(cursor.toList(), is(cursor5.toList())); - DocumentCursor cursor6 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); + DocumentCursor cursor6 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.First)); assertEquals(2, cursor6.size()); assertThat(cursor.toList(), is(cursor6.toList())); - DocumentCursor cursor7 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); + DocumentCursor cursor7 = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Default)); assertEquals(2, cursor7.size()); assertThat(cursor.toList(), is(cursor7.toList())); @@ -711,7 +713,7 @@ public void testNullOrderWithAllNull() { public void testNullOrder() { NitriteCollection coll = db.getCollection("test"); try { - coll.createIndex("startTime", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "startTime"); } catch (IndexingException e) { // ignore } @@ -727,44 +729,43 @@ public void testNullOrder() { Document doc3 = createDocument().put("id", "test-3").put("group", "groupA").put("startTime", DateTime.now().plusMinutes(1)); assertEquals(1, coll.insert(doc3).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); + cursor = coll.find(where("group").eq("groupA") , + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.First)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc3, doc2), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Default)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Last)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.First)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc2, doc3), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Default)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc2, doc3), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Last)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc2, doc3, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); @@ -786,8 +787,8 @@ public void testIssue144() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2, doc3); - DocumentCursor cursor = coll.find().sort("fruit", SortOrder.Ascending, - Collator.getInstance(Locale.FRANCE)); + DocumentCursor cursor = coll.find(orderBy("fruit", SortOrder.Ascending) + .collator(Collator.getInstance(Locale.FRANCE))); assertEquals(cursor.toList().get(1).get("fruit"), "Ôrange"); } @@ -839,7 +840,7 @@ public void testBetweenFilter() { NitriteCollection collection = db.getCollection("tag"); collection.insert(doc1, doc2, doc3, doc4, doc5); - collection.createIndex("age", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "age"); DocumentCursor cursor = collection.find(where("age").between(31, 35)); assertEquals(cursor.size(), 5); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java index 3c0828520..36d38c808 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java @@ -31,14 +31,14 @@ public class CollectionIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "lastName"); assertTrue(collection.hasIndex("lastName")); insert(); } @Test(expected = UniqueConstraintException.class) public void testCreateIndexOnArray() { - collection.createIndex("data", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "data"); assertTrue(collection.hasIndex("data")); // data array field has repetition, so unique constraint exception insert(); @@ -47,14 +47,14 @@ public void testCreateIndexOnArray() { @Test public void testCreateOnInvalidField() { insert(); - collection.createIndex("my-value", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "my-value"); assertTrue(collection.hasIndex("my-value")); } @Test(expected = IndexingException.class) public void testCreateFullTextOnNonTextField() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "birthDay"); assertTrue(collection.hasIndex("birthDay")); } @@ -65,6 +65,6 @@ public void testDropIndexOnNonIndexedField() { @Test(expected = IndexingException.class) public void testRebuildIndexInvalid() { - collection.rebuildIndex("unknown", true); + collection.rebuildIndex("unknown"); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java index 774338f70..c7ea908df 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java @@ -41,16 +41,16 @@ public class CollectionIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.Unique), "firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.hasIndex("body")); - collection.createIndex("birthDay", null); + collection.createIndex("birthDay"); assertTrue(collection.hasIndex("birthDay")); insert(); @@ -60,13 +60,13 @@ public void testCreateIndex() { public void testListIndexes() { assertEquals(collection.listIndices().size(), 0); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.hasIndex("body")); assertEquals(collection.listIndices().size(), 3); @@ -74,7 +74,7 @@ public void testListIndexes() { @Test public void testDropIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropIndex("firstName"); @@ -95,18 +95,18 @@ public void testDropAllIndexes() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); assertTrue(collection.hasIndex("lastName")); assertFalse(collection.hasIndex("body")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.hasIndex("body")); } @Test public void testDeleteWithIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); insert(); @@ -126,7 +126,7 @@ public void testDeleteWithIndex() { @Test public void testCreateIndexAsync() { insert(); - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); assertTrue(collection.isIndexing("body")); await().until(bodyIndexingCompleted()); @@ -134,38 +134,38 @@ public void testCreateIndexAsync() { @Test public void testRebuildIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), false); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); } } @Test public void testRebuildIndexAsync() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); insert(); await().until(bodyIndexingCompleted()); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); await().until(bodyIndexingCompleted()); } } @Test public void testRebuildIndexOnRunningIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); + collection.createIndex(indexOptions(IndexType.Fulltext), "body"); Collection indices = collection.listIndices(); IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); boolean error = false; try { - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); } catch (IndexingException ie) { error = true; } finally { @@ -180,8 +180,8 @@ private Callable bodyIndexingCompleted() { @Test public void testNullValueInIndexedField() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("birthDay", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "birthDay"); insert(); Document document = createDocument("firstName", null) @@ -200,12 +200,12 @@ public void testNullValueInIndexedField() { @Test public void testDropAllAndCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropAllIndices(); assertFalse(collection.hasIndex("firstName")); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection = db.getCollection("test"); @@ -228,7 +228,7 @@ public void testIssue178() { DocumentCursor cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); - collection.createIndex("field", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "field"); cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); @@ -263,10 +263,10 @@ public void testIndexEvent() { System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); }); - collection.createIndex("first", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "first"); assertEquals(collection.find().size(), 10000); - collection.createIndex("second", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "second"); assertEquals(collection.find().size(), 10000); } @@ -277,10 +277,10 @@ public void testIndexAndSearchOnNullValues() { collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); - collection.createIndex("first", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.Unique), "first"); assertEquals(collection.find(where("first").eq(null)).size(), 1); - collection.createIndex("third", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java index aa1c3cee7..a0e0c6183 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java @@ -21,13 +21,11 @@ import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexType; import org.junit.Test; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; import static org.junit.Assert.*; public class CollectionUpdateTest extends BaseCollectionTest { @@ -241,7 +239,7 @@ public void testRegisterListenerAfterDrop() { } @Test(expected = NitriteIOException.class) - public void testRegisterListenerAfterClose() { + public void testRegisterListenerAfterClose() throws Exception { NitriteCollection collection = db.getCollection("test"); collection.close(); collection.subscribe(changeInfo -> fail("should not happen")); @@ -254,7 +252,7 @@ public void testIssue151() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2); - coll.createIndex("fruit", indexOptions(IndexType.Unique)); + coll.createIndex("fruit"); assertEquals(coll.find(where("fruit").eq("Apple")).size(), 1); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java index 120ed4b8e..8d75ca0bc 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java @@ -47,7 +47,7 @@ public void testAttributes() { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/BoundedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/BoundedDocumentStreamTest.java deleted file mode 100644 index c2fb18495..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/BoundedDocumentStreamTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import com.fasterxml.jackson.databind.util.ArrayIterator; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -import java.util.NoSuchElementException; - -import static org.junit.Assert.*; - -public class BoundedDocumentStreamTest { - @Test - public void testBoundedIteratorHasNext() { - assertTrue( - (new BoundedDocumentStream.BoundedIterator<>(new ArrayIterator<>(new Object[]{"foo", "foo", "foo"}), - 1L, 3L)).hasNext()); - } - - @Test - public void testBoundedIteratorNext() { - assertEquals("foo", (new BoundedDocumentStream.BoundedIterator<>(new BoundedDocumentStream.BoundedIterator<>( - new ArrayIterator<>(new Object[]{"foo", "foo", "foo"}), 1L, 3L), 1L, 3L)).next()); - assertEquals("foo", - (new BoundedDocumentStream.BoundedIterator<>(new ArrayIterator<>(new Object[]{"foo", "foo", "foo"}), - 1L, 3L)).next()); - assertThrows(NoSuchElementException.class, () -> (new BoundedDocumentStream.BoundedIterator<>( - new ArrayIterator<>(new Object[]{"foo", "foo", "foo"}), 1L, 0L)).next()); - } - - @Test - public void testConstructor() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - assertTrue( - (new BoundedDocumentStream(new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())), 1L, 1L)) - .isEmpty()); - } - - @Test - public void testConstructor2() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - assertThrows(ValidationException.class, - () -> new BoundedDocumentStream(new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())), -1L, - 1L)); - } - - @Test - public void testConstructor3() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - assertThrows(ValidationException.class, - () -> new BoundedDocumentStream(new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())), 1L, - -1L)); - } - - @Test - public void testIterator() { - assertTrue((new BoundedDocumentStream(null, 1L, 1L)).iterator() instanceof BoundedDocumentStream.BoundedIterator); - } - - @Test - public void testIterator2() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - BoundedDocumentStream recordStream2 = new BoundedDocumentStream( - new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())), 1L, 1L); - assertTrue( - (new BoundedDocumentStream(new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())), 1L, 1L)) - .iterator() instanceof BoundedDocumentStream.BoundedIterator); - } - - @Test - public void testIterator3() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - assertTrue( - (new BoundedDocumentStream(new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())), 1L, 1L)) - .iterator() instanceof BoundedDocumentStream.BoundedIterator); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorImplTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorImplTest.java deleted file mode 100644 index dfbed7a04..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorImplTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertTrue; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -public class DocumentCursorImplTest { - @Test - public void testSort() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - assertTrue((new DocumentCursorImpl(new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())))) - .sort("field", SortOrder.Ascending, null, NullOrder.First).isEmpty()); - } - - @Test - public void testSkipLimit() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - assertTrue((new DocumentCursorImpl(new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())))) - .skipLimit(1L, 1L).isEmpty()); - } - - @Test - public void testProject() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - DocumentCursorImpl documentCursorImpl = new DocumentCursorImpl( - new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId()))); - assertTrue(documentCursorImpl.project(Document.createDocument()).isEmpty()); - } - - @Test - public void testJoin() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - DocumentCursorImpl documentCursorImpl = new DocumentCursorImpl( - new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId()))); - FilteredRecordStream recordStream2 = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream3 = new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())); - DocumentCursorImpl foreignCursor = new DocumentCursorImpl( - new FilteredRecordStream(recordStream3, Filter.byId(NitriteId.newId()))); - assertTrue(documentCursorImpl.join(foreignCursor, new Lookup()).isEmpty()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java index bc23b70e5..92666817c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java @@ -22,6 +22,7 @@ import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.DocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; import org.junit.After; import org.junit.Rule; @@ -50,7 +51,7 @@ public void testFindResult() { collection.insert(createDocument("first", "second")); DocumentCursor result = collection.find(); - assertTrue(result instanceof DocumentCursorImpl); + assertTrue(result instanceof DocumentStream); } @Test(expected = InvalidOperationException.class) @@ -79,7 +80,7 @@ public void testValidateProjection() { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/FilteredRecordStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/FilteredRecordStreamTest.java deleted file mode 100644 index 00ee32675..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/FilteredRecordStreamTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import com.fasterxml.jackson.databind.util.ArrayIterator; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -public class FilteredRecordStreamTest { - @Test - public void testFilteredIteratorHasNext() { - ArrayIterator> iterator = new ArrayIterator>(new Pair[]{}); - FilteredRecordStream.FilteredIterator iterator1 = new FilteredRecordStream.FilteredIterator(iterator, - Filter.byId(NitriteId.newId())); - assertFalse((new FilteredRecordStream.FilteredIterator(iterator1, Filter.byId(NitriteId.newId()))).hasNext()); - } - - @Test - public void testIterator() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - assertTrue((new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId()))) - .iterator() instanceof FilteredRecordStream.FilteredIterator); - } - - @Test - public void testFilteredIteratorHasNext2() { - Pair pair = new Pair(); - pair.setSecond(Document.createDocument()); - ArrayIterator> iterator = new ArrayIterator>(new Pair[]{pair}); - assertFalse((new FilteredRecordStream.FilteredIterator(iterator, Filter.byId(NitriteId.newId()))).hasNext()); - } - - @Test - public void testFilteredIteratorHasNext3() { - ArrayIterator> iterator = new ArrayIterator>(new Pair[]{}); - assertFalse((new FilteredRecordStream.FilteredIterator(iterator, Filter.byId(NitriteId.newId()))).hasNext()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexedStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexedStreamTest.java deleted file mode 100644 index 7915683e8..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexedStreamTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import com.fasterxml.jackson.databind.util.ArrayIterator; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.store.memory.InMemoryMap; -import org.junit.Test; - -public class IndexedStreamTest { - @Test - public void testIndexedStreamIteratorHasNext() { - NitriteId newIdResult = NitriteId.newId(); - NitriteId newIdResult1 = NitriteId.newId(); - ArrayIterator iterator = new ArrayIterator( - new NitriteId[]{newIdResult, newIdResult1, NitriteId.newId()}); - assertTrue( - (new IndexedStream.IndexedStreamIterator(iterator, new InMemoryMap("mapName", null))) - .hasNext()); - } - - @Test - public void testIndexedStreamIteratorNext() { - NitriteId newIdResult = NitriteId.newId(); - NitriteId newIdResult1 = NitriteId.newId(); - ArrayIterator iterator = new ArrayIterator( - new NitriteId[]{newIdResult, newIdResult1, NitriteId.newId()}); - IndexedStream.IndexedStreamIterator indexedStreamIterator = new IndexedStream.IndexedStreamIterator(iterator, - new InMemoryMap("mapName", null)); - assertNull(indexedStreamIterator.next().getSecond()); - assertTrue(indexedStreamIterator.hasNext()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java index 1e950eae4..91002f5fb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java @@ -20,11 +20,10 @@ import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.JoinedDocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.filters.Filter; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -33,7 +32,6 @@ import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -71,19 +69,9 @@ public void testIteratorRemove() { } } - @Test - public void testToString() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream3 = new FilteredRecordStream(null, null); - DocumentCursorImpl foreignCursor = new DocumentCursorImpl( - new FilteredRecordStream(recordStream3, Filter.byId(NitriteId.newId()))); - assertEquals("[]", (new JoinedDocumentStream(recordStream2, foreignCursor, new Lookup())).toString()); - } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ProjectedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ProjectedDocumentStreamTest.java deleted file mode 100644 index 5fc934208..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ProjectedDocumentStreamTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertEquals; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -public class ProjectedDocumentStreamTest { - @Test - public void testToString() { - assertEquals("[]", (new ProjectedDocumentStream(null, Document.createDocument())).toString()); - } - - @Test - public void testToString2() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - assertEquals("[]", (new ProjectedDocumentStream(recordStream2, Document.createDocument())).toString()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java deleted file mode 100644 index b9ef64bf4..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.store.memory.InMemoryMap; -import org.junit.Test; - -public class ReadOperationsTest { - @Test - public void testFind() { - InMemoryMap nitriteMap = new InMemoryMap("mapName", null); - assertTrue((new ReadOperations("collectionName", new NitriteConfig(), nitriteMap, null)).find().isEmpty()); - } - - @Test - public void testFind2() { - InMemoryMap nitriteMap = new InMemoryMap("mapName", null); - assertTrue((new ReadOperations("collectionName", new NitriteConfig(), nitriteMap, null)).find(null).isEmpty()); - } - - @Test - public void testGetById() { - InMemoryMap nitriteMap = new InMemoryMap("mapName", null); - ReadOperations readOperations = new ReadOperations("collectionName", new NitriteConfig(), nitriteMap, null); - assertNull(readOperations.getById(NitriteId.newId())); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/SortedDocumentCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/SortedDocumentCursorTest.java deleted file mode 100644 index 7af703783..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/SortedDocumentCursorTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; - -import com.fasterxml.jackson.databind.util.ArrayIterator; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.NullOrder; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -public class SortedDocumentCursorTest { - @Test - public void testIterator() { - assertFalse( - (new SortedDocumentCursor("field", SortOrder.Ascending, null, NullOrder.First, null)).iterator().hasNext()); - } - - @Test - public void testIterator2() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - assertFalse((new SortedDocumentCursor("field", SortOrder.Ascending, null, NullOrder.First, - new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())))).iterator().hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", null, null, NullOrder.Default, arrayIterator)) - .hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor2() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, NullOrder.Default, - arrayIterator)).hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor3() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, NullOrder.First, - arrayIterator)).hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor4() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", null, null, NullOrder.First, arrayIterator)) - .hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor5() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse( - (new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, null, arrayIterator)) - .hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor6() { - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, NullOrder.First, - new ArrayIterator>(new Pair[]{}))).hasNext()); - } - - @Test - public void testSortedDocumentIteratorConstructor7() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - ArrayIterator> arrayIterator = new ArrayIterator>( - new Pair[]{pair, pair1, new Pair()}); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", null, null, NullOrder.Last, arrayIterator)) - .hasNext()); - assertFalse(arrayIterator.hasNext()); - } - - @Test - public void testSortedDocumentIteratorHasNext() { - Pair pair = new Pair(); - Pair pair1 = new Pair(); - assertFalse((new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, NullOrder.First, - new ArrayIterator>(new Pair[]{pair, pair1, new Pair()}))) - .hasNext()); - } - - @Test - public void testSortedDocumentIteratorNext() { - NitriteId first = NitriteId.newId(); - Pair pair = new Pair(first, Document.createDocument()); - Pair pair1 = new Pair(); - assertSame(pair, - (new SortedDocumentCursor.SortedDocumentIterator("field", SortOrder.Ascending, null, NullOrder.First, - new ArrayIterator>(new Pair[]{pair, pair1, new Pair()}))) - .next()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/UnionStreamIteratorTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/UnionStreamIteratorTest.java deleted file mode 100644 index bfd69e99b..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/UnionStreamIteratorTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertFalse; - -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.filters.Filter; -import org.junit.Test; - -public class UnionStreamIteratorTest { - @Test - public void testHasNext() { - FilteredRecordStream recordStream = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream1 = new FilteredRecordStream(recordStream, Filter.byId(NitriteId.newId())); - FilteredRecordStream lhsStream = new FilteredRecordStream(recordStream1, Filter.byId(NitriteId.newId())); - FilteredRecordStream recordStream2 = new FilteredRecordStream(null, null); - FilteredRecordStream recordStream3 = new FilteredRecordStream(recordStream2, Filter.byId(NitriteId.newId())); - assertFalse( - (new UnionStreamIterator(lhsStream, new FilteredRecordStream(recordStream3, Filter.byId(NitriteId.newId())))) - .hasNext()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteOperationsTest.java deleted file mode 100644 index 26ab0f65c..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteOperationsTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.dizitart.no2.collection.operation; - -import static org.junit.Assert.assertTrue; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.collection.UpdateOptions; -import org.dizitart.no2.store.memory.InMemoryMap; -import org.junit.Test; - -public class WriteOperationsTest { - @Test - public void testUpdate() { - InMemoryMap nitriteMap = new InMemoryMap("mapName", null); - ReadOperations readOperations = new ReadOperations("collectionName", new NitriteConfig(), nitriteMap, null); - WriteOperations writeOperations = new WriteOperations(null, readOperations, - new InMemoryMap("mapName", null), null); - UpdateOptions updateOptions = UpdateOptions.updateOptions(true); - assertTrue(writeOperations.update(null, Document.createDocument(), updateOptions) instanceof WriteResultImpl); - } - - @Test - public void testRemove() { - InMemoryMap nitriteMap = new InMemoryMap("mapName", null); - ReadOperations readOperations = new ReadOperations("collectionName", new NitriteConfig(), nitriteMap, null); - assertTrue((new WriteOperations(null, readOperations, new InMemoryMap("mapName", null), null)) - .remove(null, true) instanceof WriteResultImpl); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteResultImplTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteResultImplTest.java index e1479fb89..aded72221 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteResultImplTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/WriteResultImplTest.java @@ -1,17 +1,17 @@ package org.dizitart.no2.collection.operation; -import static org.junit.Assert.assertEquals; +import org.dizitart.no2.collection.NitriteId; +import org.junit.Test; import java.util.HashSet; -import org.dizitart.no2.collection.NitriteId; -import org.junit.Test; +import static org.junit.Assert.assertEquals; public class WriteResultImplTest { @Test public void testSetNitriteIds() { WriteResultImpl writeResultImpl = new WriteResultImpl(); - writeResultImpl.setNitriteIds(new HashSet()); + writeResultImpl.setNitriteIds(new HashSet<>()); assertEquals("WriteResultImpl(nitriteIds=[])", writeResultImpl.toString()); } @@ -25,7 +25,7 @@ public void testAddToList() { @Test public void testAddToList2() { WriteResultImpl writeResultImpl = new WriteResultImpl(); - writeResultImpl.setNitriteIds(new HashSet()); + writeResultImpl.setNitriteIds(new HashSet<>()); writeResultImpl.addToList(NitriteId.newId()); assertEquals(1, writeResultImpl.getAffectedCount()); } diff --git a/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java b/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java index 763a2da3b..37553c5df 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java @@ -145,7 +145,7 @@ public void testDrop() { } @Test - public void testClose() { + public void testClose() throws Exception { if (employeeRepository.isOpen()) { employeeRepository.close(); } @@ -196,7 +196,7 @@ public void testSingleEventListener() { } @After - public void clear() { + public void clear() throws Exception { if (employeeRepository != null) { if (!employeeRepository.isDropped() && employeeRepository.isOpen()) { diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java index 679865239..46127768f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java @@ -20,7 +20,7 @@ import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.filters.IndexAwareFilter; +import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.mapper.Mappable; import org.dizitart.no2.mapper.MappableMapper; import org.dizitart.no2.mapper.NitriteMapper; @@ -74,7 +74,7 @@ public void testCreateUniqueFilter() { doc.getId(); Filter filter = createUniqueFilter(doc); assertNotNull(filter); - assertTrue(filter instanceof IndexAwareFilter); + assertTrue(filter instanceof ComparableFilter); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java deleted file mode 100644 index 87f5f53b6..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.dizitart.no2.filters; - -import org.dizitart.no2.exceptions.ValidationException; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class BetweenFilterTest { - @Test - public void testConstructor() { - BetweenFilter actualBetweenFilter = new BetweenFilter("field", - new BetweenFilter.Bound<>("lowerBound", "upperBound")); - Filter lhs = actualBetweenFilter.getLhs(); - assertTrue(lhs instanceof LesserEqualFilter); - Filter rhs = actualBetweenFilter.getRhs(); - assertTrue(rhs instanceof GreaterEqualFilter); - Boolean actualOnIdField = ((LesserEqualFilter) lhs).getOnIdField(); - assertFalse(actualBetweenFilter.getObjectFilter()); - assertFalse(((GreaterEqualFilter) rhs).getIsFieldIndexed()); - assertFalse(((GreaterEqualFilter) rhs).getObjectFilter()); - assertFalse(actualOnIdField); - assertEquals("field", ((GreaterEqualFilter) rhs).getField()); - assertTrue(((GreaterEqualFilter) rhs).getComparable() instanceof String); - assertFalse(((GreaterEqualFilter) rhs).getOnIdField()); - assertFalse(((LesserEqualFilter) lhs).getIsFieldIndexed()); - assertFalse(((LesserEqualFilter) lhs).getObjectFilter()); - assertEquals("field", ((LesserEqualFilter) lhs).getField()); - assertTrue(((LesserEqualFilter) lhs).getComparable() instanceof String); - } - - @Test - public void testConstructor2() { - assertThrows(ValidationException.class, - () -> new BetweenFilter("field", new BetweenFilter.Bound("lowerBound", null))); - } - - @Test - public void testConstructor3() { - assertThrows(ValidationException.class, () -> new BetweenFilter("field", null)); - } - - @Test - public void testConstructor4() { - assertThrows(ValidationException.class, - () -> new BetweenFilter("field", new BetweenFilter.Bound(null, "upperBound"))); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java index fa390f93a..a98e437d8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java @@ -3,85 +3,17 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.index.NitriteTextIndexer; -import org.dizitart.no2.index.NonUniqueIndexer; -import org.dizitart.no2.store.memory.InMemoryMap; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class EqualsFilterTest { - @Test - public void testFindIndexedIdSet() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); - equalsFilter.setIsFieldIndexed(null); - assertEquals(0, equalsFilter.findIndexedIdSet().size()); - } - - @Test - public void testFindIndexedIdSet2() { - EqualsFilter equalsFilter = new EqualsFilter("field", new NonUniqueIndexer()); - equalsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> equalsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet3() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> equalsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet4() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setIsFieldIndexed(true); - equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); - equalsFilter.setIsFieldIndexed(null); - assertEquals(0, equalsFilter.findIndexedIdSet().size()); - } - - @Test - public void testFindIndexedIdSet5() { - EqualsFilter equalsFilter = new EqualsFilter("field", null); - equalsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> equalsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet6() { - assertEquals(0, (new EqualsFilter("field", "value")).findIndexedIdSet().size()); - } - - @Test - public void testFindIdSet() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - assertEquals(0, equalsFilter.findIdSet(new InMemoryMap("mapName", null)).size()); - } - - @Test(expected = InvalidIdException.class) - public void testFindIdSet2() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setOnIdField(true); - equalsFilter.findIdSet(new InMemoryMap<>("mapName", null)); - assertTrue(equalsFilter.getValue() instanceof String); - } - - @Test - public void testFindIdSet3() { - EqualsFilter equalsFilter = new EqualsFilter("field", 42); - equalsFilter.setOnIdField(true); - assertEquals(0, equalsFilter.findIdSet(new InMemoryMap("mapName", null)).size()); - assertTrue(equalsFilter.getValue() instanceof Integer); - } @Test public void testApply() { EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - Pair pair = new Pair(); + Pair pair = new Pair<>(); pair.setSecond(Document.createDocument()); assertFalse(equalsFilter.apply(pair)); assertTrue(equalsFilter.getValue() instanceof String); @@ -91,33 +23,8 @@ public void testApply() { public void testApply2() { EqualsFilter equalsFilter = new EqualsFilter("field", "value"); NitriteId first = NitriteId.newId(); - assertFalse(equalsFilter.apply(new Pair(first, Document.createDocument()))); + assertFalse(equalsFilter.apply(new Pair<>(first, Document.createDocument()))); assertTrue(equalsFilter.getValue() instanceof String); } - - @Test - public void testSetIsFieldIndexed() { - EqualsFilter equalsFilter = new EqualsFilter("field", "value"); - equalsFilter.setIsFieldIndexed(true); - assertTrue(equalsFilter.getIsFieldIndexed()); - } - - @Test - public void testSetIsFieldIndexed2() { - EqualsFilter equalsFilter = new EqualsFilter("field", 42); - equalsFilter.setObjectFilter(true); - equalsFilter.setNitriteIndexer(null); - equalsFilter.setIsFieldIndexed(true); - assertTrue(equalsFilter.getIsFieldIndexed()); - } - - @Test - public void testSetIsFieldIndexed3() { - EqualsFilter equalsFilter = new EqualsFilter("field", 42); - equalsFilter.setNitriteIndexer(new NitriteTextIndexer()); - equalsFilter.setIsFieldIndexed(true); - assertTrue(equalsFilter.getValue() instanceof Integer); - assertTrue(equalsFilter.getIsFieldIndexed()); - } } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java index cc69af570..5da9e449b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java @@ -1,36 +1,28 @@ package org.dizitart.no2.filters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import org.junit.Test; +import static org.junit.Assert.*; + public class FluentFilterTest { @Test public void testEq() { - assertFalse(((EqualsFilter) FluentFilter.where("field").eq("value")).getOnIdField()); assertTrue(((EqualsFilter) FluentFilter.where("field").eq("value")).getValue() instanceof String); assertFalse(((EqualsFilter) FluentFilter.where("field").eq("value")).getObjectFilter()); - assertFalse(((EqualsFilter) FluentFilter.where("field").eq("value")).getIsFieldIndexed()); assertEquals("field", ((EqualsFilter) FluentFilter.where("field").eq("value")).getField()); } @Test public void testNotEq() { - assertFalse(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getOnIdField()); assertTrue(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getValue() instanceof String); assertFalse(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getObjectFilter()); - assertFalse(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getIsFieldIndexed()); assertEquals("field", ((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getField()); } @Test public void testText() { assertEquals("value", ((TextFilter) FluentFilter.where("field").text("value")).getStringValue()); - assertFalse(((TextFilter) FluentFilter.where("field").text("value")).getOnIdField()); assertFalse(((TextFilter) FluentFilter.where("field").text("value")).getObjectFilter()); - assertFalse(((TextFilter) FluentFilter.where("field").text("value")).getIsFieldIndexed()); assertEquals("field", ((TextFilter) FluentFilter.where("field").text("value")).getField()); } @@ -39,7 +31,7 @@ public void testRegex() { assertEquals("field", ((RegexFilter) FluentFilter.where("field").regex("value")).getField()); assertFalse(((RegexFilter) FluentFilter.where("field").regex("value")).getObjectFilter()); assertEquals("FieldBasedFilter(field=field, value=value, processed=true)", - ((RegexFilter) FluentFilter.where("field").regex("value")).toString()); + FluentFilter.where("field").regex("value").toString()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java index e701ab618..327b92dac 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java @@ -3,80 +3,11 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.index.NitriteTextIndexer; -import org.dizitart.no2.index.NonUniqueIndexer; -import org.dizitart.no2.store.memory.InMemoryMap; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; public class NotEqualsFilterTest { - @Test - public void testFindIndexedIdSet() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", null); - notEqualsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> notEqualsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet2() { - assertEquals(0, (new NotEqualsFilter("field", "value")).findIndexedIdSet().size()); - } - - @Test - public void testFindIndexedIdSet3() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", new NonUniqueIndexer()); - notEqualsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> notEqualsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet4() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> notEqualsFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet5() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); - notEqualsFilter.setIsFieldIndexed(null); - assertEquals(0, notEqualsFilter.findIndexedIdSet().size()); - } - - @Test - public void testFindIndexedIdSet6() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setIsFieldIndexed(true); - notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); - notEqualsFilter.setIsFieldIndexed(null); - assertEquals(0, notEqualsFilter.findIndexedIdSet().size()); - } - - @Test - public void testFindIdSet() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - assertEquals(0, notEqualsFilter.findIdSet(new InMemoryMap("mapName", null)).size()); - } - - @Test - public void testFindIdSet2() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", 42); - notEqualsFilter.setOnIdField(true); - assertEquals(0, notEqualsFilter.findIdSet(new InMemoryMap<>("mapName", null)).size()); - assertTrue(notEqualsFilter.getValue() instanceof Integer); - } - - @Test(expected = InvalidIdException.class) - public void testFindIdSet3() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setOnIdField(true); - notEqualsFilter.findIdSet(new InMemoryMap<>("mapName", null)); - assertTrue(notEqualsFilter.getValue() instanceof String); - } @Test public void testApply() { @@ -94,38 +25,5 @@ public void testApply2() { assertTrue(notEqualsFilter.apply(pair)); assertTrue(notEqualsFilter.getValue() instanceof String); } - - @Test - public void testSetIsFieldIndexed() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", 42); - notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); - notEqualsFilter.setIsFieldIndexed(true); - assertTrue(notEqualsFilter.getValue() instanceof Integer); - assertTrue(notEqualsFilter.getIsFieldIndexed()); - } - - @Test - public void testSetIsFieldIndexed2() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", 42); - notEqualsFilter.setObjectFilter(true); - notEqualsFilter.setNitriteIndexer(null); - notEqualsFilter.setIsFieldIndexed(true); - assertTrue(notEqualsFilter.getIsFieldIndexed()); - } - - @Test - public void testSetIsFieldIndexed3() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setIsFieldIndexed(true); - assertTrue(notEqualsFilter.getIsFieldIndexed()); - } - - @Test - public void testSetIsFieldIndexed4() { - NotEqualsFilter notEqualsFilter = new NotEqualsFilter("field", "value"); - notEqualsFilter.setNitriteIndexer(new NitriteTextIndexer()); - notEqualsFilter.setIsFieldIndexed(true); - assertTrue(notEqualsFilter.getValue() instanceof String); - } } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java index e93925522..cc63de37c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java @@ -1,13 +1,13 @@ package org.dizitart.no2.filters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + public class RegexFilterTest { @Test public void testConstructor() { diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java deleted file mode 100644 index b32e1e30e..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dizitart.no2.filters; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; - -import org.dizitart.no2.exceptions.FilterException; -import org.junit.Test; - -public class TextFilterTest { - @Test - public void testFindIndexedIdSet() { - assertEquals(0, (new TextFilter("field", "value")).findIndexedIdSet().size()); - } - - @Test - public void testFindIndexedIdSet2() { - TextFilter textFilter = new TextFilter("field", "value"); - textFilter.setNitriteIndexer(null); - textFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> textFilter.findIndexedIdSet()); - } - - @Test - public void testFindIndexedIdSet3() { - TextFilter textFilter = new TextFilter("field", "value"); - textFilter.setIsFieldIndexed(true); - assertThrows(FilterException.class, () -> textFilter.findIndexedIdSet()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java deleted file mode 100644 index af1884fd9..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.dizitart.no2.index; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class IndexDescriptorTest { - @Test - public void testConstructor() { - IndexDescriptor actualIndexDescriptor = new IndexDescriptor("indexType", "field", "collectionName"); - assertEquals("indexType", actualIndexDescriptor.getIndexType()); - assertEquals("collectionName", actualIndexDescriptor.getCollectionName()); - assertEquals("field", actualIndexDescriptor.getIndexFields()); - } - - @Test - public void testCompareTo() { - IndexDescriptor indexDescriptor = new IndexDescriptor("", "", "collectionName"); - assertEquals(-14, indexDescriptor.compareTo(new IndexDescriptor("indexType", "field", "collectionName"))); - } - - @Test - public void testCompareTo2() { - IndexDescriptor indexDescriptor = new IndexDescriptor("indexType", "field", "collectionName"); - assertEquals(0, indexDescriptor.compareTo(new IndexDescriptor("indexType", "field", "collectionName"))); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java index 4f6dd5652..3605f6fa6 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java @@ -7,15 +7,7 @@ public class IndexOptionsTest { @Test public void testIndexOptions() { - IndexOptions actualIndexOptionsResult = IndexOptions.indexOptions("indexType", true); - assertTrue(actualIndexOptionsResult.isAsync()); - assertEquals("indexType", actualIndexOptionsResult.getIndexType()); - } - - @Test - public void testIndexOptions2() { IndexOptions actualIndexOptionsResult = IndexOptions.indexOptions("indexType"); - assertFalse(actualIndexOptionsResult.isAsync()); assertEquals("indexType", actualIndexOptionsResult.getIndexType()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java index 4194cab7e..23064ebe9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java @@ -25,7 +25,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; import java.util.Arrays; import java.util.Collection; @@ -87,7 +86,7 @@ private void openDb() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (companyRepository != null && !companyRepository.isDropped()) { companyRepository.remove(ALL); } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java index a84e215bf..9f0519d21 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java @@ -63,7 +63,7 @@ public void setUp() { } @After - public void reset() { + public void reset() throws Exception { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { db.close(); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java index c00be30ad..29e881f29 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java @@ -49,7 +49,7 @@ public void before() { } @After - public void after() { + public void after() throws Exception { db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java index 020889637..1e45060cb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java @@ -29,8 +29,6 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; - import static org.junit.Assert.*; /** @@ -48,7 +46,7 @@ public void setUp() { } @After - public void close() throws IOException { + public void close() throws Exception { db.close(); db = null; } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java index 0e4311df9..da6754b82 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java @@ -67,7 +67,7 @@ public void setUp() { } @After - public void close() { + public void close() throws Exception { db.close(); db = null; } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java index 30c7d27e9..4e0989821 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java @@ -23,6 +23,7 @@ import java.util.Iterator; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.junit.Assert.*; /** @@ -32,28 +33,28 @@ public class ProjectionTest extends BaseObjectRepositoryTest { @Test public void testHasMore() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertFalse(iterable.isEmpty()); } @Test public void testSize() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertEquals(iterable.size(), 5); } @Test public void testToString() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertNotNull(iterable.toString()); } @Test(expected = InvalidOperationException.class) public void testRemove() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java index 7612946b0..5f4800770 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java @@ -28,6 +28,7 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.processors.Processor; import org.dizitart.no2.store.NitriteStore; import org.junit.After; import org.junit.Rule; @@ -73,7 +74,7 @@ public void testNullContext() { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } @@ -81,6 +82,11 @@ public void cleanUp() { private static class DummyCollection implements NitriteCollection { + @Override + public WriteResult insert(Document document, Document... documents) { + return null; + } + @Override public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { return null; @@ -101,6 +107,11 @@ public DocumentCursor find(Filter filter) { return null; } + @Override + public DocumentCursor find(Filter filter, FindOptions findOptions) { + return null; + } + @Override public Document getById(NitriteId nitriteId) { return null; @@ -112,12 +123,22 @@ public String getName() { } @Override - public void createIndex(String field, IndexOptions indexOptions) { + public void addProcessor(Processor processor) { + + } + + @Override + public void removeProcessor(Processor processor) { + + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fields) { } @Override - public void rebuildIndex(String field, boolean isAsync) { + public void rebuildIndex(String... fields) { } @@ -127,17 +148,17 @@ public Collection listIndices() { } @Override - public boolean hasIndex(String field) { + public boolean hasIndex(String... fields) { return false; } @Override - public boolean isIndexing(String field) { + public boolean isIndexing(String... fields) { return false; } @Override - public void dropIndex(String field) { + public void dropIndex(String... fields) { } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java index e76bd7d24..4929ec531 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java @@ -35,10 +35,10 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; import java.util.*; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.Filter.ALL; import static org.junit.Assert.*; @@ -104,7 +104,7 @@ private void openDb() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (personRepository != null && !personRepository.isDropped()) { personRepository.remove(ALL); } @@ -141,7 +141,7 @@ public void testJoin() { } } - result = personRepository.find().skipLimit(0, 5).join(addressRepository.find(), lookup, + result = personRepository.find(skipBy(0).limit(5)).join(addressRepository.find(), lookup, PersonDetails.class); assertEquals(result.size(), 5); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java index 3c259a8a8..e2f3643d8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java @@ -50,17 +50,17 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); - companyRepository.rebuildIndex("dateCreated", true); + companyRepository.rebuildIndex("dateCreated"); assertTrue(companyRepository.isIndexing("dateCreated")); await().until(() -> !companyRepository.isIndexing("dateCreated")); @@ -71,7 +71,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java index 3f836505a..004b97ff9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java @@ -33,6 +33,8 @@ import java.util.GregorianCalendar; import java.util.List; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; @@ -44,7 +46,7 @@ public class RepositorySearchTest extends BaseObjectRepositoryTest { @Test public void testFindWithOptions() { - Cursor cursor = employeeRepository.find().skipLimit(0, 1); + Cursor cursor = employeeRepository.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); assertNotNull(cursor.firstOrNull()); } @@ -251,7 +253,7 @@ public void testNotFilter() { @Test public void testGreaterFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gt(id)) @@ -263,7 +265,7 @@ public void testGreaterFilter() { @Test public void testGreaterEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gte(id)) @@ -275,7 +277,7 @@ public void testGreaterEqualFilter() { @Test public void testLesserThanFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lt(id)) @@ -287,7 +289,7 @@ public void testLesserThanFilter() { @Test public void testLesserEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lte(id)) @@ -321,7 +323,7 @@ public void testRegexFilter() { @Test public void testInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").in(id, id - 1, id - 2)) @@ -336,7 +338,7 @@ public void testInFilter() { @Test public void testNotInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").notIn(id, id - 1, id - 2)) @@ -525,12 +527,12 @@ public void testIssue62() { Filter married = where("status").eq("Married"); assertEquals(repository.find(married).size(), 2); - assertEquals(repository.find(married).sort("status", SortOrder.Descending).size(), 2); + assertEquals(repository.find(married, orderBy("status", SortOrder.Descending)).size(), 2); - assertEquals(repository.find().sort("status", SortOrder.Descending).firstOrNull().getStatus(), "Un-Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Descending)).firstOrNull().getStatus(), "Un-Married"); - assertEquals(repository.find().sort("status", SortOrder.Ascending).size(), 3); - assertEquals(repository.find().sort("status", SortOrder.Ascending).firstOrNull().getStatus(), "Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).size(), 3); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).firstOrNull().getStatus(), "Married"); } @Test @@ -551,7 +553,7 @@ public void testRepeatableIndexAnnotation() { @Test public void testIdSet() { - Cursor employees = employeeRepository.find().sort("empId", SortOrder.Ascending); + Cursor employees = employeeRepository.find(orderBy("empId", SortOrder.Ascending)); assertEquals(employees.size(), 10); } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java index 45a55d9b4..0a6386335 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java @@ -18,12 +18,11 @@ import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.data.ClassA; import org.dizitart.no2.repository.data.ClassC; import org.junit.Test; +import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -40,12 +39,10 @@ public void testFind() { assertEquals(cursor.size(), 10); assertFalse(cursor.isEmpty()); - IndexOptions indexOptions = new IndexOptions(); - indexOptions.setIndexType(IndexType.Unique); - aObjectRepository.createIndex("b.number", indexOptions); + aObjectRepository.createIndex("b.number"); - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Ascending).skipLimit(0, 10); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Ascending).skip(0).limit(10)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -55,8 +52,8 @@ public void testFind() { System.out.println(classA); } - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Descending).skipLimit(2, 7); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -66,8 +63,8 @@ public void testFind() { System.out.println(classA); } - cursor = cObjectRepository.find(where("id").gt(900)). - sort("id", SortOrder.Descending).skipLimit(2, 7); + cursor = cObjectRepository.find(where("id").gt(900), + orderBy("id", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java index 433e3ccc1..6f4809830 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java @@ -31,8 +31,6 @@ import org.junit.Before; import org.junit.Test; -import java.io.IOException; - import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; @@ -79,7 +77,7 @@ public void setUp() { @After @Override - public void clear() throws IOException { + public void clear() throws Exception { if (textRepository != null && !textRepository.isDropped()) { textRepository.remove(ALL); } diff --git a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java index 70cdf8161..0e71419fb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java @@ -1,13 +1,10 @@ package org.dizitart.no2.store.memory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - import org.apache.commons.lang3.mutable.MutableByte; import org.junit.Test; +import static org.junit.Assert.*; + public class InMemoryMapTest { @Test public void testConstructor() { @@ -82,7 +79,7 @@ public void testRemove3() { @Test public void testKeySet() { - assertTrue((new InMemoryMap("mapName", null)).keySet().isEmpty()); + assertTrue((new InMemoryMap("mapName", null)).keys().isEmpty()); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreTest.java b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreTest.java index c64f17656..8b2c7dabf 100644 --- a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreTest.java @@ -23,7 +23,7 @@ public void testIsReadOnly() { } @Test - public void testClose() { + public void testClose() throws Exception { InMemoryStore inMemoryStore = new InMemoryStore(); inMemoryStore.close(); assertTrue(inMemoryStore.isClosed()); diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java index a235b8dfd..b4a3e6856 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java @@ -48,7 +48,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -102,7 +102,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); collection.insert(createDocument("firstName", "Jane")); try (Session session = db.createSession()) { @@ -158,7 +158,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -196,7 +196,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Fulltext)); + txCol.createIndex(indexOptions(IndexType.Fulltext), "firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -220,7 +220,7 @@ public void testRollbackCreateIndex() { transaction = session.beginTransaction(); NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Unique)); + txCol.createIndex("firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -261,7 +261,7 @@ public void testCommitClear() { @Test public void testRollbackClear() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); Document document2 = createDocument("firstName", "Jane"); collection.insert(document); @@ -293,7 +293,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -315,8 +315,8 @@ public void testRollbackDropIndex() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -346,8 +346,8 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); + collection.createIndex("lastName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -371,8 +371,8 @@ public void testCommitDropAllIndices() { public void testRollbackDropAllIndices() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -433,7 +433,7 @@ public void testCommitDropCollection() { @Test public void testRollbackDropCollection() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -484,7 +484,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -522,8 +522,8 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { NitriteCollection collection = db.getCollection("test"); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); - collection.createIndex("id", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex("id"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -667,7 +667,7 @@ public void testTransactionOnDifferentCollections() { NitriteCollection col1 = db.getCollection("test1"); NitriteCollection col2 = db.getCollection("test2"); NitriteCollection col3 = db.getCollection("test3"); - col3.createIndex("id", indexOptions(IndexType.Unique)); + col3.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java index b5b947381..a9ba7ed92 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java @@ -54,7 +54,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -114,7 +114,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { ObjectRepository repository = db.getRepository(TxData.class, "rollback"); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(new TxData(1L, "Jane")); try (Session session = db.createSession()) { @@ -178,7 +178,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); TxData txData1 = new TxData(1L, "John"); repository.insert(txData1); @@ -218,7 +218,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -243,7 +243,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -288,7 +288,7 @@ public void testRollbackClear() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -318,7 +318,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -342,7 +342,7 @@ public void testRollbackDropIndex() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -372,7 +372,7 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -396,7 +396,7 @@ public void testRollbackDropAllIndices() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -459,7 +459,7 @@ public void testRollbackDropRepository() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -511,7 +511,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -549,7 +549,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.NonUnique)); + repository.createIndex(indexOptions(IndexType.NonUnique), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -690,7 +690,7 @@ public void testTransactionOnDifferentRepositoriesAndCollections() { ObjectRepository repo2 = db.getRepository(TxData.class, "2"); ObjectRepository repo3 = db.getRepository(SubEmployee.class); NitriteCollection col1 = db.getCollection("test1"); - col1.createIndex("id", indexOptions(IndexType.Unique)); + col1.createIndex("id"); Faker faker = new Faker(); diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt index c247601f3..2bf24e1f8 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt @@ -16,6 +16,8 @@ package org.dizitart.kno2 +import org.dizitart.no2.common.util.Iterables +import org.dizitart.no2.common.util.Iterables.setOf import org.dizitart.no2.mapper.JacksonExtension import org.dizitart.no2.module.NitriteModule import org.dizitart.no2.module.NitritePlugin From 51c6ff711bb47d31c162aabdb0d882943e238f05 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Thu, 3 Jun 2021 21:08:55 +0530 Subject: [PATCH 09/13] checkpoint 1 --- .github/workflows/build.yml | 5 +- nitrite-android-example/build.gradle | 7 +- .../dizitart/no2/example/android/User.java | 4 +- .../{ => common}/mapper/JacksonExtension.java | 2 +- .../{ => common}/mapper/JacksonMapper.java | 4 +- .../mapper/JacksonMapperModule.java | 6 +- .../extensions/NitriteIdDeserializer.java | 2 +- .../mapper/extensions/NitriteIdExtension.java | 4 +- .../extensions/NitriteIdSerializer.java | 2 +- .../no2/test/BaseObjectRepositoryTest.java | 2 +- .../dizitart/no2/test/NitriteIdAsIdTest.java | 4 +- .../test/ObjectRepositoryNegativeTest.java | 2 +- .../no2/test/ObjectRepositoryTest.java | 2 +- .../dizitart/no2/test/RepositoryJoinTest.java | 2 +- .../java/org/dizitart/no2/test/TestUtil.java | 2 +- .../no2/test/UniversalTextTokenizerTest.java | 4 +- .../no2/test/migrate/MigrationTest.java | 2 +- .../java/org/dizitart/no2/mapdb/MapDBMap.java | 6 - .../org/dizitart/no2/mapdb/MapDBModule.java | 2 +- .../no2/mapdb/NitriteBuilderTest.java | 6 +- .../dizitart/no2/mapdb/NitriteStressTest.java | 4 +- .../org/dizitart/no2/mapdb/NitriteTest.java | 4 +- .../org/dizitart/no2/mapdb/StressTest.java | 4 +- .../mapdb/collection/CollectionFindTest.java | 1 - .../dizitart/no2/mapdb/migrate/NewClass.java | 4 +- .../dizitart/no2/mapdb/migrate/OldClass.java | 4 +- .../repository/CustomFieldSeparatorTest.java | 4 +- .../no2/mapdb/repository/InternalClass.java | 4 +- .../repository/ObjectRepositoryTest.java | 8 +- .../mapdb/repository/RepositoryJoinTest.java | 4 +- .../repository/RepositorySearchTest.java | 4 +- .../UniversalTextTokenizerTest.java | 6 +- .../no2/mapdb/repository/data/ChildClass.java | 2 +- .../no2/mapdb/repository/data/ClassA.java | 4 +- .../no2/mapdb/repository/data/ClassB.java | 4 +- .../no2/mapdb/repository/data/ClassC.java | 4 +- .../no2/mapdb/repository/data/Company.java | 4 +- .../no2/mapdb/repository/data/ElemMatch.java | 4 +- .../no2/mapdb/repository/data/Employee.java | 4 +- .../no2/mapdb/repository/data/Note.java | 4 +- .../mapdb/repository/data/ParentClass.java | 2 +- .../mapdb/repository/data/PersonEntity.java | 4 +- .../mapdb/repository/data/ProductScore.java | 4 +- .../repository/data/RepeatableIndexTest.java | 4 +- .../mapdb/repository/data/StressRecord.java | 4 +- .../mapdb/repository/data/SubEmployee.java | 4 +- .../repository/data/SuperDuperClass.java | 4 +- .../mapdb/repository/data/WithClassField.java | 4 +- .../no2/mapdb/repository/data/WithDateId.java | 4 +- .../repository/data/WithEmptyStringId.java | 4 +- .../mapdb/repository/data/WithFinalField.java | 4 +- .../mapdb/repository/data/WithNitriteId.java | 4 +- .../no2/mapdb/repository/data/WithNullId.java | 4 +- .../mapdb/repository/data/WithObjectId.java | 4 +- .../repository/data/WithOutGetterSetter.java | 4 +- .../no2/mapdb/repository/data/WithOutId.java | 4 +- .../data/WithPrivateConstructor.java | 4 +- .../repository/data/WithPublicField.java | 4 +- .../repository/data/WithTransientField.java | 4 +- .../no2/mapdb/transaction/TxData.java | 4 +- .../dizitart/no2/mvstore/MVStoreModule.java | 4 +- .../no2/mvstore/compat/v3/MigrationUtil.java | 8 +- .../org/dizitart/no2/NitriteBuilderTest.java | 6 +- .../org/dizitart/no2/NitriteStressTest.java | 4 +- .../java/org/dizitart/no2/NitriteTest.java | 4 +- .../java/org/dizitart/no2/StressTest.java | 4 +- .../no2/collection/CollectionFindTest.java | 1 - .../org/dizitart/no2/migrate/NewClass.java | 4 +- .../org/dizitart/no2/migrate/OldClass.java | 4 +- .../repository/CustomFieldSeparatorTest.java | 4 +- .../no2/repository/InternalClass.java | 4 +- .../no2/repository/ObjectRepositoryTest.java | 8 +- .../no2/repository/RepositoryJoinTest.java | 4 +- .../repository/RepositoryOperationsTest.java | 6 +- .../no2/repository/RepositorySearchTest.java | 4 +- .../UniversalTextTokenizerTest.java | 6 +- .../no2/repository/data/ChildClass.java | 2 +- .../dizitart/no2/repository/data/ClassA.java | 4 +- .../dizitart/no2/repository/data/ClassB.java | 4 +- .../dizitart/no2/repository/data/ClassC.java | 4 +- .../dizitart/no2/repository/data/Company.java | 4 +- .../no2/repository/data/ElemMatch.java | 4 +- .../no2/repository/data/Employee.java | 4 +- .../dizitart/no2/repository/data/Note.java | 4 +- .../no2/repository/data/ParentClass.java | 2 +- .../no2/repository/data/PersonEntity.java | 4 +- .../no2/repository/data/ProductScore.java | 4 +- .../repository/data/RepeatableIndexTest.java | 4 +- .../no2/repository/data/StressRecord.java | 4 +- .../no2/repository/data/SubEmployee.java | 4 +- .../no2/repository/data/SuperDuperClass.java | 4 +- .../no2/repository/data/WithClassField.java | 4 +- .../no2/repository/data/WithDateId.java | 4 +- .../repository/data/WithEmptyStringId.java | 4 +- .../no2/repository/data/WithFinalField.java | 4 +- .../no2/repository/data/WithNitriteId.java | 4 +- .../no2/repository/data/WithNullId.java | 4 +- .../no2/repository/data/WithObjectId.java | 4 +- .../repository/data/WithOutGetterSetter.java | 4 +- .../no2/repository/data/WithOutId.java | 4 +- .../data/WithPrivateConstructor.java | 4 +- .../no2/repository/data/WithPublicField.java | 4 +- .../repository/data/WithTransientField.java | 4 +- .../org/dizitart/no2/transaction/TxData.java | 4 +- .../dizitart/no2/rocksdb/RocksDBModule.java | 2 +- .../no2/rocksdb/NitriteBuilderTest.java | 6 +- .../no2/rocksdb/NitriteStressTest.java | 4 +- .../org/dizitart/no2/rocksdb/NitriteTest.java | 4 +- .../org/dizitart/no2/rocksdb/StressTest.java | 7 +- .../collection/CollectionFindTest.java | 1 - .../no2/rocksdb/migrate/NewClass.java | 4 +- .../no2/rocksdb/migrate/OldClass.java | 4 +- .../repository/CustomFieldSeparatorTest.java | 4 +- .../no2/rocksdb/repository/InternalClass.java | 4 +- .../repository/ObjectRepositoryTest.java | 4 +- .../repository/RepositoryJoinTest.java | 4 +- .../repository/RepositorySearchTest.java | 4 +- .../UniversalTextTokenizerTest.java | 6 +- .../rocksdb/repository/data/ChildClass.java | 2 +- .../no2/rocksdb/repository/data/ClassA.java | 4 +- .../no2/rocksdb/repository/data/ClassB.java | 4 +- .../no2/rocksdb/repository/data/ClassC.java | 4 +- .../no2/rocksdb/repository/data/Company.java | 4 +- .../rocksdb/repository/data/ElemMatch.java | 4 +- .../no2/rocksdb/repository/data/Employee.java | 4 +- .../no2/rocksdb/repository/data/Note.java | 4 +- .../rocksdb/repository/data/ParentClass.java | 2 +- .../rocksdb/repository/data/PersonEntity.java | 4 +- .../rocksdb/repository/data/ProductScore.java | 4 +- .../repository/data/RepeatableIndexTest.java | 4 +- .../rocksdb/repository/data/StressRecord.java | 4 +- .../rocksdb/repository/data/SubEmployee.java | 4 +- .../repository/data/SuperDuperClass.java | 4 +- .../repository/data/WithClassField.java | 4 +- .../rocksdb/repository/data/WithDateId.java | 4 +- .../repository/data/WithEmptyStringId.java | 4 +- .../repository/data/WithFinalField.java | 4 +- .../repository/data/WithNitriteId.java | 4 +- .../rocksdb/repository/data/WithNullId.java | 4 +- .../rocksdb/repository/data/WithObjectId.java | 4 +- .../repository/data/WithOutGetterSetter.java | 4 +- .../rocksdb/repository/data/WithOutId.java | 4 +- .../data/WithPrivateConstructor.java | 4 +- .../repository/data/WithPublicField.java | 4 +- .../repository/data/WithTransientField.java | 4 +- .../no2/rocksdb/transaction/TxData.java | 4 +- .../no2/spatial/IntersectsFilter.java | 6 +- .../dizitart/no2/spatial/SpatialIndexer.java | 2 +- .../dizitart/no2/spatial/SpatialModule.java | 4 +- .../dizitart/no2/spatial/WithinFilter.java | 6 +- .../no2/spatial/mapper/GeometryExtension.java | 2 +- .../no2/spatial/test/SpatialIndexTest.java | 2 +- .../org/dizitart/no2/support/Company.java | 4 +- .../org/dizitart/no2/support/Employee.java | 4 +- .../java/org/dizitart/no2/support/Note.java | 4 +- nitrite/build.gradle | 1 + .../main/java/org/dizitart/no2/Nitrite.java | 33 +- .../java/org/dizitart/no2/NitriteBuilder.java | 2 +- .../java/org/dizitart/no2/NitriteConfig.java | 8 +- .../org/dizitart/no2/NitriteDatabase.java | 47 +- .../no2/collection/CollectionFactory.java | 2 + .../collection/DefaultNitriteCollection.java | 2 +- .../dizitart/no2/collection/FindOptions.java | 35 +- .../org/dizitart/no2/collection/FindPlan.java | 8 +- .../no2/collection/NitriteDocument.java | 1 + .../operation/CollectionOperations.java | 4 +- .../collection/operation/FindOptimizer.java | 96 ++-- .../collection/operation/IndexManager.java | 14 +- .../collection/operation/IndexOperations.java | 4 +- .../collection/operation/ReadOperations.java | 5 +- .../collection/operation/WriteOperations.java | 2 +- .../org/dizitart/no2/common/Constants.java | 5 + .../java/org/dizitart/no2/common/DBNull.java | 19 +- .../org/dizitart/no2/common/FieldValues.java | 8 +- .../no2/common/PersistentCollection.java | 2 +- .../org/dizitart/no2/common/RecordStream.java | 4 +- .../no2/common/crypto/AESEncryptor.java | 89 +-- .../dizitart/no2/common/event/EventBus.java | 5 + .../no2/{ => common}/mapper/Mappable.java | 2 +- .../{ => common}/mapper/MappableMapper.java | 2 +- .../{ => common}/mapper/NitriteMapper.java | 4 +- .../{ => common}/module/NitriteModule.java | 13 +- .../{ => common}/module/NitritePlugin.java | 2 +- .../common/module/NitritePluginFactory.java | 26 + .../{ => common}/module/PluginManager.java | 6 +- .../{ => common}/processors/Processor.java | 2 +- .../processors/ProcessorChain.java | 2 +- .../StringFieldEncryptionProcessor.java | 2 +- .../common/streams/BoundedDocumentStream.java | 7 +- .../no2/common/streams/DistinctStream.java | 95 ++++ .../no2/common/streams/DocumentSorter.java | 59 +- .../no2/common/streams/DocumentStream.java | 2 +- .../no2/common/streams/FilteredStream.java | 6 +- .../no2/common/streams/IndexedStream.java | 2 +- .../common/streams/JoinedDocumentStream.java | 18 +- .../streams/ProjectedDocumentStream.java | 14 +- .../common/streams/SortedDocumentStream.java | 7 +- .../no2/common/streams/UnionStream.java | 4 +- .../no2/common/util/DocumentUtils.java | 2 +- .../dizitart/no2/common/util/Iterables.java | 4 +- .../no2/common/util/ValidationUtils.java | 57 +- .../org/dizitart/no2/filters/AndFilter.java | 16 + .../dizitart/no2/filters/BetweenFilter.java | 4 + .../no2/filters/ComparableArrayFilter.java | 51 ++ .../no2/filters/ComparableFilter.java | 14 +- .../no2/filters/ElementMatchFilter.java | 7 + .../dizitart/no2/filters/EqualsFilter.java | 23 +- .../no2/filters/FieldBasedFilter.java | 4 +- .../no2/filters/GreaterEqualFilter.java | 18 +- .../no2/filters/GreaterThanFilter.java | 22 +- .../org/dizitart/no2/filters/InFilter.java | 16 +- .../dizitart/no2/filters/IndexScanFilter.java | 8 +- .../no2/filters/LesserEqualFilter.java | 18 +- .../no2/filters/LesserThanFilter.java | 22 +- .../dizitart/no2/filters/NitriteFilter.java | 15 + .../dizitart/no2/filters/NotEqualsFilter.java | 20 +- .../org/dizitart/no2/filters/NotFilter.java | 5 + .../org/dizitart/no2/filters/NotInFilter.java | 16 +- .../org/dizitart/no2/filters/OrFilter.java | 16 + .../org/dizitart/no2/filters/RegexFilter.java | 5 + .../org/dizitart/no2/filters/TextFilter.java | 5 + .../org/dizitart/no2/index/CompoundIndex.java | 245 ++++----- .../java/org/dizitart/no2/index/DBValue.java | 64 +++ .../dizitart/no2/index/IndexDescriptor.java | 28 +- .../java/org/dizitart/no2/index/IndexMap.java | 271 +++++++++ .../org/dizitart/no2/index/IndexScanner.java | 234 +++----- .../dizitart/no2/index/NitriteIndexer.java | 2 +- .../dizitart/no2/index/SingleFieldIndex.java | 96 ++-- .../org/dizitart/no2/index/TextIndex.java | 2 +- .../no2/migration/MigrationManager.java | 14 +- .../no2/repository/AnnotationScanner.java | 181 ++++++ .../repository/DefaultObjectRepository.java | 6 +- .../no2/repository/IndexValidator.java | 83 +++ .../no2/repository/MutatedObjectStream.java | 2 +- .../dizitart/no2/repository/ObjectCursor.java | 2 +- .../no2/repository/ObjectIdField.java | 106 ++++ .../dizitart/no2/repository/Reflector.java | 152 ++++++ .../no2/repository/RepositoryFactory.java | 2 +- .../no2/repository/RepositoryOperations.java | 358 +++--------- .../annotations/InheritIndices.java | 2 +- .../annotations/Order.java} | 34 +- .../org/dizitart/no2/store/MapMetaData.java | 61 +++ .../ModuleConfig.java => store/MetaData.java} | 14 +- .../org/dizitart/no2/store/NitriteMap.java | 5 + .../org/dizitart/no2/store/NitriteRTree.java | 5 + .../org/dizitart/no2/store/NitriteStore.java | 2 +- .../org/dizitart/no2/store/StoreCatalog.java | 57 +- ...tabaseMetaData.java => StoreMetaData.java} | 6 +- .../org/dizitart/no2/store/StoreModule.java | 2 +- .../no2/store/memory/InMemoryMap.java | 83 +-- .../no2/store/memory/InMemoryRTree.java | 2 +- .../no2/store/memory/InMemoryStoreModule.java | 2 +- .../DefaultTransactionalCollection.java | 2 +- .../DefaultTransactionalRepository.java | 6 +- .../dizitart/no2/transaction/Transaction.java | 4 +- .../no2/transaction/TransactionalConfig.java | 4 +- .../no2/transaction/TransactionalRTree.java | 2 +- .../java/org/dizitart/no2/EventTypeTest.java | 43 -- .../org/dizitart/no2/NitriteBuilderTest.java | 268 +++++---- .../org/dizitart/no2/NitriteConfigTest.java | 149 +++++ .../org/dizitart/no2/NitriteDatabaseTest.java | 62 +++ .../java/org/dizitart/no2/NitriteIdTest.java | 82 --- .../no2/collection/CollectionFactoryTest.java | 2 +- .../DefaultNitriteCollectionTest.java | 44 ++ .../no2/{ => collection}/DocumentTest.java | 24 +- .../no2/collection/FindOptionsTest.java | 125 +++++ .../dizitart/no2/collection/FindPlanTest.java | 314 +++++++++++ .../no2/collection/NitriteCollectionTest.java | 4 +- .../no2/collection/NitriteDocumentTest.java | 148 ++++- .../no2/collection/NitriteIdTest.java | 85 ++- .../collection/SnowflakeIdGeneratorTest.java | 36 ++ .../operation/CollectionOperationsTest.java | 40 ++ .../operation/DocumentIndexWriterTest.java | 88 +++ .../operation/FindOptimizerTest.java | 96 ++++ .../operation/IndexManagerTest.java | 35 ++ .../operation/IndexOperationsTest.java | 250 +++++++++ .../operation/ReadOperationsTest.java | 64 +++ .../dizitart/no2/common/FieldValuesTest.java | 89 +++ .../org/dizitart/no2/common/FieldsTest.java | 110 ++++ .../org/dizitart/no2/common/LookupTest.java | 162 ++++++ .../dizitart/no2/common/RecordStreamTest.java | 30 + .../dizitart/no2/common/SortOrderTest.java | 39 ++ .../no2/common/SortableFieldsTest.java | 52 ++ .../dizitart/no2/common/UnknownTypeTest.java | 31 ++ .../concurrent/ThreadPoolManagerTest.java | 5 +- .../no2/common/crypto/AESEncryptorTest.java | 40 ++ .../dizitart/no2/common/event/EventTest.java | 4 +- .../no2/{ => common}/mapper/Company.java | 2 +- .../no2/{ => common}/mapper/Department.java | 2 +- .../no2/{ => common}/mapper/Employee.java | 2 +- .../mapper/MappableDepartment.java | 2 +- .../{ => common}/mapper/MappableEmployee.java | 2 +- .../mapper/MappableMapperTest.java | 10 +- .../no2/{ => common}/mapper/MapperTest.java | 4 +- .../no2/common/module/PluginManagerTest.java | 68 +++ .../common/processors/ProcessorChainTest.java | 57 ++ .../streams/BoundedDocumentStreamTest.java | 75 +++ .../common/streams/DistinctStreamTest.java | 64 +++ .../common/streams/DocumentSorterTest.java | 37 ++ .../common/streams/DocumentStreamTest.java | 52 ++ .../common/streams/FilteredStreamTest.java | 48 ++ .../no2/common/streams/IndexedStreamTest.java | 44 ++ .../streams/JoinedDocumentStreamTest.java | 48 ++ .../streams/ProjectedDocumentStreamTest.java | 69 +++ .../streams/SortedDocumentStreamTest.java | 71 +++ .../no2/common/streams/UnionStreamTest.java | 39 ++ .../dizitart/no2/common/util/Base64Test.java | 209 +++++++ .../no2/common/util/CryptoUtilsTest.java | 43 ++ .../no2/common/util/DocumentUtilsTest.java | 14 +- .../no2/common/util/IndexUtilsTest.java | 45 ++ .../no2/common/util/IterablesTest.java | 4 +- .../dizitart/no2/common/util/NumbersTest.java | 2 +- .../no2/common/util/ObjectUtilsTest.java | 4 +- .../no2/common/util/SecureStringTest.java | 128 +++++ .../no2/common/util/StringUtilsTest.java | 2 +- .../no2/common/util/ValidationUtilsTest.java | 2 +- .../dizitart/no2/filters/AndFilterTest.java | 61 +++ .../no2/filters/BetweenFilterTest.java | 102 ++++ .../no2/filters/ElementMatchFilterTest.java | 31 ++ .../no2/filters/EqualsFilterTest.java | 26 +- .../org/dizitart/no2/filters/FilterTest.java | 33 ++ .../no2/filters/FluentFilterTest.java | 35 +- .../no2/filters/IndexScanFilterTest.java | 32 ++ .../no2/filters/NotEqualsFilterTest.java | 25 +- .../dizitart/no2/filters/NotFilterTest.java | 51 ++ .../dizitart/no2/filters/OrFilterTest.java | 54 ++ .../dizitart/no2/filters/RegexFilterTest.java | 25 +- .../dizitart/no2/filters/TextFilterTest.java | 67 +++ .../dizitart/no2/index/CompoundIndexTest.java | 89 +++ .../no2/index/IndexDescriptorTest.java | 62 +++ .../org/dizitart/no2/index/IndexMapTest.java | 55 ++ .../dizitart/no2/index/IndexOptionsTest.java | 3 +- .../no2/index/NitriteTextIndexerTest.java | 133 ++++- .../no2/index/NonUniqueIndexerTest.java | 12 +- .../no2/index/SingleFieldIndexTest.java | 65 +++ .../org/dizitart/no2/index/TextIndexTest.java | 95 ++++ .../dizitart/no2/index/UniqueIndexerTest.java | 11 +- .../no2/index/fulltext/TokenizerTests.java | 2 +- .../CollectionFieldIndexTest.java | 10 +- .../{ => integration}/CustomFilterTest.java | 9 +- .../{ => integration}/DbTestOperations.java | 10 +- .../DocumentMetadataTest.java | 9 +- .../{ => integration}/MultiThreadedTest.java | 12 +- .../NitriteCorruptedTest.java | 10 +- .../NitriteSecurityTest.java | 10 +- .../{ => integration}/NitriteStressTest.java | 14 +- .../no2/{ => integration}/NitriteTest.java | 14 +- .../dizitart/no2/{ => integration}/Retry.java | 19 +- .../SerializabilityTest.java | 10 +- .../no2/{ => integration}/StressTest.java | 12 +- .../no2/{ => integration}/TestUtil.java | 8 +- .../collection/BaseCollectionTest.java | 14 +- .../CollectionCompoundIndexNegativeTest.java | 98 ++++ .../CollectionCompoundIndexTest.java | 318 +++++++++++ .../CollectionDeleteNegativeTest.java | 9 +- .../collection/CollectionDeleteTest.java | 8 +- .../CollectionFindByCompoundIndexTest.java | 503 +++++++++++++++++ .../CollectionFindByIndexNegativeTest.java | 8 +- ...CollectionFindBySingleFieldIndexTest.java} | 14 +- .../CollectionFindNegativeTest.java | 15 +- .../collection/CollectionFindTest.java | 107 +--- .../CollectionInsertNegativeTest.java | 8 +- .../collection/CollectionInsertTest.java | 9 +- .../collection/CollectionJoinTest.java | 9 +- ...llectionSingleFieldIndexNegativeTest.java} | 19 +- .../CollectionSingleFieldIndexTest.java} | 66 +-- .../collection/CollectionUpdateTest.java | 11 +- .../repository/BaseObjectRepositoryTest.java | 25 +- .../repository/CustomFieldSeparatorTest.java | 20 +- .../repository/InternalClass.java | 11 +- .../repository/NitriteIdAsIdTest.java | 15 +- .../repository/ObjectCursorTest.java | 55 ++ .../ObjectRepositoryNegativeTest.java | 16 +- .../repository/ObjectRepositoryTest.java | 33 +- .../repository/ProjectionTest.java | 9 +- .../RepositoryCompoundIndexTest.java | 52 ++ .../repository/RepositoryFactoryTest.java | 242 ++++++++ .../repository/RepositoryJoinTest.java | 14 +- .../RepositoryModificationTest.java | 14 +- .../repository/RepositorySearchTest.java | 76 ++- .../repository/UnAnnotatedObjectTest.java | 15 +- .../UniversalTextTokenizerTest.java | 17 +- .../no2/integration/repository/data/Book.java | 72 +++ .../integration/repository/data/BookId.java | 55 ++ .../repository/data/ChildClass.java | 9 +- .../repository/data/ClassA.java | 23 +- .../repository/data/ClassB.java | 11 +- .../repository/data/ClassC.java | 13 +- .../repository/data/Company.java | 23 +- .../repository/data/DataGenerator.java | 95 ++-- .../repository/data/ElemMatch.java | 11 +- .../repository/data/Employee.java | 18 +- .../repository/data/Note.java | 11 +- .../repository/data/ParentClass.java | 9 +- .../repository/data/PersonEntity.java | 11 +- .../repository/data/ProductScore.java | 11 +- .../repository/data/RepeatableIndexTest.java | 11 +- .../repository/data/StressRecord.java | 11 +- .../repository/data/SubEmployee.java | 11 +- .../repository/data/SuperDuperClass.java | 11 +- .../data/WithCircularReference.java | 7 +- .../repository/data/WithClassField.java | 11 +- .../data/WithCustomConstructor.java | 7 +- .../repository/data/WithDateId.java | 11 +- .../repository/data/WithEmptyStringId.java | 11 +- .../repository/data/WithFinalField.java | 11 +- .../repository/data/WithNitriteId.java | 11 +- .../repository/data/WithNullId.java | 11 +- .../repository/data/WithObjectId.java | 11 +- .../repository/data/WithOutGetterSetter.java | 11 +- .../repository/data/WithOutId.java | 11 +- .../data/WithPrivateConstructor.java | 11 +- .../repository/data/WithPublicField.java | 11 +- .../repository/data/WithTransientField.java | 11 +- .../stream}/DocumentCursorTest.java | 11 +- .../stream}/JoinedDocumentStreamTest.java | 11 +- .../TransactionCollectionTest.java | 23 +- .../TransactionRepositoryTest.java | 25 +- .../{ => integration}/transaction/TxData.java | 11 +- .../no2/migration/InstructionTypeTest.java | 36 ++ .../no2/migration/MigrationStepTest.java | 33 ++ .../migration/NitriteInstructionsTest.java | 33 ++ .../no2/migration/commands/AddFieldTest.java | 76 +++ .../commands/ChangeDataTypeTest.java | 77 +++ .../migration/commands/DeleteFieldTest.java | 76 +++ .../migration/commands/RenameFieldTest.java | 76 +++ .../no2/repository/AnnotationScannerTest.java | 82 +++ .../DefaultObjectRepositoryTest.java | 360 ++++++++++++ .../no2/repository/IndexValidatorTest.java | 54 ++ .../no2/repository/ObjectCursorTest.java | 104 +++- .../no2/repository/ObjectIdFieldTest.java | 33 ++ .../no2/repository/ReflectorTest.java | 113 ++++ .../no2/repository/RepositoryFactoryTest.java | 229 +------- .../repository/RepositoryOperationsTest.java | 419 ++------------ .../no2/store/DatabaseMetaDataTest.java | 31 -- .../dizitart/no2/store/StoreCatalogTest.java | 81 +++ .../dizitart/no2/store/StoreMetaDataTest.java | 31 ++ .../store/UserAuthenticationServiceTest.java | 87 +++ .../no2/store/memory/InMemoryMapTest.java | 330 ++++++++--- .../store/memory/InMemoryStoreModuleTest.java | 50 ++ .../no2/transaction/ChangeTypeTest.java | 36 ++ .../DefaultTransactionalCollectionTest.java | 63 +++ .../DefaultTransactionalRepositoryTest.java | 288 ++++++++++ .../no2/transaction/JournalEntryTest.java | 122 +++++ .../transaction/NitriteTransactionTest.java | 40 ++ .../dizitart/no2/transaction/StateTest.java | 42 ++ .../transaction/TransactionContextTest.java | 60 ++ .../transaction/TransactionalConfigTest.java | 80 +++ .../no2/transaction/TransactionalMapTest.java | 515 ++++++++++++++++++ .../transaction/TransactionalRTreeTest.java | 147 +++++ .../transaction/TransactionalStoreTest.java | 144 +++++ .../no2/transaction/UndoEntryTest.java | 110 ++++ .../main/kotlin/org/dizitart/kno2/Builder.kt | 4 +- .../org/dizitart/kno2/KNO2JacksonMapper.kt | 4 +- .../kotlin/org/dizitart/kno2/KNO2Module.kt | 7 +- .../org/dizitart/kno2/BackportJavaTimeTest.kt | 2 +- .../kotlin/org/dizitart/kno2/BuilderTest.kt | 3 +- .../kotlin/org/dizitart/kno2/NitriteTest.kt | 1 - .../org/dizitart/no2/rx/FlowableCursor.java | 1 - .../no2/rx/FlowableDocumentCursor.java | 1 - .../no2/rx/RxObjectRepositoryImpl.java | 2 +- .../java/org/dizitart/no2/rx/RxBaseTest.java | 4 +- 462 files changed, 12228 insertions(+), 3010 deletions(-) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/JacksonExtension.java (95%) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/JacksonMapper.java (98%) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/JacksonMapperModule.java (89%) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/extensions/NitriteIdDeserializer.java (96%) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/extensions/NitriteIdExtension.java (93%) rename nitrite-jackson-mapper/src/main/java/org/dizitart/no2/{ => common}/mapper/extensions/NitriteIdSerializer.java (96%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/mapper/Mappable.java (97%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/mapper/MappableMapper.java (99%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/mapper/NitriteMapper.java (94%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/module/NitriteModule.java (82%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/module/NitritePlugin.java (96%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java rename nitrite/src/main/java/org/dizitart/no2/{ => common}/module/PluginManager.java (97%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/processors/Processor.java (96%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/processors/ProcessorChain.java (97%) rename nitrite/src/main/java/org/dizitart/no2/{ => common}/processors/StringFieldEncryptionProcessor.java (98%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/common/streams/DistinctStream.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/ComparableArrayFilter.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/DBValue.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/repository/Reflector.java rename nitrite/src/main/java/org/dizitart/no2/{common/NullOrder.java => repository/annotations/Order.java} (55%) create mode 100644 nitrite/src/main/java/org/dizitart/no2/store/MapMetaData.java rename nitrite/src/main/java/org/dizitart/no2/{module/ModuleConfig.java => store/MetaData.java} (74%) rename nitrite/src/main/java/org/dizitart/no2/store/{DatabaseMetaData.java => StoreMetaData.java} (92%) delete mode 100644 nitrite/src/test/java/org/dizitart/no2/EventTypeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/NitriteIdTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/DefaultNitriteCollectionTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => collection}/DocumentTest.java (94%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/FindOptionsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/FindPlanTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/SnowflakeIdGeneratorTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/CollectionOperationsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexManagerTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/FieldValuesTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/FieldsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/LookupTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/RecordStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/SortOrderTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/SortableFieldsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/UnknownTypeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/Company.java (98%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/Department.java (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/Employee.java (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/MappableDepartment.java (98%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/MappableEmployee.java (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/MappableMapperTest.java (93%) rename nitrite/src/test/java/org/dizitart/no2/{ => common}/mapper/MapperTest.java (98%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/module/PluginManagerTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/processors/ProcessorChainTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/BoundedDocumentStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/DistinctStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentSorterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/IndexedStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/JoinedDocumentStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/streams/UnionStreamTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/util/Base64Test.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/util/CryptoUtilsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/util/IndexUtilsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/AndFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/ElementMatchFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/FilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/NotFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/OrFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/CompoundIndexTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/SingleFieldIndexTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/index/TextIndexTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/CollectionFieldIndexTest.java (94%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/CustomFilterTest.java (85%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/DbTestOperations.java (96%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/DocumentMetadataTest.java (91%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/MultiThreadedTest.java (93%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/NitriteCorruptedTest.java (91%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/NitriteSecurityTest.java (86%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/NitriteStressTest.java (92%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/NitriteTest.java (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/Retry.java (66%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/SerializabilityTest.java (91%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/StressTest.java (96%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/TestUtil.java (96%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/BaseCollectionTest.java (92%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionDeleteNegativeTest.java (86%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionDeleteTest.java (94%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionFindByIndexNegativeTest.java (88%) rename nitrite/src/test/java/org/dizitart/no2/{collection/CollectionFindByIndexTest.java => integration/collection/CollectionFindBySingleFieldIndexTest.java} (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionFindNegativeTest.java (90%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionFindTest.java (86%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionInsertNegativeTest.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionInsertTest.java (87%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionJoinTest.java (93%) rename nitrite/src/test/java/org/dizitart/no2/{collection/CollectionIndexNegativeTest.java => integration/collection/CollectionSingleFieldIndexNegativeTest.java} (76%) rename nitrite/src/test/java/org/dizitart/no2/{collection/CollectionIndexTest.java => integration/collection/CollectionSingleFieldIndexTest.java} (83%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionUpdateTest.java (96%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/BaseObjectRepositoryTest.java (82%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/CustomFieldSeparatorTest.java (91%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/InternalClass.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/NitriteIdAsIdTest.java (87%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/ObjectRepositoryNegativeTest.java (94%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/ObjectRepositoryTest.java (92%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/ProjectionTest.java (89%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/RepositoryJoinTest.java (95%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/RepositoryModificationTest.java (98%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/RepositorySearchTest.java (91%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/UnAnnotatedObjectTest.java (86%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/UniversalTextTokenizerTest.java (93%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ChildClass.java (83%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ClassA.java (76%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ClassB.java (85%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ClassC.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/Company.java (79%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/DataGenerator.java (52%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ElemMatch.java (87%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/Employee.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/Note.java (82%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ParentClass.java (85%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/PersonEntity.java (89%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ProductScore.java (82%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/RepeatableIndexTest.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/StressRecord.java (85%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/SubEmployee.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/SuperDuperClass.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithCircularReference.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithClassField.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithCustomConstructor.java (83%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithDateId.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithEmptyStringId.java (80%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithFinalField.java (86%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithNitriteId.java (82%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithNullId.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithObjectId.java (80%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithOutGetterSetter.java (81%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithOutId.java (82%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithPrivateConstructor.java (84%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithPublicField.java (80%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithTransientField.java (80%) rename nitrite/src/test/java/org/dizitart/no2/{collection/operation => integration/stream}/DocumentCursorTest.java (90%) rename nitrite/src/test/java/org/dizitart/no2/{collection/operation => integration/stream}/JoinedDocumentStreamTest.java (89%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/transaction/TransactionCollectionTest.java (97%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/transaction/TransactionRepositoryTest.java (96%) rename nitrite/src/test/java/org/dizitart/no2/{ => integration}/transaction/TxData.java (82%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/InstructionTypeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/MigrationStepTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/NitriteInstructionsTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/commands/AddFieldTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/commands/ChangeDataTypeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/commands/DeleteFieldTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/migration/commands/RenameFieldTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/repository/AnnotationScannerTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/repository/DefaultObjectRepositoryTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/repository/IndexValidatorTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/repository/ObjectIdFieldTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/repository/ReflectorTest.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/store/DatabaseMetaDataTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/store/StoreCatalogTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/store/StoreMetaDataTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreModuleTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/ChangeTypeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalRepositoryTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/JournalEntryTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/StateTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/TransactionContextTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalMapTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalRTreeTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/transaction/UndoEntryTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 034c6be1d..38beecc75 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,9 +27,10 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v2.1.0 with: - java-version: 1.8.0.212 + distribution: 'zulu' + java-version: '8' java-package: jdk architecture: x64 diff --git a/nitrite-android-example/build.gradle b/nitrite-android-example/build.gradle index 47e15a0b3..358d3d865 100644 --- a/nitrite-android-example/build.gradle +++ b/nitrite-android-example/build.gradle @@ -21,7 +21,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.2' + classpath 'com.android.tools.build:gradle:4.1.1' } } @@ -51,7 +51,7 @@ android { defaultConfig { applicationId "org.dizitart.no2.example.android" minSdkVersion 19 - targetSdkVersion 29 + targetSdkVersion 28 versionCode 1 versionName "1.0" @@ -89,11 +89,12 @@ dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:multidex:1.0.3' - implementation 'com.android.support.constraint:constraint-layout:2.0.2' + implementation 'com.android.support.constraint:constraint-layout:2.0.4' implementation 'com.android.support:design:28.0.0' annotationProcessor "org.projectlombok:lombok:1.18.14" testImplementation 'junit:junit:4.13.1' + testImplementation 'org.mockito:mockito-core:3.9.0' testAnnotationProcessor "org.projectlombok:lombok:1.18.14" androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/nitrite-android-example/src/main/java/org/dizitart/no2/example/android/User.java b/nitrite-android-example/src/main/java/org/dizitart/no2/example/android/User.java index 44e34fbba..628ef3acf 100644 --- a/nitrite-android-example/src/main/java/org/dizitart/no2/example/android/User.java +++ b/nitrite-android-example/src/main/java/org/dizitart/no2/example/android/User.java @@ -17,8 +17,8 @@ package org.dizitart.no2.example.android; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonExtension.java similarity index 95% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonExtension.java index fe2643bdb..d6be1d6e1 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonExtension.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonExtension.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import com.fasterxml.jackson.databind.Module; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapper.java similarity index 98% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapper.java index 5224ed104..0af159b4f 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapper.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.core.JsonParser; @@ -29,7 +29,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.util.ObjectUtils; import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.mapper.extensions.NitriteIdExtension; +import org.dizitart.no2.common.mapper.extensions.NitriteIdExtension; import java.io.IOException; import java.lang.reflect.Modifier; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapperModule.java similarity index 89% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapperModule.java index de37d5b5a..9fe5f54bd 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/JacksonMapperModule.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/JacksonMapperModule.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; -import org.dizitart.no2.module.NitriteModule; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; import java.util.Set; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdDeserializer.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializer.java similarity index 96% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdDeserializer.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializer.java index 5d45b5370..f69a97aac 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdDeserializer.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper.extensions; +package org.dizitart.no2.common.mapper.extensions; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtension.java similarity index 93% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtension.java index ca49157bd..6523a9991 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdExtension.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtension.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.dizitart.no2.mapper.extensions; +package org.dizitart.no2.common.mapper.extensions; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.module.SimpleModule; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.mapper.JacksonExtension; +import org.dizitart.no2.common.mapper.JacksonExtension; import java.util.List; diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdSerializer.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializer.java similarity index 96% rename from nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdSerializer.java rename to nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializer.java index b39611599..2262db37d 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/extensions/NitriteIdSerializer.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper.extensions; +package org.dizitart.no2.common.mapper.extensions; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java index 6dbd8a040..ec775dd7e 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java @@ -18,7 +18,7 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.ObjectRepository; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java index 00c678320..f13488a21 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.util.Iterables; import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.mapper.JacksonMapper; +import org.dizitart.no2.common.mapper.JacksonMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; @@ -35,7 +35,7 @@ import java.nio.file.Files; import java.nio.file.Paths; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.test.BaseObjectRepositoryTest.getRandomTempDbFile; import static org.dizitart.no2.test.TestUtil.createDb; import static org.junit.Assert.assertEquals; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java index 975d3ac77..8815c3c03 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java @@ -21,7 +21,7 @@ import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.*; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.test.data.*; import org.junit.After; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java index 7e3203fed..629f71978 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java @@ -18,7 +18,7 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.test.data.*; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java index a11f13c4c..3897fd661 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java @@ -23,7 +23,7 @@ import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.ObjectRepository; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java index a38627408..de6d0e7fd 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java @@ -18,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.module.NitriteModule; +import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.mvstore.MVStoreModule; /** diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java index 8e39782af..88957bfb4 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java @@ -22,7 +22,7 @@ import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.Cursor; @@ -39,7 +39,7 @@ import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java index 87de6b589..960c629f0 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java @@ -8,7 +8,7 @@ import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java index 6669414f1..e3701f925 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java @@ -132,12 +132,6 @@ public void put(K k, V v) { if (k == null) { nullEntryMap.put(DBNull.getInstance(), v); } else { - Map.Entry firstEntry = bTreeMap.firstEntry(); - if (firstEntry != null) { - if (!firstEntry.getKey().getClass().equals(k.getClass())) { - return; - } - } bTreeMap.put(k, v); } updateLastModifiedTime(); diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java index d3a16198d..1b996c72f 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java @@ -2,7 +2,7 @@ import lombok.AccessLevel; import lombok.Setter; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreModule; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java index 949a75f7e..67f734265 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java @@ -30,8 +30,8 @@ import org.dizitart.no2.exceptions.SecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.store.StoreConfig; @@ -53,7 +53,7 @@ import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.*; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java index e813fbb31..8ea0f3ade 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java @@ -21,8 +21,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.Rule; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java index 3aec455be..ce0c99fef 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java @@ -29,8 +29,8 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java index 231da9839..401db2ef4 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java @@ -24,8 +24,8 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java index 69a772bab..465db3503 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java @@ -21,7 +21,6 @@ import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.ValidationException; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java index db2ddddb8..e10997fa2 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java index 2d2430488..cd0ea75bf 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java index 5dc484871..762574c2d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java @@ -28,8 +28,8 @@ import org.dizitart.no2.mapdb.Retry; import org.dizitart.no2.mapdb.repository.data.Company; import org.dizitart.no2.mapdb.repository.data.Note; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java index eb340f272..1c22f544e 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java @@ -18,8 +18,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java index ed786e7df..86e230db7 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java @@ -27,9 +27,9 @@ import org.dizitart.no2.mapdb.MapDBModule; import org.dizitart.no2.mapdb.Retry; import org.dizitart.no2.mapdb.repository.data.*; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.MappableMapper; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Entity; @@ -51,7 +51,7 @@ import static org.awaitility.Awaitility.await; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.*; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java index 400de9ac3..a231048d7 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java @@ -27,8 +27,8 @@ import org.dizitart.no2.mapdb.MapDBModule; import org.dizitart.no2.mapdb.MapDBModuleBuilder; import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.After; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java index 3bb0cf79d..6b8e165cf 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java @@ -24,8 +24,8 @@ import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.mapdb.repository.data.*; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java index 6637407d2..cc8de2f27 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java @@ -25,8 +25,8 @@ import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; import org.dizitart.no2.mapdb.MapDBModule; import org.dizitart.no2.mapdb.MapDBModuleBuilder; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; @@ -42,7 +42,7 @@ import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java index a48918c33..b1c14191d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java @@ -19,7 +19,7 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.InheritIndices; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java index 30e2c4c74..52d6eba2b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.UUID; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java index 0bf49ba01..fb26ae4e3 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java index 4dff3f804..beb96231b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java index d06abd742..32d153f78 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java index 80187cc2b..e2ba507bb 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java @@ -18,8 +18,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.ArrayList; import java.util.List; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java index a1323e0d6..f40062584 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java @@ -22,8 +22,8 @@ import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java index c9e6fde60..31906206d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java index e6cc7fddd..6b549ff65 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java @@ -19,7 +19,7 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java index c1c85f3f9..911ac8ca4 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java index 52e522008..cc29f74df 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java index 78686aa6e..e0030b59d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java index 8523e9e36..602d2c54f 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java index 3506e1b9d..fb4478192 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java index 7be25aba7..5fc701968 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java index fc3cdb09b..e34d7e6dc 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java index 9e37fbee8..0b2c35dc0 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java index 8d0f42320..1e84a020d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java index f74583d35..eb9e095a4 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java index 182215ac5..f6ade0d57 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java index 6ccf891b8..b77eb9c1a 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java index 9505b57c7..7e4f1f1db 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java index ef755e1a7..63e8e993a 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java index 06ba40ebc..e110c24f5 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java index d65cf7c34..b9bd97f64 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java index 33b45fe2d..19a037250 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java @@ -17,8 +17,8 @@ package org.dizitart.no2.mapdb.repository.data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java index 781b7c650..90b8005e3 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java index f31a212e2..024b9f184 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java @@ -20,8 +20,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java index d5f0478f0..9270206e7 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/MVStoreModule.java @@ -18,8 +18,8 @@ import lombok.AccessLevel; import lombok.Setter; -import org.dizitart.no2.module.NitriteModule; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreModule; diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java index 240785237..8e549b91c 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java @@ -19,8 +19,11 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.DBNull; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.index.DBValue; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; import org.dizitart.no2.store.UserCredential; @@ -76,6 +79,9 @@ private static void copyData(MVMap oldMap, MVMap newMap) { Object newKey = key; if (key instanceof Compat.NitriteId) { newKey = nitriteId((Compat.NitriteId) key); + } else { + // index map, wrap with DBValue + newKey = newKey == null ? DBNull.getInstance() : new DBValue((Comparable) newKey); } Object value = oldMap.get(key); @@ -187,7 +193,7 @@ private static IndexMeta indexMeta(Compat.IndexMeta value) { private static IndexDescriptor indexEntry(Compat.Index value) { String indexType = value.getIndexType().name(); - return new IndexDescriptor(indexType, value.getField(), value.getCollectionName()); + return new IndexDescriptor(indexType, Fields.withNames(value.getField()), value.getCollectionName()); } private static NitriteId nitriteId(Compat.NitriteId value) { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 5164f3a30..9684f41d6 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -27,8 +27,8 @@ import org.dizitart.no2.exceptions.SecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreConfig; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; @@ -53,7 +53,7 @@ import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.*; /** diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java index 29e1dddc7..4cdc786f3 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java @@ -20,8 +20,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.Rule; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java index 3ba85eebb..6df77e7f0 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java @@ -28,8 +28,8 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java index e4b12abf4..42a0f246d 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java @@ -23,8 +23,8 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java index d5bc4faca..49dae5f27 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java @@ -16,7 +16,6 @@ package org.dizitart.no2.collection; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.ValidationException; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java index a9a83d4b2..c8a982000 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java index 7808f3fb2..cf7a597ed 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java index 8cc25f0d3..073d511b8 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java @@ -25,8 +25,8 @@ import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java index b351ac40a..1c9fda1da 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java index 83da340e3..0492685cf 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java @@ -25,9 +25,9 @@ import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.MappableMapper; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; @@ -49,7 +49,7 @@ import static org.awaitility.Awaitility.await; import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.*; /** diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java index da2c0c8c9..2f5670810 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java @@ -25,8 +25,8 @@ import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.annotations.Id; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java index 44a8b5609..98426b521 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java @@ -25,8 +25,8 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.InheritIndices; @@ -153,8 +153,6 @@ public void read(NitriteMapper mapper, Document document) { NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); ObjectRepository repository = db.getRepository(Test.class); operations = new RepositoryOperations(Test.class, nitriteMapper, repository.getDocumentCollection()); - - operations.getIdField(Test.class); } @Test(expected = ValidationException.class) diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java index 3f836505a..89dae378f 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java @@ -23,8 +23,8 @@ import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.data.*; import org.junit.Test; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java index 7dea86ff7..db6100a23 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java @@ -23,8 +23,8 @@ import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.annotations.Index; @@ -40,7 +40,7 @@ import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java index 454880872..3940aaa69 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java @@ -20,7 +20,7 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.InheritIndices; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java index 4cdce3acc..47efd01f1 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.UUID; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java index 9be7793e8..23d93d5b3 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java index 4402a7109..047f83bcd 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java index 8171c4bff..635cad5a9 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java index dd0042ff1..1a30321eb 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java @@ -18,8 +18,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.ArrayList; import java.util.List; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java index 3da19271f..02a5b378b 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java @@ -24,8 +24,8 @@ import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; import java.util.Date; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java index 24dacae30..18310236a 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java index ccc9faab1..7171c2ae6 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java @@ -21,7 +21,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java index 0e1a306a6..f201d620f 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java index 9075ae5f5..06fab6a78 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java index 68e862c8e..f2076ab48 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java @@ -20,8 +20,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java index 471ae0964..a526c516d 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java index 8c845a616..fedfeb6ed 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java index edb2f3767..1b935ba4e 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java @@ -21,8 +21,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java index 5aa4c24f7..57c4b1940 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java index 16d113a2c..c0072e655 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java index abf40a668..816f1cb38 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java index 5e2f50044..3787ebbbb 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java index 11c0dc1ad..50cf53c57 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java @@ -20,8 +20,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java index f4208beac..5f8f87c3e 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java index b6efa556a..dc0324132 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java index 607967bd3..56bdbd241 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java index 08cad426e..3a252d9b5 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java index 25df54331..4332542ea 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java index 58cd082aa..2f643c251 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java @@ -18,8 +18,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java index 7c634e44b..6294a5783 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java index f5e7c02cf..20ad7d6ac 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java @@ -20,8 +20,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java index 54e303fcb..6e15fc13b 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBModule.java @@ -2,7 +2,7 @@ import lombok.AccessLevel; import lombok.Setter; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreModule; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java index 8cac9ceb4..e6e8f2bb2 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java @@ -31,8 +31,8 @@ import org.dizitart.no2.exceptions.SecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.store.StoreConfig; @@ -49,7 +49,7 @@ import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; import static org.junit.Assert.*; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java index 4b99fa812..1acfe7861 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java @@ -20,8 +20,8 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.Rule; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java index 8388a1362..fb0b1cba0 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java @@ -29,8 +29,8 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java index cea8c05be..b67d456db 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java @@ -23,19 +23,16 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; import org.junit.Before; import org.junit.Test; import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; -import java.io.IOException; -import java.text.ParseException; import java.util.ArrayList; import java.util.List; import java.util.Random; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java index 014e8aeee..d5923b4dc 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java @@ -20,7 +20,6 @@ import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.ValidationException; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java index 92035e98f..87475198a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java index a2eb259ba..7827330dd 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java @@ -3,8 +3,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java index c7eb5c5dc..3ef5b97f3 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java @@ -24,8 +24,8 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java index ec5bda278..230fac3bc 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java @@ -18,8 +18,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java index b6f59187c..b84a9b265 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java @@ -23,8 +23,8 @@ import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Entity; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java index a21a23442..dc7fe6c87 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java @@ -22,8 +22,8 @@ import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.After; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java index 9181c502e..ac8bdf37c 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java @@ -24,8 +24,8 @@ import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.rocksdb.repository.data.*; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java index 0b9c91ae9..450e76ff7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java @@ -24,8 +24,8 @@ import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; import org.dizitart.no2.rocksdb.RocksDBModule; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; @@ -40,7 +40,7 @@ import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java index d6044f010..d86fc3576 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java @@ -19,7 +19,7 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.InheritIndices; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java index bb8fceb6c..8579166d8 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.UUID; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java index 927827377..9f4d2e171 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java index 9a93a7d02..d7bd57c6f 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java index 53863170e..b13c337ad 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java @@ -21,8 +21,8 @@ import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java index 0793025ef..b8b4aee2e 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java @@ -18,8 +18,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.ArrayList; import java.util.List; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java index 7683f99d4..2f7f851c9 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java @@ -22,8 +22,8 @@ import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java index a719aa4d8..7b0686118 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java index d6278e242..8c4227abc 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java @@ -19,7 +19,7 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java index 419032405..116b2dd77 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java index 5515e45c9..6914fcadc 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java index 9f4392384..352100cb4 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java index 5c301eeab..6a36a7604 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java index 75b2b4f5c..7c03e0cc3 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java index b132700bc..0e5f8a054 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java index 276d07a6a..df3613b6a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java index 6af52e206..5790e25d0 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java index 6bbd6f35e..2cad5635f 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java index e9dd39fb5..48a9ae966 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java @@ -20,8 +20,8 @@ import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java index f26eb45c5..c4d120fee 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java @@ -19,8 +19,8 @@ import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java index dd1995486..94c36d7b8 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java index 86dc0baf3..31b02d3cc 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java index 717918eb5..bd42f1b2c 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java index fd5447e47..a96ff2224 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java index f64a0d181..3b9fc622a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java @@ -18,8 +18,8 @@ import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java index 5660db416..b02750c8a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java @@ -17,8 +17,8 @@ package org.dizitart.no2.rocksdb.repository.data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java index 87131a7d5..8f2957431 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java @@ -19,8 +19,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java index 27d0d8183..fbc0d1f7f 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java @@ -20,8 +20,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java index 1d3f8db9c..de84c3d25 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java @@ -17,10 +17,10 @@ package org.dizitart.no2.spatial; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import org.locationtech.jts.geom.Geometry; -import java.util.LinkedHashSet; +import java.util.List; /** * @author Anindya Chatterjee @@ -31,7 +31,7 @@ protected IntersectsFilter(String field, Geometry geometry) { } @Override - public LinkedHashSet applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { return false } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java index 5cf5641c7..d2bf851cd 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java @@ -23,7 +23,7 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.BoundingBox; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteRTree; import org.dizitart.no2.store.NitriteStore; diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java index 220602046..fc622fb9c 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java @@ -16,8 +16,8 @@ package org.dizitart.no2.spatial; -import org.dizitart.no2.module.NitriteModule; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; import java.util.Set; diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java index 38e13d12c..a408e7617 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java @@ -17,10 +17,10 @@ package org.dizitart.no2.spatial; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import org.locationtech.jts.geom.Geometry; -import java.util.LinkedHashSet; +import java.util.List; /** * @author Anindya Chatterjee @@ -31,7 +31,7 @@ protected WithinFilter(String field, Geometry geometry) { } @Override - public LinkedHashSet applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { return false } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java index 9f905d71c..23a7b7c51 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/mapper/GeometryExtension.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.module.SimpleModule; -import org.dizitart.no2.mapper.JacksonExtension; +import org.dizitart.no2.common.mapper.JacksonExtension; import org.locationtech.jts.geom.Geometry; import java.util.List; diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java index c0016860d..d371cb23a 100644 --- a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java @@ -25,7 +25,7 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.FluentFilter; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.mapper.JacksonMapperModule; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/Company.java b/nitrite-support/src/test/java/org/dizitart/no2/support/Company.java index 661ac8ac8..b92a9d6fe 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/Company.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/Company.java @@ -24,8 +24,8 @@ import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; import java.util.Date; diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java b/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java index ad715bdd0..5fcbe3790 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java @@ -25,8 +25,8 @@ import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; import java.util.Date; diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/Note.java b/nitrite-support/src/test/java/org/dizitart/no2/support/Note.java index 2e6aeb4f5..4f78a970b 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/Note.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/Note.java @@ -20,8 +20,8 @@ import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite/build.gradle b/nitrite/build.gradle index 87bbdf04c..00d1e7b4d 100644 --- a/nitrite/build.gradle +++ b/nitrite/build.gradle @@ -50,6 +50,7 @@ dependencies { testAnnotationProcessor "org.projectlombok:lombok:1.18.12" testImplementation "junit:junit:4.13.1" + testImplementation "org.mockito:mockito-core:3.9.0" testImplementation "uk.co.jemos.podam:podam:7.2.5.RELEASE" testImplementation "com.github.javafaker:javafaker:1.0.2" testImplementation "org.apache.lucene:lucene-core:8.6.3" diff --git a/nitrite/src/main/java/org/dizitart/no2/Nitrite.java b/nitrite/src/main/java/org/dizitart/no2/Nitrite.java index ecccf3568..4c4cf5e3d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/Nitrite.java +++ b/nitrite/src/main/java/org/dizitart/no2/Nitrite.java @@ -21,7 +21,7 @@ import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.store.DatabaseMetaData; +import org.dizitart.no2.store.StoreMetaData; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.transaction.Session; @@ -112,6 +112,30 @@ static NitriteBuilder builder() { */ ObjectRepository getRepository(Class type, String key); + /** + * Destroys a collection without opening the {@link NitriteCollection} first. + * + * @param name the name of the collection + */ + void destroyCollection(String name); + + /** + * Destroys an {@link ObjectRepository} without opening it first. + * + * @param the type parameter + * @param type the type + */ + void destroyRepository(Class type); + + /** + * Destroys an {@link ObjectRepository} without opening it first. + * + * @param the type parameter + * @param type the type + * @param key the key + */ + void destroyRepository(Class type, String key); + /** * Gets the set of all {@link NitriteCollection}s' names saved in the store. * @@ -168,7 +192,7 @@ static NitriteBuilder builder() { * * @return the database meta data */ - DatabaseMetaData getDatabaseMetaData(); + StoreMetaData getDatabaseMetaData(); /** * Creates a {@link Session} for transaction. @@ -177,6 +201,11 @@ static NitriteBuilder builder() { */ Session createSession(); + /** + * Closes the database. + * */ + void close(); + /** * Checks whether a particular {@link NitriteCollection} exists in the store. * diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java index 48ddc97d2..fd036237c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java @@ -21,7 +21,7 @@ import org.dizitart.no2.common.concurrent.ThreadPoolManager; import org.dizitart.no2.exceptions.SecurityException; import org.dizitart.no2.migration.Migration; -import org.dizitart.no2.module.NitriteModule; +import org.dizitart.no2.common.module.NitriteModule; /** * A builder utility to create a {@link Nitrite} database instance. diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java index 1d20b3377..6158c84be 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java @@ -24,11 +24,11 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.migration.Migration; -import org.dizitart.no2.module.NitriteModule; -import org.dizitart.no2.module.NitritePlugin; -import org.dizitart.no2.module.PluginManager; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; +import org.dizitart.no2.common.module.PluginManager; import org.dizitart.no2.store.NitriteStore; import java.util.HashMap; diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java index 4acfe2f0b..14834d682 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java @@ -27,7 +27,7 @@ import org.dizitart.no2.migration.MigrationManager; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.RepositoryFactory; -import org.dizitart.no2.store.DatabaseMetaData; +import org.dizitart.no2.store.StoreMetaData; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.UserAuthenticationService; @@ -39,6 +39,7 @@ import static org.dizitart.no2.common.Constants.NITRITE_VERSION; import static org.dizitart.no2.common.Constants.STORE_INFO; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; /** @@ -51,6 +52,7 @@ class NitriteDatabase implements Nitrite { private final RepositoryFactory repositoryFactory; private final NitriteConfig nitriteConfig; private final LockService lockService; + private NitriteMap storeInfo; private NitriteStore store; NitriteDatabase(NitriteConfig config) { @@ -89,6 +91,26 @@ public ObjectRepository getRepository(Class type, String key) { return repositoryFactory.getRepository(nitriteConfig, type, key); } + @Override + public void destroyCollection(String name) { + checkOpened(); + store.removeMap(name); + } + + @Override + public void destroyRepository(Class type) { + checkOpened(); + String mapName = findRepositoryName(type, null); + store.removeMap(mapName); + } + + @Override + public void destroyRepository(Class type, String key) { + checkOpened(); + String mapName = findRepositoryName(type, key); + store.removeMap(mapName); + } + @Override public Set listCollectionNames() { checkOpened(); @@ -140,6 +162,7 @@ public synchronized void close() { repositoryFactory.clear(); collectionFactory.clear(); + storeInfo.close(); store.close(); log.info("Nitrite database has been closed successfully."); } catch (NitriteIOException e) { @@ -163,16 +186,13 @@ public void commit() { } @Override - public DatabaseMetaData getDatabaseMetaData() { - NitriteMap storeInfo = this.store.openMap(STORE_INFO, - String.class, Document.class); - + public StoreMetaData getDatabaseMetaData() { Document document = storeInfo.get(STORE_INFO); if (document == null) { prepareDatabaseMetaData(); document = storeInfo.get(STORE_INFO); } - return new DatabaseMetaData(document); + return new StoreMetaData(document); } @Override @@ -229,17 +249,16 @@ private void initialize(String username, String password) { } private void prepareDatabaseMetaData() { - NitriteMap storeInfo = this.store.openMap(STORE_INFO, - String.class, Document.class); + storeInfo = this.store.openMap(STORE_INFO, String.class, Document.class); if (storeInfo.isEmpty()) { - DatabaseMetaData databaseMetadata = new DatabaseMetaData(); - databaseMetadata.setCreateTime(System.currentTimeMillis()); - databaseMetadata.setStoreVersion(store.getStoreVersion()); - databaseMetadata.setNitriteVersion(NITRITE_VERSION); - databaseMetadata.setSchemaVersion(nitriteConfig.getSchemaVersion()); + StoreMetaData storeMetadata = new StoreMetaData(); + storeMetadata.setCreateTime(System.currentTimeMillis()); + storeMetadata.setStoreVersion(store.getStoreVersion()); + storeMetadata.setNitriteVersion(NITRITE_VERSION); + storeMetadata.setSchemaVersion(nitriteConfig.getSchemaVersion()); - storeInfo.put(STORE_INFO, databaseMetadata.getInfo()); + storeInfo.put(STORE_INFO, storeMetadata.getInfo()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java b/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java index c923cdc5b..5a92b43ab 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/CollectionFactory.java @@ -74,11 +74,13 @@ private NitriteCollection createCollection(String name, NitriteConfig nitriteCon if (writeCatalog) { // ignore repository request if (store.getRepositoryRegistry().contains(name)) { + nitriteMap.close(); throw new ValidationException("a repository with same name already exists"); } for (Set set : store.getKeyedRepositoryRegistry().values()) { if (set.contains(name)) { + nitriteMap.close(); throw new ValidationException("a keyed repository with same name already exists"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 533bfc819..41c0e514c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -35,7 +35,7 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java b/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java index 1554d0883..ae8518902 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/FindOptions.java @@ -17,9 +17,10 @@ package org.dizitart.no2.collection; +import lombok.AccessLevel; import lombok.Data; +import lombok.Setter; import lombok.experimental.Accessors; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.SortableFields; @@ -33,12 +34,18 @@ */ @Data @Accessors(fluent = true, chain = true) +@Setter(AccessLevel.PACKAGE) public class FindOptions { private SortableFields orderBy; + private Long skip; + private Long limit; + + @Setter(AccessLevel.PUBLIC) private Collator collator; - private NullOrder nullOrder; - private long skip; - private long limit; + + public FindOptions() { + this.collator = Collator.getInstance(); + } public static FindOptions orderBy(String fieldName, SortOrder sortOrder) { SortableFields fields = new SortableFields(); @@ -61,6 +68,26 @@ public static FindOptions limitBy(long limit) { return findOptions; } + public FindOptions skip(Long skip) { + this.skip = skip; + return this; + } + + public FindOptions skip(Integer skip) { + this.skip = skip == null ? null : (long) skip; + return this; + } + + public FindOptions limit(Long limit) { + this.limit = limit; + return this; + } + + public FindOptions limit(Integer limit) { + this.limit = limit == null ? null : (long) limit; + return this; + } + public FindOptions thenOrderBy(String fieldName, SortOrder sortOrder) { if (orderBy != null) { orderBy.addField(fieldName, sortOrder); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java index bb93173ab..6ca9cd7ba 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java @@ -18,7 +18,6 @@ package org.dizitart.no2.collection; import lombok.Data; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.filters.Filter; @@ -26,6 +25,7 @@ import org.dizitart.no2.index.IndexDescriptor; import java.text.Collator; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -48,7 +48,11 @@ public class FindPlan { private Long limit; private Collator collator; - private NullOrder nullOrder; private List subPlans; + + public FindPlan() { + this.subPlans = new ArrayList<>(); + this.blockingSortOrder = new ArrayList<>(); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java index 9adfd2d40..95e418649 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteDocument.java @@ -176,6 +176,7 @@ public Document merge(Document document) { @Override public boolean containsKey(String key) { +// return getFields().contains(key); return super.containsKey(key); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java index 98b999506..4e2586a36 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java @@ -26,8 +26,8 @@ import org.dizitart.no2.common.event.EventBus; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.processors.Processor; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.StoreCatalog; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java index e7124906a..7336f65fb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java @@ -26,7 +26,9 @@ import java.util.*; +import static org.dizitart.no2.common.util.Iterables.firstOrNull; import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; /** @@ -45,7 +47,6 @@ public FindPlan optimize(Filter filter, if (findOptions != null) { findPlan.setCollator(findOptions.collator()); - findPlan.setNullOrder(findOptions.nullOrder()); } return findPlan; } @@ -64,19 +65,33 @@ private FindPlan createFilterPlan(Collection indexDescriptors, private FindPlan createOrPlan(Collection indexDescriptors, List filters) { FindPlan findPlan = new FindPlan(); + + Set flattenedFilter = new HashSet<>(); + + // flatten the or filter for (Filter filter : filters) { - if (filter instanceof AndFilter || filter instanceof OrFilter) { - findPlan.getSubPlans().clear(); - return findPlan; + if (filter instanceof OrFilter) { + flattenedFilter.addAll(((OrFilter) filter).getFilters()); + } else { + flattenedFilter.add(filter); } + } + for (Filter filter : flattenedFilter) { FindPlan subPlan = createFilterPlan(indexDescriptors, filter); findPlan.getSubPlans().add(subPlan); } + // check if all sub plan have index support for (FindPlan plan : findPlan.getSubPlans()) { if (plan.getIndexDescriptor() == null) { + // if one of the sub plan doesn't have any index support + // then it can not be optimized, instead the + // original filter should be set as coll-scan filter + // for the parent plan findPlan.getSubPlans().clear(); + // set the original or filter as coll scan filter + findPlan.setCollectionScanFilter(or(filters.toArray(new Filter[0]))); return findPlan; } } @@ -84,7 +99,8 @@ private FindPlan createOrPlan(Collection indexDescriptors, List } private FindPlan createAndPlan(Collection indexDescriptors, List filters) { - Map> indexFilterMap = new HashMap<>(); + // descending sort based on cardinality of indices, consider the higher cardinality index first + NavigableMap> indexFilterMap = new TreeMap<>(Collections.reverseOrder()); for (IndexDescriptor indexDescriptor : indexDescriptors) { List fieldNames = indexDescriptor.getIndexFields().getFieldNames(); @@ -104,6 +120,7 @@ private FindPlan createAndPlan(Collection indexDescriptors, Lis } if (!matchFound) { + // match not found, so can't consider this index break; } } @@ -114,15 +131,19 @@ private FindPlan createAndPlan(Collection indexDescriptors, Lis } FindPlan findPlan = new FindPlan(); - List electedFilters = new ArrayList<>(); + Set electedFilters = new HashSet<>(); for (Map.Entry> entry : indexFilterMap.entrySet()) { + // consider the filter combination if it encompasses more fields + // than the previously selected filter if (entry.getValue().size() > electedFilters.size()) { - electedFilters = entry.getValue(); + // maintain the order in set + electedFilters = new LinkedHashSet<>(entry.getValue()); findPlan.setIndexDescriptor(entry.getKey()); } } - List nonElectedFilters = new ArrayList<>(); + // maintain the order in set + Set nonElectedFilters = new LinkedHashSet<>(); for (Filter filter : filters) { if (!electedFilters.contains(filter)) { nonElectedFilters.add(filter); @@ -131,7 +152,7 @@ private FindPlan createAndPlan(Collection indexDescriptors, Lis IndexScanFilter indexScanFilter; if (electedFilters.size() == 1) { - indexScanFilter = new IndexScanFilter(Collections.singletonList(electedFilters.get(0))); + indexScanFilter = new IndexScanFilter(Collections.singletonList(firstOrNull(electedFilters))); findPlan.setIndexScanFilter(indexScanFilter); } else if (electedFilters.size() > 1) { indexScanFilter = new IndexScanFilter(electedFilters); @@ -139,7 +160,7 @@ private FindPlan createAndPlan(Collection indexDescriptors, Lis } if (nonElectedFilters.size() == 1) { - findPlan.setCollectionScanFilter(nonElectedFilters.get(0)); + findPlan.setCollectionScanFilter(firstOrNull(nonElectedFilters)); } else if (nonElectedFilters.size() > 1) { Filter andFilter = and(nonElectedFilters.toArray(new Filter[0])); findPlan.setCollectionScanFilter(andFilter); @@ -173,45 +194,46 @@ private void readSortOption(FindOptions findOptions, FindPlan findPlan) { // get index field names List indexedFieldNames = indexDescriptor.getIndexFields().getFieldNames(); - // get prefix length - int length = Math.min(indexedFieldNames.size(), findSortSpec.size()); - boolean canUseIndex = false; Map indexScanOrder = new HashMap<>(); - for (int i = 0; i < length; i++) { - String indexFieldName = indexedFieldNames.get(i); - Pair findPair = findSortSpec.get(i); - if (!indexFieldName.equals(findPair.getFirst())) { - // field mismatch in sort spec, can't use index for sorting - canUseIndex = false; - break; - } else { - canUseIndex = true; - boolean reverseScan = false; - - SortOrder findSortOrder = findPair.getSecond(); - if (findSortOrder != SortOrder.Ascending) { - // if sort order is different, reverse scan in index - reverseScan = true; - } - // add to index scan order - indexScanOrder.put(indexFieldName, reverseScan); + if (indexedFieldNames.size() >= findSortSpec.size()) { + // if all fields of the sort spec is covered by index, then only + // sorting can take help of index + + int length = findSortSpec.size(); + for (int i = 0; i < length; i++) { + String indexFieldName = indexedFieldNames.get(i); + Pair findPair = findSortSpec.get(i); + if (!indexFieldName.equals(findPair.getFirst())) { + // field mismatch in sort spec, can't use index for sorting + canUseIndex = false; + break; + } else { + canUseIndex = true; + boolean reverseScan = false; + + SortOrder findSortOrder = findPair.getSecond(); + if (findSortOrder != SortOrder.Ascending) { + // if sort order is different, reverse scan in index + reverseScan = true; + } + + // add to index scan order + indexScanOrder.put(indexFieldName, reverseScan); + } } } if (canUseIndex) { findPlan.setIndexScanOrder(indexScanOrder); - if (length < findSortSpec.size()) { - List> remainder = findSortSpec.subList(length, findSortSpec.size() - 1); - findPlan.setBlockingSortOrder(remainder); - } } else { findPlan.setBlockingSortOrder(findSortSpec); } + } else { + // no find options, so consider the index sorting order + findPlan.setBlockingSortOrder(findSortSpec); } - // no find options, so consider the index sorting order - findPlan.setBlockingSortOrder(findSortSpec); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java index 22ba13fa2..b43aa66d0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java @@ -25,10 +25,7 @@ import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; @@ -68,10 +65,7 @@ public IndexManager(String collectionName, NitriteConfig nitriteConfig) { * @return the boolean */ public boolean hasIndexDescriptor(Fields fields) { - if (!indexMetaMap.containsKey(fields)) return false; - - IndexMeta indexMeta = indexMetaMap.get(fields); - return indexMeta != null; + return !findMatchingIndexDescriptors(fields).isEmpty(); } /** @@ -87,9 +81,9 @@ public Collection getIndexDescriptors() { } public Collection findMatchingIndexDescriptors(Fields fields) { - Collection indexDescriptors = getIndexDescriptors(); + List indexDescriptors = new ArrayList<>(); - for (IndexDescriptor indexDescriptor : indexDescriptors) { + for (IndexDescriptor indexDescriptor : getIndexDescriptors()) { if (indexDescriptor.getIndexFields().startsWith(fields)) { indexDescriptors.add(indexDescriptor); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index 93c3945fa..ff74382fc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -53,8 +53,8 @@ public void close() throws Exception { } void createIndex(Fields fields, String indexType) { - IndexDescriptor indexDescriptor; - if (!hasIndexEntry(fields)) { + IndexDescriptor indexDescriptor = indexManager.findExactIndexDescriptor(fields); + if (indexDescriptor == null) { // if no index create index indexDescriptor = indexManager.createIndexDescriptor(fields, indexType); } else { diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java index 1ef870054..e8af3e5bb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java @@ -26,7 +26,7 @@ import org.dizitart.no2.filters.NitriteFilter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; import java.util.ArrayList; @@ -130,6 +130,9 @@ private RecordStream> findSuitableStream(FindPlan find } // union of all suitable stream of all sub plans rawStream = new UnionStream(subStreams); + + // return only distinct items + rawStream = new DistinctStream(rawStream); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java index eceaa4440..b010409a1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java @@ -26,7 +26,7 @@ import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.ProcessorChain; import org.dizitart.no2.store.NitriteMap; import java.util.HashSet; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Constants.java b/nitrite/src/main/java/org/dizitart/no2/common/Constants.java index 1d5339cc5..4bd245c38 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Constants.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Constants.java @@ -132,6 +132,11 @@ private Constants() {} */ public static final String TAG_KEYED_REPOSITORIES = "keyed-repositories"; + /** + * The constant TAG_COLLECTION_METADATA. + */ + public static final String TAG_MAP_METADATA = "mapNames"; + /** * The constant TAG_TYPE. */ diff --git a/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java index f80d1d4e5..48e8b7b37 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/DBNull.java @@ -1,5 +1,7 @@ package org.dizitart.no2.common; +import org.dizitart.no2.index.DBValue; + import java.io.Serializable; /** @@ -8,19 +10,30 @@ * @author Anindya Chatterjee * @since 1.0 */ -public class DBNull implements Comparable, Serializable { +public class DBNull extends DBValue implements Serializable { private static final long serialVersionUID = 1598819770L; private static final DBNull instance = new DBNull(); private DBNull() { + super(null); } @Override - public int compareTo(DBNull o) { - return 0; + public int compareTo(DBValue o) { + if (o == null || o instanceof DBNull) { + return 0; + } + + // null value always comes first + return -1; } public static DBNull getInstance() { return instance; } + + @Override + public String toString() { + return null; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java index 551443a1e..56c300f98 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/FieldValues.java @@ -3,6 +3,7 @@ import lombok.Data; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.util.StringUtils; import java.util.ArrayList; import java.util.List; @@ -54,10 +55,13 @@ public Fields getFields() { } this.fields = new Fields(); - fields.setFieldNames(new ArrayList<>()); + List fieldNames = new ArrayList<>(); for (Pair value : getValues()) { - fields.getFieldNames().add(value.getFirst()); + if (!StringUtils.isNullOrEmpty(value.getFirst())) { + fieldNames.add(value.getFirst()); + } } + fields.setFieldNames(fieldNames); return fields; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java index c085aa066..590563aeb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java @@ -25,7 +25,7 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.store.NitriteStore; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java index 35e040377..a246086d7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java @@ -139,7 +139,7 @@ default long size() { * @return the list */ default List toList() { - return Iterables.toList(this); + return Collections.unmodifiableList(Iterables.toList(this)); } /** @@ -148,7 +148,7 @@ default List toList() { * @return the set */ default Set toSet() { - return Iterables.toSet(this); + return Collections.unmodifiableSet(Iterables.toSet(this)); } /** diff --git a/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java index b757129ba..59dcff4de 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java @@ -20,6 +20,7 @@ import org.dizitart.no2.common.util.Base64; import org.dizitart.no2.common.util.CryptoUtils; import org.dizitart.no2.common.util.SecureString; +import org.dizitart.no2.exceptions.NitriteException; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -61,35 +62,38 @@ public AESEncryptor(String password) { * * @param plainText the text as byte array * @return the encrypted string - * @throws Exception the exception */ @Override - public String encrypt(byte[] plainText) throws Exception { - // 16 bytes salt - byte[] salt = CryptoUtils.getRandomNonce(SALT_LENGTH_BYTE); + public String encrypt(byte[] plainText) { + try { + // 16 bytes salt + byte[] salt = CryptoUtils.getRandomNonce(SALT_LENGTH_BYTE); - // GCM recommended 12 bytes iv? - byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE); + // GCM recommended 12 bytes iv? + byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE); - // secret key from password - SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); + // secret key from password + SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); - Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); + Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); - // ASE-GCM needs GCMParameterSpec - cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + // ASE-GCM needs GCMParameterSpec + cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); - byte[] cipherText = cipher.doFinal(plainText); + byte[] cipherText = cipher.doFinal(plainText); - // prefix IV and Salt to cipher text - byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length) - .put(iv) - .put(salt) - .put(cipherText) - .array(); + // prefix IV and Salt to cipher text + byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length) + .put(iv) + .put(salt) + .put(cipherText) + .array(); - // string representation, base64, send this string to other for decryption. - return Base64.encodeToString(cipherTextWithIvSalt, Base64.URL_SAFE); + // string representation, base64, send this string to other for decryption. + return Base64.encodeToString(cipherTextWithIvSalt, Base64.URL_SAFE); + } catch (Exception e) { + throw new SecurityException("failed to encrypt data", e); + } } /** @@ -100,28 +104,31 @@ public String encrypt(byte[] plainText) throws Exception { *

    * @param encryptedText the encrypted text * @return the plain text decrypted string - * @throws Exception the exception */ @Override - public String decrypt(String encryptedText) throws Exception { - byte[] decode = Base64.decode(encryptedText.getBytes(UTF_8), Base64.URL_SAFE); - - // get back the iv and salt from the cipher text - ByteBuffer bb = ByteBuffer.wrap(decode); - byte[] iv = new byte[IV_LENGTH_BYTE]; - bb.get(iv); - - byte[] salt = new byte[SALT_LENGTH_BYTE]; - bb.get(salt); - - byte[] cipherText = new byte[bb.remaining()]; - bb.get(cipherText); - - // get back the aes key from the same password and salt - SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); - Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); - cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); - byte[] plainText = cipher.doFinal(cipherText); - return new String(plainText, UTF_8); + public String decrypt(String encryptedText) { + try { + byte[] decode = Base64.decode(encryptedText.getBytes(UTF_8), Base64.URL_SAFE); + + // get back the iv and salt from the cipher text + ByteBuffer bb = ByteBuffer.wrap(decode); + byte[] iv = new byte[IV_LENGTH_BYTE]; + bb.get(iv); + + byte[] salt = new byte[SALT_LENGTH_BYTE]; + bb.get(salt); + + byte[] cipherText = new byte[bb.remaining()]; + bb.get(cipherText); + + // get back the aes key from the same password and salt + SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); + Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); + cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + byte[] plainText = cipher.doFinal(cipherText); + return new String(plainText, UTF_8); + } catch (Exception e) { + throw new SecurityException("failed to decrypt data", e); + } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java b/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java index afafa07ad..e9bc7538b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/event/EventBus.java @@ -49,4 +49,9 @@ public interface EventBus extends AutoCloseable { * @param eventInfo the event related information */ void post(EventInfo eventInfo); + + /** + * Closes this {@link EventBus} instance. + * */ + void close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/mapper/Mappable.java b/nitrite/src/main/java/org/dizitart/no2/common/mapper/Mappable.java similarity index 97% rename from nitrite/src/main/java/org/dizitart/no2/mapper/Mappable.java rename to nitrite/src/main/java/org/dizitart/no2/common/mapper/Mappable.java index b4c5a9ab8..d16297757 100644 --- a/nitrite/src/main/java/org/dizitart/no2/mapper/Mappable.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/mapper/Mappable.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java b/nitrite/src/main/java/org/dizitart/no2/common/mapper/MappableMapper.java similarity index 99% rename from nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java rename to nitrite/src/main/java/org/dizitart/no2/common/mapper/MappableMapper.java index e0721a290..443fb4666 100644 --- a/nitrite/src/main/java/org/dizitart/no2/mapper/MappableMapper.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/mapper/MappableMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java b/nitrite/src/main/java/org/dizitart/no2/common/mapper/NitriteMapper.java similarity index 94% rename from nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java rename to nitrite/src/main/java/org/dizitart/no2/common/mapper/NitriteMapper.java index 8bec0e1d9..1f6e606ce 100644 --- a/nitrite/src/main/java/org/dizitart/no2/mapper/NitriteMapper.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/mapper/NitriteMapper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; /** * Represents a mapper which will convert a object of one type to an object of another type. diff --git a/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java b/nitrite/src/main/java/org/dizitart/no2/common/module/NitriteModule.java similarity index 82% rename from nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java rename to nitrite/src/main/java/org/dizitart/no2/common/module/NitriteModule.java index d7b3f580c..4404d5ac7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/NitriteModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/NitriteModule.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.module; +package org.dizitart.no2.common.module; import java.util.Set; @@ -44,15 +44,4 @@ static NitriteModule module(NitritePlugin... plugins) { * @return the set */ Set plugins(); - - /** - * Creates a {@link ModuleConfig} to configure a {@link NitriteModule}. - * - * @param the type parameter - * @return the module config - */ - static T withConfig() { - return null; - } - } diff --git a/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java b/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePlugin.java similarity index 96% rename from nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java rename to nitrite/src/main/java/org/dizitart/no2/common/module/NitritePlugin.java index 7f182f892..d15f52e1e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/NitritePlugin.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePlugin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.module; +package org.dizitart.no2.common.module; import org.dizitart.no2.NitriteConfig; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java b/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java new file mode 100644 index 000000000..5ec301904 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.module; + +/** + * @author Anindya Chatterjee + */ +@FunctionalInterface +public interface NitritePluginFactory { + NitritePlugin createPlugin(); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java similarity index 97% rename from nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java rename to nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java index 433ec1c68..bfd825ca4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/PluginManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.module; +package org.dizitart.no2.common.module; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -22,8 +22,8 @@ import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.PluginException; import org.dizitart.no2.index.*; -import org.dizitart.no2.mapper.MappableMapper; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.memory.InMemoryStoreModule; diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/Processor.java b/nitrite/src/main/java/org/dizitart/no2/common/processors/Processor.java similarity index 96% rename from nitrite/src/main/java/org/dizitart/no2/processors/Processor.java rename to nitrite/src/main/java/org/dizitart/no2/common/processors/Processor.java index 06496f0c0..abad37dc6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/processors/Processor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/processors/Processor.java @@ -15,7 +15,7 @@ * */ -package org.dizitart.no2.processors; +package org.dizitart.no2.common.processors; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java b/nitrite/src/main/java/org/dizitart/no2/common/processors/ProcessorChain.java similarity index 97% rename from nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java rename to nitrite/src/main/java/org/dizitart/no2/common/processors/ProcessorChain.java index 07c049b71..3d31ad18a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/processors/ProcessorChain.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/processors/ProcessorChain.java @@ -15,7 +15,7 @@ * */ -package org.dizitart.no2.processors; +package org.dizitart.no2.common.processors; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java b/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java similarity index 98% rename from nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java rename to nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java index 3808d6de8..8c146117d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/processors/StringFieldEncryptionProcessor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java @@ -15,7 +15,7 @@ * */ -package org.dizitart.no2.processors; +package org.dizitart.no2.common.processors; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java index 8dc79fc84..41a978163 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/BoundedDocumentStream.java @@ -66,12 +66,7 @@ public Iterator> iterator() { return new BoundedIterator<>(iterator, skip, limit); } - /** - * The type Bounded iterator. - * - * @param the type parameter - */ - public static class BoundedIterator implements Iterator { + private static class BoundedIterator implements Iterator { private final Iterator iterator; private final long skip; private final long limit; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/DistinctStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/DistinctStream.java new file mode 100644 index 000000000..7e23b041f --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/DistinctStream.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; + +import java.util.*; + +/** + * Represents a document stream of distinct elements + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public class DistinctStream implements RecordStream> { + private final RecordStream> rawStream; + + /** + * Instantiates a new DistinctStream. + * + * @param rawStream the raw stream + */ + public DistinctStream(RecordStream> rawStream) { + this.rawStream = rawStream; + } + + @Override + public Iterator> iterator() { + Iterator> iterator = rawStream == null ? Collections.emptyIterator() + : rawStream.iterator(); + return new DistinctStreamIterator(iterator); + } + + private static class DistinctStreamIterator implements Iterator> { + private final Iterator> iterator; + private final Set scannedIds; + private Pair nextPair; + private boolean nextPairSet = false; + + /** + * Instantiates a new DistinctStreamIterator. + * + * @param iterator the iterator + */ + public DistinctStreamIterator(Iterator> iterator) { + this.iterator = iterator; + this.scannedIds = new HashSet<>(); // fastest lookup for ids - O(1) + } + + @Override + public boolean hasNext() { + return nextPairSet || setNextId(); + } + + @Override + public Pair next() { + if (!nextPairSet && !setNextId()) { + throw new NoSuchElementException(); + } + nextPairSet = false; + return nextPair; + } + + private boolean setNextId() { + while (iterator.hasNext()) { + final Pair pair = iterator.next(); + if (!scannedIds.contains(pair.getFirst())) { + scannedIds.add(pair.getFirst()); + nextPair = pair; + nextPairSet = true; + return true; + } + } + return false; + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java index 014e5221c..c3b7307f6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentSorter.java @@ -19,9 +19,10 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.NullOrder; +import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.ValidationException; import java.text.Collator; import java.util.Comparator; @@ -31,8 +32,7 @@ * Sorts documents based on the sort order provided. * *

    - * By default null is considered the lowest value, - * unless ordering explicitly specified by {@link NullOrder}. + * By default null is considered the lowest value. *

    * * @author Anindya Chatterjee @@ -40,61 +40,58 @@ */ public class DocumentSorter implements Comparator> { private final Collator collator; - private final NullOrder nullOrder; private final List> sortOrder; /** * Instantiates a new Document sorter. * * @param collator the collator - * @param nullOrder the null order * @param sortOrder the sort order */ - public DocumentSorter(Collator collator, NullOrder nullOrder, - List> sortOrder) { + public DocumentSorter(Collator collator, List> sortOrder) { this.collator = collator; - this.nullOrder = nullOrder; this.sortOrder = sortOrder; } @Override - @SuppressWarnings( { "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public int compare(Pair pair1, Pair pair2) { if (sortOrder != null && !sortOrder.isEmpty()) { for (Pair pair : sortOrder) { Document doc1 = pair1.getSecond(); Document doc2 = pair2.getSecond(); - Comparable c1 = doc1.get(pair.getFirst(), Comparable.class); - Comparable c2 = doc2.get(pair.getFirst(), Comparable.class); + Object value1 = doc1.get(pair.getFirst()); + Object value2 = doc2.get(pair.getFirst()); - boolean nullPresent = false; + // handle null values int result; + if ((value1 == null || value1 instanceof DBNull) && value2 != null) { + result = -1; + } else if (value1 != null && (value2 == null || value2 instanceof DBNull)) { + result = 1; + } else if (value1 == null) { + result = -1; + } else { - if (c1 == null && c2 != null) { - nullPresent = true; - if (nullOrder == NullOrder.First || nullOrder == NullOrder.Default) { - result = -1; - } else { - result = 1; + // validate comparable + if (value1.getClass().isArray() || value1 instanceof Iterable + || value2.getClass().isArray() || value2 instanceof Iterable) { + throw new ValidationException("cannot sort on an array or collection object"); } - } else if (c1 != null && c2 == null) { - nullPresent = true; - if (nullOrder == NullOrder.First || nullOrder == NullOrder.Default) { - result = 1; + + // compare values + Comparable c1 = (Comparable) value1; + Comparable c2 = (Comparable) value2; + + if (c1 instanceof String && c2 instanceof String && collator != null) { + result = collator.compare(c1, c2); } else { - result = -1; + result = c1.compareTo(c2); } - } else if (c2 == null) { - nullPresent = true; - result = 0; - } else if (c1 instanceof String && c2 instanceof String && collator != null) { - result = collator.compare(c1, c2); - } else { - result = c1.compareTo(c2); } - if (!nullPresent && pair.getSecond() == SortOrder.Descending) { + if (pair.getSecond() == SortOrder.Descending) { result *= -1; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java index df15f0e9d..66d61da9e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/DocumentStream.java @@ -28,7 +28,7 @@ import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.ProcessorChain; import java.util.Collections; import java.util.Iterator; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java index b9360740f..9c20ca7d3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/FilteredStream.java @@ -54,7 +54,8 @@ public Iterator> iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - if (filter == Filter.ALL) { + // filter can be null from read operation when coll scan filter is null + if (filter == null || filter == Filter.ALL) { return iterator; } return new FilteredIterator(iterator, filter); @@ -63,7 +64,7 @@ public Iterator> iterator() { /** * The type Filtered iterator. */ - static class FilteredIterator implements Iterator> { + private static class FilteredIterator implements Iterator> { private final Iterator> iterator; private final Filter filter; private Pair nextPair; @@ -114,5 +115,4 @@ private boolean setNextId() { return false; } } - } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java index 059da827b..9bd99e034 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/IndexedStream.java @@ -56,7 +56,7 @@ public Iterator> iterator() { /** * The type Indexed stream iterator. */ - static class IndexedStreamIterator implements Iterator> { + private static class IndexedStreamIterator implements Iterator> { private final Iterator iterator; private final NitriteMap nitriteMap; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java index 4766cd0f2..633c37245 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/JoinedDocumentStream.java @@ -20,11 +20,11 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.ProcessorChain; import java.util.Collections; import java.util.HashSet; @@ -67,7 +67,7 @@ public class JoinedDocumentStream implements RecordStream { public Iterator iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new JoinedDocumentIterator(iterator, processorChain); + return new JoinedDocumentIterator(iterator, processorChain, foreignCursor, lookup); } @Override @@ -75,9 +75,11 @@ public String toString() { return toList().toString(); } - private class JoinedDocumentIterator implements Iterator { + private static class JoinedDocumentIterator implements Iterator { private final Iterator> iterator; private final ProcessorChain processorChain; + private final DocumentCursor foreignCursor; + private final Lookup lookup; /** * Instantiates a new Joined document iterator. @@ -85,10 +87,14 @@ private class JoinedDocumentIterator implements Iterator { * @param iterator the iterator * @param processorChain the processor chain */ - JoinedDocumentIterator(Iterator> iterator, - ProcessorChain processorChain) { + public JoinedDocumentIterator(Iterator> iterator, + ProcessorChain processorChain, + DocumentCursor foreignCursor, + Lookup lookup) { this.iterator = iterator; this.processorChain = processorChain; + this.foreignCursor = foreignCursor; + this.lookup = lookup; } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java index 604497c87..1905e35d4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/ProjectedDocumentStream.java @@ -19,10 +19,10 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.processors.ProcessorChain; +import org.dizitart.no2.common.processors.ProcessorChain; import java.util.Collections; import java.util.Iterator; @@ -56,7 +56,7 @@ public ProjectedDocumentStream(RecordStream> recordStr public Iterator iterator() { Iterator> iterator = recordStream == null ? Collections.emptyIterator() : recordStream.iterator(); - return new ProjectedDocumentIterator(iterator, processorChain); + return new ProjectedDocumentIterator(iterator, processorChain, projection); } @Override @@ -64,10 +64,11 @@ public String toString() { return toList().toString(); } - private class ProjectedDocumentIterator implements Iterator { + private static class ProjectedDocumentIterator implements Iterator { private final Iterator> iterator; private final ProcessorChain processorChain; private Document nextElement = null; + private final Document projection; /** * Instantiates a new Projected document iterator. @@ -75,9 +76,12 @@ private class ProjectedDocumentIterator implements Iterator { * @param iterator the iterator * @param processorChain the processor chain */ - ProjectedDocumentIterator(Iterator> iterator, ProcessorChain processorChain) { + ProjectedDocumentIterator(Iterator> iterator, + ProcessorChain processorChain, + Document projection) { this.iterator = iterator; this.processorChain = processorChain; + this.projection = projection; nextMatch(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java index 2d065c28f..8c89985c2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/SortedDocumentStream.java @@ -22,6 +22,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.util.Iterables; import java.util.Collections; import java.util.Iterator; @@ -48,11 +49,11 @@ public Iterator> iterator() { if (recordStream == null) return Collections.emptyIterator(); DocumentSorter documentSorter = new DocumentSorter(findPlan.getCollator(), - findPlan.getNullOrder(), findPlan.getBlockingSortOrder()); + findPlan.getBlockingSortOrder()); - List> recordList = recordStream.toList(); + List> recordList = Iterables.toList(recordStream); Collections.sort(recordList, documentSorter); - return recordStream.iterator(); + return recordList.iterator(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java b/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java index 486fa9fd2..1be91dc60 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/streams/UnionStream.java @@ -25,7 +25,7 @@ import java.util.*; /** - * Represents an union of multiple nitrite document stream. + * Represents an union of multiple distinct nitrite document stream. * * @author Anindya Chatterjee * @since 4.0 @@ -54,7 +54,7 @@ public Iterator> iterator() { /** * The type Union stream iterator. */ - public static class UnionStreamIterator implements Iterator> { + private static class UnionStreamIterator implements Iterator> { private final Queue>> iteratorQueue; private Iterator> currentIterator; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java index ad2cd8f62..9c92db1ab 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java @@ -21,7 +21,7 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.ArrayList; import java.util.Objects; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java index 7ed5051e2..55b980d91 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java @@ -61,7 +61,7 @@ public static List toList(Iterable iterable) { for (T item : iterable) { list.add(item); } - return Collections.unmodifiableList(list); + return list; } /** @@ -77,7 +77,7 @@ public static Set toSet(Iterable iterable) { for (T item : iterable) { set.add(item); } - return Collections.unmodifiableSet(set); + return set; } /** diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java index 9a2a51e46..60afea147 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/ValidationUtils.java @@ -16,12 +16,10 @@ package org.dizitart.no2.common.util; -import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; -import java.util.Arrays; import java.util.Collection; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; @@ -106,31 +104,11 @@ public static void containsNull(T[] array, String message) { } } - /** - * Validates if a field of a document can be indexed. - * - * @param fieldValue the field value - * @param field the field - */ - public static void validateDocumentIndexField(Object fieldValue, String field) { - if (fieldValue == null) return; - - if (fieldValue instanceof Document) { - throw new InvalidOperationException("compound index on field " + field + " is not supported"); - } - - if (!(fieldValue instanceof Iterable || fieldValue.getClass().isArray())) { - if (!(fieldValue instanceof Comparable)) { - throw new IndexingException("cannot index on non comparable field " + field); - } - } - } - public static void validateIterableIndexField(Iterable fieldValue, String field) { if (fieldValue != null) { for (Object value : fieldValue) { if (value == null) continue; - validateArrayItem(value, field); + validateArrayIndexItem(value, field); } } } @@ -149,7 +127,7 @@ public static void validateArrayIndexField(Object arrayValue, String field) { Object[] array = convertToObjectArray(arrayValue); for (Object value : array) { if (value == null) continue; - validateArrayItem(value, field); + validateArrayIndexItem(value, field); } } } @@ -164,7 +142,26 @@ public static void validateStringArrayIndexField(Object arrayValue, String field } } - private static void validateArrayItem(Object value, String field) { + public static void validateFilterArrayField(Object arrayValue, String field) { + if (arrayValue != null) { + Object[] array = convertToObjectArray(arrayValue); + for (Object value : array) { + if (value == null) continue; + validateArrayFilterItem(value, field); + } + } + } + + public static void validateFilterIterableField(Iterable fieldValue, String field) { + if (fieldValue != null) { + for (Object value : fieldValue) { + if (value == null) continue; + validateArrayFilterItem(value, field); + } + } + } + + private static void validateArrayIndexItem(Object value, String field) { if (value instanceof Iterable || value.getClass().isArray()) { throw new InvalidOperationException("nested array index on iterable field " + field + " is not supported"); } @@ -183,4 +180,14 @@ private static void validateStringArrayItem(Object value, String field) { throw new IndexingException("cannot index on an array field containing non string values " + field); } } + + private static void validateArrayFilterItem(Object value, String field) { + if (value instanceof Iterable || value.getClass().isArray()) { + throw new InvalidOperationException("nested array is not supported"); + } + + if (!(value instanceof Comparable)) { + throw new IndexingException("cannot filter using non comparable values " + field); + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java index 0c4e96a40..9e646111b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java @@ -54,4 +54,20 @@ public boolean apply(Pair element) { } return result; } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("("); + for (int i = 0; i < getFilters().size(); i++) { + Filter filter = getFilters().get(i); + if (i == 0) { + stringBuilder.append(filter.toString()); + } else { + stringBuilder.append(" && ").append(filter.toString()); + } + } + stringBuilder.append(")"); + return stringBuilder.toString(); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/BetweenFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/BetweenFilter.java index 4a2e6731d..a8693caf6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/BetweenFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/BetweenFilter.java @@ -58,6 +58,10 @@ private static void validateBound(Bound bound) { } } + @Override + public String toString() { + return super.toString(); + } @Data public static class Bound { diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/ComparableArrayFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableArrayFilter.java new file mode 100644 index 000000000..abf104623 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableArrayFilter.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.common.mapper.NitriteMapper; + +import static org.dizitart.no2.common.util.ValidationUtils.*; + +/** + * @author Anindya Chatterjee + */ +abstract class ComparableArrayFilter extends ComparableFilter { + /** + * Instantiates a new Comparable filter. + * + * @param field the field + * @param value the value + */ + public ComparableArrayFilter(String field, Object value) { + super(field, value); + } + + @Override + protected void validateSearchTerm(NitriteMapper nitriteMapper, String field, Object value) { + notNull(field, "field cannot be null"); + notEmpty(field, "field cannot be empty"); + + if (value != null) { + if (value.getClass().isArray()) { + validateFilterArrayField(value, field); + } else if (value instanceof Iterable) { + validateFilterIterableField((Iterable) value, field); + } + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java index e67d88ac3..e2d7c64fc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java @@ -18,10 +18,9 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import java.util.List; -import java.util.Map; import java.util.NavigableMap; /** @@ -57,10 +56,10 @@ public Comparable getComparable() { /** * Apply this filter on an nitrite index. * - * @param indexScanner the index scanner + * @param indexMap the index scanner * @return the object */ - public abstract Object applyOnIndex(IndexScanner indexScanner); + public abstract List applyOnIndex(IndexMap indexMap); /** * Process values after index scanning. @@ -71,7 +70,7 @@ public Comparable getComparable() { */ @SuppressWarnings("unchecked") protected void processIndexValue(Object value, - NavigableMap, Object> subMap, + List, Object>> subMap, List nitriteIds) { if (value instanceof List) { // if its is list then add it directly to nitrite ids @@ -80,10 +79,7 @@ protected void processIndexValue(Object value, } if (value instanceof NavigableMap) { - NavigableMap, ?> result = (NavigableMap, ?>) value; - for (Map.Entry, ?> comparableEntry : result.entrySet()) { - subMap.put(comparableEntry.getKey(), comparableEntry.getValue()); - } + subMap.add((NavigableMap, Object>) value); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/ElementMatchFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/ElementMatchFilter.java index b2c99269c..842d303fd 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/ElementMatchFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/ElementMatchFilter.java @@ -76,6 +76,11 @@ public boolean apply(Pair element) { } } + @Override + public String toString() { + return "elemMatch(" + field + " : " + elementFilter.toString() + ")"; + } + @SuppressWarnings("rawtypes") private boolean matches(Iterable iterable, Filter filter) { for (Object item : iterable) { @@ -284,4 +289,6 @@ private boolean matchRegex(Object item, Filter filter) { throw new FilterException(item + " is not a string"); } } + + } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java index 86de07bf3..103343966 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java @@ -16,18 +16,19 @@ package org.dizitart.no2.filters; -import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; + +import java.util.ArrayList; +import java.util.List; import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; /** * @author Anindya Chatterjee. */ -@ToString class EqualsFilter extends ComparableFilter { EqualsFilter(String field, Object value) { super(field, value); @@ -41,7 +42,19 @@ public boolean apply(Pair element) { } @Override - public Object applyOnIndex(IndexScanner indexScanner) { - return indexScanner.get((Comparable) getValue()); + public List applyOnIndex(IndexMap indexMap) { + Object value = indexMap.get((Comparable) getValue()); + if (value instanceof List) { + return ((List) value); + } + + List result = new ArrayList<>(); + result.add(value); + return result; + } + + @Override + public String toString() { + return "(" + getField() + " == " + getValue() + ")"; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java index 4e90f6967..9112d515e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java @@ -21,7 +21,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; import static org.dizitart.no2.common.util.ValidationUtils.notNull; @@ -76,7 +76,7 @@ public Object getValue() { return value; } - private void validateSearchTerm(NitriteMapper nitriteMapper, String field, Object value) { + protected void validateSearchTerm(NitriteMapper nitriteMapper, String field, Object value) { notNull(field, "field cannot be null"); notEmpty(field, "field cannot be empty"); diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java index dfc7c2776..f3c8374bb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterEqualFilter.java @@ -20,12 +20,11 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import java.util.ArrayList; import java.util.List; import java.util.NavigableMap; -import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; @@ -59,21 +58,21 @@ public boolean apply(Pair element) { @Override @SuppressWarnings({"unchecked", "rawtypes"}) - public Object applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { Comparable comparable = getComparable(); - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List, Object>> subMap = new ArrayList<>(); // maintain the find sorting order List nitriteIds = new ArrayList<>(); - Comparable ceilingKey = indexScanner.ceilingKey(comparable); + Comparable ceilingKey = indexMap.ceilingKey(comparable); while (ceilingKey != null) { // get the starting value, it can be a navigable-map (compound index) // or list (single field index) - Object value = indexScanner.get(ceilingKey); + Object value = indexMap.get(ceilingKey); processIndexValue(value, subMap, nitriteIds); - ceilingKey = indexScanner.higherKey(ceilingKey); + ceilingKey = indexMap.higherKey(ceilingKey); } if (!subMap.isEmpty()) { @@ -85,4 +84,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " >= " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java index 712effe28..a41b71a92 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/GreaterThanFilter.java @@ -20,10 +20,11 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; import static org.dizitart.no2.common.util.Numbers.compare; @@ -58,19 +59,19 @@ public boolean apply(Pair element) { @Override @SuppressWarnings({"unchecked", "rawtypes"}) - public Object applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { Comparable comparable = getComparable(); - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - Comparable ceilingKey = indexScanner.higherKey(comparable); + Comparable ceilingKey = indexMap.higherKey(comparable); while (ceilingKey != null) { // get the starting value, it can be a navigable-map (compound index) // or list (single field index) - Object value = indexScanner.get(ceilingKey); + Object value = indexMap.get(ceilingKey); processIndexValue(value, subMap, nitriteIds); - ceilingKey = indexScanner.higherKey(ceilingKey); + ceilingKey = indexMap.higherKey(ceilingKey); } if (!subMap.isEmpty()) { @@ -82,4 +83,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " > " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java index 6b97a45d6..c4b1b065d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/InFilter.java @@ -20,15 +20,14 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; /** * @author Anindya Chatterjee */ -class InFilter extends ComparableFilter { +class InFilter extends ComparableArrayFilter { @Getter private final Set> comparableSet; @@ -51,11 +50,11 @@ public boolean apply(Pair element) { return false; } - public Object applyOnIndex(IndexScanner indexScanner) { - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + public List applyOnIndex(IndexMap indexMap) { + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - for (Pair, ?> entry : indexScanner.entries()) { + for (Pair, ?> entry : indexMap.entries()) { if (comparableSet.contains(entry.getFirst())) { processIndexValue(entry.getSecond(), subMap, nitriteIds); } @@ -70,4 +69,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " in " + Arrays.toString((Comparable[]) getValue()) + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java index 94aef5b5c..2f045cc4e 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java @@ -18,11 +18,14 @@ package org.dizitart.no2.filters; import lombok.Getter; +import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidOperationException; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -31,6 +34,7 @@ * @author Anindya Chatterjee * @since 4.0 */ +@ToString public class IndexScanFilter implements Filter { @Getter private final List filters; @@ -40,8 +44,8 @@ public class IndexScanFilter implements Filter { * * @param filters the filters */ - public IndexScanFilter(List filters) { - this.filters = filters; + public IndexScanFilter(Collection filters) { + this.filters = new ArrayList<>(filters); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java index be08e7171..0a87b0dbc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserEqualFilter.java @@ -20,12 +20,11 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import java.util.ArrayList; import java.util.List; import java.util.NavigableMap; -import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.Numbers.compare; @@ -59,19 +58,19 @@ public boolean apply(Pair element) { @Override @SuppressWarnings({"unchecked", "rawtypes"}) - public Object applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { Comparable comparable = getComparable(); - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - Comparable ceilingKey = indexScanner.floorKey(comparable); + Comparable ceilingKey = indexMap.floorKey(comparable); while (ceilingKey != null) { // get the starting value, it can be a navigable-map (compound index) // or list (single field index) - Object value = indexScanner.get(ceilingKey); + Object value = indexMap.get(ceilingKey); processIndexValue(value, subMap, nitriteIds); - ceilingKey = indexScanner.lowerKey(ceilingKey); + ceilingKey = indexMap.lowerKey(ceilingKey); } if (!subMap.isEmpty()) { @@ -83,4 +82,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " <= " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java index 21cced2f3..e522dbca8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/LesserThanFilter.java @@ -20,10 +20,11 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; import static org.dizitart.no2.common.util.Numbers.compare; @@ -57,19 +58,19 @@ public boolean apply(Pair element) { @Override @SuppressWarnings({"unchecked", "rawtypes"}) - public Object applyOnIndex(IndexScanner indexScanner) { + public List applyOnIndex(IndexMap indexMap) { Comparable comparable = getComparable(); - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - Comparable ceilingKey = indexScanner.lowerKey(comparable); + Comparable ceilingKey = indexMap.lowerKey(comparable); while (ceilingKey != null) { // get the starting value, it can be a navigable-map (compound index) // or list (single field index) - Object value = indexScanner.get(ceilingKey); + Object value = indexMap.get(ceilingKey); processIndexValue(value, subMap, nitriteIds); - ceilingKey = indexScanner.lowerKey(ceilingKey); + ceilingKey = indexMap.lowerKey(ceilingKey); } if (!subMap.isEmpty()) { @@ -81,4 +82,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " < " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java index ebf31b58f..61b97dd7a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NitriteFilter.java @@ -20,6 +20,8 @@ import lombok.Setter; import org.dizitart.no2.NitriteConfig; +import java.util.Objects; + /** * Represents a nitrite filter. * @@ -56,4 +58,17 @@ public Filter and(Filter filter) { public Filter or(Filter filter) { return new OrFilter(this, filter); } + + @Override + public boolean equals(Object o) { + if (o instanceof NitriteFilter) { + return Objects.equals(this.toString(), String.valueOf(o)); + } + return false; + } + + @Override + public int hashCode() { + return toString().hashCode(); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java index 4244a140e..daa95d9f8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotEqualsFilter.java @@ -1,20 +1,19 @@ package org.dizitart.no2.filters; -import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableMap; import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; /** * @author Anindya Chatterjee */ -@ToString class NotEqualsFilter extends ComparableFilter { protected NotEqualsFilter(String field, Object value) { super(field, value); @@ -27,11 +26,11 @@ public boolean apply(Pair element) { return !deepEquals(fieldValue, getValue()); } - public Object applyOnIndex(IndexScanner indexScanner) { - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + public List applyOnIndex(IndexMap indexMap) { + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - for (Pair, ?> entry : indexScanner.entries()) { + for (Pair, ?> entry : indexMap.entries()) { if (!deepEquals(getValue(), entry.getFirst())) { processIndexValue(entry.getSecond(), subMap, nitriteIds); } @@ -46,4 +45,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " != " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotFilter.java index e6562e7d1..b7161322d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotFilter.java @@ -36,4 +36,9 @@ class NotFilter extends NitriteFilter { public boolean apply(Pair element) { return !filter.apply(element); } + + @Override + public String toString() { + return "(!(" + filter.toString() + "))"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java index 68f3a66c9..ae2792725 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/NotInFilter.java @@ -20,15 +20,14 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.index.IndexScanner; +import org.dizitart.no2.index.IndexMap; import java.util.*; -import java.util.concurrent.ConcurrentSkipListMap; /** * @author Anindya Chatterjee */ -class NotInFilter extends ComparableFilter { +class NotInFilter extends ComparableArrayFilter { @Getter private final Set> comparableSet; @@ -50,11 +49,11 @@ public boolean apply(Pair element) { return true; } - public Object applyOnIndex(IndexScanner indexScanner) { - NavigableMap, Object> subMap = new ConcurrentSkipListMap<>(); + public List applyOnIndex(IndexMap indexMap) { + List, Object>> subMap = new ArrayList<>(); List nitriteIds = new ArrayList<>(); - for (Pair, ?> entry : indexScanner.entries()) { + for (Pair, ?> entry : indexMap.entries()) { if (!comparableSet.contains(entry.getFirst())) { processIndexValue(entry.getSecond(), subMap, nitriteIds); } @@ -69,4 +68,9 @@ public Object applyOnIndex(IndexScanner indexScanner) { return nitriteIds; } } + + @Override + public String toString() { + return "(" + getField() + " not in " + Arrays.toString((Comparable[]) getValue()) + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java index d6b7b0631..7ad22a6e1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/OrFilter.java @@ -46,4 +46,20 @@ public boolean apply(Pair element) { } return result; } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("("); + for (int i = 0; i < getFilters().size(); i++) { + Filter filter = getFilters().get(i); + if (i == 0) { + stringBuilder.append(filter.toString()); + } else { + stringBuilder.append(" || ").append(filter.toString()); + } + } + stringBuilder.append(")"); + return stringBuilder.toString(); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/RegexFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/RegexFilter.java index 3bb796276..86ea305d1 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/RegexFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/RegexFilter.java @@ -52,4 +52,9 @@ public boolean apply(Pair element) { } return false; } + + @Override + public String toString() { + return "(" + getField() + " regex " + getValue() + ")"; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java index 1d4d568ea..5a1747c98 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java @@ -54,6 +54,11 @@ public boolean apply(Pair element) { throw new FilterException(getField() + " is not full-text indexed"); } + @Override + public String toString() { + return "(" + getField() + " like " + getValue() + ")"; + } + /** * Apply on index linked hash set. * diff --git a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java index a3b0e6a77..c2970147d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java @@ -20,11 +20,11 @@ import lombok.Getter; import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.*; +import org.dizitart.no2.common.DBNull; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; @@ -33,7 +33,6 @@ import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; -import static org.dizitart.no2.common.util.Iterables.getElementType; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; /** @@ -69,26 +68,32 @@ public void write(FieldValues fieldValues) { validateIndexField(firstValue, firstField); if (firstValue == null) { - NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, null); + addIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (firstValue instanceof Comparable) { - NitriteMap, NavigableMap> indexMap = findIndexMap(firstValue.getClass()); + NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, (Comparable) firstValue); + //wrap around a db value + DBValue dbValue = new DBValue((Comparable) firstValue); + addIndexElement(indexMap, fieldValues, dbValue); } else if (firstValue.getClass().isArray()) { Object[] array = convertToObjectArray(firstValue); - NitriteMap, NavigableMap> indexMap = findIndexMap(array.getClass().getComponentType()); + NitriteMap> indexMap = findIndexMap(); for (Object item : array) { - addIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + addIndexElement(indexMap, fieldValues, dbValue); } } else if (firstValue instanceof Iterable) { Iterable iterable = (Iterable) firstValue; - NitriteMap, NavigableMap> indexMap = findIndexMap(getElementType(iterable)); + NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { - addIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item != null ? new DBValue((Comparable) item) : DBNull.getInstance(); + addIndexElement(indexMap, fieldValues, dbValue); } } } @@ -105,33 +110,39 @@ public void remove(FieldValues fieldValues) { validateIndexField(firstValue, firstField); if (firstValue == null) { - NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, null); + removeIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (firstValue instanceof Comparable) { - NitriteMap, NavigableMap> indexMap = findIndexMap(firstValue.getClass()); + NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, (Comparable) firstValue); + // wrap around db value + DBValue dbValue = new DBValue((Comparable) firstValue); + removeIndexElement(indexMap, fieldValues, dbValue); } else if (firstValue.getClass().isArray()) { Object[] array = convertToObjectArray(firstValue); - NitriteMap, NavigableMap> indexMap = findIndexMap(array.getClass().getComponentType()); + NitriteMap> indexMap = findIndexMap(); for (Object item : array) { - removeIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + removeIndexElement(indexMap, fieldValues, dbValue); } } else if (firstValue instanceof Iterable) { Iterable iterable = (Iterable) firstValue; - NitriteMap, NavigableMap> indexMap = findIndexMap(getElementType(iterable)); + NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { - removeIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item != null ? new DBValue((Comparable) item) : DBNull.getInstance(); + removeIndexElement(indexMap, fieldValues, dbValue); } } } @Override public void drop() { - NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); indexMap.clear(); indexMap.drop(); } @@ -140,25 +151,25 @@ public void drop() { public LinkedHashSet findNitriteIds(FindPlan findPlan) { if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); - NitriteMap, NavigableMap> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); return scanIndex(findPlan, indexMap); } - private void addIndexElement(NitriteMap, NavigableMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableMap subMap = indexMap.get(element); + private void addIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, DBValue element) { + NavigableMap subMap = indexMap.get(element); if (subMap == null) { // index are always in ascending order subMap = new ConcurrentSkipListMap<>(); } - populateSubMap(subMap, fieldValues, 1); indexMap.put(element, subMap); + populateSubMap(subMap, fieldValues, 1); } - private void removeIndexElement(NitriteMap, NavigableMap> indexMap, - FieldValues fieldValues, Comparable element) { - NavigableMap subMap = indexMap.get(element); + private void removeIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, DBValue element) { + NavigableMap subMap = indexMap.get(element); if (subMap != null && !subMap.isEmpty()) { deleteFromSubMap(subMap, fieldValues, 1); indexMap.put(element, subMap); @@ -167,151 +178,85 @@ private void removeIndexElement(NitriteMap, NavigableMap> in @SuppressWarnings({"rawtypes", "unchecked"}) private void populateSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { - for (int i = startIndex; i < fieldValues.getValues().size(); i++) { - Pair pair = fieldValues.getValues().get(i); - Object value = pair.getSecond(); - if (value == null) { - value = DBNull.getInstance(); + Pair pair = fieldValues.getValues().get(startIndex); + Object value = pair.getSecond(); + DBValue dbValue; + if (value == null) { + dbValue = DBNull.getInstance(); + } else { + if (Iterable.class.isAssignableFrom(value.getClass()) || value.getClass().isArray()) { + throw new IndexingException("compound multikey index is supported on the first field of the index only"); } if (!(value instanceof Comparable)) { throw new IndexingException(value + " is not comparable"); } + dbValue = new DBValue((Comparable) value); + } - if (i == fieldValues.getValues().size() - 1) { - List nitriteIds = (List) subMap.get(value); - nitriteIds = addNitriteIds(nitriteIds, fieldValues); - subMap.put(value, nitriteIds); - } else { - NavigableMap subMap2 = (NavigableMap) subMap.get(value); - if (subMap2 == null) { - // index are always in ascending order - subMap2 = new ConcurrentSkipListMap<>(); - } - - populateSubMap(subMap2, fieldValues, startIndex + 1); - subMap.put(value, subMap2); + if (startIndex == fieldValues.getValues().size() - 1) { + // terminal field + List nitriteIds = (List) subMap.get(dbValue); + nitriteIds = addNitriteIds(nitriteIds, fieldValues); + subMap.put(dbValue, nitriteIds); + } else { + // intermediate fields + NavigableMap subMap2 = (NavigableMap) subMap.get(dbValue); + if (subMap2 == null) { + // index are always in ascending order + subMap2 = new ConcurrentSkipListMap<>(); } + + subMap.put(dbValue, subMap2); + populateSubMap(subMap2, fieldValues, startIndex + 1); } } @SuppressWarnings({"rawtypes", "unchecked"}) private void deleteFromSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { - for (int i = startIndex; i < fieldValues.getValues().size(); i++) { - Pair pair = fieldValues.getValues().get(i); - Object value = pair.getSecond(); - if (value == null) { - value = DBNull.getInstance(); - } - + Pair pair = fieldValues.getValues().get(startIndex); + Object value = pair.getSecond(); + DBValue dbValue; + if (value == null) { + dbValue = DBNull.getInstance(); + } else { if (!(value instanceof Comparable)) { - continue; + return; } + dbValue = new DBValue((Comparable) value); + } - if (i == fieldValues.getValues().size() - 1) { - List nitriteIds = (List) subMap.get(value); - nitriteIds = removeNitriteIds(nitriteIds, fieldValues); - if (nitriteIds == null || nitriteIds.isEmpty()) { - subMap.remove(value); - } else { - subMap.put(value, nitriteIds); - } + if (startIndex == fieldValues.getValues().size() - 1) { + // terminal field + List nitriteIds = (List) subMap.get(dbValue); + nitriteIds = removeNitriteIds(nitriteIds, fieldValues); + if (nitriteIds == null || nitriteIds.isEmpty()) { + subMap.remove(dbValue); } else { - NavigableMap subMap2 = (NavigableMap) subMap.get(value); - if (subMap2 == null) { - continue; - } - - deleteFromSubMap(subMap2, fieldValues, startIndex + 1); - subMap.put(value, subMap2); + subMap.put(dbValue, nitriteIds); + } + } else { + // intermediate fields + NavigableMap subMap2 = (NavigableMap) subMap.get(dbValue); + if (subMap2 == null) { + return; } + + deleteFromSubMap(subMap2, fieldValues, startIndex + 1); + subMap.put(dbValue, subMap2); } } - private NitriteMap, NavigableMap> findIndexMap(Class keyType) { + private NitriteMap> findIndexMap() { String mapName = deriveIndexMapName(indexDescriptor); - return nitriteStore.openMap(mapName, keyType, ConcurrentSkipListMap.class); + return nitriteStore.openMap(mapName, DBValue.class, ConcurrentSkipListMap.class); } - @SuppressWarnings("unchecked") private LinkedHashSet scanIndex(FindPlan findPlan, - NitriteMap, NavigableMap> indexMap) { - // linked-hash-set to return only unique ids preserving the order in index - LinkedHashSet nitriteIds = new LinkedHashSet<>(); + NitriteMap> indexMap) { List filters = findPlan.getIndexScanFilter().getFilters(); - - if (filters != null && !filters.isEmpty()) { - Object scanResult = indexMap; - for (Filter filter : filters) { - if (scanResult == null) { - // invalid scanning state - break; - } - - if (filter instanceof ComparableFilter) { - ComparableFilter comparableFilter = (ComparableFilter) filter; - // filter can consume nitrite-map or sub-map - // filter can return list of nitrite-id or sub-map - - IndexScanner indexScanner = null; - boolean reverseScan = findPlan.getIndexScanOrder().get(comparableFilter.getField()); - if (scanResult instanceof NitriteMap) { - indexScanner = new IndexScanner((NitriteMap, ?>) scanResult); - } else if (scanResult instanceof NavigableMap) { - indexScanner = new IndexScanner((NavigableMap, ?>) scanResult); - } - - if (indexScanner != null) { - indexScanner.setReverseScan(reverseScan); - scanResult = comparableFilter.applyOnIndex(indexScanner); - } - } else { - throw new FilterException("index scan is not supported for " + filter.getClass().getName()); - } - } - - // final result of last filter can be a navigable map or list - if (scanResult instanceof List) { - // for linked list take the nitrite-ids maintaining the insertion order - List terminalResult = (List) scanResult; - nitriteIds.addAll(terminalResult); - } else if (scanResult instanceof NavigableMap) { - // if filter is a covered query but index still have some extra field, - // then the return type of last filter will be a navigable-map - // we need to traverse the rest of the data and collect all - // terminal nitrite-ids preserving the insertion order - NavigableMap subMap = (NavigableMap) scanResult; - - // collection all terminal nitrite-ids - List terminalResult = getTerminalNitriteIds(subMap); - nitriteIds.addAll(terminalResult); - } else { - throw new FilterException("invalid result state after index scan"); - } - } - return nitriteIds; - } - - - @SuppressWarnings("unchecked") - private List getTerminalNitriteIds(NavigableMap navigableMap) { - List terminalResult = new ArrayList<>(); - - // scan each entry of th navigable map and collect all terminal nitrite-ids - for (Map.Entry entry : navigableMap.entrySet()) { - // if the value is terminal, collect all nitrite-ids - if (entry.getValue() instanceof List) { - List nitriteIds = (List) entry.getValue(); - terminalResult.addAll(nitriteIds); - } - - // if the value is not terminal, scan recursively - if (entry.getValue() instanceof NavigableMap) { - NavigableMap subMap = (NavigableMap) entry.getValue(); - List nitriteIds = getTerminalNitriteIds(subMap); - terminalResult.addAll(nitriteIds); - } - } - return terminalResult; + IndexMap iMap = new IndexMap(indexMap); + IndexScanner indexScanner = new IndexScanner(iMap); + return indexScanner.doScan(filters, findPlan.getIndexScanOrder()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/DBValue.java b/nitrite/src/main/java/org/dizitart/no2/index/DBValue.java new file mode 100644 index 000000000..161b488ce --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/DBValue.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.Setter; +import org.dizitart.no2.common.util.Comparables; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * @author Anindya Chatterjee + */ +@Data +public class DBValue implements Comparable, Serializable { + private static final long serialVersionUID = 1617440702L; + + @Setter(AccessLevel.PRIVATE) + private Comparable value; + + public DBValue(Comparable value) { + this.value = value; + } + + @Override + public int compareTo(DBValue o) { + if (o == null || o.value == null) { + return 1; + } + + if (value == null) { + return -1; + } + + return Comparables.compare(value, o.value); + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + stream.writeObject(value); + } + + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + this.value = (Comparable) stream.readObject(); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index 8bf655375..363ad8e22 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -86,15 +86,37 @@ public IndexDescriptor(String indexType, Fields fields, String collectionName) { @Override public int compareTo(IndexDescriptor other) { - String string = collectionName + indexFields + indexType; - String otherString = other.collectionName + other.indexFields + other.indexType; - return string.compareTo(otherString); + if (other == null) return 1; + + // compound index have highest cardinality + if (this.isCompoundIndex() && !other.isCompoundIndex()) return 1; + + // unique index has the next highest cardinality + if (this.isUniqueIndex() && !other.isUniqueIndex()) return 1; + + // for two unique indices, the one with encompassing higher + // number of fields has the higher cardinality + if (this.isUniqueIndex()) { + return this.indexFields.compareTo(other.indexFields); + } + + // for two non-unique indices, the one with encompassing higher + // number of fields has the higher cardinality + if (!other.isUniqueIndex()) { + return this.indexFields.compareTo(other.indexFields); + } + + return -1; } public boolean isCompoundIndex() { return indexFields.getFieldNames().size() > 1; } + private boolean isUniqueIndex() { + return indexType.equals(IndexType.Unique); + } + private void writeObject(ObjectOutputStream stream) throws IOException { stream.writeUTF(indexType); stream.writeObject(indexFields); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java new file mode 100644 index 000000000..0f609c3d2 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import lombok.Getter; +import lombok.Setter; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.DBNull; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.store.NitriteMap; + +import java.util.*; + +/** + * Represents an index map. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +@SuppressWarnings("unchecked") +public class IndexMap { + private NitriteMap nitriteMap; + private NavigableMap navigableMap; + + @Getter + @Setter + private boolean reverseScan; + + /** + * Instantiates a new {@link IndexMap}. + * + * @param nitriteMap the nitrite map + */ + public IndexMap(NitriteMap nitriteMap) { + this.nitriteMap = nitriteMap; + } + + /** + * Instantiates a new {@link IndexMap}. + * + * @param navigableMap the navigable map + */ + public IndexMap(NavigableMap navigableMap) { + this.navigableMap = navigableMap; + } + + /** + * Get the largest key that is smaller than the given key, or null if no + * such key exists. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T lowerKey(T key) { + DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key); + if (!reverseScan) { + if (nitriteMap != null) { + dbKey = nitriteMap.lowerKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.lowerKey(dbKey); + } + } else { + if (nitriteMap != null) { + dbKey = nitriteMap.higherKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.higherKey(dbKey); + } + } + + return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue(); + } + + /** + * Get the smallest key that is larger than the given key, or null if no + * such key exists. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T higherKey(T key) { + DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key); + if (!reverseScan) { + if (nitriteMap != null) { + dbKey = nitriteMap.higherKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.higherKey(dbKey); + } + } else { + if (nitriteMap != null) { + dbKey = nitriteMap.lowerKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.lowerKey(dbKey); + } + } + + return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue(); + } + + /** + * Get the smallest key that is larger or equal to this key. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T ceilingKey(T key) { + DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key); + if (!reverseScan) { + if (nitriteMap != null) { + dbKey = nitriteMap.ceilingKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.ceilingKey(dbKey); + } + } else { + if (nitriteMap != null) { + dbKey = nitriteMap.floorKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.floorKey(dbKey); + } + } + + return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue(); + } + + /** + * Get the largest key that is smaller or equal to this key. + * + * @param the type parameter + * @param key the key + * @return the t + */ + public > T floorKey(T key) { + DBValue dbKey = key == null ? DBNull.getInstance() : new DBValue(key); + if (!reverseScan) { + if (nitriteMap != null) { + dbKey = nitriteMap.floorKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.floorKey(dbKey); + } + } else { + if (nitriteMap != null) { + dbKey = nitriteMap.ceilingKey(dbKey); + } else if (navigableMap != null) { + dbKey = navigableMap.ceilingKey(dbKey); + } + } + + return dbKey == null || dbKey instanceof DBNull ? null : (T) dbKey.getValue(); + } + + /** + * Gets the value mapped with the specified key or null otherwise. + * + * @param comparable the comparable + * @return the object + */ + public Object get(Comparable comparable) { + DBValue dbKey = comparable == null ? DBNull.getInstance() : new DBValue(comparable); + if (nitriteMap != null) { + return nitriteMap.get(dbKey); + } else if (navigableMap != null) { + return navigableMap.get(dbKey); + } + return null; + } + + /** + * Returns the iterable entries of the indexed items. + * + * @return the iterable + */ + public Iterable, ?>> entries() { + if (nitriteMap != null) { + Iterator> entryIterator; + if (!reverseScan) { + entryIterator = nitriteMap.entries().iterator(); + } else { + entryIterator = nitriteMap.reversedEntries().iterator(); + } + + return (Iterable, ?>>) () -> new Iterator, ?>>() { + @Override + public boolean hasNext() { + return entryIterator.hasNext(); + } + + @Override + public Pair, ?> next() { + Pair next = entryIterator.next(); + DBValue dbKey = next.getFirst(); + if (dbKey instanceof DBNull) { + return new Pair<>(null, next.getSecond()); + } else { + return new Pair<>(dbKey.getValue(), next.getSecond()); + } + } + }; + } else if (navigableMap != null) { + Iterator> entryIterator; + if (reverseScan) { + entryIterator = navigableMap.descendingMap().entrySet().iterator(); + } else { + entryIterator = navigableMap.entrySet().iterator(); + } + + return (Iterable, ?>>) () -> new Iterator, ?>>() { + @Override + public boolean hasNext() { + return entryIterator.hasNext(); + } + + @Override + public Pair, ?> next() { + Map.Entry next = entryIterator.next(); + DBValue dbKey = next.getKey(); + if (dbKey instanceof DBNull) { + return new Pair<>(null, next.getValue()); + } else { + return new Pair<>(dbKey.getValue(), next.getValue()); + } + } + }; + } + return null; + } + + /** + * Gets the terminal nitrite ids from this map. + * + * @return the terminal nitrite ids + */ + public List getTerminalNitriteIds() { + List terminalResult = new ArrayList<>(); + + // scan each entry of the navigable map and collect all terminal nitrite-ids + for (Pair, ?> entry : entries()) { + // if the value is terminal, collect all nitrite-ids + if (entry.getSecond() instanceof List) { + List nitriteIds = (List) entry.getSecond(); + terminalResult.addAll(nitriteIds); + } + + // if the value is not terminal, scan recursively + if (entry.getSecond() instanceof NavigableMap) { + NavigableMap subMap = (NavigableMap) entry.getSecond(); + IndexMap indexMap = new IndexMap(subMap); + List nitriteIds = indexMap.getTerminalNitriteIds(); + terminalResult.addAll(nitriteIds); + } + } + + return terminalResult; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java index 59271daee..5ff4ad391 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java @@ -17,194 +17,112 @@ package org.dizitart.no2.index; -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.filters.ComparableFilter; +import org.dizitart.no2.filters.Filter; -import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.NavigableMap; /** - * Represents an index scanner during find operation. + * Represents an {@link IndexMap} scanner. * * @author Anindya Chatterjee * @since 4.0 */ -@SuppressWarnings("unchecked") public class IndexScanner { - private NitriteMap, ?> nitriteMap; - private NavigableMap, ?> navigableMap; - - @Getter - @Setter - private boolean reverseScan; + private final IndexMap indexMap; /** - * Instantiates a new Index scanner. + * Instantiates a new {@link IndexScanner}. * - * @param nitriteMap the nitrite map + * @param indexMap the index map */ - public IndexScanner(NitriteMap, ?> nitriteMap) { - this.nitriteMap = nitriteMap; + public IndexScanner(IndexMap indexMap) { + this.indexMap = indexMap; } /** - * Instantiates a new Index scanner. + * Scans the {@link IndexMap} and returns the {@link NitriteId}s of the matching elements. * - * @param navigableMap the navigable map + * @param filters the filters + * @param indexScanOrder the index scan order + * @return the linked hash set */ - public IndexScanner(NavigableMap, ?> navigableMap) { - this.navigableMap = navigableMap; - } + @SuppressWarnings("unchecked") + public LinkedHashSet doScan(List filters, Map indexScanOrder) { + // linked-hash-set to return only unique ids preserving the order in index + LinkedHashSet nitriteIds = new LinkedHashSet<>(); - /** - * Get the largest key that is smaller than the given key, or null if no - * such key exists. - * - * @param the type parameter - * @param key the key - * @return the t - */ - public > T lowerKey(T key) { - if (!reverseScan) { - if (nitriteMap != null) { - return (T) nitriteMap.lowerKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.lowerKey(key); - } - } else { - if (nitriteMap != null) { - return (T) nitriteMap.higherKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.higherKey(key); - } - } - return null; - } + if (filters != null && !filters.isEmpty()) { + // get the first filter to start scanning + Filter filter = filters.get(0); - /** - * Get the smallest key that is larger than the given key, or null if no - * such key exists. - * - * @param the type parameter - * @param key the key - * @return the t - */ - public > T higherKey(T key) { - if (!reverseScan) { - if (nitriteMap != null) { - return (T) nitriteMap.higherKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.higherKey(key); - } - } else { - if (nitriteMap != null) { - return (T) nitriteMap.lowerKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.lowerKey(key); - } - } - return null; - } + if (filter instanceof ComparableFilter) { + ComparableFilter comparableFilter = (ComparableFilter) filter; - /** - * Get the smallest key that is larger or equal to this key. - * - * @param the type parameter - * @param key the key - * @return the t - */ - public > T ceilingKey(T key) { - if (!reverseScan) { - if (nitriteMap != null) { - return (T) nitriteMap.ceilingKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.ceilingKey(key); - } - } else { - if (nitriteMap != null) { - return (T) nitriteMap.floorKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.floorKey(key); - } - } - return null; - } + // set the scan order of the index map + boolean reverseScan = (indexScanOrder != null + && indexScanOrder.containsKey(comparableFilter.getField())) + ? indexScanOrder.get(comparableFilter.getField()) + : false; + indexMap.setReverseScan(reverseScan); - /** - * Get the largest key that is smaller or equal to this key. - * - * @param the type parameter - * @param key the key - * @return the t - */ - public > T floorKey(T key) { - if (!reverseScan) { - if (nitriteMap != null) { - return (T) nitriteMap.floorKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.floorKey(key); + // apply the filter on the index map + // result can be list of nitrite ids or list of navigable maps + List scanResult = comparableFilter.applyOnIndex(indexMap); + if (isEmptyList(scanResult)) { + // if list is empty then no need for further scanning + return nitriteIds; + } else if (isNitriteIdList(scanResult)) { + // if this is a list of nitrite ids then add those to the + // result and no further scanning is required as we have + // reached the terminal nitrite ids + List idList = (List) scanResult; + nitriteIds.addAll(idList); + } else if (isNavigableMapList(scanResult)) { + // if this is a list of sub maps, then take each of the sub map + // and the next filter and scan the sub map + List> subMaps = (List>) scanResult; + List remainingFilter = filters.subList(1, filters.size()); + + for (NavigableMap subMap : subMaps) { + // create an index map from the sub map and scan to get the + // terminal nitrite ids + IndexMap indexMap = new IndexMap(subMap); + IndexScanner subMapScanner = new IndexScanner(indexMap); + LinkedHashSet subResult = subMapScanner.doScan(remainingFilter, indexScanOrder); + nitriteIds.addAll(subResult); + } + } + } else { + // filter is not comparable filter, so index scanning can not continue + throw new FilterException("index scan is not supported for " + filter.getClass().getName()); } } else { - if (nitriteMap != null) { - return (T) nitriteMap.ceilingKey(key); - } else if (navigableMap != null) { - return (T) navigableMap.ceilingKey(key); - } + // if no more filter is left, get all terminal nitrite ids from + // index map and return them in the order. + List terminalResult = indexMap.getTerminalNitriteIds(); + nitriteIds.addAll(terminalResult); } - return null; - } - /** - * Gets the value mapped with the specified key or null otherwise. - * - * @param comparable the comparable - * @return the object - */ - public Object get(Comparable comparable) { - if (nitriteMap != null) { - return nitriteMap.get(comparable); - } else if (navigableMap != null) { - return navigableMap.get(comparable); - } - return null; + return nitriteIds; } - /** - * Returns the iterable entries of the indexed items. - * - * @return the iterable - */ - public Iterable, ?>> entries() { - if (nitriteMap != null) { - if (!reverseScan) { - return nitriteMap.entries(); - } else { - return nitriteMap.reversedEntries(); - } - } else if (navigableMap != null) { - Iterator, ?>> entryIterator; - if (reverseScan) { - entryIterator = navigableMap.descendingMap().entrySet().iterator(); - } else { - entryIterator = navigableMap.entrySet().iterator(); - } + private boolean isEmptyList(List list) { + return list == null || list.isEmpty(); + } - return (Iterable, ?>>) () -> new Iterator, ?>>() { - @Override - public boolean hasNext() { - return entryIterator.hasNext(); - } + private boolean isNitriteIdList(List list) { + Object value = list.get(0); + return value instanceof NitriteId; + } - @Override - public Pair, ?> next() { - Map.Entry, ?> entry = entryIterator.next(); - return Pair.pair(entry.getKey(), entry.getValue()); - } - }; - } - return null; + private boolean isNavigableMapList(List list) { + Object value = list.get(0); + return value instanceof NavigableMap; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java index 607906a82..850aed466 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteIndexer.java @@ -21,7 +21,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; import java.util.LinkedHashSet; diff --git a/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java index 47748b6f1..88e17df8f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java @@ -20,11 +20,9 @@ import lombok.Getter; import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; -import org.dizitart.no2.common.UnknownType; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; @@ -34,7 +32,6 @@ import java.util.List; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; -import static org.dizitart.no2.common.util.Iterables.getElementType; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; /** @@ -68,26 +65,32 @@ public void write(FieldValues fieldValues) { Object element = fieldValues.get(firstField); if (element == null) { - NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, null); + addIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (element instanceof Comparable) { - NitriteMap, List> indexMap = findIndexMap(element.getClass()); + NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, (Comparable) element); + // wrap around db value + DBValue dbValue = new DBValue((Comparable) element); + addIndexElement(indexMap, fieldValues, dbValue); } else if (element.getClass().isArray()) { Object[] array = convertToObjectArray(element); - NitriteMap, List> indexMap = findIndexMap(array.getClass().getComponentType()); + NitriteMap> indexMap = findIndexMap(); for (Object item : array) { - addIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + addIndexElement(indexMap, fieldValues, dbValue); } } else if (element instanceof Iterable) { Iterable iterable = (Iterable) element; - NitriteMap, List> indexMap = findIndexMap(getElementType(iterable)); + NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { - addIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + addIndexElement(indexMap, fieldValues, dbValue); } } } @@ -101,33 +104,39 @@ public void remove(FieldValues fieldValues) { Object element = fieldValues.get(firstField); if (element == null) { - NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, null); + removeIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (element instanceof Comparable) { - NitriteMap, List> indexMap = findIndexMap(element.getClass()); + NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, (Comparable) element); + // wrap around db value + DBValue dbValue = new DBValue((Comparable) element); + removeIndexElement(indexMap, fieldValues, dbValue); } else if (element.getClass().isArray()) { Object[] array = convertToObjectArray(element); - NitriteMap, List> indexMap = findIndexMap(array.getClass().getComponentType()); + NitriteMap> indexMap = findIndexMap(); for (Object item : array) { - removeIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + removeIndexElement(indexMap, fieldValues, dbValue); } } else if (element instanceof Iterable) { Iterable iterable = (Iterable) element; - NitriteMap, List> indexMap = findIndexMap(getElementType(iterable)); + NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { - removeIndexElement(indexMap, fieldValues, (Comparable) item); + // wrap around db value + DBValue dbValue = item == null ? DBNull.getInstance() : new DBValue((Comparable) item); + removeIndexElement(indexMap, fieldValues, dbValue); } } } @Override public void drop() { - NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); indexMap.clear(); indexMap.drop(); } @@ -136,21 +145,21 @@ public void drop() { public LinkedHashSet findNitriteIds(FindPlan findPlan) { if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); - NitriteMap, List> indexMap = findIndexMap(UnknownType.class); + NitriteMap> indexMap = findIndexMap(); return scanIndex(findPlan, indexMap); } @SuppressWarnings("unchecked") - private void addIndexElement(NitriteMap, List> indexMap, - FieldValues fieldValues, Comparable element) { + private void addIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, DBValue element) { List nitriteIds = (List) indexMap.get(element); nitriteIds = addNitriteIds(nitriteIds, fieldValues); indexMap.put(element, nitriteIds); } @SuppressWarnings("unchecked") - private void removeIndexElement(NitriteMap, List> indexMap, - FieldValues fieldValues, Comparable element) { + private void removeIndexElement(NitriteMap> indexMap, + FieldValues fieldValues, DBValue element) { List nitriteIds = (List) indexMap.get(element); if (nitriteIds != null && !nitriteIds.isEmpty()) { nitriteIds.remove(fieldValues.getNitriteId()); @@ -162,39 +171,16 @@ private void removeIndexElement(NitriteMap, List> indexMap, } } - private NitriteMap, List> findIndexMap(Class keyType) { + private NitriteMap> findIndexMap() { String mapName = deriveIndexMapName(indexDescriptor); - return nitriteStore.openMap(mapName, keyType, ArrayList.class); + return nitriteStore.openMap(mapName, DBValue.class, ArrayList.class); } - @SuppressWarnings("unchecked") private LinkedHashSet scanIndex(FindPlan findPlan, - NitriteMap, List> indexMap) { - // linked-hash-set to return only unique ids preserving the order in index - LinkedHashSet nitriteIds = new LinkedHashSet<>(); + NitriteMap> indexMap) { List filters = findPlan.getIndexScanFilter().getFilters(); - - if (filters != null && filters.size() == 1) { - Filter filter = filters.get(0); - if (filter instanceof ComparableFilter) { - ComparableFilter comparableFilter = (ComparableFilter) filter; - // filter will return a list of nitrite-ids - - IndexScanner indexScanner = new IndexScanner(indexMap); - boolean reverseScan = findPlan.getIndexScanOrder().get(comparableFilter.getField()); - indexScanner.setReverseScan(reverseScan); - - Object scanResult = comparableFilter.applyOnIndex(indexScanner); - - if (scanResult instanceof List) { - // for list take the nitrite-ids maintaining the insertion order - List terminalResult = (List) scanResult; - nitriteIds.addAll(terminalResult); - return nitriteIds; - } - } - } - - throw new FilterException("invalid result state after index scan"); + IndexMap iMap = new IndexMap(indexMap); + IndexScanner indexScanner = new IndexScanner(iMap); + return indexScanner.doScan(filters, findPlan.getIndexScanOrder()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java index 93a9e5021..39d94ebfa 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java @@ -181,7 +181,7 @@ private void addIndexElement(NitriteMap> indexMap, FieldValues f } nitriteIds = addNitriteIds(nitriteIds, fieldValues); - indexMap.put(value, nitriteIds); + indexMap.put(word, nitriteIds); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java index 150460d44..7da5cea89 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/MigrationManager.java @@ -11,7 +11,7 @@ import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.migration.commands.*; -import org.dizitart.no2.store.DatabaseMetaData; +import org.dizitart.no2.store.StoreMetaData; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.UserAuthenticationService; @@ -31,7 +31,7 @@ */ public class MigrationManager { private final NitriteConfig nitriteConfig; - private final DatabaseMetaData databaseMetadata; + private final StoreMetaData storeMetadata; private final Nitrite database; /** @@ -42,7 +42,7 @@ public class MigrationManager { public MigrationManager(Nitrite nitrite) { this.database = nitrite; this.nitriteConfig = nitrite.getConfig(); - this.databaseMetadata = nitrite.getDatabaseMetaData(); + this.storeMetadata = nitrite.getDatabaseMetaData(); } /** @@ -50,7 +50,7 @@ public MigrationManager(Nitrite nitrite) { */ public void doMigrate() { if (isMigrationNeeded()) { - Integer existingVersion = databaseMetadata.getSchemaVersion(); + Integer existingVersion = storeMetadata.getSchemaVersion(); Integer incomingVersion = nitriteConfig.getSchemaVersion(); Queue migrationPath = findMigrationPath(existingVersion, incomingVersion); @@ -63,7 +63,7 @@ public void doMigrate() { } throw new MigrationException("schema version mismatch, as no migration path found from version " - + databaseMetadata.getSchemaVersion() + " to " + nitriteConfig.getSchemaVersion()); + + storeMetadata.getSchemaVersion() + " to " + nitriteConfig.getSchemaVersion()); } int length = migrationPath.size(); @@ -78,7 +78,7 @@ public void doMigrate() { } private boolean isMigrationNeeded() { - Integer existingVersion = databaseMetadata.getSchemaVersion(); + Integer existingVersion = storeMetadata.getSchemaVersion(); Integer incomingVersion = nitriteConfig.getSchemaVersion(); if (existingVersion == null) { @@ -146,7 +146,7 @@ private void executeMigrationSteps(Queue migrationSteps) { } } - DatabaseMetaData metaData = database.getDatabaseMetaData(); + StoreMetaData metaData = database.getDatabaseMetaData(); metaData.setSchemaVersion(nitriteConfig.getSchemaVersion()); NitriteMap storeInfo = database.getStore().openMap(STORE_INFO, diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java b/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java new file mode 100644 index 000000000..0daab41a4 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import lombok.Getter; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.NotIdentifiableException; +import org.dizitart.no2.repository.annotations.*; + +import java.lang.reflect.Field; +import java.util.*; + +import static org.dizitart.no2.index.IndexOptions.indexOptions; + +/** + * @author Anindya Chatterjee + */ +class AnnotationScanner { + private final Set indices; + private final Class type; + private final NitriteMapper nitriteMapper; + private final Reflector reflector; + private final NitriteCollection collection; + private final IndexValidator indexValidator; + + @Getter + private ObjectIdField objectIdField; + + public AnnotationScanner(Class type, NitriteCollection collection, NitriteMapper nitriteMapper) { + this.type = type; + this.nitriteMapper = nitriteMapper; + this.collection = collection; + this.reflector = new Reflector(); + this.indices = new HashSet<>(); + this.indexValidator = new IndexValidator(reflector); + } + + public void createIndices() { + for (Index index : indices) { + String[] fields = index.value(); + if (!collection.hasIndex(fields)) { + collection.createIndex(indexOptions(index.type()), fields); + } + } + } + + public void createIdIndex() { + if (objectIdField != null) { + String[] fieldNames = objectIdField.getFieldNames(nitriteMapper); + if (!collection.hasIndex(fieldNames)) { + collection.createIndex(fieldNames); + } + } + } + + public void scanIndices() { + // populate from @Indices + scanIndicesAnnotation(); + + // populate from @Index + scanIndexAnnotation(); + + // populate from @Entity + scanEntityAnnotation(); + + // populate from @Id + scanIdAnnotation(); + } + + private void scanIndicesAnnotation() { + List indicesList; + if (type.isAnnotationPresent(InheritIndices.class)) { + indicesList = reflector.findInheritedAnnotations(Indices.class, type); + } else { + indicesList = new ArrayList<>(); + Indices indices = type.getAnnotation(Indices.class); + if (indices != null) indicesList.add(indices); + } + + for (Indices indices : indicesList) { + Index[] indexList = indices.value(); + populateIndex(Arrays.asList(indexList)); + } + } + + private void scanIndexAnnotation() { + List indexList; + if (type.isAnnotationPresent(InheritIndices.class)) { + indexList = reflector.findInheritedAnnotations(Index.class, type); + } else { + indexList = new ArrayList<>(); + Index index = type.getAnnotation(Index.class); + if (index != null) indexList.add(index); + } + populateIndex(indexList); + } + + private void scanEntityAnnotation() { + List indexList = new ArrayList<>(); + if (type.isAnnotationPresent(InheritIndices.class)) { + List entities = reflector.findInheritedAnnotations(Entity.class, type); + if (!entities.isEmpty()) { + for (Entity entity : entities) { + indexList.addAll(Arrays.asList(entity.indices())); + } + } + } else if (type.isAnnotationPresent(Entity.class)) { + Entity entity = type.getAnnotation(Entity.class); + indexList.addAll(Arrays.asList(entity.indices())); + } + + populateIndex(indexList); + } + + private void scanIdAnnotation() { + List fieldList = reflector.getAllFields(type); + + boolean alreadyIdFound = false; + for (Field field : fieldList) { + if (field.isAnnotationPresent(Id.class)) { + indexValidator.validate(field.getType(), field.getName(), nitriteMapper); + if (alreadyIdFound) { + throw new NotIdentifiableException("multiple id fields found for the type"); + } else { + alreadyIdFound = true; + objectIdField = new ObjectIdField(); + objectIdField.setField(field); + objectIdField.setEmbedded(isEmbeddedId(field)); + } + } + } + } + + private boolean isEmbeddedId(Field field) { + List fields = reflector.getAllFields(field.getType()); + if (fields.size() == 0) return false; + + for (Field f : fields) { + if (!f.isAnnotationPresent(Order.class)) { + return false; + } + } + return true; + } + + private void populateIndex(List indexList) { + for (Index index : indexList) { + String[] names = index.value(); + List entityFields = new ArrayList<>(); + + for (String name : names) { + Field field = reflector.getField(type, name); + if (field != null) { + entityFields.add(field); + indexValidator.validate(field.getType(), field.getName(), nitriteMapper); + } + } + + if (entityFields.size() == names.length) { + // validation for all field are success + indices.add(index); + } + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java index 85385620f..1f6a6a0ce 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java @@ -26,8 +26,8 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.store.NitriteStore; import java.util.Collection; @@ -223,7 +223,7 @@ public NitriteCollection getDocumentCollection() { private void initialize() { NitriteMapper nitriteMapper = nitriteConfig.nitriteMapper(); operations = new RepositoryOperations(type, nitriteMapper, collection); - operations.createIndexes(); + operations.createIndices(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java b/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java new file mode 100644 index 000000000..17200c43d --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.repository.annotations.Order; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; + +import static org.dizitart.no2.common.util.DocumentUtils.skeletonDocument; + +/** + * @author Anindya Chatterjee + */ +public class IndexValidator { + private final Reflector reflector; + + public IndexValidator(Reflector reflector) { + this.reflector = reflector; + } + + /** + * Validate an index field of an {@link org.dizitart.no2.repository.annotations.Entity} object. + * + * @param fieldType the field type + * @param field the field + * @param nitriteMapper the nitrite mapper + */ + public void validate(Class fieldType, String field, NitriteMapper nitriteMapper) { + if (fieldType.isPrimitive() + || fieldType == NitriteId.class + || fieldType.isInterface() + || nitriteMapper.isValueType(fieldType) + || Modifier.isAbstract(fieldType.getModifiers()) + || fieldType.isArray() + || Iterable.class.isAssignableFrom(fieldType)) { + // we will validate the solid class during insertion/update + return; + } + + Document document; + try { + document = skeletonDocument(nitriteMapper, fieldType); + if (document.size() > 1) { + // compound index + List fields = reflector.getAllFields(fieldType); + for (Field indexField : fields) { + if (!indexField.isAnnotationPresent(Order.class)) { + throw new IndexingException("@Order must be specified for all fields in the embedded id object"); + } + } + } else { + if (!Comparable.class.isAssignableFrom(fieldType)) { + throw new IndexingException("cannot index on non comparable field " + field); + } + } + } catch (IndexingException ie) { + throw ie; + } catch (Throwable e) { + throw new IndexingException("invalid type specified " + fieldType.getName() + " for indexing", e); + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/MutatedObjectStream.java b/nitrite/src/main/java/org/dizitart/no2/repository/MutatedObjectStream.java index 0ef54fd66..abf3845dc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/MutatedObjectStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/MutatedObjectStream.java @@ -19,7 +19,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Iterator; diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java index 1c902a3c0..0087a6b6c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectCursor.java @@ -23,7 +23,7 @@ import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.lang.reflect.Modifier; import java.util.Iterator; diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java new file mode 100644 index 000000000..04a6e02fc --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import lombok.Getter; +import lombok.Setter; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.repository.annotations.Order; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.NavigableMap; +import java.util.Set; +import java.util.TreeMap; + +import static org.dizitart.no2.filters.FluentFilter.where; + +/** + * @author Anindya Chatterjee + */ +class ObjectIdField { + private final Reflector reflector; + private final IndexValidator indexValidator; + private String[] fieldNames; + + @Getter + @Setter + private Field field; + @Getter + @Setter + private boolean isEmbedded; + + public ObjectIdField() { + this.reflector = new Reflector(); + this.indexValidator = new IndexValidator(reflector); + } + + public String[] getFieldNames(NitriteMapper nitriteMapper) { + if (fieldNames != null) { + return fieldNames; + } + + if (!isEmbedded) { + fieldNames = new String[]{field.getName()}; + return fieldNames; + } + + List fieldList = reflector.getAllFields(field.getType()); + NavigableMap orderedFieldName = new TreeMap<>(); + for (Field field : fieldList) { + String name = this.field.getName() + NitriteConfig.getFieldSeparator() + field.getName(); + indexValidator.validate(field.getType(), name, nitriteMapper); + + int order = getOrder(field); + orderedFieldName.put(order, name); + } + + fieldNames = orderedFieldName.values().toArray(new String[0]); + return fieldNames; + } + + public Filter createUniqueFilter(Object value, NitriteMapper nitriteMapper) { + if (fieldNames.length == 1) { + return where(field.getName()).eq(value); + } else { + Document document = nitriteMapper.convert(value, Document.class); + Set fields = document.getFields(); + Filter[] filters = new Filter[fields.size()]; + + int index = 0; + for (String field : fields) { + Object fieldValue = document.get(field); + filters[index++] = where(field).eq(fieldValue); + } + + return Filter.and(filters); + } + } + + private int getOrder(Field field) { + if (field.isAnnotationPresent(Order.class)) { + Order order = field.getAnnotation(Order.class); + return order.value(); + } + throw new IndexingException("no order specified for the field " + field.getName()); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/Reflector.java b/nitrite/src/main/java/org/dizitart/no2/repository/Reflector.java new file mode 100644 index 000000000..b229cfeca --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/repository/Reflector.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.repository.annotations.InheritIndices; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; + +/** + * @author Anindya Chatterjee + */ +class Reflector { + @SuppressWarnings("rawtypes") + public List findInheritedAnnotations(Class annotation, Class type) { + notNull(type, "type cannot be null"); + notNull(annotation, "annotationClass cannot be null"); + List annotations = new ArrayList<>(); + + T t = type.getAnnotation(annotation); + if (t != null) annotations.add(t); + + Class[] interfaces = type.getInterfaces(); + for (Class anInterface : interfaces) { + T ann = anInterface.getAnnotation(annotation); + if (ann != null) annotations.add(ann); + } + + Class parentClass = type.getSuperclass(); + if (parentClass != null && !parentClass.equals(Object.class)) { + List list = findInheritedAnnotations(annotation, parentClass); + annotations.addAll(list); + } + + return annotations; + } + + public Field getEmbeddedField(Class startingClass, String embeddedField) { + String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); + String[] split = embeddedField.split(regex, 2); + String key = split[0]; + String remaining = split.length == 2 ? split[1] : ""; + + if (isNullOrEmpty(key)) { + throw new ValidationException("invalid embedded field provided"); + } + + Field field; + try { + field = startingClass.getDeclaredField(key); + } catch (NoSuchFieldException e) { + throw new ValidationException("no such field '" + key + "' for type " + startingClass.getName(), e); + } + + if (!isNullOrEmpty(remaining) || remaining.contains(NitriteConfig.getFieldSeparator())) { + return getEmbeddedField(field.getType(), remaining); + } else { + return field; + } + } + + public List getFieldsUpto(Class startClass, Class exclusiveParent) { + notNull(startClass, "startClass cannot be null"); + List currentClassFields = new ArrayList<>(Arrays.asList(startClass.getDeclaredFields())); + filterSynthetics(currentClassFields); + Class parentClass = startClass.getSuperclass(); + + if (parentClass != null && !(parentClass.equals(exclusiveParent))) { + List parentClassFields = getFieldsUpto(parentClass, exclusiveParent); + currentClassFields.addAll(parentClassFields); + } + + return currentClassFields; + } + + public Field getField(Class type, String name) { + if (name.contains(NitriteConfig.getFieldSeparator())) { + return getEmbeddedField(type, name); + } else { + // first check declared fields (fix for kotlin properties, ref: issue #54) + // if nothing found and is-recursive then check recursively + Field[] declaredFields = type.getDeclaredFields(); + Field field = null; + for (Field declaredField : declaredFields) { + if (declaredField.getName().equals(name)) { + field = declaredField; + break; + } + } + + if (field == null) { + List fields = getFieldsUpto(type, Object.class); + for (Field recursiveField : fields) { + if (recursiveField.getName().equals(name)) { + field = recursiveField; + break; + } + } + } + if (field == null) { + throw new ValidationException("no such field '" + name + "' for type " + type.getName()); + } + return field; + } + } + + public List getAllFields(Class type) { + List fields; + if (type.isAnnotationPresent(InheritIndices.class)) { + fields = getFieldsUpto(type, Object.class); + } else { + fields = Arrays.asList(type.getDeclaredFields()); + } + return fields; + } + + public void filterSynthetics(List fields) { + if (fields == null || fields.isEmpty()) return; + Iterator iterator = fields.iterator(); + if (iterator.hasNext()) { + do { + Field f = iterator.next(); + if (f.isSynthetic()) iterator.remove(); + } while (iterator.hasNext()); + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java index 9ff2624ce..2fe8de751 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryFactory.java @@ -22,7 +22,7 @@ import org.dizitart.no2.common.util.StringUtils; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreCatalog; diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java index 3dc7a299b..5e9eb096a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java @@ -16,29 +16,20 @@ package org.dizitart.no2.repository; -import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.*; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.*; +import org.dizitart.no2.exceptions.InvalidIdException; +import org.dizitart.no2.exceptions.NotIdentifiableException; +import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.filters.NitriteFilter; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.*; -import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.text.MessageFormat; -import java.util.*; import static org.dizitart.no2.common.Constants.DOC_ID; -import static org.dizitart.no2.common.util.DocumentUtils.skeletonDocument; import static org.dizitart.no2.common.util.ObjectUtils.isCompatibleTypes; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.common.util.ValidationUtils.notNull; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; /** * The {@link ObjectRepository} operations. @@ -53,7 +44,8 @@ public class RepositoryOperations { private final NitriteMapper nitriteMapper; private final Class type; private final NitriteCollection collection; - private Field idField; + private final AnnotationScanner annotationScanner; + private ObjectIdField objectIdField; /** * Instantiates a new {@link RepositoryOperations}. @@ -68,27 +60,25 @@ public RepositoryOperations(Class type, this.type = type; this.nitriteMapper = nitriteMapper; this.collection = collection; + this.annotationScanner = new AnnotationScanner(type, collection, nitriteMapper); validateCollection(); } - public void createIndexes() { - Set indexes = extractIndices(type); - for (Index idx : indexes) { - String[] fields = idx.value(); - if (!collection.hasIndex(fields)) { - collection.createIndex(indexOptions(idx.type()), fields); - } - } - - idField = getIdField(type); - if (idField != null) { - String field = idField.getName(); - if (!collection.hasIndex(field)) { - collection.createIndex(indexOptions(IndexType.Unique), field); - } - } + /** + * Create indices. + */ + public void createIndices() { + annotationScanner.scanIndices(); + annotationScanner.createIndices(); + annotationScanner.createIdIndex(); + objectIdField = annotationScanner.getObjectIdField(); } + /** + * Serialize fields. + * + * @param document the document + */ public void serializeFields(Document document) { if (document != null) { for (Pair pair : document) { @@ -101,6 +91,13 @@ public void serializeFields(Document document) { } } + /** + * To documents document [ ]. + * + * @param the type parameter + * @param others the others + * @return the document [ ] + */ public Document[] toDocuments(T[] others) { if (others == null || others.length == 0) return null; Document[] documents = new Document[others.length]; @@ -110,9 +107,20 @@ public Document[] toDocuments(T[] others) { return documents; } + /** + * To document document. + * + * @param the type parameter + * @param object the object + * @param update the update + * @return the document + */ public Document toDocument(T object, boolean update) { Document document = nitriteMapper.convert(object, Document.class); - if (idField != null) { + + if (objectIdField != null) { + Field idField = objectIdField.getField(); + if (idField.getType() == NitriteId.class) { try { idField.setAccessible(true); @@ -127,6 +135,7 @@ public Document toDocument(T object, boolean update) { throw new InvalidIdException("auto generated id value cannot be accessed"); } } + Object idValue = document.get(idField.getName()); if (idValue == null) { throw new InvalidIdException("id cannot be null"); @@ -138,47 +147,74 @@ public Document toDocument(T object, boolean update) { return document; } + /** + * Create unique filter filter. + * + * @param object the object + * @return the filter + */ public Filter createUniqueFilter(Object object) { - if (idField == null) { + if (objectIdField == null) { throw new NotIdentifiableException("update operation failed as no id value found for the object"); } + Field idField = objectIdField.getField(); idField.setAccessible(true); try { Object value = idField.get(object); if (value == null) { throw new InvalidIdException("id value cannot be null"); } - return where(idField.getName()).eq(value); + return objectIdField.createUniqueFilter(value, nitriteMapper); } catch (IllegalAccessException iae) { throw new InvalidIdException("id field is not accessible"); } } + /** + * Remove nitrite id. + * + * @param document the document + */ public void removeNitriteId(Document document) { document.remove(DOC_ID); - if (idField != null && idField.getType() == NitriteId.class) { - document.remove(idField.getName()); + if (objectIdField != null) { + Field idField = objectIdField.getField(); + if (idField != null && !objectIdField.isEmbedded() + && idField.getType() == NitriteId.class) { + document.remove(idField.getName()); + } } } + /** + * Create id filter filter. + * + * @param the type parameter + * @param id the id + * @return the filter + */ public Filter createIdFilter(I id) { - if (idField != null) { + if (objectIdField != null) { if (id == null) { throw new InvalidIdException("a null id is not a valid id"); } - - if (isCompatibleTypes(idField.getType(), id.getClass())) { - return where(idField.getName()).eq(id); - } else { - throw new InvalidIdException(id.getClass().getName() + " is not assignable to id type " - + idField.getType().getName()); + if (!isCompatibleTypes(id.getClass(), objectIdField.getField().getType())) { + throw new InvalidIdException("a value of invalid type is provided as id"); } + + return objectIdField.createUniqueFilter(id, nitriteMapper); } else { throw new NotIdentifiableException(type.getName() + " does not have any id field"); } } + /** + * As object filter filter. + * + * @param filter the filter + * @return the filter + */ public Filter asObjectFilter(Filter filter) { if (filter instanceof NitriteFilter) { NitriteFilter nitriteFilter = (NitriteFilter) filter; @@ -188,238 +224,6 @@ public Filter asObjectFilter(Filter filter) { return filter; } - Field getIdField(Class type) { - List fields; - if (type.isAnnotationPresent(InheritIndices.class)) { - fields = getFieldsUpto(type, Object.class); - } else { - fields = Arrays.asList(type.getDeclaredFields()); - } - - boolean alreadyIdFound = false; - Field idField = null; - for (Field field : fields) { - if (field.isAnnotationPresent(Id.class)) { - validateObjectIndexField(nitriteMapper, field.getType(), field.getName()); - if (alreadyIdFound) { - throw new NotIdentifiableException("multiple id fields found for the type"); - } else { - alreadyIdFound = true; - idField = field; - } - } - } - return idField; - } - - Set extractIndices(Class type) { - notNull(type, "type cannot be null"); - - // populate from @Indices - List indicesList; - if (type.isAnnotationPresent(InheritIndices.class)) { - indicesList = findAnnotations(Indices.class, type); - } else { - indicesList = new ArrayList<>(); - Indices indices = type.getAnnotation(Indices.class); - if (indices != null) indicesList.add(indices); - } - - Set indexSet = new LinkedHashSet<>(); - for (Indices indices : indicesList) { - Index[] indexList = indices.value(); - populateIndex(nitriteMapper, type, Arrays.asList(indexList), indexSet); - } - - // populate from @Index - List indexList; - if (type.isAnnotationPresent(InheritIndices.class)) { - indexList = findAnnotations(Index.class, type); - } else { - indexList = new ArrayList<>(); - Index index = type.getAnnotation(Index.class); - if (index != null) indexList.add(index); - } - - // populate from @Entity - if (type.isAnnotationPresent(InheritIndices.class)) { - List entities = findAnnotations(Entity.class, type); - if (!entities.isEmpty()) { - for (Entity entity : entities) { - indexList.addAll(Arrays.asList(entity.indices())); - } - } - } else if (type.isAnnotationPresent(Entity.class)) { - Entity entity = type.getAnnotation(Entity.class); - indexList.addAll(Arrays.asList(entity.indices())); - } - - populateIndex(nitriteMapper, type, indexList, indexSet); - - return indexSet; - } - - Field getField(Class type, String name) { - if (name.contains(NitriteConfig.getFieldSeparator())) { - return getEmbeddedField(type, name); - } else { - // first check declared fields (fix for kotlin properties, ref: issue #54) - // if nothing found and is-recursive then check recursively - Field[] declaredFields = type.getDeclaredFields(); - Field field = null; - for (Field declaredField : declaredFields) { - if (declaredField.getName().equals(name)) { - field = declaredField; - break; - } - } - - if (field == null) { - List fields = getFieldsUpto(type, Object.class); - for (Field recursiveField : fields) { - if (recursiveField.getName().equals(name)) { - field = recursiveField; - break; - } - } - } - if (field == null) { - throw new ValidationException("no such field '" + name + "' for type " + type.getName()); - } - return field; - } - } - - List getFieldsUpto(Class startClass, Class exclusiveParent) { - notNull(startClass, "startClass cannot be null"); - List currentClassFields = new ArrayList<>(Arrays.asList(startClass.getDeclaredFields())); - filterSynthetics(currentClassFields); - Class parentClass = startClass.getSuperclass(); - - if (parentClass != null && !(parentClass.equals(exclusiveParent))) { - List parentClassFields = getFieldsUpto(parentClass, exclusiveParent); - currentClassFields.addAll(parentClassFields); - } - - return currentClassFields; - } - - private static void filterSynthetics(List fields) { - if (fields == null || fields.isEmpty()) return; - Iterator iterator = fields.iterator(); - if (iterator.hasNext()) { - do { - Field f = iterator.next(); - if (f.isSynthetic()) iterator.remove(); - } while (iterator.hasNext()); - } - } - - private void validateCollection() { - if (collection == null) { - throw new ValidationException("repository has not been initialized properly"); - } - } - - private Field getEmbeddedField(Class startingClass, String embeddedField) { - String regex = MessageFormat.format("\\{0}", NitriteConfig.getFieldSeparator()); - String[] split = embeddedField.split(regex, 2); - String key = split[0]; - String remaining = split.length == 2 ? split[1] : ""; - - if (isNullOrEmpty(key)) { - throw new ValidationException("invalid embedded field provided"); - } - - Field field; - try { - field = startingClass.getDeclaredField(key); - } catch (NoSuchFieldException e) { - throw new ValidationException("no such field '" + key + "' for type " + startingClass.getName(), e); - } - - if (!isNullOrEmpty(remaining) || remaining.contains(NitriteConfig.getFieldSeparator())) { - return getEmbeddedField(field.getType(), remaining); - } else { - return field; - } - } - - private void populateIndex(NitriteMapper nitriteMapper, Class type, - List indexList, Set indexSet) { - for (Index index : indexList) { - String[] names = index.value(); - List entityFields = new ArrayList<>(); - - for (String name : names) { - Field field = getField(type, name); - if (field != null) { - entityFields.add(field); - validateObjectIndexField(nitriteMapper, field.getType(), field.getName()); - } - } - - if (entityFields.size() == names.length) { - // validation for all field are success - indexSet.add(index); - } - } - } - - private void validateObjectIndexField(NitriteMapper nitriteMapper, Class fieldType, String field) { - if (!Comparable.class.isAssignableFrom(fieldType) && !fieldType.isPrimitive()) { - throw new IndexingException("cannot index on non comparable field " + field); - } - - if (Iterable.class.isAssignableFrom(fieldType) || fieldType.isArray()) { - throw new IndexingException("indexing on arrays or collections for field " + field - + " are not supported"); - } - - if (fieldType.isPrimitive() - || fieldType == NitriteId.class - || fieldType.isInterface() - || nitriteMapper.isValueType(fieldType) - || Modifier.isAbstract(fieldType.getModifiers())) { - // we will validate the solid class during insertion/update - return; - } - - Document document; - try { - document = skeletonDocument(nitriteMapper, fieldType); - if (document == null || document.size() > 0) { - throw new InvalidOperationException("invalid type specified " + fieldType.getName() + " for indexing"); - } - } catch (Throwable e) { - throw new IndexingException("failed to index field " + fieldType.getName(), e); - } - } - - @SuppressWarnings("rawtypes") - private List findAnnotations(Class annotation, Class type) { - notNull(type, "type cannot be null"); - notNull(annotation, "annotationClass cannot be null"); - List annotations = new ArrayList<>(); - - T t = type.getAnnotation(annotation); - if (t != null) annotations.add(t); - - Class[] interfaces = type.getInterfaces(); - for (Class anInterface : interfaces) { - T ann = anInterface.getAnnotation(annotation); - if (ann != null) annotations.add(ann); - } - - Class parentClass = type.getSuperclass(); - if (parentClass != null && !parentClass.equals(Object.class)) { - List list = findAnnotations(annotation, parentClass); - annotations.addAll(list); - } - - return annotations; - } - /** * Find cursor. * @@ -433,4 +237,10 @@ public Cursor find(Filter filter, FindOptions findOptions, Class type) DocumentCursor documentCursor = collection.find(asObjectFilter(filter), findOptions); return new ObjectCursor<>(nitriteMapper, documentCursor, type); } + + private void validateCollection() { + if (collection == null) { + throw new ValidationException("repository has not been initialized properly"); + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java index 9ef47c0b0..119e7303a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/InheritIndices.java @@ -20,7 +20,7 @@ /** * Indicates that a class should consider all index related - * annotations - @Id@Id, @Index, + * annotations - @Id, @Index, * @Indices from its superclass. * * @author Anindya Chatterjee diff --git a/nitrite/src/main/java/org/dizitart/no2/common/NullOrder.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java similarity index 55% rename from nitrite/src/main/java/org/dizitart/no2/common/NullOrder.java rename to nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java index 4d913964f..6e1ae0210 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/NullOrder.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java @@ -1,40 +1,32 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.common; +package org.dizitart.no2.repository.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** - * An enum to specify where to place `null` values during sort. - * * @author Anindya Chatterjee - * @since 3.1.0 */ -public enum NullOrder { - /** - * Places `null` values at first. - */ - First, - - /** - * Places `null` values at last. - */ - Last, - - /** - * Places `null` values at default location. - */ - Default +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Order { + int value(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/MapMetaData.java b/nitrite/src/main/java/org/dizitart/no2/store/MapMetaData.java new file mode 100644 index 000000000..840ebed23 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/store/MapMetaData.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.store; + +import lombok.Data; +import lombok.Getter; +import org.dizitart.no2.collection.Document; + +import java.util.HashSet; +import java.util.Set; + +import static org.dizitart.no2.common.Constants.TAG_MAP_METADATA; + +/** + * The Map metadata. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +@Data +public class MapMetaData implements MetaData { + @Getter + private Set mapNames; + + /** + * Instantiates a new {@link MapMetaData}. + * + * @param metadata the metadata + */ + public MapMetaData(Document metadata) { + populateInfo(metadata); + } + + @Override + public Document getInfo() { + return Document.createDocument(TAG_MAP_METADATA, mapNames); + } + + @SuppressWarnings("unchecked") + private void populateInfo(Document metadata) { + mapNames = (Set) metadata.get(TAG_MAP_METADATA, Set.class); + if (mapNames == null) { + mapNames = new HashSet<>(); + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java b/nitrite/src/main/java/org/dizitart/no2/store/MetaData.java similarity index 74% rename from nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java rename to nitrite/src/main/java/org/dizitart/no2/store/MetaData.java index 49537b414..24b4ac7b9 100644 --- a/nitrite/src/main/java/org/dizitart/no2/module/ModuleConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/MetaData.java @@ -15,19 +15,21 @@ * */ -package org.dizitart.no2.module; +package org.dizitart.no2.store; + +import org.dizitart.no2.collection.Document; /** - * Represents a {@link NitriteModule} configurator. + * The Metadata interface. * * @author Anindya Chatterjee * @since 4.0 */ -public interface ModuleConfig { +public interface MetaData { /** - * Builds a {@link NitriteModule} form this configuration. + * Gets metadata of the instance. * - * @return the nitrite module + * @return the info */ - NitriteModule build(); + Document getInfo(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java index d8675b8f2..5711fd77f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteMap.java @@ -56,6 +56,11 @@ public interface NitriteMap extends MetadataAware, AutoCloseable { */ void clear(); + /** + * Closes this {@link NitriteMap}. + * */ + void close(); + /** * Gets a {@link RecordStream} view of the values contained in * this map. diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java index f222b866a..615caa40d 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java @@ -66,4 +66,9 @@ public interface NitriteRTree extends AutoCloseable { * @return the size */ long size(); + + /** + * Closes this {@link NitriteRTree} instance. + * */ + void close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java index 851447e69..5ab4989d2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java @@ -18,7 +18,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.index.BoundingBox; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.store.events.StoreEventListener; diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java index 24ca5105d..9f7cb43dc 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreCatalog.java @@ -55,9 +55,16 @@ public StoreCatalog(NitriteStore nitriteStore) { */ public void writeCollectionEntry(String name) { Document document = catalogMap.get(TAG_COLLECTIONS); - if (document == null) document = Document.createDocument(); - document.put(name, true); - catalogMap.put(TAG_COLLECTIONS, document); + if (document == null) { + document = Document.createDocument(); + } + + // parse the document to create collection meta data object + MapMetaData metaData = new MapMetaData(document); + metaData.getMapNames().add(name); + + // convert the meta data object to document and save + catalogMap.put(TAG_COLLECTIONS, metaData.getInfo()); } /** @@ -67,9 +74,16 @@ public void writeCollectionEntry(String name) { */ public void writeRepositoryEntry(String name) { Document document = catalogMap.get(TAG_REPOSITORIES); - if (document == null) document = Document.createDocument(); - document.put(name, true); - catalogMap.put(TAG_REPOSITORIES, document); + if (document == null) { + document = Document.createDocument(); + } + + // parse the document to create collection meta data object + MapMetaData metaData = new MapMetaData(document); + metaData.getMapNames().add(name); + + // convert the meta data object to document and save + catalogMap.put(TAG_REPOSITORIES, metaData.getInfo()); } /** @@ -79,9 +93,15 @@ public void writeRepositoryEntry(String name) { */ public void writeKeyedRepositoryEntries(String name) { Document document = catalogMap.get(TAG_KEYED_REPOSITORIES); - if (document == null) document = Document.createDocument(); - document.put(name, true); - catalogMap.put(TAG_KEYED_REPOSITORIES, document); + if (document == null) { + document = Document.createDocument(); + } + + // parse the document to create collection meta data object + MapMetaData metaData = new MapMetaData(document); + metaData.getMapNames().add(name); + + catalogMap.put(TAG_KEYED_REPOSITORIES, metaData.getInfo()); } /** @@ -93,7 +113,8 @@ public Set getCollectionNames() { Document document = catalogMap.get(TAG_COLLECTIONS); if (document == null) return new HashSet<>(); - return document.getFields(); + MapMetaData metaData = new MapMetaData(document); + return metaData.getMapNames(); } /** @@ -105,7 +126,8 @@ public Set getRepositoryNames() { Document document = catalogMap.get(TAG_REPOSITORIES); if (document == null) return new HashSet<>(); - return document.getFields(); + MapMetaData metaData = new MapMetaData(document); + return metaData.getMapNames(); } /** @@ -117,8 +139,11 @@ public Map> getKeyedRepositoryNames() { Document document = catalogMap.get(TAG_KEYED_REPOSITORIES); if (document == null) return new HashMap<>(); + MapMetaData metaData = new MapMetaData(document); + Set keyedRepositoryNames = metaData.getMapNames(); + Map> resultMap = new HashMap<>(); - for (String field : document.getFields()) { + for (String field : keyedRepositoryNames) { String key = getKeyName(field); String type = getKeyedRepositoryType(field); @@ -146,9 +171,11 @@ public void remove(String name) { String catalogue = entry.getFirst(); Document document = entry.getSecond(); - if (document.containsKey(name)) { - document.remove(name); - catalogMap.put(catalogue, document); + MapMetaData metaData = new MapMetaData(document); + + if (metaData.getMapNames().contains(name)) { + metaData.getMapNames().remove(name); + catalogMap.put(catalogue, metaData.getInfo()); break; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreMetaData.java similarity index 92% rename from nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java rename to nitrite/src/main/java/org/dizitart/no2/store/StoreMetaData.java index 8da309d87..13181bc73 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/DatabaseMetaData.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreMetaData.java @@ -28,18 +28,18 @@ */ @Data @NoArgsConstructor -public class DatabaseMetaData { +public class StoreMetaData implements MetaData { private Long createTime; private String storeVersion; private String nitriteVersion; private Integer schemaVersion; /** - * Instantiates a new {@link DatabaseMetaData}. + * Instantiates a new {@link StoreMetaData}. * * @param document the document */ - public DatabaseMetaData(Document document) { + public StoreMetaData(Document document) { populateInfo(document); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java b/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java index 323091547..f49f27a63 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/StoreModule.java @@ -1,6 +1,6 @@ package org.dizitart.no2.store; -import org.dizitart.no2.module.NitriteModule; +import org.dizitart.no2.common.module.NitriteModule; /** * Represents a nitrite store module to load as a storage engine for the database. diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java index cd1d1c212..8c11f0b85 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java @@ -1,6 +1,5 @@ package org.dizitart.no2.store.memory; -import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.util.Comparables; @@ -24,7 +23,6 @@ */ public class InMemoryMap implements NitriteMap { private final NavigableMap backingMap; - private final NavigableMap nullEntryMap; private final NitriteStore nitriteStore; private final String mapName; @@ -37,7 +35,6 @@ public class InMemoryMap implements NitriteMap { public InMemoryMap(String mapName, NitriteStore nitriteStore) { this.mapName = mapName; this.nitriteStore = nitriteStore; - this.nullEntryMap = new ConcurrentSkipListMap<>(); this.backingMap = new ConcurrentSkipListMap<>((o1, o2) -> Comparables.compare((Comparable) o1, (Comparable) o2)); @@ -45,17 +42,11 @@ public InMemoryMap(String mapName, NitriteStore nitriteStore) { @Override public boolean containsKey(Key key) { - if (key == null) { - return nullEntryMap.containsKey(DBNull.getInstance()); - } return backingMap.containsKey(key); } @Override public Value get(Key key) { - if (key == null) { - return nullEntryMap.get(DBNull.getInstance()); - } return backingMap.get(key); } @@ -67,7 +58,6 @@ public NitriteStore getStore() { @Override public void clear() { backingMap.clear(); - nullEntryMap.clear(); updateLastModifiedTime(); } @@ -78,67 +68,31 @@ public String getName() { @Override public RecordStream values() { - return RecordStream.fromCombined(backingMap.values(), nullEntryMap.values()); + return RecordStream.fromIterable(backingMap.values()); } @Override public Value remove(Key key) { - Value value; - if (key == null) { - value = nullEntryMap.remove(DBNull.getInstance()); - } else { - value = backingMap.remove(key); - } + Value value = backingMap.remove(key); updateLastModifiedTime(); return value; } @Override public RecordStream keys() { - return RecordStream.fromIterable(() -> new Iterator() { - final Iterator keyIterator = backingMap.keySet().iterator(); - final Iterator nullEntryIterator = nullEntryMap.keySet().iterator(); - - @Override - public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return keyIterator.hasNext(); - } - return true; - } - - @Override - public Key next() { - if (nullEntryIterator.hasNext()) { - return null; - } else { - return keyIterator.next(); - } - } - }); + return RecordStream.fromIterable(backingMap.keySet()); } @Override public void put(Key key, Value value) { notNull(value, "value cannot be null"); - if (key == null) { - nullEntryMap.put(DBNull.getInstance(), value); - } else { - Map.Entry firstEntry = backingMap.firstEntry(); - if (firstEntry != null) { - if (!firstEntry.getKey().getClass().equals(key.getClass())) { - return; - } - } - backingMap.put(key, value); - } + backingMap.put(key, value); updateLastModifiedTime(); } @Override public long size() { - return backingMap.size() + nullEntryMap.size(); + return backingMap.size(); } @Override @@ -155,12 +109,12 @@ public Value putIfAbsent(Key key, Value value) { @Override public RecordStream> entries() { - return getStream(backingMap, nullEntryMap); + return getStream(backingMap); } @Override public RecordStream> reversedEntries() { - return getStream(backingMap.descendingMap(), nullEntryMap.descendingMap()); + return getStream(backingMap.descendingMap()); } @Override @@ -197,7 +151,7 @@ public Key floorKey(Key key) { @Override public boolean isEmpty() { - return backingMap.isEmpty() && nullEntryMap.isEmpty(); + return backingMap.isEmpty(); } @Override @@ -211,32 +165,19 @@ public void close() { } - private RecordStream> getStream(NavigableMap primaryMap, - NavigableMap nullEntryMap) { + private RecordStream> getStream(NavigableMap primaryMap) { return RecordStream.fromIterable(() -> new Iterator>() { private final Iterator> entryIterator = primaryMap.entrySet().iterator(); - private final Iterator> nullEntryIterator = - nullEntryMap.entrySet().iterator(); - @Override public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return entryIterator.hasNext(); - } - return true; + return entryIterator.hasNext(); } @Override public Pair next() { - if (nullEntryIterator.hasNext()) { - Map.Entry entry = nullEntryIterator.next(); - return new Pair<>(null, entry.getValue()); - } else { - Map.Entry entry = entryIterator.next(); - return new Pair<>(entry.getKey(), entry.getValue()); - } + Map.Entry entry = entryIterator.next(); + return new Pair<>(entry.getKey(), entry.getValue()); } }); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java index ec54d6cb5..78139b6b2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java @@ -108,7 +108,7 @@ private SpatialKey getKey(Key key, long id) { } @Override - public void close() throws Exception { + public void close() { } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java index ef42e892c..e32ac6c96 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStoreModule.java @@ -2,7 +2,7 @@ import lombok.AccessLevel; import lombok.Setter; -import org.dizitart.no2.module.NitritePlugin; +import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreModule; diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java index 6ad0c4c4e..4ef1e2b52 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java @@ -17,7 +17,7 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java index 6d0029e00..f58a31a71 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java @@ -10,8 +10,8 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.processors.Processor; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.RepositoryOperations; @@ -220,6 +220,6 @@ public NitriteCollection getDocumentCollection() { private void initialize() { NitriteMapper nitriteMapper = nitriteConfig.nitriteMapper(); this.operations = new RepositoryOperations(type, nitriteMapper, backingCollection); - this.operations.createIndexes(); + this.operations.createIndices(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java b/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java index d1c8a2d9e..5986c6cc7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/Transaction.java @@ -61,6 +61,8 @@ public interface Transaction extends AutoCloseable { */ void rollback(); - @Override + /** + * Closes this {@link Transaction}. + * */ void close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java index eafa902fc..8dfdcee7a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java @@ -4,8 +4,8 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.module.NitriteModule; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.store.NitriteStore; /** diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java index 74c3de933..5bb6354e5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java @@ -101,7 +101,7 @@ private SpatialKey getKey(Key key, long id) { } @Override - public void close() throws Exception { + public void close() { map.clear(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/EventTypeTest.java b/nitrite/src/test/java/org/dizitart/no2/EventTypeTest.java deleted file mode 100644 index 4fd93bf08..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/EventTypeTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.events.EventType; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class EventTypeTest { - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testValueOf() { - assertEquals(EventType.valueOf("Insert"), EventType.Insert); - assertEquals(EventType.valueOf("Update"), EventType.Update); - assertEquals(EventType.valueOf("Remove"), EventType.Remove); - assertEquals(EventType.valueOf("IndexStart"), EventType.IndexStart); - assertEquals(EventType.valueOf("IndexEnd"), EventType.IndexEnd); - - assertEquals(EventType.values().length, 5); - } -} diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 865cdd2ad..5e9319d9d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -1,17 +1,18 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2; @@ -22,29 +23,31 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; +import org.dizitart.no2.common.module.PluginManager; import org.dizitart.no2.exceptions.SecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.module.PluginManager; -import org.dizitart.no2.repository.annotations.Index; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.migration.Migration; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreConfig; +import org.dizitart.no2.store.memory.InMemoryConfig; import org.junit.After; import org.junit.Rule; import org.junit.Test; +import java.util.HashSet; import java.util.LinkedHashSet; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.module.NitriteModule.module; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; -/** - * @author Anindya Chatterjee. - */ public class NitriteBuilderTest { private Nitrite db; @@ -52,7 +55,7 @@ public class NitriteBuilderTest { public Retry retry = new Retry(3); @After - public void cleanup() throws Exception { + public void cleanup() { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { @@ -61,7 +64,145 @@ public void cleanup() throws Exception { } @Test - public void testConfig() throws Exception { + public void testConstructor() { + NitriteConfig nitriteConfig = (new NitriteBuilder()).getNitriteConfig(); + assertTrue(nitriteConfig.getMigrations().isEmpty()); + assertFalse(nitriteConfig.configured); + assertEquals(1, nitriteConfig.getSchemaVersion().intValue()); + assertNull(nitriteConfig.getNitriteStore()); + PluginManager pluginManager = nitriteConfig.getPluginManager(); + assertSame(nitriteConfig, pluginManager.getNitriteConfig()); + assertTrue(pluginManager.getIndexerMap().isEmpty()); + } + + @Test + public void testFieldSeparator() { + NitriteBuilder builderResult = Nitrite.builder(); + assertSame(builderResult, builderResult.fieldSeparator("Separator")); + + db = Nitrite.builder() + .fieldSeparator("::") + .openOrCreate(); + + Document document = createDocument("firstName", "John") + .put("colorCodes", new Document[]{createDocument("color", "Red"), createDocument("color", "Green")}) + .put("address", createDocument("street", "ABCD Road")); + + String street = document.get("address::street", String.class); + assertEquals("ABCD Road", street); + + // use default separator, it should return null + street = document.get("address.street", String.class); + assertNull(street); + + assertEquals(document.get("colorCodes::1::color"), "Green"); + } + + @Test + public void testLoadModule() { + NitriteBuilder builderResult = Nitrite.builder(); + NitriteModule nitriteModule = mock(NitriteModule.class); + when(nitriteModule.plugins()).thenReturn(new HashSet()); + assertSame(builderResult, builderResult.loadModule(nitriteModule)); + verify(nitriteModule, times(2)).plugins(); + } + + @Test + public void testAddMigrations() { + NitriteBuilder builderResult = Nitrite.builder(); + assertSame(builderResult, builderResult.addMigrations(null, null, null)); + } + + @Test + public void testAddMigrations2() { + NitriteBuilder builderResult = Nitrite.builder(); + Migration migration = mock(Migration.class); + when(migration.getEndVersion()).thenReturn(1); + when(migration.getStartVersion()).thenReturn(1); + assertSame(builderResult, builderResult.addMigrations(migration, null, null)); + verify(migration).getEndVersion(); + verify(migration).getStartVersion(); + } + + @Test + public void testSchemaVersion() { + NitriteBuilder builderResult = Nitrite.builder(); + assertSame(builderResult, builderResult.schemaVersion(1)); + } + + @Test + public void testOpenOrCreate() { + Nitrite actualOpenOrCreateResult = Nitrite.builder().openOrCreate("janedoe", "iloveyou"); + PluginManager pluginManager = actualOpenOrCreateResult.getConfig().getPluginManager(); + NitriteStore store = actualOpenOrCreateResult.getStore(); + assertFalse(actualOpenOrCreateResult.isClosed()); + assertFalse(store.isClosed()); + assertSame(store, pluginManager.getNitriteStore()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + } + + @Test + public void testOpenOrCreate2() { + Nitrite actualOpenOrCreateResult = Nitrite.builder().openOrCreate(); + assertFalse(actualOpenOrCreateResult.isClosed()); + NitriteConfig config = actualOpenOrCreateResult.getConfig(); + assertTrue(config.configured); + NitriteStore store = actualOpenOrCreateResult.getStore(); + assertTrue(store.getRepositoryRegistry().isEmpty()); + assertFalse(store.isClosed()); + PluginManager pluginManager = config.getPluginManager(); + assertEquals(3, pluginManager.getIndexerMap().size()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + assertTrue(store.getCatalog().getKeyedRepositoryNames().isEmpty()); + assertSame(store, pluginManager.getNitriteStore()); + assertTrue(((InMemoryConfig) store.getStoreConfig()).eventListeners().isEmpty()); + } + + @Test + public void testOpenOrCreate3() { + Nitrite actualOpenOrCreateResult = Nitrite.builder().openOrCreate("janedoe", "iloveyou"); + assertFalse(actualOpenOrCreateResult.isClosed()); + NitriteConfig config = actualOpenOrCreateResult.getConfig(); + assertTrue(config.configured); + NitriteStore store = actualOpenOrCreateResult.getStore(); + assertTrue(store.getRepositoryRegistry().isEmpty()); + assertFalse(store.isClosed()); + PluginManager pluginManager = config.getPluginManager(); + assertEquals(3, pluginManager.getIndexerMap().size()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + assertTrue(store.getCatalog().getKeyedRepositoryNames().isEmpty()); + assertSame(store, pluginManager.getNitriteStore()); + assertTrue(((InMemoryConfig) store.getStoreConfig()).eventListeners().isEmpty()); + } + + @Test + public void testOpenOrCreate4() { + NitriteBuilder builderResult = Nitrite.builder(); + builderResult.openOrCreate("", "iloveyou"); + NitriteConfig nitriteConfig = builderResult.getNitriteConfig(); + PluginManager pluginManager = nitriteConfig.getPluginManager(); + assertEquals(3, pluginManager.getIndexerMap().size()); + NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); + assertSame(nitriteStore, pluginManager.getNitriteStore()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + assertFalse(nitriteStore.isClosed()); + assertTrue(((InMemoryConfig) nitriteStore.getStoreConfig()).eventListeners().isEmpty()); + } + + @Test(expected = SecurityException.class) + public void testOpenOrCreate5() { + NitriteBuilder builderResult = Nitrite.builder(); + builderResult.openOrCreate("", "iloveyou"); + NitriteConfig nitriteConfig = builderResult.getNitriteConfig(); + PluginManager pluginManager = nitriteConfig.getPluginManager(); + NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); + assertFalse(nitriteStore.isClosed()); + assertSame(nitriteStore, pluginManager.getNitriteStore()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + } + + @Test + public void testConfig() { NitriteBuilder nitriteBuilder = Nitrite.builder(); nitriteBuilder.loadModule(module(new CustomIndexer())); @@ -75,7 +216,7 @@ public void testConfig() throws Exception { } @Test - public void testConfigWithFile() throws Exception { + public void testConfigWithFile() { db = Nitrite.builder() .openOrCreate(); StoreConfig storeConfig = db.getStore().getStoreConfig(); @@ -91,7 +232,7 @@ public void testConfigWithFile() throws Exception { } @Test - public void testConfigWithFileNull() throws Exception { + public void testConfigWithFileNull() { db = Nitrite.builder().openOrCreate(); StoreConfig storeConfig = db.getStore().getStoreConfig(); @@ -119,55 +260,12 @@ public void testOpenOrCreateNullUserId() { builder.openOrCreate(null, "abcd"); } - @Test - public void testOpenOrCreate() { - Nitrite actualOpenOrCreateResult = Nitrite.builder().openOrCreate("janedoe", "iloveyou"); - PluginManager pluginManager = actualOpenOrCreateResult.getConfig().getPluginManager(); - NitriteStore store = actualOpenOrCreateResult.getStore(); - assertFalse(actualOpenOrCreateResult.isClosed()); - assertFalse(store.isClosed()); - assertSame(store, pluginManager.getNitriteStore()); - assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.mapper.MappableMapper); - } - - @Test(expected = SecurityException.class) - public void testOpenOrCreate2() { - NitriteBuilder builderResult = Nitrite.builder(); - builderResult.openOrCreate("", "iloveyou"); - NitriteConfig nitriteConfig = builderResult.getNitriteConfig(); - PluginManager pluginManager = nitriteConfig.getPluginManager(); - NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); - assertFalse(nitriteStore.isClosed()); - assertSame(nitriteStore, pluginManager.getNitriteStore()); - assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.mapper.MappableMapper); - } - @Test(expected = SecurityException.class) public void testOpenOrCreateNullPassword() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate("abcd", null); } - @Test - public void testFieldSeparator() { - db = Nitrite.builder() - .fieldSeparator("::") - .openOrCreate(); - - Document document = createDocument("firstName", "John") - .put("colorCodes", new Document[]{createDocument("color", "Red"), createDocument("color", "Green")}) - .put("address", createDocument("street", "ABCD Road")); - - String street = document.get("address::street", String.class); - assertEquals("ABCD Road", street); - - // use default separator, it should return null - street = document.get("address.street", String.class); - assertNull(street); - - assertEquals(document.get("colorCodes::1::color"), "Green"); - } - private static class CustomIndexer implements NitriteIndexer { @Override @@ -230,59 +328,5 @@ public void initialize(NitriteConfig nitriteConfig) { } } - @Index(value = "longValue") - private static class TestObject implements Mappable { - private String stringValue; - private Long longValue; - - public TestObject() { - } - - public TestObject(String stringValue, Long longValue) { - this.longValue = longValue; - this.stringValue = stringValue; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - this.stringValue = document.get("stringValue", String.class); - this.longValue = document.get("longValue", Long.class); - } - } - } - - @Index(value = "longValue") - private static class TestObject2 implements Mappable { - private String stringValue; - private Long longValue; - - public TestObject2() { - } - - public TestObject2(String stringValue, Long longValue) { - this.longValue = longValue; - this.stringValue = stringValue; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - this.stringValue = document.get("stringValue", String.class); - this.longValue = document.get("longValue", Long.class); - } - } - } } + diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java new file mode 100644 index 000000000..e4b4b8281 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2; + +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.module.NitritePlugin; +import org.dizitart.no2.common.module.PluginManager; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.migration.Migration; +import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.memory.InMemoryConfig; +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class NitriteConfigTest { + @Test + public void testConstructor() { + NitriteConfig actualNitriteConfig = new NitriteConfig(); + assertTrue(actualNitriteConfig.getMigrations().isEmpty()); + assertFalse(actualNitriteConfig.configured); + assertEquals(1, actualNitriteConfig.getSchemaVersion().intValue()); + assertNull(actualNitriteConfig.getNitriteStore()); + PluginManager pluginManager = actualNitriteConfig.getPluginManager(); + assertSame(actualNitriteConfig, pluginManager.getNitriteConfig()); + assertTrue(pluginManager.getIndexerMap().isEmpty()); + } + + @Test + public void testFieldSeparator() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new NitriteConfig()).fieldSeparator("Separator"); + } + + @Test + public void testLoadModule() { + NitriteConfig nitriteConfig = new NitriteConfig(); + NitriteModule nitriteModule = mock(NitriteModule.class); + when(nitriteModule.plugins()).thenReturn(new HashSet()); + assertSame(nitriteConfig, nitriteConfig.loadModule(nitriteModule)); + verify(nitriteModule, times(2)).plugins(); + } + + @Test + public void testAddMigration() { + NitriteConfig nitriteConfig = new NitriteConfig(); + assertSame(nitriteConfig, nitriteConfig.addMigration(null)); + } + + @Test + public void testAddMigration2() { + NitriteConfig nitriteConfig = new NitriteConfig(); + Migration migration = mock(Migration.class); + when(migration.getEndVersion()).thenReturn(1); + when(migration.getStartVersion()).thenReturn(1); + assertSame(nitriteConfig, nitriteConfig.addMigration(migration)); + verify(migration).getEndVersion(); + verify(migration).getStartVersion(); + } + + @Test + public void testAddMigration3() { + NitriteConfig nitriteConfig = new NitriteConfig(); + Migration migration = mock(Migration.class); + when(migration.getEndVersion()).thenReturn(4); + when(migration.getStartVersion()).thenReturn(1); + assertSame(nitriteConfig, nitriteConfig.addMigration(migration)); + verify(migration).getEndVersion(); + verify(migration).getStartVersion(); + } + + @Test + public void testAddMigration4() { + NitriteConfig nitriteConfig = new NitriteConfig(); + Migration migration = mock(Migration.class); + when(migration.getEndVersion()).thenReturn(1); + when(migration.getStartVersion()).thenReturn(4); + assertSame(nitriteConfig, nitriteConfig.addMigration(migration)); + verify(migration).getEndVersion(); + verify(migration).getStartVersion(); + } + + @Test + public void testSchemaVersion() { + NitriteConfig nitriteConfig = new NitriteConfig(); + NitriteConfig actualSchemaVersionResult = nitriteConfig.schemaVersion(1); + assertSame(nitriteConfig, actualSchemaVersionResult); + assertEquals(1, actualSchemaVersionResult.getSchemaVersion().intValue()); + } + + @Test + public void testAutoConfigure() { + NitriteConfig nitriteConfig = new NitriteConfig(); + nitriteConfig.autoConfigure(); + PluginManager pluginManager = nitriteConfig.getPluginManager(); + assertEquals(3, pluginManager.getIndexerMap().size()); + NitriteStore nitriteStore = nitriteConfig.getNitriteStore(); + assertSame(nitriteStore, pluginManager.getNitriteStore()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + assertFalse(nitriteStore.isClosed()); + assertTrue(((InMemoryConfig) nitriteStore.getStoreConfig()).eventListeners().isEmpty()); + } + + @Test + public void testFindIndexer() { + assertThrows(IndexingException.class, () -> (new NitriteConfig()).findIndexer("Index Type")); + } + + @Test + public void testNitriteMapper() { + assertNull((new NitriteConfig()).nitriteMapper()); + } + + @Test + public void testGetNitriteStore() { + assertNull((new NitriteConfig()).getNitriteStore()); + } + + @Test + public void testInitialize() { + NitriteConfig nitriteConfig = new NitriteConfig(); + nitriteConfig.initialize(); + assertTrue(nitriteConfig.configured); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java new file mode 100644 index 000000000..5d5f35526 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2; + +import org.dizitart.no2.exceptions.NitriteIOException; +import org.dizitart.no2.exceptions.SecurityException; +import org.junit.Test; + +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +public class NitriteDatabaseTest { + @Test + public void testConstructor() { + NitriteConfig nitriteConfig = new NitriteConfig(); + new NitriteDatabase("janedoe", "iloveyou", nitriteConfig); + assertTrue(nitriteConfig.configured); + } + + @Test + public void testConstructor2() { + assertThrows(SecurityException.class, () -> new NitriteDatabase("", "iloveyou", new NitriteConfig())); + } + + @Test + public void testConstructor3() { + assertThrows(SecurityException.class, () -> new NitriteDatabase("janedoe", "", new NitriteConfig())); + } + + @Test + public void testConstructor4() { + assertThrows(NitriteIOException.class, () -> new NitriteDatabase("janedoe", "iloveyou", null)); + } + + @Test + public void testConstructor5() { + NitriteConfig nitriteConfig = new NitriteConfig(); + new NitriteDatabase(nitriteConfig); + assertTrue(nitriteConfig.configured); + } + + @Test + public void testConstructor6() { + assertThrows(NitriteIOException.class, () -> new NitriteDatabase(null)); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteIdTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteIdTest.java deleted file mode 100644 index 2a516c60d..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteIdTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class NitriteIdTest { - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testLimit() { - NitriteId one = NitriteId.createId(Long.toString(Long.MAX_VALUE)); - NitriteId two = NitriteId.createId(Long.toString(Long.MIN_VALUE)); - assertEquals(one.compareTo(two), 1); - } - - @Test - public void testHashEquals() { - NitriteId one = NitriteId.createId("1"); - NitriteId two = NitriteId.createId("1"); - - assertEquals(one, two); - assertEquals(one.hashCode(), two.hashCode()); - - NitriteId third = NitriteId.createId("2"); - assertNotEquals(one, third); - assertNotEquals(one.hashCode(), third.hashCode()); - } - - @Test - public void testCompare() { - NitriteId one = NitriteId.createId("1"); - NitriteId two = NitriteId.createId("2"); - NitriteId three = NitriteId.createId("3"); - - assertEquals(one.compareTo(two), -1); - assertEquals(three.compareTo(one), 1); - - one = NitriteId.createId("10"); - two = NitriteId.createId("20"); - assertEquals(one.compareTo(two), -1); - - one = NitriteId.newId(); - two = NitriteId.newId(); - - assertFalse(one.compareTo(two) == 0); - } - - @Test(expected = InvalidIdException.class) - public void testToString() { - NitriteId nullId = NitriteId.createId(null); - assertNotEquals(nullId.toString(), ""); - } - - @Test(expected = InvalidIdException.class) - public void testCompareNull() { - NitriteId first = NitriteId.newId(); - NitriteId second = NitriteId.createId(null); - assertEquals(first.compareTo(second), 1); - } -} diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java index 47677200a..7b52816de 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.collection; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; import org.junit.Rule; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/DefaultNitriteCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/DefaultNitriteCollectionTest.java new file mode 100644 index 000000000..ce6d367fc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/DefaultNitriteCollectionTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class DefaultNitriteCollectionTest { + @Test + public void testConstructor() { + InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + DefaultNitriteCollection actualDefaultNitriteCollection = new DefaultNitriteCollection("Name", nitriteMap, + nitriteConfig, new LockService()); + assertEquals("Name", actualDefaultNitriteCollection.getName()); + assertTrue(actualDefaultNitriteCollection.nitriteMap instanceof InMemoryMap); + assertEquals(0L, actualDefaultNitriteCollection.size()); + assertFalse(actualDefaultNitriteCollection.isDropped()); + verify(nitriteConfig, times(2)).getNitriteStore(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/DocumentTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/DocumentTest.java similarity index 94% rename from nitrite/src/test/java/org/dizitart/no2/DocumentTest.java rename to nitrite/src/test/java/org/dizitart/no2/collection/DocumentTest.java index adef2dae3..772d71d73 100644 --- a/nitrite/src/test/java/org/dizitart/no2/DocumentTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/DocumentTest.java @@ -1,47 +1,48 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.collection; -import org.dizitart.no2.collection.Document; +import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.ValidationException; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import java.io.*; import java.util.*; -import static org.dizitart.no2.TestUtil.parse; +import static org.dizitart.no2.integration.TestUtil.parse; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.Constants.DOC_ID; import static org.dizitart.no2.common.util.Iterables.listOf; import static org.junit.Assert.*; -/** - * @author Anindya Chatterjee - */ public class DocumentTest { private Document doc; - @Rule - public Retry retry = new Retry(3); + @Test + public void testCreateDocument() { + assertTrue(((NitriteDocument) Document.createDocument()).isEmpty()); + assertEquals(1, Document.createDocument("Key", "Value").size()); + assertTrue(((NitriteDocument) Document.createDocument(new HashMap<>(1))).isEmpty()); + } @Before public void setUp() { @@ -288,3 +289,4 @@ public void testDeepRemove() { assertNull(doc.get("location.address")); } } + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/FindOptionsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/FindOptionsTest.java new file mode 100644 index 000000000..db71d7ff3 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/FindOptionsTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection; + +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.SortableFields; +import org.junit.Test; + +import java.text.Collator; +import java.text.RuleBasedCollator; + +import static org.junit.Assert.*; + +public class FindOptionsTest { + @Test + public void testConstructor() { + FindOptions actualFindOptions = new FindOptions(); + actualFindOptions.limit(1L); + actualFindOptions.skip(1L); + Collator collatorResult = actualFindOptions.collator(); + assertTrue(collatorResult instanceof RuleBasedCollator); + assertEquals(1L, actualFindOptions.skip().longValue()); + assertEquals(1L, actualFindOptions.limit().longValue()); + assertNull(actualFindOptions.orderBy()); + assertEquals(0, collatorResult.getDecomposition()); + assertEquals( + "='​'=‌=‍=‎=‏=\u0000 =\u0001 =\u0002 =\u0003 =\u0004=\u0005 =\u0006 =\u0007 =\b ='\t'='\u000b' =\u000e=\u000f ='\u0010' =\u0011 =\u0012 =\u0013=\u0014 =\u0015 =\u0016 =\u0017 =\u0018=\u0019 =\u001a =\u001b =\u001c =\u001d=\u001e =\u001f" + + " ==€ = =‚ =ƒ =„ =…=† =‡ =ˆ =‰ =Š =‹=Œ = =Ž = = =‘=’ =“ =” =• =– =—=˜ =™ =š =› =œ ==ž =Ÿ;' ';' ';'" + + " ';' ';' ';' ';' ';' ';' ';' ';' ';' ';' ';' ';'';'\r' ;'\t' ;'\n" + + "';'\f';'\u000b';́;̀;̆;̂;̌;̊;̍;̈;̋;̃;̇;̄;̷;̧;̨;̣;̲;̅;̉;̎;̏;̐;̑;̒;̓;̔;̕;̖;̗;̘;̙;̚;̛;̜;̝;̞;̟;̠;̡;̢;̤;̥;̦;̩;̪;" + + "̫;̬;̭;̮;̯;̰;̱;̳;̴;̵;̶;̸;̹;̺;̻;̼;̽;̾;̿;͂;̈́;ͅ;͠;͡;҃;҄;҅;҆;⃐;⃑;⃒;⃓;⃔;⃕;⃖;⃗;⃘;⃙;⃚;⃛;⃜;⃝;⃞;⃟;⃠;⃡,'-';­;‐;" + + "‑;‒;–;—;―;−<'_'<¯<','<';'<':'<'!'<¡<'?'<¿<'/'<'.'<´<'`'<'^'<¨<'~'<·<¸<'''<'\"'<«<»<'('<')'<'['<']'<'{" + + "'<'}'<§<¶<©<®<'@'<¤<฿<¢<₡<₢<'$'<₫<€<₣<₤<₥<₦<₧<£<₨<₪<₩<¥<'*'<'\\'<'&'<'#'<'%'<'+'<±<÷<×<'<'<'='<'>'<¬<" + + "'|'<¦<°<µ<0<1<2<3<4<5<6<7<8<9<¼<½<¾())); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals19() { + FindPlan findPlan = new FindPlan(); + findPlan.setIndexScanOrder(new HashMap(1)); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals2() { + FindPlan findPlan = new FindPlan(); + assertTrue(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals20() { + FindPlan findPlan = new FindPlan(); + + FindPlan findPlan1 = new FindPlan(); + findPlan1.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + assertFalse(findPlan.equals(findPlan1)); + } + + @Test + public void testEquals21() { + FindPlan findPlan = new FindPlan(); + + FindPlan findPlan1 = new FindPlan(); + findPlan1.setIndexScanFilter(new IndexScanFilter(new ArrayList())); + assertFalse(findPlan.equals(findPlan1)); + } + + @Test + public void testEquals3() { + FindPlan findPlan = new FindPlan(); + findPlan.setSubPlans(null); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals4() { + FindPlan findPlan = new FindPlan(); + findPlan.setLimit(0L); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals5() { + FindPlan findPlan = new FindPlan(); + findPlan.setCollectionScanFilter(mock(Filter.class)); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals6() { + FindPlan findPlan = new FindPlan(); + findPlan.setSkip(0L); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals7() { + FindPlan findPlan = new FindPlan(); + findPlan.setBlockingSortOrder(null); + assertFalse(findPlan.equals(new FindPlan())); + } + + @Test + public void testEquals8() { + FindPlan findPlan = new FindPlan(); + + FindPlan findPlan1 = new FindPlan(); + findPlan1.setSubPlans(null); + assertFalse(findPlan.equals(findPlan1)); + } + + @Test + public void testEquals9() { + FindPlan findPlan = new FindPlan(); + + FindPlan findPlan1 = new FindPlan(); + findPlan1.setLimit(0L); + assertFalse(findPlan.equals(findPlan1)); + } + + @Test + public void testHashCode() { + assertEquals(157971442, (new FindPlan()).hashCode()); + } + + @Test + public void testHashCode10() { + ArrayList findPlanList = new ArrayList(); + findPlanList.add(new FindPlan()); + + FindPlan findPlan = new FindPlan(); + findPlan.setSubPlans(findPlanList); + assertEquals(315942914, findPlan.hashCode()); + } + + @Test + public void testHashCode11() { + ArrayList findPlanList = new ArrayList(); + findPlanList.add(new FindPlan()); + findPlanList.add(new FindPlan()); + + FindPlan findPlan = new FindPlan(); + findPlan.setSubPlans(findPlanList); + assertEquals(918091250, findPlan.hashCode()); + } + + @Test + public void testHashCode2() { + FindPlan findPlan = new FindPlan(); + findPlan.setSubPlans(null); + assertEquals(157971484, findPlan.hashCode()); + } + + @Test + public void testHashCode3() { + FindPlan findPlan = new FindPlan(); + findPlan.setLimit(0L); + assertEquals(1549271361, findPlan.hashCode()); + } + + @Test + public void testHashCode4() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + FindPlan findPlan = new FindPlan(); + findPlan.setCollectionScanFilter(mock(Filter.class)); + findPlan.hashCode(); + } + + @Test + public void testHashCode5() { + FindPlan findPlan = new FindPlan(); + findPlan.setSkip(0L); + assertEquals(640288039, findPlan.hashCode()); + } + + @Test + public void testHashCode6() { + FindPlan findPlan = new FindPlan(); + findPlan.setBlockingSortOrder(null); + assertEquals(158117644, findPlan.hashCode()); + } + + @Test + public void testHashCode7() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + FindPlan findPlan = new FindPlan(); + findPlan.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + findPlan.hashCode(); + } + + @Test + public void testHashCode8() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + FindPlan findPlan = new FindPlan(); + findPlan.setIndexScanFilter(new IndexScanFilter(new ArrayList())); + findPlan.hashCode(); + } + + @Test + public void testHashCode9() { + FindPlan findPlan = new FindPlan(); + findPlan.setIndexScanOrder(new HashMap(1)); + assertEquals(-363075081, findPlan.hashCode()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java index 8d75ca0bc..37ec3a5dd 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java @@ -17,13 +17,13 @@ package org.dizitart.no2.collection; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.meta.Attributes; import org.junit.After; import org.junit.Rule; import org.junit.Test; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.junit.Assert.assertEquals; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java index 49d8340a5..6b5d90999 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java @@ -1,10 +1,12 @@ package org.dizitart.no2.collection; import com.fasterxml.jackson.databind.introspect.AnnotatedMethodMap; +import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; import org.junit.Test; +import java.util.ArrayList; import java.util.Set; import static org.junit.Assert.*; @@ -26,22 +28,49 @@ public void testPut2() { @Test public void testGet() { Class type = Object.class; - assertNull((new NitriteDocument()).get(null, type)); + assertNull((new NitriteDocument()).get(null, type)); + assertNull((new NitriteDocument()).get("Field")); + assertNull((new NitriteDocument()).get(null)); + assertNull((new NitriteDocument()).get("java.io.Serializable")); } @Test public void testGet2() { - Class type = Object.class; - assertNull((new NitriteDocument()).get("key", type)); + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("java.io.Serializable", "Value"); + assertEquals("Value", nitriteDocument.get("java.io.Serializable")); } @Test public void testGet3() { - assertNull((new NitriteDocument()).get("key")); + NitriteDocument nitriteDocument = new NitriteDocument(); + assertNull(nitriteDocument.get("Field", Object.class)); + } + + @Test + public void testGet4() { + NitriteDocument nitriteDocument = new NitriteDocument(); + assertNull(nitriteDocument.get(null, Object.class)); + } + + @Test + public void testGetId() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.putIfAbsent("_id", "42"); + assertEquals("42", nitriteDocument.getId().getIdValue()); + } + + @Test + public void testGetId2() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("_id", 42); + assertThrows(InvalidIdException.class, nitriteDocument::getId); } @Test public void testGetFields() { + assertTrue((new NitriteDocument()).getFields().isEmpty()); + NitriteDocument nitriteDocument = new NitriteDocument(); nitriteDocument.put("foo", "foo"); Set actualFields = nitriteDocument.getFields(); @@ -65,7 +94,25 @@ public void testGetFields3() { @Test public void testGetFields4() { - assertEquals(0, (new NitriteDocument()).getFields().size()); + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.putIfAbsent("", new NitriteDocument()); + assertTrue(nitriteDocument.getFields().isEmpty()); + } + + @Test + public void testGetFields5() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.putIfAbsent("", new ArrayList()); + assertTrue(nitriteDocument.getFields().isEmpty()); + } + + @Test + public void testGetFields6() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("java.io.Serializable", "Value"); + Set actualFields = nitriteDocument.getFields(); + assertEquals(1, actualFields.size()); + assertTrue(actualFields.contains("java.io.Serializable")); } @Test @@ -73,11 +120,32 @@ public void testHasId() { assertFalse((new NitriteDocument()).hasId()); } + @Test + public void testHasId2() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.putIfAbsent("_id", "42"); + assertTrue(nitriteDocument.hasId()); + } + @Test public void testClone() { assertEquals(0, (new NitriteDocument()).clone().size()); } + @Test + public void testClone2() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", "Value"); + assertEquals(1, nitriteDocument.clone().size()); + } + + @Test + public void testClone3() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", new NitriteDocument()); + assertEquals(1, nitriteDocument.clone().size()); + } + @Test public void testContainsKey() { assertFalse((new NitriteDocument()).containsKey("key")); @@ -85,20 +153,80 @@ public void testContainsKey() { @Test public void testEquals() { - NitriteDocument nitriteDocument = new NitriteDocument(); - nitriteDocument.put("foo", "foo"); - assertFalse(nitriteDocument.equals(new NitriteDocument())); + assertFalse((new NitriteDocument()).equals("Other")); } @Test public void testEquals2() { - assertFalse((new NitriteDocument()).equals("other")); + NitriteDocument nitriteDocument = new NitriteDocument(); + assertTrue(nitriteDocument.equals(new NitriteDocument())); } @Test public void testEquals3() { NitriteDocument nitriteDocument = new NitriteDocument(); - assertTrue(nitriteDocument.equals(new NitriteDocument())); + nitriteDocument.put("Field", "Value"); + assertFalse(nitriteDocument.equals(new NitriteDocument())); + } + + @Test + public void testEquals4() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", "Value"); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.put("Field", "Value"); + assertTrue(nitriteDocument.equals(nitriteDocument1)); + } + + @Test + public void testEquals5() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", "Value"); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.putIfAbsent("foo", "42"); + assertFalse(nitriteDocument.equals(nitriteDocument1)); + } + + @Test + public void testEquals6() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", null); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.put("Field", "Value"); + assertFalse(nitriteDocument.equals(nitriteDocument1)); + } + + @Test + public void testEquals7() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", new NitriteDocument()); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.put("Field", "Value"); + assertFalse(nitriteDocument.equals(nitriteDocument1)); + } + + @Test + public void testEquals8() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", null); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.putIfAbsent("foo", "42"); + assertFalse(nitriteDocument.equals(nitriteDocument1)); + } + + @Test + public void testEquals9() { + NitriteDocument nitriteDocument = new NitriteDocument(); + nitriteDocument.put("Field", null); + + NitriteDocument nitriteDocument1 = new NitriteDocument(); + nitriteDocument1.put("Field", null); + assertTrue(nitriteDocument.equals(nitriteDocument1)); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteIdTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteIdTest.java index a12bcc714..6ff816554 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteIdTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteIdTest.java @@ -6,9 +6,69 @@ import static org.junit.Assert.*; public class NitriteIdTest { + @Test + public void testLimit() { + NitriteId one = NitriteId.createId(Long.toString(Long.MAX_VALUE)); + NitriteId two = NitriteId.createId(Long.toString(Long.MIN_VALUE)); + assertEquals(one.compareTo(two), 1); + } + + @Test + public void testHashEquals() { + NitriteId one = NitriteId.createId("1"); + NitriteId two = NitriteId.createId("1"); + + assertEquals(one, two); + assertEquals(one.hashCode(), two.hashCode()); + + NitriteId third = NitriteId.createId("2"); + assertNotEquals(one, third); + assertNotEquals(one.hashCode(), third.hashCode()); + } + + @Test + public void testCompare() { + NitriteId one = NitriteId.createId("1"); + NitriteId two = NitriteId.createId("2"); + NitriteId three = NitriteId.createId("3"); + + assertEquals(one.compareTo(two), -1); + assertEquals(three.compareTo(one), 1); + + one = NitriteId.createId("10"); + two = NitriteId.createId("20"); + assertEquals(one.compareTo(two), -1); + + one = NitriteId.newId(); + two = NitriteId.newId(); + + assertFalse(one.compareTo(two) == 0); + } + + @Test(expected = InvalidIdException.class) + public void testToString() { + NitriteId nullId = NitriteId.createId(null); + assertNotEquals(nullId.toString(), ""); + } + + @Test(expected = InvalidIdException.class) + public void testCompareNull() { + NitriteId first = NitriteId.newId(); + NitriteId second = NitriteId.createId(null); + assertEquals(first.compareTo(second), 1); + } + + @Test + public void testCreateId() { + assertEquals("42", NitriteId.createId("42").getIdValue()); + assertThrows(InvalidIdException.class, () -> NitriteId.createId(null)); + assertThrows(InvalidIdException.class, () -> NitriteId.createId("Value")); + } + @Test public void testValidId() { - assertThrows(InvalidIdException.class, () -> NitriteId.validId("value")); + assertThrows(InvalidIdException.class, () -> NitriteId.validId("Value")); + assertThrows(InvalidIdException.class, () -> NitriteId.validId(null)); assertTrue(NitriteId.validId(42)); } @@ -17,5 +77,28 @@ public void testCompareTo() { NitriteId newIdResult = NitriteId.newId(); assertEquals(-1, newIdResult.compareTo(NitriteId.newId())); } + + @Test + public void testCompareTo2() { + NitriteId newIdResult = NitriteId.newId(); + assertEquals(1, newIdResult.compareTo(NitriteId.createId("42"))); + } + + @Test + public void testEquals() { + assertFalse(NitriteId.newId().equals("42")); + } + + @Test + public void testEquals2() { + NitriteId newIdResult = NitriteId.newId(); + assertFalse(newIdResult.equals(NitriteId.newId())); + } + + @Test + public void testEquals3() { + NitriteId createIdResult = NitriteId.createId("42"); + assertTrue(createIdResult.equals(NitriteId.createId("42"))); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/SnowflakeIdGeneratorTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/SnowflakeIdGeneratorTest.java new file mode 100644 index 000000000..5c0273aa4 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/SnowflakeIdGeneratorTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class SnowflakeIdGeneratorTest { + + @Test + public void testTillNextMillis() { + assertTrue((new SnowflakeIdGenerator()).tillNextMillis(1L) > 1); + } + + @Test + public void testGetId() { + assertTrue((new SnowflakeIdGenerator()).getId() != 0); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/CollectionOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/CollectionOperationsTest.java new file mode 100644 index 000000000..7200ec7fc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/CollectionOperationsTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class CollectionOperationsTest { + @Test + public void testConstructor() { + InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + assertEquals(0L, (new CollectionOperations("Collection Name", nitriteMap, nitriteConfig, null)).getSize()); + verify(nitriteConfig).getNitriteStore(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java new file mode 100644 index 000000000..5efb43f35 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndexer; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.mockito.Mockito.*; + +public class DocumentIndexWriterTest { + @Test + public void testWriteIndexEntry() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + doNothing().when(nitriteIndexer).writeIndexEntry(any(), any(), any()); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).writeIndexEntry(createDocument("a", "b")); + verify(indexManager).getIndexDescriptors(); + } + + @Test + public void testRemoveIndexEntry() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + doNothing().when(nitriteIndexer).removeIndexEntry(any(), any(), any()); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).removeIndexEntry(createDocument("a", "b")); + verify(indexManager).getIndexDescriptors(); + } + + @Test + public void testUpdateIndexEntry() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + doNothing().when(nitriteIndexer).removeIndexEntry(any(), any(), any()); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).updateIndexEntry(createDocument("x", "y"), + createDocument("a", "b")); + verify(indexManager).getIndexDescriptors(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java new file mode 100644 index 000000000..e2b5da575 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class FindOptimizerTest { + @Test + public void testOptimize() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + FindOptions findOptions = new FindOptions(); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList<>()); + assertNull(actualOptimizeResult.getSkip()); + assertNull(actualOptimizeResult.getLimit()); + assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); + } + + @Test + public void testOptimize2() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + findOptimizer.optimize(filter, null, new ArrayList<>()); + } + + @Test + public void testOptimize3() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + FindOptions findOptions = FindOptions.orderBy("Field Name", SortOrder.Ascending); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList<>()); + assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); + assertNull(actualOptimizeResult.getSkip()); + assertNull(actualOptimizeResult.getLimit()); + } + + @Test + public void testOptimize4() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + FindOptions findOptions = new FindOptions(); + + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, indexDescriptorList); + assertNull(actualOptimizeResult.getSkip()); + assertNull(actualOptimizeResult.getLimit()); + assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); + } + + @Test + public void testOptimize5() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + FindOptions findOptions = new FindOptions(); + + Fields fields = new Fields(); + fields.addField("Field"); + IndexDescriptor e = new IndexDescriptor("Index Type", fields, "Collection Name"); + + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(e); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, indexDescriptorList); + assertNull(actualOptimizeResult.getSkip()); + assertNull(actualOptimizeResult.getLimit()); + assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexManagerTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexManagerTest.java new file mode 100644 index 000000000..3769b47fd --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexManagerTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.mockito.Mockito.*; + +public class IndexManagerTest { + @Test + public void testConstructor() { + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + new IndexManager("Collection Name", nitriteConfig); + verify(nitriteConfig).getNitriteStore(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java new file mode 100644 index 000000000..19347cacd --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndexer; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class IndexOperationsTest { + @Test + public void testCreateIndex() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.findExactIndexDescriptor(any())) + .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertThrows(IndexingException.class, () -> indexOperations.createIndex(new Fields(), "Index Type")); + verify(indexManager).findExactIndexDescriptor(any()); + } + + @Test + public void testCreateIndex2() { + IndexManager indexManager = mock(IndexManager.class); + doNothing().when(indexManager).beginIndexing(any()); + doNothing().when(indexManager).endIndexing(any()); + when(indexManager.createIndexDescriptor(any(), anyString())) + .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + when(indexManager.findExactIndexDescriptor(any())).thenReturn(null); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + indexOperations.createIndex(new Fields(), "Index Type"); + verify(indexManager).endIndexing(any()); + verify(indexManager).createIndexDescriptor(any(), anyString()); + verify(indexManager).findExactIndexDescriptor(any()); + verify(indexManager).beginIndexing(any()); + } + + @Test + public void testBuildIndex() { + IndexManager indexManager = mock(IndexManager.class); + doNothing().when(indexManager).beginIndexing(any()); + doNothing().when(indexManager).endIndexing(any()); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + indexOperations.buildIndex(new IndexDescriptor("Index Type", new Fields(), "Collection Name"), true); + verify(indexManager).endIndexing(any()); + verify(indexManager).beginIndexing(any()); + } + + @Test + public void testDropIndex() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.findExactIndexDescriptor(any())) + .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + indexOperations.dropIndex(new Fields()); + verify(indexManager).findExactIndexDescriptor(any()); + } + + @Test + public void testDropIndex2() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.findExactIndexDescriptor(any())).thenReturn(null); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertThrows(IndexingException.class, () -> indexOperations.dropIndex(new Fields())); + verify(indexManager).findExactIndexDescriptor(any()); + } + + @Test + public void testDropIndex3() { + IndexDescriptor indexDescriptor = mock(IndexDescriptor.class); + when(indexDescriptor.getIndexType()).thenReturn("foo"); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.findExactIndexDescriptor(any())).thenReturn(indexDescriptor); + + NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); + + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + indexOperations.dropIndex(new Fields()); + verify(indexDescriptor).getIndexType(); + verify(indexManager).findExactIndexDescriptor(any()); + } + + @Test(expected = IndexingException.class) + public void testDropAllIndices() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name")); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + NitriteConfig nitriteConfig = new NitriteConfig(); + (new IndexOperations(nitriteConfig, new InMemoryMap<>("Map Name", null), null, indexManager)) + .dropAllIndices(); + verify(indexManager).getIndexDescriptors(); + } + + @Test(expected = IndexingException.class) + public void testDropAllIndices2() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name")); + indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("b"), "Collection Name")); + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + NitriteConfig nitriteConfig = new NitriteConfig(); + (new IndexOperations(nitriteConfig, new InMemoryMap<>("Map Name", null), null, indexManager)) + .dropAllIndices(); + verify(indexManager).getIndexDescriptors(); + } + + @Test + public void testIsIndexing() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.hasIndexDescriptor(any())).thenReturn(true); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertFalse(indexOperations.isIndexing(new Fields())); + verify(indexManager).hasIndexDescriptor(any()); + } + + @Test + public void testIsIndexing2() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.hasIndexDescriptor(any())).thenReturn(false); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertFalse(indexOperations.isIndexing(new Fields())); + verify(indexManager).hasIndexDescriptor(any()); + } + + @Test + public void testHasIndexEntry() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.hasIndexDescriptor(any())).thenReturn(true); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertTrue(indexOperations.hasIndexEntry(new Fields())); + verify(indexManager).hasIndexDescriptor(any()); + } + + @Test + public void testListIndexes() { + IndexManager indexManager = mock(IndexManager.class); + ArrayList indexDescriptorList = new ArrayList<>(); + when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); + NitriteConfig nitriteConfig = new NitriteConfig(); + Collection actualListIndexesResult = (new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager)).listIndexes(); + assertSame(indexDescriptorList, actualListIndexesResult); + assertTrue(actualListIndexesResult.isEmpty()); + verify(indexManager).getIndexDescriptors(); + } + + @Test + public void testFindIndexDescriptor() { + IndexManager indexManager = mock(IndexManager.class); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + when(indexManager.findExactIndexDescriptor(any())).thenReturn(indexDescriptor); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertSame(indexDescriptor, indexOperations.findIndexDescriptor(new Fields())); + verify(indexManager).findExactIndexDescriptor(any()); + } + + @Test + public void testGetBuildFlag() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, null); + indexOperations.getBuildFlag(new Fields()); + } + + @Test + public void testShouldRebuildIndex() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.isDirtyIndex(any())).thenReturn(true); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertTrue(indexOperations.shouldRebuildIndex(new Fields())); + verify(indexManager).isDirtyIndex(any()); + } + + @Test + public void testShouldRebuildIndex2() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.isDirtyIndex(any())).thenReturn(false); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + assertFalse(indexOperations.shouldRebuildIndex(new Fields())); + verify(indexManager).isDirtyIndex(any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java new file mode 100644 index 000000000..af092f3c5 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.collection.operation; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class ReadOperationsTest { + @Test + public void testFind() { + IndexManager indexManager = mock(IndexManager.class); + when(indexManager.getIndexDescriptors()).thenReturn(new ArrayList<>()); + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, indexManager); + NitriteConfig nitriteConfig1 = new NitriteConfig(); + InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); + ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig1, nitriteMap, + new ProcessorChain()); + Filter filter = mock(Filter.class); + assertTrue(readOperations.find(filter, new FindOptions()).toList().isEmpty()); + verify(indexManager).getIndexDescriptors(); + } + + @Test + public void testGetById() { + NitriteConfig nitriteConfig = new NitriteConfig(); + IndexOperations indexOperations = new IndexOperations(nitriteConfig, + new InMemoryMap<>("Map Name", null), null, null); + NitriteConfig nitriteConfig1 = new NitriteConfig(); + InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); + ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig1, nitriteMap, + new ProcessorChain()); + assertNull(readOperations.getById(NitriteId.newId())); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/FieldValuesTest.java b/nitrite/src/test/java/org/dizitart/no2/common/FieldValuesTest.java new file mode 100644 index 000000000..96c42cfbb --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/FieldValuesTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.*; + +public class FieldValuesTest { + @Test + public void testConstructor() { + assertEquals("FieldValues(nitriteId=null, fields=[], values=[])", (new FieldValues()).toString()); + } + + @Test + public void testGet() { + FieldValues fieldValues = new FieldValues(); + fieldValues.setFields(new Fields()); + assertNull(fieldValues.get("Field")); + } + + @Test + public void testGet2() { + Fields fields = new Fields(); + fields.addField("Field"); + + FieldValues fieldValues = new FieldValues(); + fieldValues.setFields(fields); + assertNull(fieldValues.get("Field")); + } + + @Test + public void testGetFields() { + FieldValues fieldValues = new FieldValues(); + assertEquals("[]", fieldValues.getFields().toString()); + assertEquals("FieldValues(nitriteId=null, fields=[], values=[])", fieldValues.toString()); + } + + @Test + public void testGetFields2() { + FieldValues fieldValues = new FieldValues(); + Fields fields = new Fields(); + fieldValues.setFields(fields); + assertSame(fields, fieldValues.getFields()); + } + + @Test + public void testGetFields3() { + ArrayList> pairList = new ArrayList<>(); + pairList.add(new Pair<>()); + + FieldValues fieldValues = new FieldValues(); + fieldValues.setValues(pairList); + fieldValues.getFields(); + assertEquals("FieldValues(nitriteId=null, fields=[], values=[Pair(first=null, second=null)])", + fieldValues.toString()); + } + + @Test + public void testGetFields4() { + ArrayList> pairList = new ArrayList<>(); + pairList.add(Pair.pair("First", "Second")); + + FieldValues fieldValues = new FieldValues(); + fieldValues.setValues(pairList); + fieldValues.getFields(); + assertEquals("FieldValues(nitriteId=null, fields=[First], values=[Pair(first=First, second=Second)])", + fieldValues.toString()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/FieldsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/FieldsTest.java new file mode 100644 index 000000000..34887c467 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/FieldsTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.*; + +public class FieldsTest { + @Test + public void testConstructor() { + assertEquals("[]", (new Fields()).toString()); + } + + @Test + public void testWithNames() { + Fields actualWithNamesResult = Fields.withNames("Fields"); + assertEquals("[Fields]", actualWithNamesResult.toString()); + List stringList = actualWithNamesResult.fieldNames; + assertEquals(1, stringList.size()); + assertEquals("Fields", stringList.get(0)); + } + + @Test + public void testAddField() { + Fields fields = new Fields(); + assertSame(fields, fields.addField("Field")); + } + + @Test + public void testGetFieldNames() { + assertTrue((new Fields()).getFieldNames().isEmpty()); + } + + @Test + public void testStartsWith() { + Fields fields = new Fields(); + assertTrue(fields.startsWith(new Fields())); + } + + @Test + public void testStartsWith2() { + assertFalse((new Fields()).startsWith(null)); + } + + @Test + public void testStartsWith3() { + Fields fields = new Fields(); + assertFalse(fields.startsWith(Fields.withNames("foo", "foo", "foo"))); + } + + @Test + public void testGetEncodedName() { + assertEquals("", (new Fields()).getEncodedName()); + } + + @Test + public void testCompareTo() { + Fields fields = new Fields(); + assertEquals(0, fields.compareTo(new Fields())); + } + + @Test + public void testCompareTo2() { + Fields withNamesResult = Fields.withNames("foo", "foo", "foo"); + assertEquals(1, withNamesResult.compareTo(new Fields())); + } + + @Test + public void testCompareTo3() { + assertEquals(1, (new Fields()).compareTo(null)); + } + + @Test + public void testCompareTo4() { + Fields fields = new Fields(); + fields.setFieldNames(null); + assertEquals(1, fields.compareTo(null)); + } + + @Test + public void testCompareTo5() { + Fields withNamesResult = Fields.withNames("foo", "foo", "foo"); + assertEquals(0, withNamesResult.compareTo(Fields.withNames("foo", "foo", "foo"))); + } + + @Test + public void testCompareTo6() { + Fields withNamesResult = Fields.withNames("Fields", "foo", "foo"); + assertEquals(-32, withNamesResult.compareTo(Fields.withNames("foo", "foo", "foo"))); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/LookupTest.java b/nitrite/src/test/java/org/dizitart/no2/common/LookupTest.java new file mode 100644 index 000000000..e290fc9f1 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/LookupTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class LookupTest { + @Test + public void testCanEqual() { + assertFalse((new Lookup()).canEqual("Other")); + } + + @Test + public void testCanEqual2() { + Lookup lookup = new Lookup(); + assertTrue(lookup.canEqual(new Lookup())); + } + + @Test + public void testConstructor() { + Lookup actualLookup = new Lookup(); + actualLookup.setForeignField("Foreign Field"); + actualLookup.setLocalField("Local Field"); + actualLookup.setTargetField("Target Field"); + assertEquals("Foreign Field", actualLookup.getForeignField()); + assertEquals("Local Field", actualLookup.getLocalField()); + assertEquals("Target Field", actualLookup.getTargetField()); + } + + @Test + public void testEquals() { + assertFalse((new Lookup()).equals("42")); + } + + @Test + public void testEquals10() { + Lookup lookup = new Lookup(); + lookup.setLocalField("Local Field"); + + Lookup lookup1 = new Lookup(); + lookup1.setLocalField("Local Field"); + assertTrue(lookup.equals(lookup1)); + } + + @Test + public void testEquals11() { + Lookup lookup = new Lookup(); + lookup.setTargetField("Target Field"); + + Lookup lookup1 = new Lookup(); + lookup1.setTargetField("Target Field"); + assertTrue(lookup.equals(lookup1)); + } + + @Test + public void testEquals2() { + Lookup lookup = new Lookup(); + assertTrue(lookup.equals(new Lookup())); + } + + @Test + public void testEquals3() { + Lookup lookup = new Lookup(); + lookup.setForeignField("Foreign Field"); + assertFalse(lookup.equals(new Lookup())); + } + + @Test + public void testEquals4() { + Lookup lookup = new Lookup(); + lookup.setLocalField("Local Field"); + assertFalse(lookup.equals(new Lookup())); + } + + @Test + public void testEquals5() { + Lookup lookup = new Lookup(); + lookup.setTargetField("Target Field"); + assertFalse(lookup.equals(new Lookup())); + } + + @Test + public void testEquals6() { + Lookup lookup = new Lookup(); + + Lookup lookup1 = new Lookup(); + lookup1.setForeignField("Foreign Field"); + assertFalse(lookup.equals(lookup1)); + } + + @Test + public void testEquals7() { + Lookup lookup = new Lookup(); + + Lookup lookup1 = new Lookup(); + lookup1.setLocalField("Local Field"); + assertFalse(lookup.equals(lookup1)); + } + + @Test + public void testEquals8() { + Lookup lookup = new Lookup(); + + Lookup lookup1 = new Lookup(); + lookup1.setTargetField("Target Field"); + assertFalse(lookup.equals(lookup1)); + } + + @Test + public void testEquals9() { + Lookup lookup = new Lookup(); + lookup.setForeignField("Foreign Field"); + + Lookup lookup1 = new Lookup(); + lookup1.setForeignField("Foreign Field"); + assertTrue(lookup.equals(lookup1)); + } + + @Test + public void testHashCode() { + assertEquals(357642, (new Lookup()).hashCode()); + } + + @Test + public void testHashCode2() { + Lookup lookup = new Lookup(); + lookup.setForeignField("Foreign Field"); + assertEquals(1964140155, lookup.hashCode()); + } + + @Test + public void testHashCode3() { + Lookup lookup = new Lookup(); + lookup.setLocalField("Local Field"); + assertEquals(1343314452, lookup.hashCode()); + } + + @Test + public void testHashCode4() { + Lookup lookup = new Lookup(); + lookup.setTargetField("Target Field"); + assertEquals(-1878733174, lookup.hashCode()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/RecordStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/RecordStreamTest.java new file mode 100644 index 000000000..604854e0e --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/RecordStreamTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class RecordStreamTest { + @Test + public void testEmpty() { + assertTrue(RecordStream.empty().toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/SortOrderTest.java b/nitrite/src/test/java/org/dizitart/no2/common/SortOrderTest.java new file mode 100644 index 000000000..ce59d4e21 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/SortOrderTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SortOrderTest { + + @Test + public void testValueOf() { + assertEquals(SortOrder.Ascending, SortOrder.valueOf("Ascending")); + } + + @Test + public void testValues() { + SortOrder[] actualValuesResult = SortOrder.values(); + assertEquals(2, actualValuesResult.length); + assertEquals(SortOrder.Ascending, actualValuesResult[0]); + assertEquals(SortOrder.Descending, actualValuesResult[1]); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/SortableFieldsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/SortableFieldsTest.java new file mode 100644 index 000000000..8019c7775 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/SortableFieldsTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.*; + +public class SortableFieldsTest { + @Test + public void testConstructor() { + assertEquals("[]", (new SortableFields()).toString()); + } + + @Test + public void testWithNames() { + SortableFields actualWithNamesResult = SortableFields.withNames("Fields"); + assertEquals("[Fields]", actualWithNamesResult.toString()); + List stringList = actualWithNamesResult.fieldNames; + assertEquals(1, stringList.size()); + assertEquals("Fields", stringList.get(0)); + } + + @Test + public void testAddField() { + SortableFields sortableFields = new SortableFields(); + assertSame(sortableFields, sortableFields.addField("Field", SortOrder.Ascending)); + } + + @Test + public void testGetSortingOrders() { + assertTrue((new SortableFields()).getSortingOrders().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/UnknownTypeTest.java b/nitrite/src/test/java/org/dizitart/no2/common/UnknownTypeTest.java new file mode 100644 index 000000000..96f9edf8b --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/UnknownTypeTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class UnknownTypeTest { + @Test + public void testCompareTo() { + UnknownType unknownType = new UnknownType(); + assertEquals(0, unknownType.compareTo(new UnknownType())); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/concurrent/ThreadPoolManagerTest.java b/nitrite/src/test/java/org/dizitart/no2/common/concurrent/ThreadPoolManagerTest.java index bd02d15d4..b64c32385 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/concurrent/ThreadPoolManagerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/concurrent/ThreadPoolManagerTest.java @@ -1,13 +1,14 @@ package org.dizitart.no2.common.concurrent; -import static org.junit.Assert.assertTrue; - import org.junit.Test; +import static org.junit.Assert.assertTrue; + public class ThreadPoolManagerTest { @Test public void testGetThreadPool() { assertTrue(ThreadPoolManager.getThreadPool(3, "threadName") instanceof java.util.concurrent.ThreadPoolExecutor); + assertTrue(ThreadPoolManager.getThreadPool(1, "foo") instanceof java.util.concurrent.ThreadPoolExecutor); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java b/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java new file mode 100644 index 000000000..1184e72d9 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.crypto; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class AESEncryptorTest { + @Test + public void testEncryptDecrypt() throws Exception { + AESEncryptor aesEncryptor = new AESEncryptor("iloveyou"); + String encrypted = aesEncryptor.encrypt("iloveyou".getBytes("UTF-8")); + assertNotNull(encrypted); + + assertEquals("iloveyou", aesEncryptor.decrypt(encrypted)); + } + + @Test(expected = SecurityException.class) + public void testDecrypt2() { + (new AESEncryptor("iloveyou")).decrypt("bad base-64"); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java b/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java index 37553c5df..bf73a45bb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/event/EventTest.java @@ -18,10 +18,10 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.data.Employee; +import org.dizitart.no2.integration.repository.data.Employee; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/Company.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Company.java similarity index 98% rename from nitrite/src/test/java/org/dizitart/no2/mapper/Company.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/Company.java index 79dbec25a..ad947db76 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/Company.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Company.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import lombok.Data; import org.dizitart.no2.collection.Document; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/Department.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Department.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/mapper/Department.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/Department.java index 330c744b3..5d1a5eb59 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/Department.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Department.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import lombok.Data; import lombok.ToString; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/Employee.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Employee.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/mapper/Employee.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/Employee.java index d1dfd1a9f..057a0f0cb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/Employee.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/Employee.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import lombok.Data; import lombok.ToString; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableDepartment.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableDepartment.java similarity index 98% rename from nitrite/src/test/java/org/dizitart/no2/mapper/MappableDepartment.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableDepartment.java index a549e3c50..b61548d0f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableDepartment.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableDepartment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import lombok.Data; import lombok.ToString; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableEmployee.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableEmployee.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/mapper/MappableEmployee.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableEmployee.java index c4660c991..a2d7f79a1 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableEmployee.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableEmployee.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; import lombok.Data; import lombok.ToString; diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableMapperTest.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableMapperTest.java similarity index 93% rename from nitrite/src/test/java/org/dizitart/no2/mapper/MappableMapperTest.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableMapperTest.java index 07cbca574..1e64953db 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/MappableMapperTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MappableMapperTest.java @@ -1,7 +1,7 @@ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; -import org.dizitart.no2.NitriteStressTest; -import org.dizitart.no2.NitriteTest; +import org.dizitart.no2.integration.NitriteStressTest; +import org.dizitart.no2.integration.NitriteTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; import org.junit.Test; @@ -11,7 +11,7 @@ public class MappableMapperTest { @Test public void testConvert() { - MappableMapper mappableMapper = new MappableMapper(null); + MappableMapper mappableMapper = new MappableMapper(Integer.class); assertEquals(0, ((Integer) mappableMapper.convert(0, Object.class)).intValue()); } @@ -36,7 +36,7 @@ public void testConvertFromDocument() { Class forNameResult = Object.class; Class forNameResult1 = Object.class; MappableMapper mappableMapper = new MappableMapper(forNameResult, forNameResult1, Object.class); - assertNull(mappableMapper.convertFromDocument(null, Object.class)); + assertNull(mappableMapper.convertFromDocument(null, Object.class)); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/mapper/MapperTest.java b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MapperTest.java similarity index 98% rename from nitrite/src/test/java/org/dizitart/no2/mapper/MapperTest.java rename to nitrite/src/test/java/org/dizitart/no2/common/mapper/MapperTest.java index cc8cff608..e8eb86a86 100644 --- a/nitrite/src/test/java/org/dizitart/no2/mapper/MapperTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/mapper/MapperTest.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.dizitart.no2.mapper; +package org.dizitart.no2.common.mapper; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.junit.Rule; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/module/PluginManagerTest.java b/nitrite/src/test/java/org/dizitart/no2/common/module/PluginManagerTest.java new file mode 100644 index 000000000..591e93492 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/module/PluginManagerTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.module; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.store.NitriteStore; +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class PluginManagerTest { + @Test + public void testConstructor() { + NitriteConfig nitriteConfig = new NitriteConfig(); + assertSame(nitriteConfig, (new PluginManager(nitriteConfig)).getNitriteConfig()); + } + + @Test + public void testLoadModule() { + PluginManager pluginManager = new PluginManager(new NitriteConfig()); + NitriteModule nitriteModule = mock(NitriteModule.class); + when(nitriteModule.plugins()).thenReturn(new HashSet<>()); + pluginManager.loadModule(nitriteModule); + verify(nitriteModule, times(2)).plugins(); + } + + @Test + public void testLoadModule2() { + PluginManager pluginManager = new PluginManager(new NitriteConfig()); + + HashSet nitritePluginSet = new HashSet<>(); + nitritePluginSet.add(mock(NitritePlugin.class)); + NitriteModule nitriteModule = mock(NitriteModule.class); + when(nitriteModule.plugins()).thenReturn(nitritePluginSet); + pluginManager.loadModule(nitriteModule); + verify(nitriteModule, times(2)).plugins(); + } + + @Test + public void testFindAndLoadPlugins() { + PluginManager pluginManager = new PluginManager(new NitriteConfig()); + pluginManager.findAndLoadPlugins(); + NitriteStore nitriteStore = pluginManager.getNitriteStore(); + assertTrue(nitriteStore instanceof org.dizitart.no2.store.memory.InMemoryStore); + assertEquals(3, pluginManager.getIndexerMap().size()); + assertTrue(pluginManager.getNitriteMapper() instanceof org.dizitart.no2.common.mapper.MappableMapper); + assertFalse(nitriteStore.isClosed()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/processors/ProcessorChainTest.java b/nitrite/src/test/java/org/dizitart/no2/common/processors/ProcessorChainTest.java new file mode 100644 index 000000000..fddf3c192 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/processors/ProcessorChainTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.processors; + +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +public class ProcessorChainTest { + @Test + public void testRemove() { + ProcessorChain processorChain = new ProcessorChain(); + processorChain.add(new ProcessorChain()); + processorChain.remove(mock(Processor.class)); + } + + @Test + public void testProcessBeforeWrite() { + assertNull((new ProcessorChain()).processBeforeWrite(null)); + } + + @Test + public void testProcessBeforeWrite2() { + ProcessorChain processorChain = new ProcessorChain(); + processorChain.add(new ProcessorChain()); + assertNull(processorChain.processBeforeWrite(null)); + } + + @Test + public void testProcessAfterRead() { + assertNull((new ProcessorChain()).processAfterRead(null)); + } + + @Test + public void testProcessAfterRead2() { + ProcessorChain processorChain = new ProcessorChain(); + processorChain.add(new ProcessorChain()); + assertNull(processorChain.processAfterRead(null)); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/BoundedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/BoundedDocumentStreamTest.java new file mode 100644 index 000000000..4aa3a7054 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/BoundedDocumentStreamTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.ValidationException; +import org.junit.Test; + +import java.util.Iterator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.*; + +public class BoundedDocumentStreamTest { + @Test + public void testConstructor() { + new BoundedDocumentStream(1L, 1L, (RecordStream>) mock(RecordStream.class)); + } + + @Test + public void testConstructor2() { + assertThrows(ValidationException.class, + () -> new BoundedDocumentStream(-1L, 1L, (RecordStream>) mock(RecordStream.class))); + } + + @Test + public void testConstructor3() { + assertThrows(ValidationException.class, + () -> new BoundedDocumentStream(1L, -1L, (RecordStream>) mock(RecordStream.class))); + } + + @Test + public void testIterator() { + RecordStream> recordStream = () -> new Iterator>() { + int i = 0; + + @Override + public boolean hasNext() { + return i != 3; + } + + @Override + public Pair next() { + i++; + return Pair.pair(NitriteId.newId(), Document.createDocument("value", i)); + } + }; + + BoundedDocumentStream stream = new BoundedDocumentStream(2L, 1L, recordStream); + + for (Pair pair : stream) { + assertEquals(3, (int) pair.getSecond().get("value", Integer.class)); + } + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/DistinctStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/DistinctStreamTest.java new file mode 100644 index 000000000..defa949da --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/DistinctStreamTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import java.util.Iterator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class DistinctStreamTest { + @Test + public void testConstructor() { + DistinctStream distinctStream = new DistinctStream(null); + assertFalse(distinctStream.iterator().hasNext()); + } + + @Test + public void testConstructor2() { + RecordStream> recordStream = () -> new Iterator>() { + int i = 0; + + // same id for all entries + final NitriteId id = NitriteId.newId(); + + @Override + public boolean hasNext() { + return i != 2; + } + + @Override + public Pair next() { + i++; + return Pair.pair(id, Document.createDocument("value", i)); + } + }; + + assertEquals(2, recordStream.size()); + + DistinctStream distinctStream = new DistinctStream(recordStream); + assertEquals(1, distinctStream.size()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentSorterTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentSorterTest.java new file mode 100644 index 000000000..976a5971b --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentSorterTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.assertEquals; + +public class DocumentSorterTest { + @Test + public void testCompare() { + DocumentSorter documentSorter = new DocumentSorter(null, new ArrayList<>()); + Pair pair1 = new Pair<>(); + assertEquals(0, documentSorter.compare(pair1, new Pair<>())); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentStreamTest.java new file mode 100644 index 000000000..1ebeba433 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/DocumentStreamTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Lookup; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +@SuppressWarnings("unchecked") +public class DocumentStreamTest { + @Test + public void testConstructor() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + assertNull((new DocumentStream(recordStream, new ProcessorChain())).getFindPlan()); + } + + @Test + public void testJoin() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream documentStream = new DocumentStream(recordStream, new ProcessorChain()); + RecordStream> recordStream1 = (RecordStream>) mock( + RecordStream.class); + DocumentStream foreignCursor = new DocumentStream(recordStream1, new ProcessorChain()); + assertTrue(documentStream.join(foreignCursor, new Lookup()) instanceof JoinedDocumentStream); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java new file mode 100644 index 000000000..e61dbba61 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import com.fasterxml.jackson.databind.util.ArrayIterator; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.Filter; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +@SuppressWarnings("unchecked") +public class FilteredStreamTest { + + @Test + public void testIterator() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + Pair pair = new Pair<>(); + Pair pair1 = new Pair<>(); + when(recordStream.iterator()).thenReturn( + new ArrayIterator>(new Pair[]{pair, pair1, new Pair()})); + FilteredStream filteredStream = new FilteredStream(recordStream, mock(Filter.class)); + filteredStream.iterator(); + verify(recordStream).iterator(); + assertTrue(filteredStream.toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/IndexedStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/IndexedStreamTest.java new file mode 100644 index 000000000..40a9667c7 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/IndexedStreamTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.assertTrue; + +public class IndexedStreamTest { + @Test + public void testConstructor() { + HashSet nitriteIds = new HashSet<>(); + assertTrue( + (new IndexedStream(nitriteIds, new InMemoryMap<>("Map Name", null))).toList().isEmpty()); + } + + @Test + public void testIterator() { + HashSet nitriteIds = new HashSet<>(); + IndexedStream indexedStream = new IndexedStream(nitriteIds, new InMemoryMap<>("Map Name", null)); + indexedStream.iterator(); + assertTrue(indexedStream.toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/JoinedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/JoinedDocumentStreamTest.java new file mode 100644 index 000000000..302947a71 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/JoinedDocumentStreamTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Lookup; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +@SuppressWarnings("unchecked") +public class JoinedDocumentStreamTest { + @Test + public void testConstructor() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + RecordStream> recordStream1 = (RecordStream>) mock( + RecordStream.class); + DocumentStream documentStream = new DocumentStream(recordStream1, new ProcessorChain()); + Lookup lookup = new Lookup(); + new JoinedDocumentStream(recordStream, documentStream, lookup, new ProcessorChain()); + assertNull(documentStream.getFindPlan()); + assertNull(lookup.getForeignField()); + assertNull(lookup.getTargetField()); + assertNull(lookup.getLocalField()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java new file mode 100644 index 000000000..b07e1c288 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import com.fasterxml.jackson.databind.util.ArrayIterator; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +@SuppressWarnings("unchecked") +public class ProjectedDocumentStreamTest { + @Test + public void testConstructor() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + new ProjectedDocumentStream(recordStream, null, new ProcessorChain()); + assertNull(null); + } + + @Test + public void testIterator() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + Pair pair = new Pair<>(); + Pair pair1 = new Pair<>(); + when(recordStream.iterator()).thenReturn( + new ArrayIterator>(new Pair[]{pair, pair1, new Pair()})); + ProjectedDocumentStream projectedDocumentStream = new ProjectedDocumentStream(recordStream, null, + new ProcessorChain()); + projectedDocumentStream.iterator(); + verify(recordStream).iterator(); + assertTrue(projectedDocumentStream.toList().isEmpty()); + } + + @Test + public void testIterator2() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + when(recordStream.iterator()).thenReturn(new ArrayIterator>(new Pair[]{})); + ProjectedDocumentStream projectedDocumentStream = new ProjectedDocumentStream(recordStream, null, + new ProcessorChain()); + projectedDocumentStream.iterator(); + verify(recordStream).iterator(); + assertTrue(projectedDocumentStream.toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java new file mode 100644 index 000000000..5440a196a --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import com.fasterxml.jackson.databind.util.ArrayIterator; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +@SuppressWarnings("unchecked") +public class SortedDocumentStreamTest { + @Test + public void testConstructor() { + FindPlan findPlan = new FindPlan(); + new SortedDocumentStream(findPlan, (RecordStream>) mock(RecordStream.class)); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertTrue(blockingSortOrder instanceof java.util.ArrayList); + assertEquals("FindPlan(indexDescriptor=null, indexScanFilter=null, indexScanOrder=null, collectionScanFilter=null," + + " blockingSortOrder=[], skip=null, limit=null, collator=null, subPlans=[])", findPlan.toString()); + assertTrue(blockingSortOrder.isEmpty()); + List subPlans = findPlan.getSubPlans(); + assertTrue(subPlans instanceof java.util.ArrayList); + assertNull(findPlan.getSkip()); + assertTrue(subPlans.isEmpty()); + assertNull(findPlan.getLimit()); + assertNull(findPlan.getIndexScanOrder()); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getCollectionScanFilter()); + assertNull(findPlan.getCollator()); + } + + @Test + public void testIterator() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + Pair pair = new Pair<>(); + Pair pair1 = new Pair<>(); + when(recordStream.iterator()).thenReturn( + new ArrayIterator>(new Pair[]{pair, pair1, new Pair()})); + SortedDocumentStream sortedDocumentStream = new SortedDocumentStream(new FindPlan(), recordStream); + sortedDocumentStream.iterator(); + verify(recordStream).iterator(); + assertTrue(sortedDocumentStream.toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/UnionStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/UnionStreamTest.java new file mode 100644 index 000000000..4d6724e39 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/UnionStreamTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.streams; + +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.assertTrue; + +public class UnionStreamTest { + @Test + public void testConstructor() { + assertTrue((new UnionStream(new ArrayList<>())).toList().isEmpty()); + } + + @Test + public void testIterator() { + UnionStream unionStream = new UnionStream(new ArrayList<>()); + unionStream.iterator(); + assertTrue(unionStream.toList().isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/Base64Test.java b/nitrite/src/test/java/org/dizitart/no2/common/util/Base64Test.java new file mode 100644 index 000000000..dc5eafd89 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/Base64Test.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import org.junit.Test; + +import java.io.UnsupportedEncodingException; + +import static org.junit.Assert.*; + +public class Base64Test { + @Test + public void testDecode() throws UnsupportedEncodingException { + byte[] actualDecodeResult = Base64.decode("AAAAAAAA".getBytes("UTF-8"), 1); + assertEquals(6, actualDecodeResult.length); + assertEquals((byte) 0, actualDecodeResult[0]); + assertEquals((byte) 0, actualDecodeResult[1]); + assertEquals((byte) 0, actualDecodeResult[2]); + assertEquals((byte) 0, actualDecodeResult[3]); + assertEquals((byte) 0, actualDecodeResult[4]); + assertEquals((byte) 0, actualDecodeResult[5]); + } + + @Test + public void testDecode2() { + byte[] actualDecodeResult = Base64.decode(new byte[]{0, 'A', 'A', 'A', 'A', 'A', 'A', 'A'}, 1); + assertEquals(5, actualDecodeResult.length); + assertEquals((byte) 0, actualDecodeResult[0]); + assertEquals((byte) 0, actualDecodeResult[1]); + assertEquals((byte) 0, actualDecodeResult[2]); + assertEquals((byte) 0, actualDecodeResult[3]); + assertEquals((byte) 0, actualDecodeResult[4]); + } + + @Test + public void testDecode3() throws UnsupportedEncodingException { + byte[] actualDecodeResult = Base64.decode("AAAAAAAA".getBytes("UTF-8"), 2, 3, 1); + assertEquals(2, actualDecodeResult.length); + assertEquals((byte) 0, actualDecodeResult[0]); + assertEquals((byte) 0, actualDecodeResult[1]); + } + + @Test + public void testDecode4() { + assertThrows(IllegalArgumentException.class, + () -> Base64.decode(new byte[]{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}, 1, 1, 1)); + } + + @Test + public void testDecode5() { + byte[] actualDecodeResult = Base64.decode(new byte[]{'A', 'A', 0, 'A', 'A', 'A', 'A', 'A'}, 2, 3, 1); + assertEquals(1, actualDecodeResult.length); + assertEquals((byte) 0, actualDecodeResult[0]); + } + + @Test + public void testDecode7() { + assertThrows(NegativeArraySizeException.class, + () -> Base64.decode("AAAAAAAA".getBytes("UTF-8"), 2, Integer.MIN_VALUE, 1)); + } + + @Test + public void testDecoderConstructor() throws UnsupportedEncodingException { + assertEquals(24, (new Base64.Decoder(1, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8"))).output.length); + assertEquals(24, (new Base64.Decoder(8, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8"))).output.length); + } + + @Test + public void testEncodeToString() throws UnsupportedEncodingException { + assertEquals("QUFBQUFBQUE\n", Base64.encodeToString("AAAAAAAA".getBytes("UTF-8"), 1)); + assertEquals("", Base64.encodeToString(new byte[]{}, 1)); + assertEquals("QUFBQUFBQUFBQUFBQUFBQQ\n", Base64.encodeToString("AAAAAAAAAAAAAAAA".getBytes("UTF-8"), 1)); + assertEquals("QUFBQUFBQUE=\n", Base64.encodeToString("AAAAAAAA".getBytes("UTF-8"), 0)); + assertEquals("QUFBQUFBQUE=", Base64.encodeToString("AAAAAAAA".getBytes("UTF-8"), 2)); + assertEquals("QUFBQUFBQUE=\r\n", Base64.encodeToString("AAAAAAAA".getBytes("UTF-8"), 4)); + assertEquals("", Base64.encodeToString(new byte[]{}, 0)); + } + + @Test + public void testEncode() throws UnsupportedEncodingException { + assertEquals(12, Base64.encode("AAAAAAAA".getBytes("UTF-8"), 1).length); + assertEquals(0, Base64.encode(new byte[]{}, 1).length); + assertEquals(23, Base64.encode("AAAAAAAAAAAAAAAA".getBytes("UTF-8"), 1).length); + assertEquals(13, Base64.encode("AAAAAAAA".getBytes("UTF-8"), 0).length); + assertEquals(12, Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2).length); + assertEquals(14, Base64.encode("AAAAAAAA".getBytes("UTF-8"), 4).length); + assertEquals(0, Base64.encode(new byte[]{}, 0).length); + assertEquals(0, Base64.encode(new byte[]{'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}, 1, 0, 1).length); + } + + @Test + public void testEncode2() throws UnsupportedEncodingException { + byte[] actualEncodeResult = Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2, 3, 1); + assertEquals(5, actualEncodeResult.length); + assertEquals('Q', actualEncodeResult[0]); + assertEquals('U', actualEncodeResult[1]); + assertEquals('F', actualEncodeResult[2]); + assertEquals('B', actualEncodeResult[3]); + assertEquals((byte) 10, actualEncodeResult[4]); + } + + @Test + public void testEncode4() throws UnsupportedEncodingException { + byte[] actualEncodeResult = Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2, 1, 1); + assertEquals(3, actualEncodeResult.length); + assertEquals('Q', actualEncodeResult[0]); + assertEquals('Q', actualEncodeResult[1]); + assertEquals((byte) 10, actualEncodeResult[2]); + } + + @Test + public void testEncode5() throws UnsupportedEncodingException { + byte[] actualEncodeResult = Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2, 2, 1); + assertEquals(4, actualEncodeResult.length); + assertEquals('Q', actualEncodeResult[0]); + assertEquals('U', actualEncodeResult[1]); + assertEquals('E', actualEncodeResult[2]); + assertEquals((byte) 10, actualEncodeResult[3]); + } + + @Test + public void testEncode6() throws UnsupportedEncodingException { + byte[] actualEncodeResult = Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2, 1, 0); + assertEquals(5, actualEncodeResult.length); + assertEquals('Q', actualEncodeResult[0]); + assertEquals('Q', actualEncodeResult[1]); + assertEquals('=', actualEncodeResult[2]); + assertEquals('=', actualEncodeResult[3]); + assertEquals((byte) 10, actualEncodeResult[4]); + } + + @Test + public void testEncode8() throws UnsupportedEncodingException { + byte[] actualEncodeResult = Base64.encode("AAAAAAAA".getBytes("UTF-8"), 2, 3, 4); + assertEquals(6, actualEncodeResult.length); + assertEquals('Q', actualEncodeResult[0]); + assertEquals('U', actualEncodeResult[1]); + assertEquals('F', actualEncodeResult[2]); + assertEquals('B', actualEncodeResult[3]); + assertEquals((byte) 13, actualEncodeResult[4]); + assertEquals((byte) 10, actualEncodeResult[5]); + } + + @Test + public void testEncoderConstructor() throws UnsupportedEncodingException { + Base64.Encoder actualEncoder = new Base64.Encoder(1, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8")); + assertFalse(actualEncoder.do_cr); + assertEquals(0, actualEncoder.tailLen); + assertEquals(24, actualEncoder.output.length); + assertFalse(actualEncoder.do_padding); + assertTrue(actualEncoder.do_newline); + } + + @Test + public void testEncoderConstructor2() throws UnsupportedEncodingException { + Base64.Encoder actualEncoder = new Base64.Encoder(0, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8")); + assertFalse(actualEncoder.do_cr); + assertEquals(0, actualEncoder.tailLen); + assertEquals(24, actualEncoder.output.length); + assertTrue(actualEncoder.do_padding); + assertTrue(actualEncoder.do_newline); + } + + @Test + public void testEncoderConstructor3() throws UnsupportedEncodingException { + Base64.Encoder actualEncoder = new Base64.Encoder(2, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8")); + assertFalse(actualEncoder.do_cr); + assertEquals(0, actualEncoder.tailLen); + assertEquals(24, actualEncoder.output.length); + assertTrue(actualEncoder.do_padding); + assertFalse(actualEncoder.do_newline); + } + + @Test + public void testEncoderConstructor4() throws UnsupportedEncodingException { + Base64.Encoder actualEncoder = new Base64.Encoder(4, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8")); + assertTrue(actualEncoder.do_cr); + assertEquals(0, actualEncoder.tailLen); + assertEquals(24, actualEncoder.output.length); + assertTrue(actualEncoder.do_padding); + assertTrue(actualEncoder.do_newline); + } + + @Test + public void testEncoderConstructor5() throws UnsupportedEncodingException { + Base64.Encoder actualEncoder = new Base64.Encoder(8, "AAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8")); + assertFalse(actualEncoder.do_cr); + assertEquals(0, actualEncoder.tailLen); + assertEquals(24, actualEncoder.output.length); + assertTrue(actualEncoder.do_padding); + assertTrue(actualEncoder.do_newline); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/CryptoUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/CryptoUtilsTest.java new file mode 100644 index 000000000..70548f8cc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/CryptoUtilsTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import org.junit.Test; + +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +import static org.junit.Assert.*; + +public class CryptoUtilsTest { + @Test + public void testGetRandomNonce() { + assertEquals(10, CryptoUtils.getRandomNonce(10).length); + assertThrows(NegativeArraySizeException.class, () -> CryptoUtils.getRandomNonce(-1)); + } + + @Test + public void testGetAESKeyFromPassword() + throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException { + char[] password = "AAAA".toCharArray(); + assertTrue(CryptoUtils.getAESKeyFromPassword(password, + "AAAAAAAA".getBytes("UTF-8")) instanceof javax.crypto.spec.SecretKeySpec); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java index 46127768f..8776519f7 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/DocumentUtilsTest.java @@ -17,13 +17,13 @@ package org.dizitart.no2.common.util; import org.dizitart.no2.NitriteBuilderTest; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.filters.ComparableFilter; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.MappableMapper; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; @@ -31,10 +31,6 @@ import static org.dizitart.no2.common.Constants.DOC_REVISION; import static org.dizitart.no2.common.util.DocumentUtils.*; import static org.junit.Assert.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; public class DocumentUtilsTest { diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/IndexUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/IndexUtilsTest.java new file mode 100644 index 000000000..d3de97e68 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/IndexUtilsTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.index.IndexDescriptor; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class IndexUtilsTest { + @Test + public void testDeriveIndexMapName() { + assertEquals("$nitrite_index|Collection Name||Index Type", + IndexUtils.deriveIndexMapName(new IndexDescriptor("Index Type", new Fields(), "Collection Name"))); + } + + @Test + public void testDeriveIndexMapName2() { + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + indexDescriptor.setIndexFields(new Fields()); + assertEquals("$nitrite_index|Collection Name||Index Type", IndexUtils.deriveIndexMapName(indexDescriptor)); + } + + @Test + public void testDeriveIndexMetaMapName() { + assertEquals("$nitrite_index_meta|Collection Name", IndexUtils.deriveIndexMetaMapName("Collection Name")); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/IterablesTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/IterablesTest.java index 66bb9c01c..dbb5aae24 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/IterablesTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/IterablesTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2.common.util; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; @@ -112,7 +112,7 @@ public void testArrayContains() { @Test public void testListOf() { assertEquals(1, Iterables.listOf("items").size()); - assertEquals(0, Iterables.listOf( null).size()); + assertEquals(1, Iterables.listOf((Object) null).size()); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/NumbersTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/NumbersTest.java index 5b319ac7e..872ab873e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/NumbersTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/NumbersTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2.common.util; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java index d18f483df..8a6fea0db 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java @@ -28,8 +28,8 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.data.ChildClass; -import org.dizitart.no2.repository.data.Employee; +import org.dizitart.no2.integration.repository.data.ChildClass; +import org.dizitart.no2.integration.repository.data.Employee; import org.junit.Test; import java.io.Serializable; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java new file mode 100644 index 000000000..6c7a02cc0 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +public class SecureStringTest { + @Test + public void testConstructor() { + assertThrows(ArrayIndexOutOfBoundsException.class, () -> new SecureString(1, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + assertEquals(2, (new SecureString(1, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String("foo"))))))).length()); + assertEquals(2, (new SecureString(1, 3, new String("foo"))).length()); + assertThrows(NegativeArraySizeException.class, () -> new SecureString(Integer.MIN_VALUE, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + assertEquals(0, + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(new String())))))) + .length()); + assertEquals(1, + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A'))))))) + .length()); + assertEquals(0, (new SecureString(new String())).length()); + assertEquals(1, (new SecureString(String.valueOf('A'))).length()); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> new SecureString(1, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> new SecureString(1, 3, new SecureString(new SecureString(new SecureString(Long.toString(1L)))))); + assertEquals(2, (new SecureString(1, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String("foo"))))))).length()); + assertEquals(2, (new SecureString(1, 3, new String("foo"))).length()); + assertThrows(NegativeArraySizeException.class, () -> new SecureString(Integer.MIN_VALUE, 3, + new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + assertEquals(0, + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(new String())))))) + .length()); + assertEquals(1, + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A'))))))) + .length()); + assertEquals(0, (new SecureString(new String())).length()); + assertEquals(1, (new SecureString(String.valueOf('A'))).length()); + } + + @Test + public void testCharAt2() { + assertEquals('o', + (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).charAt(1)); + } + + @Test + public void testCharAt4() { + assertEquals('o', + (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).charAt(1)); + } + + @Test + public void testLength() { + assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).length()); + assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).length()); + } + + + @Test + public void testSubSequence2() { + assertEquals(2, + (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).subSequence(1, 3) + .length()); + } + + @Test + public void testSubSequence3() { + assertThrows(NegativeArraySizeException.class, + () -> (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))) + .subSequence(Integer.MIN_VALUE, 3)); + } + + + @Test + public void testSubSequence5() { + assertEquals(2, + (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).subSequence(1, 3) + .length()); + } + + @Test + public void testSubSequence6() { + assertThrows(NegativeArraySizeException.class, + () -> (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))) + .subSequence(Integer.MIN_VALUE, 3)); + } + + @Test + public void testAsString() { + assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).asString()); + assertEquals("A", + (new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A')))))).asString()); + assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).asString()); + assertEquals("A", + (new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A')))))).asString()); + } + + @Test + public void testToString() { + assertEquals("Secure:XXXXX", + (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).toString()); + assertEquals("Secure:XXXXX", + (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).toString()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/StringUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/StringUtilsTest.java index b923a8699..1279d8842 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/StringUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/StringUtilsTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2.common.util; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/ValidationUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/ValidationUtilsTest.java index f03b13237..cd7721924 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/ValidationUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/ValidationUtilsTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2.common.util; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.exceptions.ValidationException; import org.junit.Rule; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/AndFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/AndFilterTest.java new file mode 100644 index 000000000..15408f80c --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/AndFilterTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class AndFilterTest { + @Test + public void testConstructor() { + assertFalse((new AndFilter(mock(Filter.class), mock(Filter.class), mock(Filter.class))).getObjectFilter()); + } + + @Test + public void testApply() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(true); + Filter filter1 = mock(Filter.class); + when(filter1.apply(any())).thenReturn(true); + Filter filter2 = mock(Filter.class); + when(filter2.apply(any())).thenReturn(true); + AndFilter andFilter = new AndFilter(filter, filter1, filter2); + assertTrue(andFilter.apply(new Pair<>())); + verify(filter1).apply(any()); + verify(filter2).apply(any()); + verify(filter).apply(any()); + } + + @Test + public void testApply2() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(false); + Filter filter1 = mock(Filter.class); + when(filter1.apply(any())).thenReturn(true); + Filter filter2 = mock(Filter.class); + when(filter2.apply(any())).thenReturn(true); + AndFilter andFilter = new AndFilter(filter, filter1, filter2); + assertFalse(andFilter.apply(new Pair<>())); + verify(filter).apply(any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java new file mode 100644 index 000000000..cc1aecc29 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/BetweenFilterTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.exceptions.ValidationException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class BetweenFilterTest { + @Test + public void testBoundConstructor() { + BetweenFilter.Bound actualBound = new BetweenFilter.Bound<>("Lower Bound", "Upper Bound"); + Object lowerBound = actualBound.getLowerBound(); + assertTrue(lowerBound instanceof String); + assertEquals( + "BetweenFilter.Bound(upperBound=Upper Bound, lowerBound=Lower Bound, upperInclusive=true, lowerInclusive" + + "=true)", + actualBound.toString()); + assertEquals("Lower Bound", lowerBound); + assertTrue(actualBound.isUpperInclusive()); + assertTrue(actualBound.isLowerInclusive()); + Object upperBound = actualBound.getUpperBound(); + assertTrue(upperBound instanceof String); + assertEquals("Upper Bound", upperBound); + } + + @Test + public void testBoundConstructor2() { + BetweenFilter.Bound actualBound = new BetweenFilter.Bound<>("Lower Bound", "Upper Bound", true); + Object lowerBound = actualBound.getLowerBound(); + assertTrue(lowerBound instanceof String); + assertEquals( + "BetweenFilter.Bound(upperBound=Upper Bound, lowerBound=Lower Bound, upperInclusive=true, lowerInclusive" + + "=true)", + actualBound.toString()); + assertEquals("Lower Bound", lowerBound); + assertTrue(actualBound.isUpperInclusive()); + assertTrue(actualBound.isLowerInclusive()); + Object upperBound = actualBound.getUpperBound(); + assertTrue(upperBound instanceof String); + assertEquals("Upper Bound", upperBound); + } + + @Test + public void testBoundConstructor3() { + BetweenFilter.Bound actualBound = new BetweenFilter.Bound<>("Lower Bound", "Upper Bound", true, true); + Object lowerBound = actualBound.getLowerBound(); + assertTrue(lowerBound instanceof String); + assertEquals( + "BetweenFilter.Bound(upperBound=Upper Bound, lowerBound=Lower Bound, upperInclusive=true, lowerInclusive" + + "=true)", + actualBound.toString()); + assertEquals("Lower Bound", lowerBound); + assertTrue(actualBound.isUpperInclusive()); + assertTrue(actualBound.isLowerInclusive()); + Object upperBound = actualBound.getUpperBound(); + assertTrue(upperBound instanceof String); + assertEquals("Upper Bound", upperBound); + } + + @Test + public void testConstructor() { + BetweenFilter actualBetweenFilter = new BetweenFilter<>("Field", + new BetweenFilter.Bound<>("Lower Bound", "Upper Bound")); + assertEquals("((Field <= Upper Bound) && (Field >= Lower Bound))", actualBetweenFilter.toString()); + assertFalse(actualBetweenFilter.getObjectFilter()); + } + + @Test + public void testConstructor2() { + assertThrows(ValidationException.class, + () -> new BetweenFilter<>("Field", new BetweenFilter.Bound<>(null, "Upper Bound"))); + } + + @Test + public void testConstructor3() { + assertThrows(ValidationException.class, + () -> new BetweenFilter<>("Field", new BetweenFilter.Bound<>("Lower Bound", null))); + } + + @Test + public void testConstructor4() { + assertThrows(ValidationException.class, () -> new BetweenFilter<>("Field", null)); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/ElementMatchFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/ElementMatchFilterTest.java new file mode 100644 index 000000000..ffcf6f039 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/ElementMatchFilterTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.mock; + +public class ElementMatchFilterTest { + @Test + public void testConstructor() { + assertFalse((new ElementMatchFilter("Field", mock(Filter.class))).getObjectFilter()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java index a98e437d8..e6603ac20 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/EqualsFilterTest.java @@ -5,10 +5,32 @@ import org.dizitart.no2.common.tuples.Pair; import org.junit.Test; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class EqualsFilterTest { + @Test + public void testConstructor() { + EqualsFilter actualEqualsFilter = new EqualsFilter("Field", "Value"); + assertEquals("(Field == Value)", actualEqualsFilter.toString()); + assertFalse(actualEqualsFilter.getObjectFilter()); + assertEquals("Field", actualEqualsFilter.getField()); + } + + @Test + public void testToString() { + EqualsFilter equalsFilter = new EqualsFilter("Field", "Value"); + assertEquals("(Field == Value)", equalsFilter.toString()); + assertEquals("(!((Field == Value)))", equalsFilter.not().toString()); + } + + @Test + public void testToString2() { + EqualsFilter equalsFilter = new EqualsFilter("Field", "Value"); + equalsFilter.setProcessed(true); + equalsFilter.setObjectFilter(true); + assertEquals("(Field == Value)", equalsFilter.toString()); + } @Test public void testApply() { diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/FilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/FilterTest.java new file mode 100644 index 000000000..49256af76 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/FilterTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.collection.NitriteId; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class FilterTest { + @Test + public void testById() { + assertTrue(((EqualsFilter) Filter.byId(NitriteId.newId())).getValue() instanceof String); + assertFalse(((EqualsFilter) Filter.byId(NitriteId.newId())).getObjectFilter()); + assertEquals("_id", ((EqualsFilter) Filter.byId(NitriteId.newId())).getField()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java index 5da9e449b..5c9851180 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/FluentFilterTest.java @@ -3,35 +3,44 @@ import org.junit.Test; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; public class FluentFilterTest { @Test public void testEq() { - assertTrue(((EqualsFilter) FluentFilter.where("field").eq("value")).getValue() instanceof String); - assertFalse(((EqualsFilter) FluentFilter.where("field").eq("value")).getObjectFilter()); - assertEquals("field", ((EqualsFilter) FluentFilter.where("field").eq("value")).getField()); + NitriteFilter actualEqResult = FluentFilter.where("Field").eq("Value"); + assertEquals("(Field == Value)", actualEqResult.toString()); + assertFalse(actualEqResult.getObjectFilter()); + assertEquals("Field", ((EqualsFilter) actualEqResult).getField()); } @Test public void testNotEq() { - assertTrue(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getValue() instanceof String); - assertFalse(((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getObjectFilter()); - assertEquals("field", ((NotEqualsFilter) FluentFilter.where("field").notEq("value")).getField()); + NitriteFilter actualNotEqResult = FluentFilter.where("Field").notEq("Value"); + assertEquals("(Field != Value)", actualNotEqResult.toString()); + assertFalse(actualNotEqResult.getObjectFilter()); + assertEquals("Field", ((NotEqualsFilter) actualNotEqResult).getField()); } @Test public void testText() { - assertEquals("value", ((TextFilter) FluentFilter.where("field").text("value")).getStringValue()); - assertFalse(((TextFilter) FluentFilter.where("field").text("value")).getObjectFilter()); - assertEquals("field", ((TextFilter) FluentFilter.where("field").text("value")).getField()); + NitriteFilter actualTextResult = FluentFilter.where("Field").text("42"); + assertEquals("Field", ((TextFilter) actualTextResult).getField()); + assertFalse(actualTextResult.getObjectFilter()); + assertEquals("42", ((TextFilter) actualTextResult).getStringValue()); } @Test public void testRegex() { - assertEquals("field", ((RegexFilter) FluentFilter.where("field").regex("value")).getField()); - assertFalse(((RegexFilter) FluentFilter.where("field").regex("value")).getObjectFilter()); - assertEquals("FieldBasedFilter(field=field, value=value, processed=true)", - FluentFilter.where("field").regex("value").toString()); + NitriteFilter actualRegexResult = FluentFilter.where("Field").regex("42"); + assertEquals("(Field regex 42)", actualRegexResult.toString()); + assertEquals("Field", ((RegexFilter) actualRegexResult).getField()); + assertFalse(actualRegexResult.getObjectFilter()); + } + + @Test + public void testElemMatch() { + assertFalse(FluentFilter.where("Field").elemMatch(mock(Filter.class)).getObjectFilter()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java new file mode 100644 index 000000000..6fe56c5e8 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.junit.Test; + +import java.util.ArrayList; + +import static org.junit.Assert.assertEquals; + +public class IndexScanFilterTest { + @Test + public void testConstructor() { + assertEquals("IndexScanFilter(filters=[])", (new IndexScanFilter(new ArrayList())).toString()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java index 327b92dac..b1c8d0cb3 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/NotEqualsFilterTest.java @@ -5,9 +5,32 @@ import org.dizitart.no2.common.tuples.Pair; import org.junit.Test; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class NotEqualsFilterTest { + @Test + public void testConstructor() { + NotEqualsFilter actualNotEqualsFilter = new NotEqualsFilter("Field", "Value"); + assertEquals("(Field != Value)", actualNotEqualsFilter.toString()); + assertFalse(actualNotEqualsFilter.getObjectFilter()); + assertEquals("Field", actualNotEqualsFilter.getField()); + } + + @Test + public void testToString() { + NotEqualsFilter notEqualsFilter = new NotEqualsFilter("Field", "Value"); + assertEquals("(Field != Value)", notEqualsFilter.toString()); + assertEquals("(!((Field != Value)))", notEqualsFilter.not().toString()); + } + + @Test + public void testToString2() { + NotEqualsFilter notEqualsFilter = new NotEqualsFilter("Field", "Value"); + notEqualsFilter.setProcessed(true); + notEqualsFilter.setObjectFilter(true); + assertEquals("(Field != Value)", notEqualsFilter.toString()); + } @Test public void testApply() { diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/NotFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/NotFilterTest.java new file mode 100644 index 000000000..6049fa700 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/NotFilterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class NotFilterTest { + @Test + public void testConstructor() { + assertFalse((new NotFilter(mock(Filter.class))).getObjectFilter()); + } + + @Test + public void testApply() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(true); + NotFilter notFilter = new NotFilter(filter); + assertFalse(notFilter.apply(new Pair<>())); + verify(filter).apply(any()); + } + + @Test + public void testApply2() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(false); + NotFilter notFilter = new NotFilter(filter); + assertTrue(notFilter.apply(new Pair<>())); + verify(filter).apply(any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/OrFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/OrFilterTest.java new file mode 100644 index 000000000..8316a6b7a --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/OrFilterTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.common.tuples.Pair; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class OrFilterTest { + @Test + public void testConstructor() { + assertFalse((new OrFilter(mock(Filter.class), mock(Filter.class), mock(Filter.class))).getObjectFilter()); + } + + @Test + public void testApply() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(true); + OrFilter orFilter = new OrFilter(filter, mock(Filter.class), mock(Filter.class)); + assertTrue(orFilter.apply(new Pair<>())); + verify(filter).apply(any()); + } + + @Test + public void testApply2() { + Filter filter = mock(Filter.class); + when(filter.apply(any())).thenReturn(false); + Filter filter1 = mock(Filter.class); + when(filter1.apply(any())).thenReturn(true); + OrFilter orFilter = new OrFilter(filter, filter1, mock(Filter.class)); + assertTrue(orFilter.apply(new Pair<>())); + verify(filter1).apply(any()); + verify(filter).apply(any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java index cc63de37c..d5a8d8f4f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/RegexFilterTest.java @@ -11,16 +11,31 @@ public class RegexFilterTest { @Test public void testConstructor() { - RegexFilter actualRegexFilter = new RegexFilter("field", "value"); - assertEquals("field", actualRegexFilter.getField()); + RegexFilter actualRegexFilter = new RegexFilter("Field", "42"); + assertEquals("(Field regex 42)", actualRegexFilter.toString()); + assertEquals("Field", actualRegexFilter.getField()); assertFalse(actualRegexFilter.getObjectFilter()); - assertEquals("FieldBasedFilter(field=field, value=value, processed=true)", actualRegexFilter.toString()); + } + + @Test + public void testToString() { + RegexFilter regexFilter = new RegexFilter("Field", "42"); + assertEquals("(Field regex 42)", regexFilter.toString()); + assertEquals("(!((Field regex 42)))", regexFilter.not().toString()); + } + + @Test + public void testToString2() { + RegexFilter regexFilter = new RegexFilter("Field", "42"); + regexFilter.setProcessed(true); + regexFilter.setObjectFilter(true); + assertEquals("(Field regex 42)", regexFilter.toString()); } @Test public void testApply() { RegexFilter regexFilter = new RegexFilter("field", "value"); - Pair pair = new Pair(); + Pair pair = new Pair<>(); pair.setSecond(Document.createDocument()); assertFalse(regexFilter.apply(pair)); } @@ -29,7 +44,7 @@ public void testApply() { public void testApply2() { RegexFilter regexFilter = new RegexFilter("field", "value"); NitriteId first = NitriteId.newId(); - assertFalse(regexFilter.apply(new Pair(first, Document.createDocument()))); + assertFalse(regexFilter.apply(new Pair<>(first, Document.createDocument()))); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java new file mode 100644 index 000000000..c942d0e33 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/filters/TextFilterTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.index.fulltext.EnglishTextTokenizer; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class TextFilterTest { + @Test + public void testConstructor() { + TextFilter actualTextFilter = new TextFilter("Field", "42"); + assertEquals("Field", actualTextFilter.getField()); + assertFalse(actualTextFilter.getObjectFilter()); + assertEquals("42", actualTextFilter.getStringValue()); + } + + @Test + public void testToString() { + TextFilter textFilter = new TextFilter("Field", "42"); + assertEquals("(Field like 42)", textFilter.toString()); + assertEquals("42", textFilter.getStringValue()); + } + + @Test + public void testToString2() { + TextFilter textFilter = new TextFilter("Field", "42"); + textFilter.setProcessed(true); + textFilter.setObjectFilter(true); + assertEquals("(Field like 42)", textFilter.toString()); + } + + @Test + public void testApplyOnIndex() { + TextFilter textFilter = new TextFilter("Field", "42"); + textFilter.setTextTokenizer(new EnglishTextTokenizer()); + assertTrue(textFilter.applyOnIndex(new InMemoryMap<>("Map Name", null)).isEmpty()); + assertEquals("42", textFilter.getStringValue()); + } + + @Test + public void testApplyOnIndex3() { + TextFilter textFilter = new TextFilter("Field", "*"); + textFilter.setTextTokenizer(new EnglishTextTokenizer()); + assertThrows(FilterException.class, + () -> textFilter.applyOnIndex(new InMemoryMap<>("Map Name", null))); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/CompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/index/CompoundIndexTest.java new file mode 100644 index 000000000..2e07be283 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/CompoundIndexTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class CompoundIndexTest { + @Test + public void testConstructor() { + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + assertSame(indexDescriptor, (new CompoundIndex(indexDescriptor, null)).getIndexDescriptor()); + } + + @Test + public void testWrite() { + CompoundIndex compoundIndex = new CompoundIndex(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name"), + new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", 1)); + compoundIndex.write(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testRemove() { + CompoundIndex compoundIndex = new CompoundIndex(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name"), + new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", 1)); + compoundIndex.remove(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test(expected = IndexingException.class) + public void testDrop() { + Fields fields = mock(Fields.class); + when(fields.getEncodedName()).thenThrow(new IndexingException("An error occurred")); + CompoundIndex compoundIndex = new CompoundIndex(new IndexDescriptor("Index Type", fields, "Collection Name"), + new InMemoryStore()); + compoundIndex.drop(); + verify(fields).getEncodedName(); + assertFalse(compoundIndex.getIndexDescriptor().isCompoundIndex()); + } + + @Test + public void testDrop2() { + Fields fields = mock(Fields.class); + when(fields.getEncodedName()).thenReturn("foo"); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", fields, "Collection Name"); + CompoundIndex compoundIndex = new CompoundIndex(indexDescriptor, new InMemoryStore()); + compoundIndex.drop(); + verify(fields).getEncodedName(); + assertFalse(compoundIndex.getIndexDescriptor().isCompoundIndex()); + } + + @Test + public void testFindNitriteIds() { + CompoundIndex compoundIndex = new CompoundIndex(new IndexDescriptor("Index Type", new Fields(), "Collection Name"), + null); + assertTrue(compoundIndex.findNitriteIds(new FindPlan()).isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java new file mode 100644 index 000000000..0b5cc9919 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexDescriptorTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.exceptions.ValidationException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class IndexDescriptorTest { + @Test + public void testConstructor() { + IndexDescriptor actualIndexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + assertEquals("Collection Name", actualIndexDescriptor.getCollectionName()); + assertFalse(actualIndexDescriptor.isCompoundIndex()); + assertEquals("Index Type", actualIndexDescriptor.getIndexType()); + } + + @Test(expected = ValidationException.class) + public void testConstructor3() { + Fields fields = new Fields(); + new IndexDescriptor("Index Type", fields, ""); + assertEquals("", fields.getEncodedName()); + assertEquals("[]", fields.toString()); + } + + @Test + public void testCompareTo() { + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + assertEquals(0, indexDescriptor.compareTo(new IndexDescriptor("Index Type", new Fields(), "Collection Name"))); + } + + @Test + public void testIsCompoundIndex() { + assertFalse((new IndexDescriptor("Index Type", new Fields(), "Collection Name")).isCompoundIndex()); + } + + @Test + public void testIsCompoundIndex2() { + Fields fields = new Fields(); + fields.addField("Field"); + fields.addField("Field"); + assertTrue((new IndexDescriptor("Index Type", fields, "Collection Name")).isCompoundIndex()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java new file mode 100644 index 000000000..bf8c48c3e --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.junit.Test; + +import java.util.List; +import java.util.TreeMap; + +import static org.junit.Assert.*; + +public class IndexMapTest { + @Test + public void testConstructor() { + TreeMap dbValueObjectMap = new TreeMap<>(); + IndexMap actualIndexMap = new IndexMap(dbValueObjectMap); + List terminalNitriteIds = actualIndexMap.getTerminalNitriteIds(); + assertTrue(terminalNitriteIds instanceof java.util.ArrayList); + assertFalse(actualIndexMap.isReverseScan()); + assertTrue(terminalNitriteIds.isEmpty()); + assertTrue(dbValueObjectMap.isEmpty()); + } + + @Test + public void testConstructor2() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", null); + IndexMap actualIndexMap = new IndexMap(inMemoryMap); + List terminalNitriteIds = actualIndexMap.getTerminalNitriteIds(); + assertTrue(terminalNitriteIds instanceof java.util.ArrayList); + assertFalse(actualIndexMap.isReverseScan()); + assertTrue(terminalNitriteIds.isEmpty()); + assertEquals("Map Name", inMemoryMap.getName()); + assertEquals(0L, inMemoryMap.size()); + assertTrue(inMemoryMap.isEmpty()); + assertNull(inMemoryMap.getStore()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java index 3605f6fa6..39b10ad38 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexOptionsTest.java @@ -7,8 +7,7 @@ public class IndexOptionsTest { @Test public void testIndexOptions() { - IndexOptions actualIndexOptionsResult = IndexOptions.indexOptions("indexType"); - assertEquals("indexType", actualIndexOptionsResult.getIndexType()); + assertEquals("Index Type", IndexOptions.indexOptions("Index Type").getIndexType()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java index c31207dfc..8347f4fb5 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java @@ -1,12 +1,22 @@ package org.dizitart.no2.index; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.index.fulltext.EnglishTextTokenizer; +import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; public class NitriteTextIndexerTest { @Test public void testConstructor() { + assertEquals(IndexType.Fulltext, (new NitriteTextIndexer(new EnglishTextTokenizer())).getIndexType()); assertEquals("Fulltext", (new NitriteTextIndexer()).getIndexType()); } @@ -14,5 +24,126 @@ public void testConstructor() { public void testGetIndexType() { assertEquals("Fulltext", (new NitriteTextIndexer()).getIndexType()); } + + @Test + public void testInitialize() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + NitriteConfig nitriteConfig = new NitriteConfig(); + nitriteTextIndexer.initialize(nitriteConfig); + assertEquals(1, nitriteConfig.getSchemaVersion().intValue()); + } + + @Test + public void testValidateIndex() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + Fields fields = new Fields(); + nitriteTextIndexer.validateIndex(fields); + assertEquals("[]", fields.toString()); + } + + @Test + public void testValidateIndex2() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + + Fields fields = new Fields(); + fields.addField("Field"); + nitriteTextIndexer.validateIndex(fields); + assertEquals("[Field]", fields.toString()); + } + + @Test + public void testValidateIndex3() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + + Fields fields = new Fields(); + fields.addField("Field"); + fields.addField("Field"); + assertThrows(IndexingException.class, () -> nitriteTextIndexer.validateIndex(fields)); + } + + @Test(expected = IndexingException.class) + public void testDropIndex() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + Fields fields = mock(Fields.class); + when(fields.getEncodedName()).thenThrow(new IndexingException("An error occurred")); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", fields, "Collection Name"); + nitriteTextIndexer.dropIndex(indexDescriptor, new NitriteConfig()); + verify(fields).getEncodedName(); + assertFalse(indexDescriptor.isCompoundIndex()); + } + + @Test(expected = IndexingException.class) + public void testDropIndex2() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + IndexDescriptor indexDescriptor = mock(IndexDescriptor.class); + when(indexDescriptor.getIndexType()).thenThrow(new IndexingException("An error occurred")); + when(indexDescriptor.getIndexFields()).thenReturn(new Fields()); + when(indexDescriptor.getCollectionName()).thenReturn("foo"); + nitriteTextIndexer.dropIndex(indexDescriptor, new NitriteConfig()); + verify(indexDescriptor).getIndexType(); + verify(indexDescriptor).getIndexFields(); + verify(indexDescriptor).getCollectionName(); + } + + @Test + public void testDropIndex3() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + IndexDescriptor indexDescriptor = mock(IndexDescriptor.class); + when(indexDescriptor.getIndexType()).thenReturn("foo"); + when(indexDescriptor.getIndexFields()).thenReturn(new Fields()); + when(indexDescriptor.getCollectionName()).thenReturn("foo"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + nitriteTextIndexer.dropIndex(indexDescriptor, nitriteConfig); + verify(indexDescriptor).getIndexType(); + verify(indexDescriptor).getIndexFields(); + verify(indexDescriptor).getCollectionName(); + verify(nitriteConfig).getNitriteStore(); + } + + @Test + public void testWriteIndexEntry() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", "1")); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + nitriteTextIndexer.writeIndexEntry(fieldValues, indexDescriptor, nitriteConfig); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testRemoveIndexEntry() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", "1")); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + nitriteTextIndexer.removeIndexEntry(fieldValues, indexDescriptor, nitriteConfig); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testFindByFilter() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + + FindPlan findPlan = new FindPlan(); + findPlan.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + assertTrue(nitriteTextIndexer.findByFilter(findPlan, new NitriteConfig()).isEmpty()); + } + + @Test + public void testFindByFilter2() { + NitriteTextIndexer nitriteTextIndexer = new NitriteTextIndexer(); + + FindPlan findPlan = new FindPlan(); + findPlan.setIndexScanFilter(null); + findPlan.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + assertTrue(nitriteTextIndexer.findByFilter(findPlan, new NitriteConfig()).isEmpty()); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java index da4642b06..8fb86e862 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java @@ -1,11 +1,19 @@ package org.dizitart.no2.index; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import org.junit.Test; - public class NonUniqueIndexerTest { + + @Test + public void testConstructor() { + NonUniqueIndexer actualNonUniqueIndexer = new NonUniqueIndexer(); + assertEquals(IndexType.NonUnique, actualNonUniqueIndexer.getIndexType()); + assertFalse(actualNonUniqueIndexer.isUnique()); + } + @Test public void testIsUnique() { assertFalse((new NonUniqueIndexer()).isUnique()); diff --git a/nitrite/src/test/java/org/dizitart/no2/index/SingleFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/index/SingleFieldIndexTest.java new file mode 100644 index 000000000..b033fc100 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/SingleFieldIndexTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.dizitart.no2.common.tuples.Pair.pair; +import static org.junit.Assert.*; + +public class SingleFieldIndexTest { + @Test + public void testConstructor() { + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + assertSame(indexDescriptor, (new SingleFieldIndex(indexDescriptor, null)).getIndexDescriptor()); + } + + @Test + public void testWrite() { + SingleFieldIndex singleFieldIndex = new SingleFieldIndex( + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(pair("a", 1)); + singleFieldIndex.write(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testRemove() { + SingleFieldIndex singleFieldIndex = new SingleFieldIndex( + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(pair("a", 1)); + singleFieldIndex.remove(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testFindNitriteIds() { + SingleFieldIndex singleFieldIndex = new SingleFieldIndex( + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), null); + assertTrue(singleFieldIndex.findNitriteIds(new FindPlan()).isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/TextIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/index/TextIndexTest.java new file mode 100644 index 000000000..1dfff7611 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/index/TextIndexTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.index; + +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.index.fulltext.EnglishTextTokenizer; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class TextIndexTest { + @Test + public void testConstructor() { + EnglishTextTokenizer textTokenizer = new EnglishTextTokenizer(); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); + assertSame(indexDescriptor, (new TextIndex(textTokenizer, indexDescriptor, null)).getIndexDescriptor()); + } + + @Test + public void testWrite() { + EnglishTextTokenizer textTokenizer = new EnglishTextTokenizer(); + TextIndex textIndex = new TextIndex(textTokenizer, + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", "1")); + textIndex.write(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test + public void testRemove() { + EnglishTextTokenizer textTokenizer = new EnglishTextTokenizer(); + TextIndex textIndex = new TextIndex(textTokenizer, + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), new InMemoryStore()); + FieldValues fieldValues = new FieldValues(); + fieldValues.getValues().add(Pair.pair("a", "1")); + textIndex.remove(fieldValues); + assertEquals("FieldValues(nitriteId=null, fields=[a], values=[Pair(first=a, second=1)])", fieldValues.toString()); + assertEquals("[a]", fieldValues.getFields().toString()); + } + + @Test(expected = IndexingException.class) + public void testDrop() { + Fields fields = mock(Fields.class); + when(fields.getEncodedName()).thenThrow(new IndexingException("An error occurred")); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", fields, "Collection Name"); + TextIndex textIndex = new TextIndex(new EnglishTextTokenizer(), indexDescriptor, null); + textIndex.drop(); + verify(fields).getEncodedName(); + assertFalse(textIndex.getIndexDescriptor().isCompoundIndex()); + } + + @Test + public void testDrop2() { + Fields fields = mock(Fields.class); + when(fields.getEncodedName()).thenReturn("foo"); + IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", fields, "Collection Name"); + EnglishTextTokenizer textTokenizer = new EnglishTextTokenizer(); + TextIndex textIndex = new TextIndex(textTokenizer, indexDescriptor, new InMemoryStore()); + textIndex.drop(); + verify(fields).getEncodedName(); + assertFalse(textIndex.getIndexDescriptor().isCompoundIndex()); + } + + @Test + public void testFindNitriteIds() { + EnglishTextTokenizer textTokenizer = new EnglishTextTokenizer(); + TextIndex textIndex = new TextIndex(textTokenizer, + new IndexDescriptor("Index Type", new Fields(), "Collection Name"), null); + assertTrue(textIndex.findNitriteIds(new FindPlan()).isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java index 12305e965..f80bd996d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java @@ -1,11 +1,18 @@ package org.dizitart.no2.index; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.Test; - public class UniqueIndexerTest { + @Test + public void testConstructor() { + UniqueIndexer actualUniqueIndexer = new UniqueIndexer(); + assertEquals(IndexType.Unique, actualUniqueIndexer.getIndexType()); + assertTrue(actualUniqueIndexer.isUnique()); + } + @Test public void testGetIndexType() { assertEquals("Unique", (new UniqueIndexer()).getIndexType()); diff --git a/nitrite/src/test/java/org/dizitart/no2/index/fulltext/TokenizerTests.java b/nitrite/src/test/java/org/dizitart/no2/index/fulltext/TokenizerTests.java index a8a0a6ea6..5d1fe83c2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/fulltext/TokenizerTests.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/fulltext/TokenizerTests.java @@ -16,7 +16,7 @@ package org.dizitart.no2.index.fulltext; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java similarity index 94% rename from nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java index f2796c16a..97f99f1bd 100644 --- a/nitrite/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -25,7 +27,7 @@ import org.junit.Rule; import org.junit.Test; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; diff --git a/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java similarity index 85% rename from nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java index 7ba99494f..e162cf21c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/CustomFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java @@ -1,22 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; -import org.dizitart.no2.collection.BaseCollectionTest; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.index.IndexType; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java b/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java similarity index 96% rename from nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java rename to nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java index 4bdf06148..dc3fbb421 100644 --- a/nitrite/src/test/java/org/dizitart/no2/DbTestOperations.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -28,7 +30,7 @@ import java.text.SimpleDateFormat; import java.util.*; -import static org.dizitart.no2.TestUtil.isSorted; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.Filter.*; diff --git a/nitrite/src/test/java/org/dizitart/no2/DocumentMetadataTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java similarity index 91% rename from nitrite/src/test/java/org/dizitart/no2/DocumentMetadataTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java index 3a912de78..15d01451f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/DocumentMetadataTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java @@ -1,22 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; -import org.dizitart.no2.collection.BaseCollectionTest; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.events.EventType; diff --git a/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java similarity index 93% rename from nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java index bccb17eef..e77dc7cda 100644 --- a/nitrite/src/test/java/org/dizitart/no2/MultiThreadedTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -34,8 +36,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java similarity index 91% rename from nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java index 4288b1def..21a2d5731 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.concurrent.ThreadPoolManager; @@ -26,7 +28,7 @@ import java.util.concurrent.ExecutorService; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.Filter.ALL; import static org.junit.Assert.assertFalse; diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java similarity index 86% rename from nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java index 10ce57aa2..df0242dcc 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteSecurityTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java @@ -1,27 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; import org.junit.After; import org.junit.Rule; import org.junit.Test; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertEquals; diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java similarity index 92% rename from nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index 1fa0fea66..046c92e28 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteStressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -1,27 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.Data; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.Rule; @@ -34,7 +36,7 @@ import java.util.ArrayList; import java.util.List; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/NitriteTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java index aade2165f..27bc65d8e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java @@ -1,24 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; @@ -30,8 +32,8 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; @@ -52,7 +54,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; import static org.dizitart.no2.common.Constants.META_MAP_NAME; diff --git a/nitrite/src/test/java/org/dizitart/no2/Retry.java b/nitrite/src/test/java/org/dizitart/no2/integration/Retry.java similarity index 66% rename from nitrite/src/test/java/org/dizitart/no2/Retry.java rename to nitrite/src/test/java/org/dizitart/no2/integration/Retry.java index b9706d1a0..3d6a27d11 100644 --- a/nitrite/src/test/java/org/dizitart/no2/Retry.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/Retry.java @@ -1,4 +1,21 @@ -package org.dizitart.no2; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration; import org.junit.rules.TestRule; import org.junit.runner.Description; diff --git a/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java similarity index 91% rename from nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java index f38a4e27a..7a759aeb3 100644 --- a/nitrite/src/test/java/org/dizitart/no2/SerializabilityTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.Data; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.exceptions.ValidationException; @@ -27,7 +29,7 @@ import java.io.Serializable; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; /** * @author Anindya Chatterjee diff --git a/nitrite/src/test/java/org/dizitart/no2/StressTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java similarity index 96% rename from nitrite/src/test/java/org/dizitart/no2/StressTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java index 739b2ad05..27a23e173 100644 --- a/nitrite/src/test/java/org/dizitart/no2/StressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java @@ -1,30 +1,32 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.Data; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; diff --git a/nitrite/src/test/java/org/dizitart/no2/TestUtil.java b/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java similarity index 96% rename from nitrite/src/test/java/org/dizitart/no2/TestUtil.java rename to nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java index b71985ec5..c1d9e4b89 100644 --- a/nitrite/src/test/java/org/dizitart/no2/TestUtil.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.core.JsonParser; @@ -22,6 +23,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java similarity index 92% rename from nitrite/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java index e6ab26352..121068b5f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java @@ -1,29 +1,31 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.integration.Retry; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -46,7 +48,7 @@ public abstract class BaseCollectionTest { protected Document doc1, doc2, doc3; protected SimpleDateFormat simpleDateFormat; - @Rule +// @Rule public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Secured = {0}") diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java new file mode 100644 index 000000000..d22be7ba8 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Date; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexNegativeTest extends BaseCollectionTest { + + @Test(expected = UniqueConstraintException.class) + public void testCreateInvalidUniqueIndex() { + doc1 = createDocument("firstName", "fn3") + .put("lastName", "ln2") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", Arrays.asList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + + collection.createIndex("lastName", "firstName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateUniqueMultiKeyIndexOnArray() { + collection.createIndex("data", "lastName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateOnInvalidField() { + insert(); + // multiple null value will be created + collection.createIndex( "my-value", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testDropIndexOnNonIndexedField() { + collection.dropIndex("data", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testRebuildIndexInvalid() { + collection.rebuildIndex("unknown", "firstName"); + } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameFields() { + collection.createIndex(indexOptions(IndexType.Unique), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testIndexAlreadyExists() { + collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateCompoundTextIndex() { + collection.createIndex(indexOptions(IndexType.Fulltext), "body", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateMultiKeyIndexSecondField() { + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "data"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java new file mode 100644 index 000000000..51af747be --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.awaitility.Awaitility.await; +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexTest extends BaseCollectionTest { + @Test + public void testCreateAndCheckIndex() { + collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertFalse(collection.hasIndex("firstName", "lastName", "birthDay")); + assertFalse(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testCreateMultiKeyIndexFirstField() { + collection.createIndex(indexOptions(IndexType.NonUnique), "data", "lastName"); + assertTrue(collection.hasIndex("data")); + assertTrue(collection.hasIndex("data", "lastName")); + assertFalse(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testListIndexes() { + assertEquals(collection.listIndices().size(), 0); + collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + assertEquals(collection.listIndices().size(), 1); + + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + assertEquals(collection.listIndices().size(), 2); + } + + @Test + public void testDropIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + collection.dropIndex("firstName", "lastName"); + assertFalse(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertFalse(collection.hasIndex("firstName")); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testHasIndex() { + assertFalse(collection.hasIndex("lastName")); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + assertTrue(collection.hasIndex("lastName")); + } + + @Test + public void testDropAllIndexes() { + collection.dropAllIndices(); + + collection.createIndex("firstName", "lastName"); + collection.createIndex("firstName"); + assertEquals(collection.listIndices().size(), 2); + + collection.dropAllIndices(); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testRebuildIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + insert(); + collection.rebuildIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + } + + @Test + public void testDeleteWithIndex() { + collection.createIndex("firstName", "lastName"); + + insert(); + + WriteResult result = collection.remove(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + assertEquals(result.getAffectedCount(), 1); + + result = collection.remove(and(where("firstName").eq("fn2"), + where("birthDay").gte(new Date()))); + assertEquals(result.getAffectedCount(), 0); + } + + @Test + public void testRebuildIndexOnRunningIndex() { + insert(); + db.getStore().subscribe(System.out::println); + + collection.createIndex("firstName", "lastName"); + collection.rebuildIndex("firstName", "lastName"); + + assertTrue(collection.hasIndex("firstName", "lastName")); + } + + @Test + public void testNullValuesInIndexedFields() { + collection.createIndex("firstName", "lastName"); + collection.createIndex("birthDay", "lastName"); + Document document = createDocument("firstName", null) + .put("lastName", "ln1") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) + .put("body", "a quick brown fox jump over the lazy dog"); + + insert(); + collection.insert(document); + + DocumentCursor cursor = collection.find(where("fistName").eq(null)); + assertEquals("ln1", cursor.firstOrNull().get("lastName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + document = createDocument("firstName", "fn4") + .put("lastName", null) + .put("birthDay", null) + .put("data", new byte[]{1, 2, 3}) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) + .put("body", "a quick brown fox jump over the lazy dog"); + collection.insert(document); + + cursor = collection.find(where("lastName").eq(null)); + assertEquals("fn4", cursor.firstOrNull().get("firstName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + cursor = collection.find(and(where("lastName").eq(null), where("birthDay").eq(null))); + assertNull(cursor.firstOrNull().get("lastName", String.class)); + } + + @Test + public void testDropAllAndCreateIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + + DocumentCursor cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + FindPlan findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + + collection.dropAllIndices(); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + + collection.createIndex("firstName", "lastName"); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + } + + @Test + public void testIssue178() { + collection.dropAllIndices(); + collection.remove(Filter.ALL); + + Document doc1 = createDocument("field1", 5); + Document doc2 = createDocument("field1", 4.3).put("field2", 3.5); + Document doc3 = createDocument("field1", 0.03).put("field2", 5); + Document doc4 = createDocument("field1", 4).put("field2", 4.5); + Document doc5 = createDocument("field1", 5.0).put("field2", 5.0); + + collection.insert(doc1, doc2, doc3, doc4, doc5); + + DocumentCursor cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + + collection.createIndex("field1", "field2"); + cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + } + + @Test + public void testIndexEvent() { + NitriteCollection collection = db.getCollection("index-test"); + Random random = new Random(); + for (int i = 0; i < 10000; i++) { + Document document = createDocument("first", random.nextInt()) + .put("second", random.nextDouble()); + collection.insert(document); + } + + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); + collection.subscribe(eventInfo -> { + switch (eventInfo.getEventType()) { + case Insert: + case Remove: + case Update: + failed.set(true); + break; + case IndexStart: + case IndexEnd: + completed.set(true); + break; + } + }); + + collection.createIndex(indexOptions(IndexType.NonUnique), "first", "second"); + assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); + } + + @Test + public void testIndexAndSearchOnNullValues() { + NitriteCollection collection = db.getCollection("index-on-null"); + collection.insert(createDocument("first", null).put("second", 123).put("third", new Integer[]{1, 2, null})); + collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); + collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); + + collection.createIndex("third", "first"); + assertEquals(collection.find(where("first").eq(null)).size(), 1); + + assertEquals(collection.find(where("third").eq(null)).size(), 2); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java similarity index 86% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java index 61ac96fc5..9c9d9bd6a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java @@ -1,21 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.NitriteIOException; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java similarity index 94% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java index c948624db..f0c81e241 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java new file mode 100644 index 000000000..d119f0844 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.AndFilter; +import org.dizitart.no2.filters.IndexScanFilter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.text.ParseException; +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionFindByCompoundIndexTest extends BaseCollectionTest { + + @Test + public void testFindByAndFilter() { + insert(); + collection.createIndex("list", "lastName", "firstName"); + DocumentCursor cursor = collection.find(and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1"), + where("list").eq("four") + )); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(findPlan.getIndexDescriptor(), collection.listIndices().toArray()[0]); + + IndexScanFilter indexScanFilter = findPlan.getIndexScanFilter(); + assertEquals(indexScanFilter.getFilters().get(0), where("list").eq("four")); + assertEquals(indexScanFilter.getFilters().get(1), where("lastName").eq("ln2")); + assertEquals(indexScanFilter.getFilters().get(2), where("firstName").notEq("fn1")); + + List documents = cursor.toList(); + assertEquals(documents.size(), 1); + assertEquals(documents.get(0).get("body", String.class), "quick hello world from nitrite"); + } + + @Test + public void testFindByOrFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + or( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getSubPlans()); + + assertEquals(2, findPlan.getSubPlans().size()); + assertNotNull(findPlan.getSubPlans().get(0).getIndexScanFilter()); + assertNotNull(findPlan.getSubPlans().get(1).getIndexScanFilter()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn2") + && d.get("lastName", String.class).equals("ln2")).count()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn3") + && d.get("lastName", String.class).equals("ln2")).count()); + } + + @Test + public void testFindByAndFilterOrFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ), findPlan.getCollectionScanFilter()); + } + + @Test + public void testFindByAndFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(1, cursor.size()); + FindPlan findPlan = cursor.getFindPlan(); + + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(collection.listIndices().toArray()[0], findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getIndexScanFilter()); + assertEquals(findPlan.getIndexScanFilter().getFilters(), + ((AndFilter) and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + )).getFilters()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(where("firstName").eq("fn3"), findPlan.getCollectionScanFilter()); + + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(cursor.toList().get(0).get("firstName", String.class), "fn3"); + } + + @Test + public void testFindByOrFilter() throws ParseException { + // all or clause has index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + collection.createIndex("birthDay"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(3, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindOrNoIndex() throws ParseException { + // on of the or clause has no index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(0, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindAndNoIndex() throws ParseException { + // index at second field + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + where("firstName").notEq("fn1"), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(0, cursor.size()); + } + + @Test + public void testSortByIndex() throws ParseException { + // multiple field sort in both direction + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } + + @Test + public void testBlockingSort() throws ParseException { + // multiple field sort in memory + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortNotCoveredByIndex() throws ParseException { + // some field sort by index, some by memory + + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortByIndexPrefix() throws ParseException { + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + // duplicate birthday will have natural sort order - ascending + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + } + + @Test + public void testLimitAndSkip() throws ParseException { + // test skip and limit + + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + .skip(2) + .limit(1) + ); + + List documents = cursor.toList(); + assertEquals(1, documents.size()); + + Document document = documents.get(0); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + assertEquals(2L, (long)findPlan.getSkip()); + assertEquals(1L, (long)findPlan.getLimit()); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java similarity index 88% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java index d0256f1c7..4be3bd9fd 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java index 8f6f8ee1d..aaf2b8616 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java @@ -1,22 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import com.github.javafaker.Faker; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; @@ -29,7 +33,7 @@ import java.util.Date; import java.util.List; -import static org.dizitart.no2.TestUtil.isSorted; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.Filter.and; import static org.dizitart.no2.filters.Filter.or; @@ -40,7 +44,7 @@ /** * @author Anindya Chatterjee. */ -public class CollectionFindByIndexTest extends BaseCollectionTest { +public class CollectionFindBySingleFieldIndexTest extends BaseCollectionTest { @Test public void testFindByUniqueIndex() throws ParseException { diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java similarity index 90% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java index 953f46352..c0e84a688 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java @@ -1,21 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.ValidationException; @@ -52,12 +55,6 @@ public void testFindOptionsNegativeSize() { collection.find(skipBy(0).limit(-1)); } - @Test(expected = ValidationException.class) - public void testFindOptionsInvalidOffset() { - insert(); - assertEquals(collection.find(skipBy(10).limit(1)).size(), 0); - } - @Test(expected = ValidationException.class) public void testFindInvalidSort() { insert(); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java similarity index 86% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java index 78edf3a05..967ba438c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java @@ -1,22 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; -import org.dizitart.no2.common.NullOrder; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.ValidationException; @@ -30,7 +34,7 @@ import java.util.*; import java.util.stream.Collectors; -import static org.dizitart.no2.TestUtil.isSorted; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.collection.FindOptions.*; import static org.dizitart.no2.common.Constants.*; @@ -635,7 +639,8 @@ public void testIssue72() { assertNull(cursor.toList().get(1).get("startTime")); assertNotNull(cursor.toList().get(0).get("startTime")); - cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Ascending)); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(0).get("startTime")); assertNotNull(cursor.toList().get(1).get("startTime")); @@ -653,64 +658,14 @@ public void testIssue93() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); } - @Test - public void testNullOrderWithAllNull() { - NitriteCollection coll = db.getCollection("test"); - - coll.remove(ALL); - - Document doc = createDocument().put("id", "test-2").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - doc = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); - assertEquals(2, cursor.size()); - - DocumentCursor cursor2 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Default)); - assertEquals(2, cursor2.size()); - - assertThat(cursor.toList(), is(cursor2.toList())); - - DocumentCursor cursor3 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.First)); - assertEquals(2, cursor3.size()); - - assertThat(cursor.toList(), is(cursor3.toList())); - - DocumentCursor cursor4 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Last)); - assertEquals(2, cursor4.size()); - - assertThat(cursor.toList(), is(cursor4.toList())); - - DocumentCursor cursor5 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Last)); - assertEquals(2, cursor5.size()); - - assertThat(cursor.toList(), is(cursor5.toList())); - - DocumentCursor cursor6 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.First)); - assertEquals(2, cursor6.size()); - - assertThat(cursor.toList(), is(cursor6.toList())); - - DocumentCursor cursor7 = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Default)); - assertEquals(2, cursor7.size()); - - assertThat(cursor.toList(), is(cursor7.toList())); - } @Test - public void testNullOrder() { + public void testDefaultNullOrder() { NitriteCollection coll = db.getCollection("test"); try { coll.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "startTime"); @@ -729,46 +684,18 @@ public void testNullOrder() { Document doc3 = createDocument().put("id", "test-3").put("group", "groupA").put("startTime", DateTime.now().plusMinutes(1)); assertEquals(1, coll.insert(doc3).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA"), orderBy("startTime", SortOrder.Descending)); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA") , - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.First)); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc3, doc2), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Default)); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Descending).nullOrder(NullOrder.Last)); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.First)); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc2, doc3), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); cursor = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Default)); + orderBy("startTime", SortOrder.Ascending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc2, doc3), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA"), - orderBy("startTime", SortOrder.Ascending).nullOrder(NullOrder.Last)); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc2, doc3, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java index 90c1ba0ef..02358caf6 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java similarity index 87% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java index f7d538c31..cd9558946 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java @@ -1,21 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; import org.junit.Test; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java similarity index 93% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java index 2d8ef5ac5..caff44d61 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java @@ -1,22 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.junit.Before; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java similarity index 76% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java index 36d38c808..3f7d1dfbc 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; @@ -22,12 +23,13 @@ import org.dizitart.no2.index.IndexType; import org.junit.Test; +import static org.dizitart.no2.index.IndexOptions.indexOptions; import static org.junit.Assert.assertTrue; /** * @author Anindya Chatterjee. */ -public class CollectionIndexNegativeTest extends BaseCollectionTest { +public class CollectionSingleFieldIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { @@ -44,9 +46,10 @@ public void testCreateIndexOnArray() { insert(); } - @Test + @Test(expected = UniqueConstraintException.class) public void testCreateOnInvalidField() { insert(); + // multiple null value will be created collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "my-value"); assertTrue(collection.hasIndex("my-value")); } @@ -67,4 +70,10 @@ public void testDropIndexOnNonIndexedField() { public void testRebuildIndexInvalid() { collection.rebuildIndex("unknown"); } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameField() { + collection.createIndex(indexOptions(IndexType.Unique), "lastName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java similarity index 83% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java index c7ea908df..e840e2c27 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java @@ -1,21 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; @@ -27,6 +31,7 @@ import java.util.Collection; import java.util.Random; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; import static org.awaitility.Awaitility.await; import static org.dizitart.no2.collection.Document.createDocument; @@ -37,7 +42,7 @@ /** * @author Anindya Chatterjee. */ -public class CollectionIndexTest extends BaseCollectionTest { +public class CollectionSingleFieldIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { @@ -123,15 +128,6 @@ public void testDeleteWithIndex() { assertEquals(cursor.size(), 1); } - @Test - public void testCreateIndexAsync() { - insert(); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); - assertTrue(collection.isIndexing("body")); - - await().until(bodyIndexingCompleted()); - } - @Test public void testRebuildIndex() { collection.createIndex(indexOptions(IndexType.Fulltext), "body"); @@ -142,34 +138,19 @@ public void testRebuildIndex() { } } - @Test - public void testRebuildIndexAsync() { - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); - insert(); - await().until(bodyIndexingCompleted()); - - Collection indices = collection.listIndices(); - for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); - await().until(bodyIndexingCompleted()); - } - } - @Test public void testRebuildIndexOnRunningIndex() { collection.createIndex(indexOptions(IndexType.Fulltext), "body"); - Collection indices = collection.listIndices(); - IndexDescriptor idx = indices.iterator().next(); insert(); - collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); + collection.rebuildIndex("body"); boolean error = false; try { - collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); + collection.rebuildIndex("body"); } catch (IndexingException ie) { error = true; } finally { - assertTrue(error); + assertFalse(error); await().until(bodyIndexingCompleted()); } } @@ -244,23 +225,20 @@ public void testIndexEvent() { collection.insert(document); } + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); collection.subscribe(eventInfo -> { switch (eventInfo.getEventType()) { case Insert: - fail("wrong event Insert"); - break; - case Update: - fail("wrong event Update"); - break; case Remove: - fail("wrong event Remove"); + case Update: + failed.set(true); break; case IndexStart: case IndexEnd: + completed.set(true); break; } - assertTrue(eventInfo.getItem() instanceof String); - System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); }); collection.createIndex(indexOptions(IndexType.NonUnique), "first"); @@ -268,6 +246,9 @@ public void testIndexEvent() { collection.createIndex(indexOptions(IndexType.NonUnique), "second"); assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); } @Test @@ -283,4 +264,11 @@ public void testIndexAndSearchOnNullValues() { collection.createIndex(indexOptions(IndexType.NonUnique), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } + + @Test + public void testCreateCompoundAndSingleFieldIndexOnSameField() { + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java similarity index 96% rename from nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java index a0e0c6183..86bff59b5 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java @@ -1,21 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.UpdateOptions; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.NotIdentifiableException; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java index 23064ebe9..f3ae1b720 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java @@ -1,27 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -40,8 +43,9 @@ public abstract class BaseObjectRepositoryTest { protected ObjectRepository employeeRepository; protected ObjectRepository aObjectRepository; protected ObjectRepository cObjectRepository; + protected ObjectRepository bookRepository; -// @Rule + @Rule public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Protected = {0}") @@ -62,6 +66,8 @@ public void setUp() { aObjectRepository = db.getRepository(ClassA.class); cObjectRepository = db.getRepository(ClassC.class); + bookRepository = db.getRepository(Book.class); + for (int i = 0; i < 10; i++) { Company company = DataGenerator.generateCompanyRecord(); companyRepository.insert(company); @@ -71,6 +77,9 @@ public void setUp() { aObjectRepository.insert(ClassA.create(i + 50)); cObjectRepository.insert(ClassC.create(i + 30)); + + Book book = DataGenerator.randomBook(); + bookRepository.insert(book); } } @@ -103,6 +112,10 @@ public void clear() throws Exception { cObjectRepository.remove(ALL); } + if (bookRepository != null && !bookRepository.isDropped()) { + bookRepository.remove(ALL); + } + if (db != null && !db.isClosed()) { db.commit(); db.close(); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java similarity index 91% rename from nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java index 9f0519d21..42f6f2983 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,16 +23,17 @@ import lombok.ToString; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.dizitart.no2.repository.data.Company; -import org.dizitart.no2.repository.data.Note; +import org.dizitart.no2.integration.repository.data.Company; +import org.dizitart.no2.integration.repository.data.Note; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -63,7 +65,7 @@ public void setUp() { } @After - public void reset() throws Exception { + public void reset() { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { db.close(); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/InternalClass.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/InternalClass.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java index a23f1736c..1a52708ce 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/InternalClass.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java similarity index 87% rename from nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java index 29e881f29..cc1036d16 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java @@ -1,29 +1,32 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.util.Iterables; import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.repository.data.WithNitriteId; +import org.dizitart.no2.integration.repository.data.WithNitriteId; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; import org.junit.Rule; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java new file mode 100644 index 000000000..c5127bb0e --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.integration.repository.data.Employee; +import org.junit.Test; + +import java.util.AbstractCollection; + +/** + * @author Anindya Chatterjee + */ +public class ObjectCursorTest extends BaseObjectRepositoryTest { + + @Test(expected = ValidationException.class) + public void testProjectForInterface() { + Cursor cursor = employeeRepository.find(); + cursor.project(Comparable.class); + } + + @Test(expected = ValidationException.class) + public void testProjectForPrimitive() { + Cursor cursor = employeeRepository.find(); + cursor.project(int.class); + } + + @Test(expected = ValidationException.class) + public void testProjectForArray() { + Cursor cursor = employeeRepository.find(); + cursor.project(String[].class); + } + + @Test(expected = ValidationException.class) + public void testProjectForAbstractClass() { + Cursor cursor = employeeRepository.find(); + cursor.project(AbstractCollection.class); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java similarity index 94% rename from nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java index 1e45060cb..dbba4d63b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java @@ -1,29 +1,31 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.*; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.integration.repository.data.*; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -124,7 +126,7 @@ public void testFindResultRemove() { result.iterator().remove(); } - @Test(expected = InvalidOperationException.class) + @Test(expected = IndexingException.class) public void testWithObjectId() { ObjectRepository repository = db.getRepository(WithObjectId.class); WithOutId id = new WithOutId(); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java similarity index 92% rename from nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index da6754b82..94ec5cb3a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -1,37 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import com.github.javafaker.Faker; import lombok.Data; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.MappableMapper; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.integration.repository.data.*; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.data.*; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -43,8 +46,8 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.awaitility.Awaitility.await; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.module.NitriteModule.module; import static org.junit.Assert.*; /** @@ -294,12 +297,12 @@ public void testKeyedRepository() { assertEquals(db.listRepositories().size(), 1); assertEquals(db.listKeyedRepository().size(), 2); - assertEquals(employeeRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(employeeRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(managerRepo.find(where("address").eq("xyz")).size(), 0); - assertEquals(managerRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("abcd")).size(), 0); + assertEquals(employeeRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(employeeRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(managerRepo.find(where("address").text("xyz")).size(), 0); + assertEquals(managerRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(developerRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(developerRepo.find(where("address").text("abcd")).size(), 0); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java similarity index 89% rename from nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java index 4e0989821..a384735ad 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ProjectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java @@ -1,24 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.repository.data.SubEmployee; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.junit.Test; import java.util.Iterator; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java new file mode 100644 index 000000000..20d3aa784 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import lombok.val; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteBuilder; +import org.dizitart.no2.integration.repository.data.DataGenerator; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.integration.repository.data.Book; +import org.junit.Test; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryCompoundIndexTest /*extends BaseObjectRepositoryTest*/ { + private Nitrite db; + + @Test + public void test() { + NitriteBuilder nitriteBuilder = Nitrite.builder() + .fieldSeparator("."); + db = nitriteBuilder.openOrCreate(); + + val bookRepository = db.getRepository(Book.class); + + for (int i = 0; i < 10; i++) { + Book book = DataGenerator.randomBook(); + bookRepository.insert(book); + } + + Cursor bookCursor = bookRepository.find(); + for (Book book : bookCursor) { + System.out.println(book); + } + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java new file mode 100644 index 000000000..d29b4cf22 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; +import org.dizitart.no2.collection.*; +import org.dizitart.no2.collection.events.CollectionEventListener; +import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.repository.RepositoryFactory; +import org.dizitart.no2.store.NitriteStore; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; + +import java.util.Collection; + +import static org.junit.Assert.assertNotNull; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryFactoryTest { + private Nitrite db; + + @Rule + public Retry retry = new Retry(3); + + @Test + public void testRepositoryFactory() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertNotNull(factory); + } + + @Test(expected = ValidationException.class) + public void testNullType() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + db = TestUtil.createDb(); + factory.getRepository(db.getConfig(), null, "dummy"); + } + + @Test + public void testNullCollection() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + db = TestUtil.createDb(); + factory.getRepository(db.getConfig(), DummyCollection.class, null); + } + + @Test(expected = ValidationException.class) + public void testNullContext() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + factory.getRepository(null, DummyCollection.class, "dummy"); + } + + @After + public void cleanUp() throws Exception { + if (db != null && !db.isClosed()) { + db.close(); + } + } + + private static class DummyCollection implements NitriteCollection { + + @Override + public WriteResult insert(Document document, Document... documents) { + return null; + } + + @Override + public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { + return null; + } + + @Override + public WriteResult remove(Filter filter, boolean justOne) { + return null; + } + + @Override + public DocumentCursor find() { + return null; + } + + @Override + public DocumentCursor find(Filter filter) { + return null; + } + + @Override + public DocumentCursor find(Filter filter, FindOptions findOptions) { + return null; + } + + @Override + public Document getById(NitriteId nitriteId) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public void addProcessor(Processor processor) { + + } + + @Override + public void removeProcessor(Processor processor) { + + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fields) { + + } + + @Override + public void rebuildIndex(String... fields) { + + } + + @Override + public Collection listIndices() { + return null; + } + + @Override + public boolean hasIndex(String... fields) { + return false; + } + + @Override + public boolean isIndexing(String... fields) { + return false; + } + + @Override + public void dropIndex(String... fields) { + + } + + @Override + public void dropAllIndices() { + + } + + @Override + public WriteResult insert(Document[] elements) { + return null; + } + + @Override + public WriteResult update(Document element, boolean insertIfAbsent) { + return null; + } + + @Override + public WriteResult remove(Document element) { + return null; + } + + @Override + public void clear() { + + } + + @Override + public void drop() { + + } + + @Override + public boolean isDropped() { + return false; + } + + @Override + public boolean isOpen() { + return false; + } + + @Override + public void close() { + + } + + @Override + public long size() { + return 0; + } + + @Override + public NitriteStore getStore() { + return null; + } + + @Override + public void subscribe(CollectionEventListener listener) { + + } + + @Override + public void unsubscribe(CollectionEventListener listener) { + + } + + @Override + public Attributes getAttributes() { + return null; + } + + @Override + public void setAttributes(Attributes attributes) { + + } + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java similarity index 95% rename from nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java index 4929ec531..84b60956d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java @@ -1,32 +1,34 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.After; import org.junit.Before; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java similarity index 98% rename from nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index e2f3643d8..439f03868 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; @@ -25,7 +26,9 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.integration.repository.data.*; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; import java.text.ParseException; @@ -61,7 +64,8 @@ public void testRebuildIndex() { assertFalse(companyRepository.isIndexing("dateCreated")); companyRepository.rebuildIndex("dateCreated"); - assertTrue(companyRepository.isIndexing("dateCreated")); + // rebuild is sync + assertFalse(companyRepository.isIndexing("dateCreated")); await().until(() -> !companyRepository.isIndexing("dateCreated")); } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java similarity index 91% rename from nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java index 004b97ff9..7de9d5691 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java @@ -1,31 +1,34 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.Getter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.integration.repository.data.*; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; import java.util.Calendar; @@ -35,7 +38,7 @@ import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.collection.FindOptions.skipBy; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.*; @@ -117,11 +120,8 @@ public void testGetByIdNoId() { Note n2 = DataGenerator.randomNote(); Note n3 = DataGenerator.randomNote(); - assert n1 != null; n1.setNoteId(1000000L); - assert n2 != null; n2.setNoteId(2000000L); - assert n3 != null; n3.setNoteId(3000000L); repository.insert(n1, n2, n3); @@ -216,12 +216,14 @@ public void testAndFilter() { String address = emp.getAddress(); Date joinDate = emp.getJoinDate(); - Employee employee = employeeRepository.find( - where("empId").eq(id) - .and( - where("address").regex(address) - .and( - where("joinDate").eq(joinDate)))).firstOrNull(); + Cursor cursor = employeeRepository.find( + and( + where("empId").eq(id), + where("address").regex(address), + where("joinDate").eq(joinDate) + ) + ); + Employee employee = cursor.firstOrNull(); assertEquals(emp, employee); } @@ -232,11 +234,11 @@ public void testOrFilter() { long id = emp.getEmpId(); Employee employee = employeeRepository.find( - where("empId").eq(id) - .or( - where("address").regex("n/a") - .or( - where("joinDate").eq(null)))).firstOrNull(); + or( + where("empId").eq(id), + where("address").text("n/a"), + where("joinDate").eq(null) + )).firstOrNull(); assertEquals(emp, employee); } @@ -312,10 +314,11 @@ public void testTextFilter() { @Test public void testRegexFilter() { - RecordStream employees = employeeRepository.find(); + Cursor employees = employeeRepository.find(); int count = employees.toList().size(); - List employeeList = employeeRepository.find(where("employeeNote.text").regex(".*")) + List employeeList = employeeRepository.find(where("emailAddress") + .regex("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$")) .toList(); assertEquals(employeeList.size(), count); @@ -478,7 +481,7 @@ public void testFilterAll() { assertEquals(cursor.size(), 1); } - @Test + @Test(expected = FilterException.class) public void testEqualsOnTextIndex() { PersonEntity p1 = new PersonEntity("jhonny"); PersonEntity p2 = new PersonEntity("jhonny"); @@ -491,21 +494,6 @@ public void testEqualsOnTextIndex() { List sameNamePeople = repository.find(where("name").eq("jhonny")).toList(); assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhonny")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").text("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 3); } @Test @@ -561,11 +549,11 @@ public void testIdSet() { public void testBetweenFilter() { @Getter class TestData implements Mappable { - private Date age; + private Date age; - public TestData(Date age) { - this.age = age; - } + public TestData(Date age) { + this.age = age; + } @Override public Document write(NitriteMapper mapper) { diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java similarity index 86% rename from nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java index 0a6386335..5ed5e452d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java @@ -1,25 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.repository.data.ClassA; -import org.dizitart.no2.repository.data.ClassC; +import org.dizitart.no2.integration.repository.data.ClassA; +import org.dizitart.no2.integration.repository.data.ClassC; +import org.dizitart.no2.repository.Cursor; import org.junit.Test; import static org.dizitart.no2.collection.FindOptions.orderBy; @@ -33,9 +35,8 @@ public class UnAnnotatedObjectTest extends BaseObjectRepositoryTest { @Test - @SuppressWarnings("unchecked") public void testFind() { - Cursor cursor = aObjectRepository.find(); + Cursor cursor = aObjectRepository.find(); assertEquals(cursor.size(), 10); assertFalse(cursor.isEmpty()); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java similarity index 93% rename from nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index 6f4809830..6fc86b22c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; @@ -23,18 +24,20 @@ import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; import org.junit.After; import org.junit.Before; import org.junit.Test; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.module.NitriteModule.module; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java new file mode 100644 index 000000000..9e2981c35 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Entity; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; + +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity(value = "books", indices = { + @Index(value = "tags", type = IndexType.NonUnique), + @Index(value = "description", type = IndexType.Fulltext), + @Index(value = { "price", "publisher" }) +}) +public class Book implements Mappable { + @Id + private BookId bookId; + + private String publisher; + + private Double price; + + private List tags; + + private String description; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("bookId", mapper.convert(bookId, Document.class)) + .put("publisher", publisher) + .put("price", price) + .put("tags", tags) + .put("description", description); + } + + @Override + @SuppressWarnings("unchecked") + public void read(NitriteMapper mapper, Document document) { + bookId = mapper.convert(document.get("bookId"), BookId.class); + publisher = document.get("publisher", String.class); + price = document.get("price", Double.class); + tags = (List) document.get("tags", List.class); + description = document.get("description", String.class); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java new file mode 100644 index 000000000..05cf9ea07 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Order; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +public class BookId implements Mappable { + @Order(0) + private String isbn; + + @Order(1) + private String name; + + @Order(2) + private String author; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("isbn", isbn) + .put("name", name) + .put("author", author); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + isbn = document.get("isbn", String.class); + name = document.get("name", String.class); + author = document.get("author", String.class); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ChildClass.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java similarity index 83% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ChildClass.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java index f6c2fabb5..d3c2ba644 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ChildClass.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.InheritIndices; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassA.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java similarity index 76% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ClassA.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java index 4cdce3acc..a8161c4e2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassA.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.UUID; @@ -31,7 +32,7 @@ public class ClassA implements Mappable { @Getter @Setter - private ClassB classB; + private ClassB b; @Getter @Setter private UUID uid; @@ -45,7 +46,7 @@ public class ClassA implements Mappable { public static ClassA create(int seed) { ClassB classB = ClassB.create(seed); ClassA classA = new ClassA(); - classA.classB = classB; + classA.b = classB; classA.uid = new UUID(seed, seed + 50); classA.string = Integer.toHexString(seed); classA.blob = new byte[]{(byte) seed}; @@ -55,7 +56,7 @@ public static ClassA create(int seed) { @Override public Document write(NitriteMapper mapper) { return Document.createDocument() - .put("classB", classB != null ? classB.write(mapper) : null) + .put("b", b != null ? b.write(mapper) : null) .put("uid", uid) .put("string", string) .put("blob", blob); @@ -63,9 +64,9 @@ public Document write(NitriteMapper mapper) { @Override public void read(NitriteMapper mapper, Document document) { - if (document.get("classB") != null) { - classB = new ClassB(); - classB.read(mapper, document.get("classB", Document.class)); + if (document.get("b") != null) { + b = new ClassB(); + b.read(mapper, document.get("b", Document.class)); } uid = document.get("uid", UUID.class); string = document.get("string", String.class); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassB.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java similarity index 85% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ClassB.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java index 9be7793e8..a546b91e2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassB.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassC.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ClassC.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java index 4402a7109..860fe1e93 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ClassC.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; @EqualsAndHashCode @ToString @@ -39,7 +40,7 @@ public class ClassC implements Mappable { public static ClassC create(int seed) { ClassC classC = new ClassC(); - classC.id = seed * 5000; + classC.id = seed * 5000L; classC.digit = seed * 69.65; classC.parent = ClassA.create(seed); return classC; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/Company.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java similarity index 79% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/Company.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java index 8171c4bff..84d76786e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/Company.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java @@ -1,28 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; -import lombok.ToString; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; @@ -35,7 +35,6 @@ /** * @author Anindya Chatterjee. */ -@ToString @EqualsAndHashCode @Indices({ @Index(value = "companyName") @@ -80,4 +79,14 @@ public void read(NitriteMapper mapper, Document document) { departments = document.get("departments", List.class); employeeRecord = document.get("employeeRecord", Map.class); } + + @Override + public String toString() { + return "Company{" + + "companyId=" + companyId + + ", companyName='" + companyName + '\'' + + ", dateCreated=" + dateCreated + + ", departments=" + departments + + '}'; + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java similarity index 52% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java index c0a0352be..26e0dcf4a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java @@ -1,26 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; + +import com.github.javafaker.Faker; +import lombok.val; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** @@ -29,14 +31,15 @@ public class DataGenerator { private static final Random random = new Random(System.currentTimeMillis()); private static final AtomicInteger counter = new AtomicInteger(random.nextInt()); + private static final Faker faker = new Faker(random); private DataGenerator() {} public static Company generateCompanyRecord() { Company company = new Company(); company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); - company.setCompanyName(randomCompanyName()); - company.setDateCreated(randomDate()); + company.setCompanyName(faker.company().name()); + company.setDateCreated(faker.date().past(10, TimeUnit.DAYS)); List departments = departments(); company.setDepartments(departments); @@ -62,65 +65,41 @@ private static List generateEmployeeRecords(Company company, int count public static Employee generateEmployee() { Employee employee = new Employee(); employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); - employee.setJoinDate(randomDate()); - employee.setAddress(UUID.randomUUID().toString().replace('-', ' ')); + employee.setJoinDate(faker.date().birthday()); + employee.setAddress(faker.address().fullAddress()); - byte[] blob = new byte[random.nextInt(8000)]; - random.nextBytes(blob); - employee.setBlob(blob); + employee.setBlob(faker.lorem().paragraph().getBytes(StandardCharsets.UTF_8)); employee.setEmployeeNote(randomNote()); + employee.setEmailAddress(faker.internet().emailAddress()); return employee; } - private static Date randomDate() { - return new Date(-946771200000L + - (Math.abs(random.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000))); - } - public static Note randomNote() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.text"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - long line = random.nextInt(49); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - Note note = new Note(); - note.setNoteId(line); - note.setText(strLine); - return note; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; + Note note = new Note(); + note.setNoteId(System.nanoTime() + counter.incrementAndGet()); + note.setText(faker.lorem().paragraph()); + return note; } - private static String randomCompanyName() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("english.stop"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - int line = random.nextInt(570); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - return strLine + System.nanoTime() + " inc."; - } - count++; - } - } catch (IOException e) { - // ignore + public static Book randomBook() { + BookId bookId = new BookId(); + val bookFaker = faker.book(); + bookId.setIsbn(faker.idNumber().ssnValid()); + bookId.setAuthor(bookFaker.author()); + bookId.setName(bookFaker.title()); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription(faker.backToTheFuture().quote()); + book.setPrice(faker.number().randomDouble(2, 100, 500)); + book.setPublisher(bookFaker.publisher()); + List tags = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + tags.add(bookFaker.genre()); } - // ignore - return null; + book.setTags(tags); + return book; } private static List departments() { diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java similarity index 87% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java index dd0042ff1..cb5304e29 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.ArrayList; import java.util.List; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/Employee.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/Employee.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 552adde62..3f4e231f3 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/Employee.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,8 +23,8 @@ import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; @@ -52,6 +53,10 @@ public class Employee implements Serializable, Mappable { @Setter private String address; + @Getter + @Setter + private String emailAddress; + @Getter @Setter private transient Company company; @@ -74,6 +79,7 @@ public Employee(Employee copy) { company = copy.company; blob = copy.blob; employeeNote = copy.employeeNote; + emailAddress = copy.emailAddress; } @Override @@ -83,6 +89,7 @@ public Document write(NitriteMapper mapper) { .put("joinDate", joinDate) .put("address", address) .put("blob", blob) + .put("emailAddress", emailAddress) .put("employeeNote", employeeNote != null ? employeeNote.write(mapper) : null); } @@ -92,6 +99,7 @@ public void read(NitriteMapper mapper, Document document) { joinDate = document.get("joinDate", Date.class); address = document.get("address", String.class); blob = document.get("blob", byte[].class); + emailAddress = document.get("emailAddress", String.class); if (document.get("employeeNote") != null) { employeeNote = new Note(); diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/Note.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Note.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/Note.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Note.java index 24dacae30..67dc307d1 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/Note.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Note.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ParentClass.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java similarity index 85% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ParentClass.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java index 296655f29..bc2514543 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ParentClass.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java similarity index 89% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index 0e1a306a6..63626c769 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/ProductScore.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/ProductScore.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java index 9075ae5f5..65550d182 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/ProductScore.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index 85bfe165d..5c3eae9bd 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/StressRecord.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java similarity index 85% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/StressRecord.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java index 471ae0964..d1cb199c4 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/StressRecord.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java index 8c845a616..8eaa3faf1 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index 26f7e783f..c4e803b8d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Index; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java index ea80f05ca..efbb6766a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithClassField.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithClassField.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java index ebed1725b..79cafe0dc 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithClassField.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java similarity index 83% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java index 3f611bacd..bea5dabe9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithDateId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithDateId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java index 16d113a2c..229f1aaf7 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithDateId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java similarity index 80% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java index 9364a46d8..a0048a6bb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java similarity index 86% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java index 5e2f50044..05afc21e8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java index f219dd263..2364be76d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithNullId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithNullId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java index ecd49c64f..0dc3fb68b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithNullId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java similarity index 80% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java index 295428867..5f00f97d4 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java similarity index 81% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java index 607967bd3..a7a2c56c9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutId.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java index 08cad426e..09b63c2c2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithOutId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java similarity index 84% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java index 25df54331..a425209fb 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; /** * @author Anindya Chatterjee. diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java similarity index 80% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java index 05c0ffc9c..793388231 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java @@ -1,24 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java similarity index 80% rename from nitrite/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java rename to nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java index 9642b8f30..9c1ade657 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java similarity index 90% rename from nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java index 92666817c..ae795393c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java @@ -1,23 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.integration.stream; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -30,7 +31,7 @@ import java.util.Iterator; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java similarity index 89% rename from nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java index 91002f5fb..f8459a1ea 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java @@ -1,23 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.integration.stream; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Lookup; @@ -30,7 +31,7 @@ import java.util.Iterator; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java similarity index 97% rename from nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java index b4a3e6856..d50157908 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java @@ -1,13 +1,32 @@ -package org.dizitart.no2.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; -import org.dizitart.no2.collection.BaseCollectionTest; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.transaction.Session; +import org.dizitart.no2.transaction.Transaction; import org.junit.Test; import java.util.*; diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java similarity index 96% rename from nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index a9ba7ed92..1c8d08e41 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; import org.dizitart.no2.collection.Document; @@ -7,9 +24,11 @@ import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.BaseObjectRepositoryTest; +import org.dizitart.no2.integration.repository.BaseObjectRepositoryTest; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.data.SubEmployee; +import org.dizitart.no2.integration.repository.data.SubEmployee; +import org.dizitart.no2.transaction.Session; +import org.dizitart.no2.transaction.Transaction; import org.junit.Test; import java.util.*; diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TxData.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TxData.java similarity index 82% rename from nitrite/src/test/java/org/dizitart/no2/transaction/TxData.java rename to nitrite/src/test/java/org/dizitart/no2/integration/transaction/TxData.java index f5e7c02cf..1e5ed7ca6 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TxData.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TxData.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.transaction; +package org.dizitart.no2.integration.transaction; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; /** diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/InstructionTypeTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/InstructionTypeTest.java new file mode 100644 index 000000000..6b0fdb25c --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/InstructionTypeTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class InstructionTypeTest { + + @Test + public void testValueOf() { + assertEquals(InstructionType.AddPassword, InstructionType.valueOf("AddPassword")); + } + + @Test + public void testValues() { + assertEquals(21, InstructionType.values().length); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/MigrationStepTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/MigrationStepTest.java new file mode 100644 index 000000000..dfc0d8feb --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/MigrationStepTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MigrationStepTest { + @Test + public void testConstructor() { + MigrationStep actualMigrationStep = new MigrationStep(); + actualMigrationStep.setArguments("Arguments"); + actualMigrationStep.setInstructionType(InstructionType.AddPassword); + assertEquals(InstructionType.AddPassword, actualMigrationStep.getInstructionType()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/NitriteInstructionsTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/NitriteInstructionsTest.java new file mode 100644 index 000000000..0b1e7c621 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/NitriteInstructionsTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration; + +import org.junit.Test; + +import java.util.LinkedList; + +import static org.junit.Assert.assertSame; + +public class NitriteInstructionsTest { + @Test + public void testConstructor() { + LinkedList migrationStepList = new LinkedList<>(); + assertSame(migrationStepList, (new NitriteInstructions(migrationStepList)).getMigrationSteps()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/commands/AddFieldTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/commands/AddFieldTest.java new file mode 100644 index 000000000..73ca7a5fa --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/commands/AddFieldTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration.commands; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class AddFieldTest { + @Test + public void testExecute() { + AddField addField = new AddField("Collection Name", "Field Name", "Default Value"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + addField.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = addField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, addField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, addField.operations.getSize()); + } + + @Test + public void testExecute2() { + AddField addField = new AddField("Collection Name", "Field Name", "Default Value"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + addField.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = addField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, addField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, addField.operations.getSize()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/commands/ChangeDataTypeTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/commands/ChangeDataTypeTest.java new file mode 100644 index 000000000..80b0c42fc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/commands/ChangeDataTypeTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration.commands; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.migration.TypeConverter; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class ChangeDataTypeTest { + @Test + public void testExecute() { + ChangeDataType changeDataType = new ChangeDataType("Collection Name", "Field Name", mock(TypeConverter.class)); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + changeDataType.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = changeDataType.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, changeDataType.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, changeDataType.operations.getSize()); + } + + @Test + public void testExecute2() { + ChangeDataType changeDataType = new ChangeDataType("Collection Name", "Field Name", mock(TypeConverter.class)); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + changeDataType.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = changeDataType.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, changeDataType.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, changeDataType.operations.getSize()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/commands/DeleteFieldTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/commands/DeleteFieldTest.java new file mode 100644 index 000000000..ed65a16d1 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/commands/DeleteFieldTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration.commands; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class DeleteFieldTest { + @Test + public void testExecute() { + DeleteField deleteField = new DeleteField("Collection Name", "Field Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + deleteField.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = deleteField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, deleteField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, deleteField.operations.getSize()); + } + + @Test + public void testExecute2() { + DeleteField deleteField = new DeleteField("Collection Name", "Field Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + deleteField.execute(nitrite); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig).getNitriteStore(); + NitriteMap nitriteMap = deleteField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, deleteField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, deleteField.operations.getSize()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/migration/commands/RenameFieldTest.java b/nitrite/src/test/java/org/dizitart/no2/migration/commands/RenameFieldTest.java new file mode 100644 index 000000000..f28d18d49 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/migration/commands/RenameFieldTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.migration.commands; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class RenameFieldTest { + @Test + public void testExecute() { + RenameField renameField = new RenameField("Collection Name", "Old Name", "New Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + renameField.execute(nitrite); + verify(nitrite, times(2)).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig, times(2)).getNitriteStore(); + NitriteMap nitriteMap = renameField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, renameField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, renameField.operations.getSize()); + } + + @Test + public void testExecute2() { + RenameField renameField = new RenameField("Collection Name", "Old Name", "New Name"); + NitriteConfig nitriteConfig = mock(NitriteConfig.class); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(nitriteConfig); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitrite).getStore(); + renameField.execute(nitrite); + verify(nitrite, times(2)).getConfig(); + verify(nitrite).getStore(); + verify(nitriteConfig, times(2)).getNitriteStore(); + NitriteMap nitriteMap = renameField.nitriteMap; + assertTrue(nitriteMap instanceof org.dizitart.no2.store.memory.InMemoryMap); + assertSame(inMemoryStore, renameField.nitriteStore); + assertNull(nitriteMap.getAttributes()); + assertTrue(nitriteMap.isEmpty()); + assertEquals("Collection Name", nitriteMap.getName()); + assertEquals(0L, renameField.operations.getSize()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/AnnotationScannerTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/AnnotationScannerTest.java new file mode 100644 index 000000000..615c43162 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/repository/AnnotationScannerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.NitriteBuilderTest; +import org.dizitart.no2.collection.NitriteCollection; +import org.junit.Test; + +import java.lang.reflect.Field; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +public class AnnotationScannerTest { + @Test + public void testConstructor() { + Class type = Object.class; + assertNull((new AnnotationScanner(type, null, new NitriteBuilderTest.CustomNitriteMapper())).getObjectIdField()); + } + + @Test + public void testCreateIndices() { + Class type = Object.class; + AnnotationScanner annotationScanner = new AnnotationScanner(type, null, + new NitriteBuilderTest.CustomNitriteMapper()); + annotationScanner.createIndices(); + assertNull(annotationScanner.getObjectIdField()); + } + + @Test + public void testCreateIdIndex() { + Class type = Object.class; + AnnotationScanner annotationScanner = new AnnotationScanner(type, null, + new NitriteBuilderTest.CustomNitriteMapper()); + annotationScanner.createIdIndex(); + assertNull(annotationScanner.getObjectIdField()); + } + + @Test + public void testScanIndices() { + Class type = Object.class; + AnnotationScanner annotationScanner = new AnnotationScanner(type, null, + new NitriteBuilderTest.CustomNitriteMapper()); + annotationScanner.scanIndices(); + assertNull(annotationScanner.getObjectIdField()); + } + + @Test + public void testScanIndices2() { + Class type = Field.class; + AnnotationScanner annotationScanner = new AnnotationScanner(type, null, + new NitriteBuilderTest.CustomNitriteMapper()); + annotationScanner.scanIndices(); + assertNull(annotationScanner.getObjectIdField()); + } + + @Test + public void testScanIndices3() { + Class type = Object.class; + NitriteCollection collection = mock(NitriteCollection.class); + AnnotationScanner annotationScanner = new AnnotationScanner(type, collection, + new NitriteBuilderTest.CustomNitriteMapper()); + annotationScanner.scanIndices(); + assertNull(annotationScanner.getObjectIdField()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/DefaultObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/DefaultObjectRepositoryTest.java new file mode 100644 index 000000000..726cce323 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/repository/DefaultObjectRepositoryTest.java @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.collection.events.CollectionEventListener; +import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.common.streams.DocumentStream; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class DefaultObjectRepositoryTest { + @Test + public void testAddProcessor() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).addProcessor(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.addProcessor(new ProcessorChain()); + verify(nitriteCollection).addProcessor(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testRemoveProcessor() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).removeProcessor(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.removeProcessor(new ProcessorChain()); + verify(nitriteCollection).removeProcessor(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testCreateIndex() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).createIndex(any(), any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.createIndex(IndexOptions.indexOptions("Index Type"), "foo", "foo", "foo"); + verify(nitriteCollection).createIndex(any(), any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testRebuildIndex() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).rebuildIndex(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.rebuildIndex("foo", "foo", "foo"); + verify(nitriteCollection).rebuildIndex(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testListIndices() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + ArrayList indexDescriptorList = new ArrayList<>(); + when(nitriteCollection.listIndices()).thenReturn(indexDescriptorList); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + Collection actualListIndicesResult = defaultObjectRepository.listIndices(); + assertSame(indexDescriptorList, actualListIndicesResult); + assertTrue(actualListIndicesResult.isEmpty()); + verify(nitriteCollection).listIndices(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testHasIndex() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.hasIndex(any())).thenReturn(true); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertTrue(defaultObjectRepository.hasIndex("foo", "foo", "foo")); + verify(nitriteCollection).hasIndex(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testIsIndexing() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.isIndexing(any())).thenReturn(true); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertTrue(defaultObjectRepository.isIndexing("foo", "foo", "foo")); + verify(nitriteCollection).isIndexing(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testDropIndex() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).dropIndex(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.dropIndex("foo", "foo", "foo"); + verify(nitriteCollection).dropIndex(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testDropAllIndices() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).dropAllIndices(); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.dropAllIndices(); + verify(nitriteCollection).dropAllIndices(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testInsert() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.insert(any())).thenReturn(mock(WriteResult.class)); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.insert(new Object[]{}); + verify(nitriteCollection).insert(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testUpdate2() { + DefaultObjectRepository defaultObjectRepository = (DefaultObjectRepository) mock( + DefaultObjectRepository.class); + when(defaultObjectRepository.update(any(), (Object) any(), anyBoolean())).thenReturn(null); + defaultObjectRepository.update(mock(Filter.class), "Update", true); + verify(defaultObjectRepository).update(any(), (Object) any(), anyBoolean()); + } + + @Test + public void testRemove2() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.remove(any(), anyBoolean())).thenReturn(mock(WriteResult.class)); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.remove(mock(Filter.class), true); + verify(nitriteCollection).remove(any(), anyBoolean()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testClear() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).clear(); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.clear(); + verify(nitriteCollection).clear(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testFind() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + when(nitriteCollection.find(any(), any())) + .thenReturn(new DocumentStream(recordStream, new ProcessorChain())); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + Filter filter = mock(Filter.class); + assertNull(defaultObjectRepository.find(filter, new FindOptions()).getFindPlan()); + verify(nitriteCollection).find(any(), any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testDrop() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).drop(); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.drop(); + verify(nitriteCollection).drop(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testIsDropped() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.isDropped()).thenReturn(true); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertTrue(defaultObjectRepository.isDropped()); + verify(nitriteCollection).isDropped(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testIsOpen() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.isOpen()).thenReturn(true); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertTrue(defaultObjectRepository.isOpen()); + verify(nitriteCollection).isOpen(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testClose() throws Exception { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).close(); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.close(); + verify(nitriteCollection).close(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testSize() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + when(nitriteCollection.size()).thenReturn(1L); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertEquals(1L, defaultObjectRepository.size()); + verify(nitriteCollection).size(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testGetStore() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + InMemoryStore inMemoryStore = new InMemoryStore(); + doReturn(inMemoryStore).when(nitriteCollection).getStore(); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertSame(inMemoryStore, defaultObjectRepository.getStore()); + verify(nitriteCollection).getStore(); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testSubscribe() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).subscribe(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.subscribe(mock(CollectionEventListener.class)); + verify(nitriteCollection).subscribe(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testUnsubscribe() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).unsubscribe(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.unsubscribe(mock(CollectionEventListener.class)); + verify(nitriteCollection).unsubscribe(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test + public void testGetAttributes() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + Attributes attributes = new Attributes(); + when(nitriteCollection.getAttributes()).thenReturn(attributes); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + assertSame(attributes, defaultObjectRepository.getAttributes()); + verify(nitriteCollection).getAttributes(); + assertNull(defaultObjectRepository.getStore()); + } + + @Test + public void testSetAttributes() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + doNothing().when(nitriteCollection).setAttributes(any()); + Class type = Object.class; + DefaultObjectRepository defaultObjectRepository = new DefaultObjectRepository<>(type, + nitriteCollection, new NitriteConfig()); + defaultObjectRepository.setAttributes(new Attributes()); + verify(nitriteCollection).setAttributes(any()); + assertNull(defaultObjectRepository.getAttributes()); + } + + @Test(expected = ValidationException.class) + public void testConstructor() { + Class type = Object.class; + NitriteConfig nitriteConfig = new NitriteConfig(); + new DefaultObjectRepository<>(type, null, nitriteConfig); + assertTrue(nitriteConfig.getMigrations().isEmpty()); + assertEquals(1, nitriteConfig.getSchemaVersion().intValue()); + assertNull(nitriteConfig.getNitriteStore()); + } + + @Test + public void testConstructor2() { + Class forNameResult = Object.class; + NitriteCollection collection = mock(NitriteCollection.class); + DefaultObjectRepository actualDefaultObjectRepository = new DefaultObjectRepository<>(forNameResult, + collection, new NitriteConfig()); + assertNull(actualDefaultObjectRepository.getAttributes()); + assertSame(forNameResult, actualDefaultObjectRepository.getType()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/IndexValidatorTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/IndexValidatorTest.java new file mode 100644 index 000000000..0c812ed53 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/repository/IndexValidatorTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.NitriteBuilderTest; +import org.dizitart.no2.exceptions.IndexingException; +import org.junit.Test; + +import java.lang.reflect.Field; + +import static org.junit.Assert.assertThrows; + +public class IndexValidatorTest { + + @Test + public void testValidate() { + IndexValidator indexValidator = new IndexValidator(new Reflector()); + Class fieldType = Object.class; + assertThrows(IndexingException.class, + () -> indexValidator.validate(fieldType, "Field", new NitriteBuilderTest.CustomNitriteMapper())); + } + + @Test + public void testValidate3() { + IndexValidator indexValidator = new IndexValidator(new Reflector()); + Class fieldType = Field.class; + assertThrows(IndexingException.class, + () -> indexValidator.validate(fieldType, "Field", new NitriteBuilderTest.CustomNitriteMapper())); + } + + @Test + public void testValidate4() { + IndexValidator indexValidator = new IndexValidator(new Reflector()); + Class fieldType = Object.class; + assertThrows(IndexingException.class, () -> indexValidator.validate(fieldType, "invalid type specified ", + new NitriteBuilderTest.CustomNitriteMapper())); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java index b5b17c593..b2edd5e3e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java @@ -1,53 +1,109 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2.repository; +import com.fasterxml.jackson.databind.util.ArrayIterator; +import org.dizitart.no2.NitriteBuilderTest; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.Lookup; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.mapper.MappableMapper; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.common.streams.DocumentStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.repository.data.Employee; import org.junit.Test; -import java.util.AbstractCollection; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; -/** - * @author Anindya Chatterjee - */ -public class ObjectCursorTest extends BaseObjectRepositoryTest { +public class ObjectCursorTest { + @Test + public void testSize() { + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + Pair pair = new Pair<>(); + Pair pair1 = new Pair<>(); + when(recordStream.iterator()).thenReturn( + new ArrayIterator>(new Pair[]{pair, pair1, new Pair()})); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + NitriteBuilderTest.CustomNitriteMapper nitriteMapper = new NitriteBuilderTest.CustomNitriteMapper(); + ObjectCursor objectCursor = new ObjectCursor<>(nitriteMapper, cursor, Object.class); + assertEquals(3L, objectCursor.size()); + verify(recordStream).iterator(); + assertTrue(objectCursor.toList().isEmpty()); + } - @Test(expected = ValidationException.class) - public void testProjectForInterface() { - Cursor cursor = employeeRepository.find(); - cursor.project(Comparable.class); + @Test + public void testConstructor() { + NitriteBuilderTest.CustomNitriteMapper nitriteMapper = new NitriteBuilderTest.CustomNitriteMapper(); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + assertNull((new ObjectCursor<>(nitriteMapper, cursor, Object.class)).getFindPlan()); } - @Test(expected = ValidationException.class) - public void testProjectForPrimitive() { - Cursor cursor = employeeRepository.find(); - cursor.project(int.class); + @Test + public void testGetFindPlan() { + NitriteBuilderTest.CustomNitriteMapper nitriteMapper = new NitriteBuilderTest.CustomNitriteMapper(); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + assertNull((new ObjectCursor<>(nitriteMapper, cursor, Object.class)).getFindPlan()); } - @Test(expected = ValidationException.class) - public void testProjectForArray() { - Cursor cursor = employeeRepository.find(); - cursor.project(String[].class); + @Test + public void testProject() { + NitriteBuilderTest.CustomNitriteMapper nitriteMapper = new NitriteBuilderTest.CustomNitriteMapper(); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + ObjectCursor objectCursor = new ObjectCursor<>(nitriteMapper, cursor, Object.class); + assertThrows(ValidationException.class, () -> objectCursor.project(Object.class)); } - @Test(expected = ValidationException.class) - public void testProjectForAbstractClass() { - Cursor cursor = employeeRepository.find(); - cursor.project(AbstractCollection.class); + @Test + public void testProject3() { + Class forNameResult = Object.class; + Class forNameResult1 = Object.class; + MappableMapper nitriteMapper = new MappableMapper(forNameResult, forNameResult1, Object.class); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + ObjectCursor objectCursor = new ObjectCursor<>(nitriteMapper, cursor, Object.class); + assertThrows(ValidationException.class, () -> objectCursor.project(Object.class)); + } + + @Test + public void testJoin() { + NitriteBuilderTest.CustomNitriteMapper nitriteMapper = new NitriteBuilderTest.CustomNitriteMapper(); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor = new DocumentStream(recordStream, new ProcessorChain()); + ObjectCursor objectCursor = new ObjectCursor<>(nitriteMapper, cursor, Object.class); + NitriteBuilderTest.CustomNitriteMapper nitriteMapper1 = new NitriteBuilderTest.CustomNitriteMapper(); + RecordStream> recordStream1 = (RecordStream>) mock( + RecordStream.class); + DocumentStream cursor1 = new DocumentStream(recordStream1, new ProcessorChain()); + ObjectCursor foreignCursor = new ObjectCursor<>(nitriteMapper1, cursor1, Object.class); + Lookup lookup = new Lookup(); + assertTrue(objectCursor.join(foreignCursor, lookup, Object.class) instanceof MutatedObjectStream); } } + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectIdFieldTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectIdFieldTest.java new file mode 100644 index 000000000..0e37591de --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectIdFieldTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +public class ObjectIdFieldTest { + @Test + public void testConstructor() { + ObjectIdField actualObjectIdField = new ObjectIdField(); + assertNull(actualObjectIdField.getField()); + assertFalse(actualObjectIdField.isEmbedded()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ReflectorTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ReflectorTest.java new file mode 100644 index 000000000..4a19153bb --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ReflectorTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.repository; + +import org.dizitart.no2.exceptions.ValidationException; +import org.junit.Test; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +import static org.junit.Assert.*; + +public class ReflectorTest { + @Test + public void testFindInheritedAnnotations() { + Reflector reflector = new Reflector(); + Class annotation = Annotation.class; + assertTrue(reflector.findInheritedAnnotations(annotation, Object.class).isEmpty()); + } + + @Test + public void testFindInheritedAnnotations3() { + Reflector reflector = new Reflector(); + Class annotation = Annotation.class; + assertTrue(reflector.findInheritedAnnotations(annotation, Field.class).isEmpty()); + } + + @Test + public void testGetEmbeddedField() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getEmbeddedField(Object.class, "Embedded Field")); + } + + @Test + public void testGetEmbeddedField2() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getEmbeddedField(Object.class, "\\{0}")); + } + + @Test + public void testGetEmbeddedField3() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getEmbeddedField(Object.class, "")); + } + + @Test + public void testGetEmbeddedField4() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getEmbeddedField(Object.class, "java.lang.Object")); + } + + @Test + public void testGetFieldsUpto() { + Reflector reflector = new Reflector(); + Class startClass = Object.class; + assertTrue(reflector.getFieldsUpto(startClass, Object.class).isEmpty()); + } + + @Test + public void testGetFieldsUpto2() { + Reflector reflector = new Reflector(); + Class startClass = Field.class; + assertEquals(Short.SIZE, reflector.getFieldsUpto(startClass, Object.class).size()); + } + + @Test + public void testGetField() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getField(Object.class, "Name")); + } + + + @Test + public void testGetField3() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, + () -> reflector.getField(Object.class, "startClass cannot be null")); + } + + @Test + public void testGetField4() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getField(Object.class, "no such field '")); + } + + @Test + public void testGetField5() { + Reflector reflector = new Reflector(); + assertThrows(ValidationException.class, () -> reflector.getField(Object.class, "java.lang.Object")); + } + + @Test + public void testGetAllFields() { + Reflector reflector = new Reflector(); + assertTrue(reflector.getAllFields(Object.class).isEmpty()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java index 5f4800770..27eeed486 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java @@ -1,240 +1,55 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2.repository; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; -import org.dizitart.no2.collection.*; -import org.dizitart.no2.collection.events.CollectionEventListener; -import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.CollectionFactory; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.processors.Processor; -import org.dizitart.no2.store.NitriteStore; -import org.junit.After; -import org.junit.Rule; import org.junit.Test; -import java.util.Collection; - -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; -/** - * @author Anindya Chatterjee - */ public class RepositoryFactoryTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); @Test - public void testRepositoryFactory() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - assertNotNull(factory); - } - - @Test(expected = ValidationException.class) - public void testNullType() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); - factory.getRepository(db.getConfig(), null, "dummy"); + public void testGetRepository() { + RepositoryFactory repositoryFactory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertThrows(ValidationException.class, () -> repositoryFactory.getRepository(null, Object.class)); } @Test - public void testNullCollection() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); - factory.getRepository(db.getConfig(), DummyCollection.class, null); - } - - @Test(expected = ValidationException.class) - public void testNullContext() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - factory.getRepository(null, DummyCollection.class, "dummy"); + public void testGetRepository2() { + RepositoryFactory repositoryFactory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertThrows(ValidationException.class, () -> repositoryFactory.getRepository(new NitriteConfig(), null)); } - @After - public void cleanUp() throws Exception { - if (db != null && !db.isClosed()) { - db.close(); - } + @Test + public void testGetRepository3() { + RepositoryFactory repositoryFactory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertThrows(ValidationException.class, () -> repositoryFactory.getRepository(null, Object.class, "Key")); } - private static class DummyCollection implements NitriteCollection { - - @Override - public WriteResult insert(Document document, Document... documents) { - return null; - } - - @Override - public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { - return null; - } - - @Override - public WriteResult remove(Filter filter, boolean justOne) { - return null; - } - - @Override - public DocumentCursor find() { - return null; - } - - @Override - public DocumentCursor find(Filter filter) { - return null; - } - - @Override - public DocumentCursor find(Filter filter, FindOptions findOptions) { - return null; - } - - @Override - public Document getById(NitriteId nitriteId) { - return null; - } - - @Override - public String getName() { - return null; - } - - @Override - public void addProcessor(Processor processor) { - - } - - @Override - public void removeProcessor(Processor processor) { - - } - - @Override - public void createIndex(IndexOptions indexOptions, String... fields) { - - } - - @Override - public void rebuildIndex(String... fields) { - - } - - @Override - public Collection listIndices() { - return null; - } - - @Override - public boolean hasIndex(String... fields) { - return false; - } - - @Override - public boolean isIndexing(String... fields) { - return false; - } - - @Override - public void dropIndex(String... fields) { - - } - - @Override - public void dropAllIndices() { - - } - - @Override - public WriteResult insert(Document[] elements) { - return null; - } - - @Override - public WriteResult update(Document element, boolean insertIfAbsent) { - return null; - } - - @Override - public WriteResult remove(Document element) { - return null; - } - - @Override - public void clear() { - - } - - @Override - public void drop() { - - } - - @Override - public boolean isDropped() { - return false; - } - - @Override - public boolean isOpen() { - return false; - } - - @Override - public void close() { - - } - - @Override - public long size() { - return 0; - } - - @Override - public NitriteStore getStore() { - return null; - } - - @Override - public void subscribe(CollectionEventListener listener) { - - } - - @Override - public void unsubscribe(CollectionEventListener listener) { - - } - - @Override - public Attributes getAttributes() { - return null; - } - - @Override - public void setAttributes(Attributes attributes) { - - } + @Test + public void testGetRepository4() { + RepositoryFactory repositoryFactory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertThrows(ValidationException.class, + () -> repositoryFactory.getRepository(new NitriteConfig(), null, "Key")); } } + diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java index 52b6a8c91..df3580ea8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java @@ -1,401 +1,102 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2.repository; -import lombok.Getter; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; +import org.dizitart.no2.NitriteBuilderTest; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.util.ObjectUtilsTest; -import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.common.streams.DocumentStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.InheritIndices; -import org.dizitart.no2.repository.data.Employee; -import org.junit.Before; -import org.junit.Rule; +import org.dizitart.no2.filters.Filter; import org.junit.Test; -import java.math.BigDecimal; -import java.util.Iterator; -import java.util.Set; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; -/** - * @author Anindya Chatterjee - */ public class RepositoryOperationsTest { - private RepositoryOperations operations; - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = TestUtil.createDb(); - } - @Test - public void testIndexes() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(TestObjectWithIndex.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - Set indexes = operations.extractIndices(TestObjectWithIndex.class); - assertEquals(indexes.size(), 2); - } - - @Test(expected = IndexingException.class) - public void testInvalidIndexNonComparable() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ObjectWithNonComparableIndex.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - Set indexes = operations.extractIndices(ObjectWithNonComparableIndex.class); - assertEquals(indexes.size(), 2); - } - - @Test(expected = IndexingException.class) - public void testInvalidIndexComparableAndIterable() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ObjectWithIterableIndex.class); - operations = new RepositoryOperations(ObjectWithIterableIndex.class, nitriteMapper, repository.getDocumentCollection()); - operations.extractIndices(ObjectWithIterableIndex.class); - } - - @Test(expected = ValidationException.class) - public void testGetFieldsUpToNullStartClass() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Employee.class); - operations = new RepositoryOperations(Employee.class, nitriteMapper, repository.getDocumentCollection()); - assertEquals(operations.getFieldsUpto(null, null).size(), 0); - } - - @Test(expected = ValidationException.class) - public void testGetFieldNoSuchField() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(getClass(), "test"); + public void testConstructor() { + Class type = Object.class; + assertThrows(ValidationException.class, + () -> new RepositoryOperations(type, new NitriteBuilderTest.CustomNitriteMapper(), null)); } @Test - public void testGetFieldsUpTo() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Employee.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - - assertEquals(operations.getFieldsUpto(A.class, B.class).size(), 3); - assertEquals(operations.getFieldsUpto(A.class, Object.class).size(), 5); - assertEquals(operations.getFieldsUpto(A.class, null).size(), 5); - - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - Object.class).size(), 5); - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - null).size(), 5); - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - ClassWithNoAnnotatedFields.class).size(), 3); - } - - @Test(expected = NotIdentifiableException.class) - public void testCreateUniqueFilterInvalidId() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(B.class); - operations = new RepositoryOperations(B.class, nitriteMapper, repository.getDocumentCollection()); - - B b = new B(); - operations.createUniqueFilter(b); - } - - @Test(expected = NotIdentifiableException.class) - public void testGetIdFieldMultipleId() { - class Test implements Mappable { - @Id - private String id1; - - @Id - private Long id2; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("id1", id1) - .put("id2", id2); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id1 = document.get("id1", String.class); - id2 = document.get("id2", Long.class); - } - } - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Test.class); - operations = new RepositoryOperations(Test.class, nitriteMapper, repository.getDocumentCollection()); - - operations.getIdField(Test.class); - } - - @Test(expected = ValidationException.class) - public void testInvalidEmbeddedKey() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(ClassWithAnnotatedFields.class, ".."); - } - - @Test(expected = ValidationException.class) - public void testInvalidGetField() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(ClassWithAnnotatedFields.class, "fake.fake"); - } - - @Test(expected = ValidationException.class) - public void testExtractInvalidIndex() { - @Index(value = "fake") - class Test implements Mappable { - private String test; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("test", test); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - test = document.get("test", String.class); - } - } - - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Test.class); - operations = new RepositoryOperations(Test.class, nitriteMapper, repository.getDocumentCollection()); - - operations.extractIndices(Test.class); + public void testToDocuments() { + Class type = Object.class; + assertEquals(3, + (new RepositoryOperations(type, new NitriteBuilderTest.CustomNitriteMapper(), mock(NitriteCollection.class))) + .toDocuments(new Object[]{"42", "42", "42"}).length); } @Test - public void testFindAnnotationFromInterface() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(TestInterface.class); - operations = new RepositoryOperations(TestInterface.class, nitriteMapper, repository.getDocumentCollection()); - - Set indices = operations.extractIndices(TestInterface.class); - assertFalse(indices.isEmpty()); + public void testToDocuments2() { + assertNull((new RepositoryOperations(Object.class, null, mock(NitriteCollection.class))).toDocuments(null)); } - @Index(value = "value") - private interface Interface { - String getValue(); - } - - private static class ClassWithAnnotatedFields extends ClassWithNoAnnotatedFields { - @Deprecated - Long longValue; - private String stringValue; - @Deprecated - private String anotherValue; - - @Deprecated - public ClassWithAnnotatedFields() { - } - - @Override - public Document write(NitriteMapper mapper) { - return super.write(mapper) - .put("stringValue", stringValue) - .put("anotherValue", anotherValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - super.read(mapper, document); - stringValue = document.get("stringValue", String.class); - anotherValue = document.get("anotherValue", String.class); - longValue = document.get("longValue", Long.class); - } - } - - private static class ClassWithNoAnnotatedFields implements Mappable { - private String stringValue; - private Integer integer; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("stringValue", stringValue) - .put("integer", integer); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - stringValue = document.get("stringValue", String.class); - integer = document.get("integer", Integer.class); - } - } - - private static class A extends B { - private String a; - private Long b; - private Integer c; - } - - private static class B implements Mappable { - String a; - private Short d; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("a", a) - .put("d", d); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - a = document.get("a", String.class); - d = document.get("d", Short.class); - } - } - - @Index(value = "testClass") - private static class ObjectWithNonComparableIndex implements Mappable { - private ObjectUtilsTest testClass; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("testClass", testClass); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - testClass = document.get("testClass", ObjectUtilsTest.class); - } - } - - @Index(value = "testClass") - private static class ObjectWithIterableIndex implements Mappable { - private TestClass testClass; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("testClass", testClass.write(mapper)); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - TestClass tc = new TestClass(); - tc.read(mapper, document.get("testClass", Document.class)); - testClass = tc; - } + @Test + public void testToDocuments3() { + assertNull((new RepositoryOperations(Object.class, null, mock(NitriteCollection.class))) + .toDocuments(new Object[]{})); } - private static class TestClass implements Comparable, Iterable, Mappable { - @Override - public int compareTo(TestClass o) { - return 0; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument(); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - - } + @Test + public void testToDocument() { + Class type = Object.class; + assertNull( + (new RepositoryOperations(type, new NitriteBuilderTest.CustomNitriteMapper(), mock(NitriteCollection.class))) + .toDocument("Object", true)); } - @InheritIndices - private static class TestInterface implements Interface, Mappable { - @Getter - private String value; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("value", value); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - value = document.get("value", String.class); - } + @Test + public void testCreateUniqueFilter() { + Class type = Object.class; + assertThrows(NotIdentifiableException.class, () -> (new RepositoryOperations(type, + new NitriteBuilderTest.CustomNitriteMapper(), mock(NitriteCollection.class))).createUniqueFilter("Object")); } - @Index(value = "longValue") - @Index(value = "decimal") - private class TestObjectWithIndex implements Mappable { - private long longValue; - - private TestObject testObject; - - private BigDecimal decimal; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("longValue", longValue) - .put("testObject", testObject.write(mapper)) - .put("decimal", decimal.toPlainString()); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - longValue = document.get("longValue", Long.class); - testObject = new TestObject(); - testObject.read(mapper, document.get("testObject", Document.class)); - String decimalString = document.get("decimal", String.class); - decimal = new BigDecimal(decimalString); - } + @Test + public void testCreateIdFilter() { + Class type = Object.class; + assertThrows(NotIdentifiableException.class, () -> (new RepositoryOperations(type, + new NitriteBuilderTest.CustomNitriteMapper(), mock(NitriteCollection.class))).createIdFilter("Id")); } - @Index(value = "longValue") - private class TestObject implements Mappable { - private String stringValue; - - private Long longValue; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - stringValue = document.get("stringValue", String.class); - longValue = document.get("longValue", Long.class); - } + @Test + public void testFind() { + NitriteCollection nitriteCollection = mock(NitriteCollection.class); + RecordStream> recordStream = (RecordStream>) mock( + RecordStream.class); + when(nitriteCollection.find(any(), any())) + .thenReturn(new DocumentStream(recordStream, new ProcessorChain())); + Class type = Object.class; + RepositoryOperations repositoryOperations = new RepositoryOperations(type, + new NitriteBuilderTest.CustomNitriteMapper(), nitriteCollection); + Filter filter = mock(Filter.class); + FindOptions findOptions = new FindOptions(); + assertNull(repositoryOperations.find(filter, findOptions, Object.class).getFindPlan()); + verify(nitriteCollection).find(any(), any()); } } + diff --git a/nitrite/src/test/java/org/dizitart/no2/store/DatabaseMetaDataTest.java b/nitrite/src/test/java/org/dizitart/no2/store/DatabaseMetaDataTest.java deleted file mode 100644 index 963eb1410..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/store/DatabaseMetaDataTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.dizitart.no2.store; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import org.dizitart.no2.collection.Document; -import org.junit.Test; - -public class DatabaseMetaDataTest { - @Test - public void testConstructor() { - DatabaseMetaData actualDatabaseMetaData = new DatabaseMetaData(Document.createDocument()); - assertNull(actualDatabaseMetaData.getStoreVersion()); - assertNull(actualDatabaseMetaData.getSchemaVersion()); - assertNull(actualDatabaseMetaData.getNitriteVersion()); - assertNull(actualDatabaseMetaData.getCreateTime()); - } - - @Test - public void testGetInfo() { - DatabaseMetaData databaseMetaData = new DatabaseMetaData(); - databaseMetaData.setNitriteVersion("1.0.2"); - assertEquals(4, databaseMetaData.getInfo().size()); - } - - @Test - public void testGetInfo2() { - assertEquals(4, (new DatabaseMetaData()).getInfo().size()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/store/StoreCatalogTest.java b/nitrite/src/test/java/org/dizitart/no2/store/StoreCatalogTest.java new file mode 100644 index 000000000..ded81e974 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/store/StoreCatalogTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.store; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +public class StoreCatalogTest { + @Test + public void testConstructor() { + assertTrue((new StoreCatalog(new InMemoryStore())).getCollectionNames().isEmpty()); + } + + @Test + public void testWriteCollectionEntry() { + StoreCatalog storeCatalog = new StoreCatalog(new InMemoryStore()); + storeCatalog.writeCollectionEntry("Name"); + assertEquals(1, storeCatalog.getCollectionNames().size()); + assertTrue(storeCatalog.getRepositoryNames().isEmpty()); + } + + @Test + public void testWriteRepositoryEntry() { + StoreCatalog storeCatalog = new StoreCatalog(new InMemoryStore()); + storeCatalog.writeRepositoryEntry("Name"); + assertTrue(storeCatalog.getCollectionNames().isEmpty()); + assertEquals(1, storeCatalog.getRepositoryNames().size()); + } + + @Test + public void testWriteKeyedRepositoryEntries() { + StoreCatalog storeCatalog = new StoreCatalog(new InMemoryStore()); + storeCatalog.writeKeyedRepositoryEntries("Name"); + assertTrue(storeCatalog.getCollectionNames().isEmpty()); + } + + @Test + public void testGetCollectionNames() { + assertTrue((new StoreCatalog(new InMemoryStore())).getCollectionNames().isEmpty()); + } + + @Test + public void testGetRepositoryNames() { + assertTrue((new StoreCatalog(new InMemoryStore())).getRepositoryNames().isEmpty()); + } + + @Test + public void testGetKeyedRepositoryNames() { + assertTrue((new StoreCatalog(new InMemoryStore())).getKeyedRepositoryNames().isEmpty()); + } + + @Test + public void testRemove() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new StoreCatalog(new InMemoryStore())).remove("Name"); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/store/StoreMetaDataTest.java b/nitrite/src/test/java/org/dizitart/no2/store/StoreMetaDataTest.java new file mode 100644 index 000000000..0cb5209d5 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/store/StoreMetaDataTest.java @@ -0,0 +1,31 @@ +package org.dizitart.no2.store; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.dizitart.no2.collection.Document; +import org.junit.Test; + +public class StoreMetaDataTest { + @Test + public void testConstructor() { + StoreMetaData actualStoreMetaData = new StoreMetaData(Document.createDocument()); + assertNull(actualStoreMetaData.getStoreVersion()); + assertNull(actualStoreMetaData.getSchemaVersion()); + assertNull(actualStoreMetaData.getNitriteVersion()); + assertNull(actualStoreMetaData.getCreateTime()); + } + + @Test + public void testGetInfo() { + StoreMetaData storeMetaData = new StoreMetaData(); + storeMetaData.setNitriteVersion("1.0.2"); + assertEquals(4, storeMetaData.getInfo().size()); + } + + @Test + public void testGetInfo2() { + assertEquals(4, (new StoreMetaData()).getInfo().size()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java b/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java new file mode 100644 index 000000000..4d6fbfe8e --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.store; + +import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.assertThrows; + +public class UserAuthenticationServiceTest { + @Test + public void testConstructor() { + // TODO: This test is incomplete. + // Reason: Nothing to assert: the constructed class does not have observers (e.g. getters or public fields). + // Add observers (e.g. getters or public fields) to the class. + // See https://diff.blue/R002 + + new UserAuthenticationService(null); + } + + @Test + public void testAuthenticate() { + assertThrows(SecurityException.class, + () -> (new UserAuthenticationService(new InMemoryStore())).authenticate("janedoe", "iloveyou", true)); + } + + @Test + public void testAuthenticate2() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new UserAuthenticationService(new InMemoryStore())).authenticate("", "iloveyou", true); + } + + @Test + public void testAuthenticate3() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new UserAuthenticationService(new InMemoryStore())).authenticate("janedoe", "", true); + } + + @Test + public void testAuthenticate4() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new UserAuthenticationService(new InMemoryStore())).authenticate("janedoe", "iloveyou", false); + } + + @Test + public void testAuthenticate5() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new UserAuthenticationService(new InMemoryStore())).authenticate("", "iloveyou", false); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java index 0e71419fb..4bf390ec8 100644 --- a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryMapTest.java @@ -1,205 +1,389 @@ package org.dizitart.no2.store.memory; -import org.apache.commons.lang3.mutable.MutableByte; +import org.dizitart.no2.exceptions.ValidationException; import org.junit.Test; import static org.junit.Assert.*; public class InMemoryMapTest { - @Test - public void testConstructor() { - InMemoryMap actualInMemoryMap = new InMemoryMap("mapName", null); - assertEquals("mapName", actualInMemoryMap.getName()); - assertEquals(0L, actualInMemoryMap.size()); - assertNull(actualInMemoryMap.getStore()); - } @Test public void testContainsKey() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put(null, "value"); - assertFalse(inMemoryMap.containsKey("key")); + assertFalse((new InMemoryMap<>("Map Name", null)).containsKey("Key")); } @Test public void testContainsKey2() { - assertFalse((new InMemoryMap("mapName", null)).containsKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + assertTrue(inMemoryMap.containsKey("Key")); } @Test public void testContainsKey3() { - assertFalse((new InMemoryMap("mapName", null)).containsKey(null)); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + inMemoryMap.put("Key", "Value"); + assertTrue(inMemoryMap.containsKey("Key")); } @Test public void testContainsKey4() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertTrue(inMemoryMap.containsKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("42", "Value"); + assertFalse(inMemoryMap.containsKey("Key")); } @Test public void testGet() { - assertNull((new InMemoryMap("mapName", null)).get("key")); + assertNull((new InMemoryMap<>("Map Name", null)).get("Key")); } @Test public void testGet2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertEquals("value", inMemoryMap.get("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + assertEquals("Value", inMemoryMap.get("Key")); + } + + @Test + public void testGet3() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("42", "Value"); + assertNull(inMemoryMap.get("Key")); + } + + @Test + public void testGet4() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put((byte) 'A', "Value"); + assertNull(inMemoryMap.get((byte) 0)); + } + + @Test + public void testClear() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + inMemoryMap.clear(); + assertEquals(0L, inMemoryMap.size()); + } + + @Test + public void testClear2() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + inMemoryMap.clear(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testClear3() { + InMemoryMap inMemoryMap = new InMemoryMap<>("lastModifiedTime", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + inMemoryMap.clear(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testClear4() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.clear(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testClear5() { + InMemoryMap inMemoryMap = new InMemoryMap<>("owner", new InMemoryStore()); + inMemoryMap.clear(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test public void testValues() { - assertTrue((new InMemoryMap("mapName", null)).values().isEmpty()); + assertTrue((new InMemoryMap<>("Map Name", null)).values().toList().isEmpty()); } @Test public void testRemove() { - InMemoryMap inMemoryMap = new InMemoryMap("", null); - assertNull(inMemoryMap.remove("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + assertEquals("Value", inMemoryMap.remove("Key")); assertEquals(0L, inMemoryMap.size()); } @Test public void testRemove2() { - InMemoryMap inMemoryMap = new InMemoryMap("", null); - assertNull(inMemoryMap.remove(null)); + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + assertEquals("Value", inMemoryMap.remove("Key")); assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test public void testRemove3() { - InMemoryMap inMemoryMap = new InMemoryMap("", null); - inMemoryMap.put(new MutableByte(), "value"); - assertNull(inMemoryMap.remove(0)); - assertFalse(inMemoryMap.isEmpty()); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("", "Value"); + assertNull(inMemoryMap.remove("Key")); + assertEquals(1L, inMemoryMap.size()); + } + + @Test + public void testRemove4() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + assertNull(inMemoryMap.remove("42")); + assertEquals(1L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test - public void testKeySet() { - assertTrue((new InMemoryMap("mapName", null)).keys().isEmpty()); + public void testKeys() { + assertTrue((new InMemoryMap<>("Map Name", null)).keys().toList().isEmpty()); } @Test public void testPut() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put(null, "value"); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + inMemoryMap.put("Key", "Value"); assertEquals(1L, inMemoryMap.size()); } @Test public void testPut2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertFalse(inMemoryMap.isEmpty()); + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + inMemoryMap.put("Key", "Value"); + assertEquals(1L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test public void testPut3() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", 1); - assertFalse(inMemoryMap.isEmpty()); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("value cannot be null", "Value"); + inMemoryMap.put("Key", "Value"); + assertEquals(2L, inMemoryMap.size()); + } + + @Test(expected = ValidationException.class) + public void testPut4() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put((byte) 'A', "Value"); + inMemoryMap.put("Key", null); + } + + @Test + public void testPut5() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("42", "Value"); + inMemoryMap.put("Key", "Value"); + assertEquals(2L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test public void testSize() { - assertEquals(0L, (new InMemoryMap("mapName", null)).size()); + assertEquals(0L, (new InMemoryMap<>("Map Name", null)).size()); } @Test public void testPutIfAbsent() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - assertNull(inMemoryMap.putIfAbsent(null, "value")); - assertEquals(1L, inMemoryMap.size()); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); + assertEquals("Value", inMemoryMap.putIfAbsent("Key", "Value")); } @Test public void testPutIfAbsent2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - assertNull(inMemoryMap.putIfAbsent("key", "value")); - assertFalse(inMemoryMap.isEmpty()); + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + assertEquals("Value", inMemoryMap.putIfAbsent("Key", "Value")); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testPutIfAbsent3() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("value cannot be null", "Value"); + assertNull(inMemoryMap.putIfAbsent("Key", "Value")); + assertEquals(2L, inMemoryMap.size()); + } + + @Test(expected = ValidationException.class) + public void testPutIfAbsent4() { + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put((byte) 'A', "Value"); + inMemoryMap.putIfAbsent("Key", null); + } + + @Test + public void testPutIfAbsent5() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + assertNull(inMemoryMap.putIfAbsent("42", "Value")); + assertEquals(2L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); } @Test public void testEntries() { - assertTrue((new InMemoryMap("mapName", null)).entries().isEmpty()); + assertTrue((new InMemoryMap<>("Map Name", null)).entries().toList().isEmpty()); + } + + @Test + public void testReversedEntries() { + assertTrue((new InMemoryMap<>("Map Name", null)).reversedEntries().toList().isEmpty()); } @Test public void testHigherKey() { - assertNull((new InMemoryMap("mapName", null)).higherKey("key")); - assertNull((new InMemoryMap("mapName", null)).higherKey(null)); + assertNull((new InMemoryMap<>("Map Name", null)).higherKey("Key")); + assertNull((new InMemoryMap<>("Map Name", null)).higherKey(null)); } @Test public void testHigherKey2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertNull(inMemoryMap.higherKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put("Key", "Value"); + assertNull(inMemoryMap.higherKey("Key")); + } + + @Test + public void testHigherKey3() { + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put((byte) 'A', "Value"); + assertEquals('A', ((Byte) inMemoryMap.higherKey(-1)).byteValue()); } @Test public void testCeilingKey() { - assertNull((new InMemoryMap("mapName", null)).ceilingKey("key")); - assertNull((new InMemoryMap("mapName", null)).ceilingKey(null)); + assertNull((new InMemoryMap<>("Map Name", null)).ceilingKey("Key")); + assertNull((new InMemoryMap<>("Map Name", null)).ceilingKey(null)); } @Test public void testCeilingKey2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertEquals("key", inMemoryMap.ceilingKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put("Key", "Value"); + assertEquals("Key", inMemoryMap.ceilingKey("Key")); } @Test public void testCeilingKey3() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put(null, "value"); - assertNull(inMemoryMap.ceilingKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put((byte) 'A', "Value"); + assertEquals('A', ((Byte) inMemoryMap.ceilingKey(0)).byteValue()); } @Test public void testLowerKey() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertNull(inMemoryMap.lowerKey("key")); + assertNull((new InMemoryMap<>("Map Name", null)).lowerKey("Key")); + assertNull((new InMemoryMap<>("Map Name", null)).lowerKey(null)); } @Test public void testLowerKey2() { - assertNull((new InMemoryMap("mapName", null)).lowerKey(null)); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put("Key", "Value"); + assertNull(inMemoryMap.lowerKey("Key")); } @Test public void testLowerKey3() { - assertNull((new InMemoryMap("mapName", null)).lowerKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put((byte) 'A', "Value"); + assertNull(inMemoryMap.lowerKey(10.0f)); } @Test public void testFloorKey() { - assertNull((new InMemoryMap("mapName", null)).floorKey("key")); - assertNull((new InMemoryMap("mapName", null)).floorKey(null)); + assertNull((new InMemoryMap<>("Map Name", null)).floorKey("Key")); + assertNull((new InMemoryMap<>("Map Name", null)).floorKey(null)); } @Test public void testFloorKey2() { - InMemoryMap inMemoryMap = new InMemoryMap(null, null); - inMemoryMap.put("key", "value"); - assertEquals("key", inMemoryMap.floorKey("key")); + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put("Key", "Value"); + assertEquals("Key", inMemoryMap.floorKey("Key")); + } + + @Test + public void testFloorKey3() { + InMemoryMap inMemoryMap = new InMemoryMap<>(null, null); + inMemoryMap.put((byte) 'A', "Value"); + assertNull(inMemoryMap.floorKey(0)); } @Test public void testIsEmpty() { - assertTrue((new InMemoryMap("mapName", null)).isEmpty()); + assertTrue((new InMemoryMap<>("Map Name", null)).isEmpty()); } @Test public void testIsEmpty2() { - InMemoryMap inMemoryMap = new InMemoryMap("", null); - inMemoryMap.put("key", "value"); + InMemoryMap inMemoryMap = new InMemoryMap<>("", null); + inMemoryMap.put("Key", "Value"); assertFalse(inMemoryMap.isEmpty()); } + + @Test + public void testDrop() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + inMemoryMap.drop(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testDrop2() { + InMemoryMap inMemoryMap = new InMemoryMap<>("42", new InMemoryStore()); + inMemoryMap.put("Key", "Value"); + inMemoryMap.drop(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testDrop3() { + InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", new InMemoryStore()); + inMemoryMap.drop(); + assertEquals(0L, inMemoryMap.size()); + assertEquals(4, inMemoryMap.getAttributes().getAttributes().size()); + } + + @Test + public void testClose() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new InMemoryMap<>("Map Name", null)).close(); + } + + @Test + public void testConstructor() { + InMemoryMap actualInMemoryMap = new InMemoryMap<>("Map Name", null); + assertEquals("Map Name", actualInMemoryMap.getName()); + assertNull(actualInMemoryMap.getStore()); + } + + @Test + public void testConstructor2() { + InMemoryMap actualInMemoryMap = new InMemoryMap<>("Map Name", null); + assertEquals("Map Name", actualInMemoryMap.getName()); + assertEquals(0L, actualInMemoryMap.size()); + assertNull(actualInMemoryMap.getStore()); + } + } diff --git a/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreModuleTest.java b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreModuleTest.java new file mode 100644 index 000000000..13444df87 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/store/memory/InMemoryStoreModuleTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.store.memory; + +import org.dizitart.no2.store.NitriteStore; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class InMemoryStoreModuleTest { + @Test + public void testConstructor() { + NitriteStore store = (new InMemoryStoreModule()).getStore(); + assertTrue(store instanceof InMemoryStore); + assertTrue(((InMemoryConfig) store.getStoreConfig()).eventListeners().isEmpty()); + } + + @Test + public void testWithConfig() { + InMemoryModuleBuilder actualWithConfigResult = InMemoryStoreModule.withConfig(); + assertTrue(actualWithConfigResult.eventListeners().isEmpty()); + assertTrue(actualWithConfigResult.dbConfig().eventListeners().isEmpty()); + } + + @Test + public void testGetStore() { + assertFalse((new InMemoryStoreModule()).getStore().isClosed()); + } + + @Test + public void testPlugins() { + assertEquals(1, (new InMemoryStoreModule()).plugins().size()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/ChangeTypeTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/ChangeTypeTest.java new file mode 100644 index 000000000..599c37904 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/ChangeTypeTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ChangeTypeTest { + + @Test + public void testValueOf3() { + assertEquals(ChangeType.AddProcessor, ChangeType.valueOf("AddProcessor")); + } + + @Test + public void testValues() { + assertEquals(12, ChangeType.values().length); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java new file mode 100644 index 000000000..425e223f0 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.StoreConfig; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class DefaultTransactionalCollectionTest { + @Test + public void testConstructor() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + when(nitriteStore.openMap(anyString(), any(), any())) + .thenReturn(new TransactionalMap<>("Map Name", primary2, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))); + when(nitriteStore.hasMap(anyString())).thenReturn(true); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(nitriteStore)); + TransactionalConfig config = new TransactionalConfig(new NitriteConfig(), transactionalStore); + + TransactionContext transactionContext = new TransactionContext(); + transactionContext.setConfig(config); + DefaultTransactionalCollection actualDefaultTransactionalCollection = new DefaultTransactionalCollection(null, + transactionContext, null); + assertNull(actualDefaultTransactionalCollection.getCollectionName()); + assertFalse(actualDefaultTransactionalCollection.isDropped()); + assertSame(transactionContext, actualDefaultTransactionalCollection.getTransactionContext()); + NitriteStore store = actualDefaultTransactionalCollection.getStore(); + assertSame(transactionalStore, store); + assertNull(actualDefaultTransactionalCollection.getPrimary()); + assertNull(actualDefaultTransactionalCollection.getNitrite()); + assertNull(actualDefaultTransactionalCollection.getNitriteMap()); + assertNull(actualDefaultTransactionalCollection.getCollectionOperations().getAttributes()); + assertNull(store.getStoreVersion()); + verify(nitriteStore, times(2)).hasMap(anyString()); + verify(nitriteStore).openMap(anyString(), any(), any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalRepositoryTest.java new file mode 100644 index 000000000..ad9947681 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalRepositoryTest.java @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.collection.FindOptions; +import org.dizitart.no2.collection.events.CollectionEventListener; +import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexOptions; +import org.junit.Test; + +import java.util.ArrayList; + +import static org.mockito.Mockito.*; + +public class DefaultTransactionalRepositoryTest { + @Test + public void testAddProcessor() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).addProcessor(any()); + defaultTransactionalRepository.addProcessor(new ProcessorChain()); + verify(defaultTransactionalRepository).addProcessor(any()); + } + + @Test + public void testRemoveProcessor() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository) + .removeProcessor(any()); + defaultTransactionalRepository.removeProcessor(new ProcessorChain()); + verify(defaultTransactionalRepository).removeProcessor(any()); + } + + @Test + public void testCreateIndex() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).createIndex(any(), any()); + defaultTransactionalRepository.createIndex(IndexOptions.indexOptions("Index Type"), "foo", "foo", "foo"); + verify(defaultTransactionalRepository).createIndex(any(), any()); + } + + @Test + public void testRebuildIndex() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).rebuildIndex(any()); + defaultTransactionalRepository.rebuildIndex("foo", "foo", "foo"); + verify(defaultTransactionalRepository).rebuildIndex(any()); + } + + @Test + public void testListIndices() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.listIndices()).thenReturn(new ArrayList<>()); + defaultTransactionalRepository.listIndices(); + verify(defaultTransactionalRepository).listIndices(); + } + + @Test + public void testHasIndex() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.hasIndex(any())).thenReturn(true); + defaultTransactionalRepository.hasIndex("foo", "foo", "foo"); + verify(defaultTransactionalRepository).hasIndex(any()); + } + + @Test + public void testIsIndexing() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.isIndexing(any())).thenReturn(true); + defaultTransactionalRepository.isIndexing("foo", "foo", "foo"); + verify(defaultTransactionalRepository).isIndexing(any()); + } + + @Test + public void testDropIndex() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).dropIndex(any()); + defaultTransactionalRepository.dropIndex("foo", "foo", "foo"); + verify(defaultTransactionalRepository).dropIndex(any()); + } + + @Test + public void testDropAllIndices() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).dropAllIndices(); + defaultTransactionalRepository.dropAllIndices(); + verify(defaultTransactionalRepository).dropAllIndices(); + } + + @Test + public void testInsert() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.insert(any())).thenReturn(null); + defaultTransactionalRepository.insert(new Object[]{"42", "42", "42"}); + verify(defaultTransactionalRepository).insert(any()); + } + + @Test + public void testUpdate() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.update(any(), anyBoolean())).thenReturn(null); + defaultTransactionalRepository.update("Element", true); + verify(defaultTransactionalRepository).update(any(), anyBoolean()); + } + + @Test + public void testUpdate2() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.update(any(), (Object) any(), anyBoolean())).thenReturn(null); + defaultTransactionalRepository.update(mock(Filter.class), "Update", true); + verify(defaultTransactionalRepository).update(any(), (Object) any(), anyBoolean()); + } + + @Test + public void testUpdate3() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.update(any(), any(), anyBoolean())).thenReturn(null); + defaultTransactionalRepository.update(mock(Filter.class), null, true); + verify(defaultTransactionalRepository).update(any(), any(), anyBoolean()); + } + + @Test + public void testRemove() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.remove((Object) any())).thenReturn(null); + defaultTransactionalRepository.remove("Element"); + verify(defaultTransactionalRepository).remove((Object) any()); + } + + @Test + public void testRemove2() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.remove(any(), anyBoolean())).thenReturn(null); + defaultTransactionalRepository.remove(mock(Filter.class), true); + verify(defaultTransactionalRepository).remove(any(), anyBoolean()); + } + + @Test + public void testClear() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).clear(); + defaultTransactionalRepository.clear(); + verify(defaultTransactionalRepository).clear(); + } + + @Test + public void testFind() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.find(any(), any())).thenReturn(null); + Filter filter = mock(Filter.class); + defaultTransactionalRepository.find(filter, new FindOptions()); + verify(defaultTransactionalRepository).find(any(), any()); + } + + @Test + public void testGetById() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.getById(any())).thenReturn("42"); + defaultTransactionalRepository.getById("Id"); + verify(defaultTransactionalRepository).getById(any()); + } + + @Test + public void testDrop() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).drop(); + defaultTransactionalRepository.drop(); + verify(defaultTransactionalRepository).drop(); + } + + @Test + public void testIsDropped() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.isDropped()).thenReturn(true); + defaultTransactionalRepository.isDropped(); + verify(defaultTransactionalRepository).isDropped(); + } + + @Test + public void testIsOpen() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.isOpen()).thenReturn(true); + defaultTransactionalRepository.isOpen(); + verify(defaultTransactionalRepository).isOpen(); + } + + @Test + public void testClose() throws Exception { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).close(); + defaultTransactionalRepository.close(); + verify(defaultTransactionalRepository).close(); + } + + @Test + public void testSize() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.size()).thenReturn(1L); + defaultTransactionalRepository.size(); + verify(defaultTransactionalRepository).size(); + } + + @Test + public void testGetStore() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doReturn(new TransactionalStore<>(new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))).when(defaultTransactionalRepository).getStore(); + defaultTransactionalRepository.getStore(); + verify(defaultTransactionalRepository).getStore(); + } + + @Test + public void testSubscribe() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).subscribe(any()); + defaultTransactionalRepository.subscribe(mock(CollectionEventListener.class)); + verify(defaultTransactionalRepository).subscribe(any()); + } + + @Test + public void testUnsubscribe() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).unsubscribe(any()); + defaultTransactionalRepository.unsubscribe(mock(CollectionEventListener.class)); + verify(defaultTransactionalRepository).unsubscribe(any()); + } + + @Test + public void testGetAttributes() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + when(defaultTransactionalRepository.getAttributes()).thenReturn(new Attributes()); + defaultTransactionalRepository.getAttributes(); + verify(defaultTransactionalRepository).getAttributes(); + } + + @Test + public void testSetAttributes() { + DefaultTransactionalRepository defaultTransactionalRepository = (DefaultTransactionalRepository) mock( + DefaultTransactionalRepository.class); + doNothing().when(defaultTransactionalRepository).setAttributes(any()); + defaultTransactionalRepository.setAttributes(new Attributes()); + verify(defaultTransactionalRepository).setAttributes(any()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/JournalEntryTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/JournalEntryTest.java new file mode 100644 index 000000000..831a9e6dc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/JournalEntryTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class JournalEntryTest { + @Test + public void testCanEqual() { + assertFalse((new JournalEntry()).canEqual("Other")); + } + + @Test + public void testCanEqual2() { + JournalEntry journalEntry = new JournalEntry(); + assertTrue(journalEntry.canEqual(new JournalEntry())); + } + + @Test + public void testConstructor() { + JournalEntry actualJournalEntry = new JournalEntry(); + actualJournalEntry.setChangeType(ChangeType.Insert); + actualJournalEntry.setCommit(mock(Command.class)); + actualJournalEntry.setRollback(mock(Command.class)); + assertEquals(ChangeType.Insert, actualJournalEntry.getChangeType()); + } + + @Test + public void testConstructor2() { + JournalEntry actualJournalEntry = new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class)); + actualJournalEntry.setChangeType(ChangeType.Insert); + actualJournalEntry.setCommit(mock(Command.class)); + actualJournalEntry.setRollback(mock(Command.class)); + assertEquals(ChangeType.Insert, actualJournalEntry.getChangeType()); + } + + @Test + public void testEquals() { + assertFalse((new JournalEntry()).equals("42")); + } + + @Test + public void testEquals2() { + JournalEntry journalEntry = new JournalEntry(); + assertTrue(journalEntry.equals(new JournalEntry())); + } + + @Test + public void testEquals3() { + JournalEntry journalEntry = new JournalEntry(); + assertFalse(journalEntry.equals(new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class)))); + } + + @Test + public void testEquals4() { + JournalEntry journalEntry = new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class)); + assertFalse(journalEntry.equals(new JournalEntry())); + } + + @Test + public void testEquals5() { + JournalEntry journalEntry = new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class)); + assertFalse(journalEntry.equals(new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class)))); + } + + @Test + public void testEquals6() { + JournalEntry journalEntry = new JournalEntry(); + assertFalse(journalEntry.equals(new JournalEntry(null, mock(Command.class), mock(Command.class)))); + } + + @Test + public void testEquals7() { + JournalEntry journalEntry = new JournalEntry(); + journalEntry.setRollback(mock(Command.class)); + assertFalse(journalEntry.equals(new JournalEntry())); + } + + @Test + public void testEquals8() { + JournalEntry journalEntry = new JournalEntry(); + + JournalEntry journalEntry1 = new JournalEntry(); + journalEntry1.setRollback(mock(Command.class)); + assertFalse(journalEntry.equals(journalEntry1)); + } + + @Test + public void testHashCode() { + assertEquals(357642, (new JournalEntry()).hashCode()); + } + + @Test + public void testHashCode2() { + // TODO: This test is incomplete. + // Reason: No meaningful assertions found. + // To help Diffblue Cover to find assertions, please add getters to the + // class under test that return fields written by the method under test. + // See https://diff.blue/R004 + + (new JournalEntry(ChangeType.Insert, mock(Command.class), mock(Command.class))).hashCode(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java new file mode 100644 index 000000000..7fd397c5d --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.concurrent.LockService; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class NitriteTransactionTest { + @Test + public void testConstructor() { + Nitrite nitrite = mock(Nitrite.class); + when(nitrite.getConfig()).thenReturn(new NitriteConfig()); + doReturn(new TransactionalStore<>(new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))).when(nitrite).getStore(); + assertEquals(State.Active, (new NitriteTransaction(nitrite, new LockService())).getState()); + verify(nitrite).getConfig(); + verify(nitrite).getStore(); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/StateTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/StateTest.java new file mode 100644 index 000000000..ba93373cc --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/StateTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class StateTest { + @Test + public void testValueOf2() { + assertEquals(State.Aborted, State.valueOf("Aborted")); + } + + @Test + public void testValues() { + State[] actualValuesResult = State.values(); + assertEquals(6, actualValuesResult.length); + assertEquals(State.Active, actualValuesResult[0]); + assertEquals(State.PartiallyCommitted, actualValuesResult[1]); + assertEquals(State.Committed, actualValuesResult[2]); + assertEquals(State.Closed, actualValuesResult[3]); + assertEquals(State.Failed, actualValuesResult[4]); + assertEquals(State.Aborted, actualValuesResult[5]); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionContextTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionContextTest.java new file mode 100644 index 000000000..d5a12e2b6 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionContextTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import java.util.LinkedList; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TransactionContextTest { + @Test + public void testConstructor() { + assertEquals("TransactionContext(collectionName=null, journal=null, nitriteMap=null, config=null, active=true)", + (new TransactionContext()).toString()); + } + + @Test + public void testClose() throws Exception { + LinkedList journalEntryList = new LinkedList<>(); + journalEntryList.add(new JournalEntry()); + + TransactionContext transactionContext = new TransactionContext(); + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + transactionContext + .setNitriteMap(new TransactionalMap<>("Map Name", primary2, new InMemoryStore())); + transactionContext.setJournal(journalEntryList); + transactionContext.close(); + assertTrue(transactionContext.getJournal().isEmpty()); + NitriteMap nitriteMap = transactionContext.getNitriteMap(); + assertEquals(0L, nitriteMap.size()); + assertTrue(nitriteMap.entries().toList().isEmpty()); + assertEquals(4, nitriteMap.getAttributes().getAttributes().size()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java new file mode 100644 index 000000000..b0ac9499f --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.store.StoreConfig; +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class TransactionalConfigTest { + @Test + public void testConstructor() { + NitriteConfig config = new NitriteConfig(); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalConfig actualTransactionalConfig = new TransactionalConfig(config, transactionalStore); + assertTrue(actualTransactionalConfig.getMigrations().isEmpty()); + assertEquals(1, actualTransactionalConfig.getSchemaVersion().intValue()); + assertSame(transactionalStore, actualTransactionalConfig.getNitriteStore()); + } + + @Test + public void testFindIndexer() { + NitriteConfig config = new NitriteConfig(); + assertThrows(IndexingException.class, + () -> (new TransactionalConfig(config, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))) + .findIndexer("Index Type")); + } + + @Test + public void testLoadModule() { + NitriteConfig config = new NitriteConfig(); + TransactionalConfig transactionalConfig = new TransactionalConfig(config, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + NitriteModule nitriteModule = mock(NitriteModule.class); + when(nitriteModule.plugins()).thenReturn(new HashSet<>()); + assertSame(transactionalConfig, transactionalConfig.loadModule(nitriteModule)); + verify(nitriteModule, times(2)).plugins(); + } + + @Test + public void testNitriteMapper() { + NitriteConfig config = new NitriteConfig(); + assertNull((new TransactionalConfig(config, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))).nitriteMapper()); + } + + @Test + public void testGetNitriteStore() { + NitriteConfig config = new NitriteConfig(); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))); + assertSame(transactionalStore, (new TransactionalConfig(config, transactionalStore)).getNitriteStore()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalMapTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalMapTest.java new file mode 100644 index 000000000..88c794f7b --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalMapTest.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.store.StoreConfig; +import org.dizitart.no2.store.memory.InMemoryMap; +import org.dizitart.no2.store.memory.InMemoryStore; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class TransactionalMapTest { + @Test + public void testContainsKey() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertFalse(transactionalMap.containsKey("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testContainsKey2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalMap.put("42", "42"); + assertTrue(transactionalMap.containsKey("42")); + assertEquals(1, transactionalMap.entries().toList().size()); + } + + @Test + public void testContainsKey3() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalMap.put("foo", "42"); + assertFalse(transactionalMap.containsKey("42")); + assertEquals(1, transactionalMap.entries().toList().size()); + } + + @Test + public void testGet() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.get("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testGet2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.get(0)); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testClear() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new InMemoryStore()); + transactionalMap.clear(); + assertTrue(transactionalMap.entries().toList().isEmpty()); + assertEquals(0L, transactionalMap.size()); + assertEquals(4, transactionalMap.getAttributes().getAttributes().size()); + } + + @Test + public void testValues() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertTrue(transactionalMap.values().toList().isEmpty()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testRemove() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.remove("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testRemove2() { + InMemoryMap primary = new InMemoryMap<>("Map Name", + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.remove("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testRemove3() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalMap.put("42", "42"); + assertEquals("42", transactionalMap.remove("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + assertEquals(0L, transactionalMap.size()); + } + + @Test + public void testRemove4() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalMap.put("", "42"); + assertNull(transactionalMap.remove("42")); + assertEquals(1, transactionalMap.entries().toList().size()); + } + + @Test + public void testKeys() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertTrue(transactionalMap.keys().toList().isEmpty()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testPut() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new InMemoryStore()); + transactionalMap.put("42", "42"); + assertEquals(1, transactionalMap.entries().toList().size()); + assertEquals(1L, transactionalMap.size()); + assertEquals(4, transactionalMap.getAttributes().getAttributes().size()); + } + + @Test + public void testSize() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertEquals(0L, transactionalMap.size()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testPutIfAbsent() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new InMemoryStore()); + assertNull(transactionalMap.putIfAbsent("Key", "Value")); + assertEquals(1, transactionalMap.entries().toList().size()); + assertEquals(1L, transactionalMap.size()); + assertEquals(4, transactionalMap.getAttributes().getAttributes().size()); + } + + @Test + public void testEntries() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + assertTrue((new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))).entries() + .toList() + .isEmpty()); + } + + @Test + public void testReversedEntries() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertTrue(transactionalMap.reversedEntries().toList().isEmpty()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testHigherKey() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.higherKey("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testHigherKey2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + + TransactionalMap transactionalMap = new TransactionalMap<>(null, primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + transactionalMap.putIfAbsent("Key", "Value"); + TransactionalMap transactionalMap1 = new TransactionalMap<>("Map Name", + transactionalMap, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertEquals("Key", transactionalMap1.higherKey("42")); + assertEquals(1, transactionalMap1.entries().toList().size()); + } + + @Test + public void testCeilingKey() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.ceilingKey("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testCeilingKey2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + + TransactionalMap transactionalMap = new TransactionalMap<>(null, primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + transactionalMap.put("42", "42"); + TransactionalMap transactionalMap1 = new TransactionalMap<>("Map Name", + transactionalMap, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertEquals("42", transactionalMap1.ceilingKey("42")); + assertEquals(1, transactionalMap1.entries().toList().size()); + } + + @Test + public void testLowerKey() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.lowerKey("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testFloorKey() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertNull(transactionalMap.floorKey("42")); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testFloorKey2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + + TransactionalMap transactionalMap = new TransactionalMap<>(null, primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + transactionalMap.put("42", "42"); + TransactionalMap transactionalMap1 = new TransactionalMap<>("Map Name", + transactionalMap, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertEquals("42", transactionalMap1.floorKey("42")); + assertEquals(1, transactionalMap1.entries().toList().size()); + } + + @Test + public void testIsEmpty() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertTrue(transactionalMap.isEmpty()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testIsEmpty2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalMap.put("42", "42"); + assertFalse(transactionalMap.isEmpty()); + assertEquals(1, transactionalMap.entries().toList().size()); + } + + @Test + public void testIsEmpty3() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + + TransactionalMap transactionalMap = new TransactionalMap<>("", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + transactionalMap.put("42", "42"); + TransactionalMap transactionalMap1 = new TransactionalMap<>("Map Name", + transactionalMap, new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + assertFalse(transactionalMap1.isEmpty()); + assertEquals(1, transactionalMap1.entries().toList().size()); + } + + @Test + public void testDrop() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new InMemoryStore()); + transactionalMap.drop(); + assertTrue(transactionalMap.entries().toList().isEmpty()); + assertEquals(0L, transactionalMap.size()); + assertEquals(4, transactionalMap.getAttributes().getAttributes().size()); + } + + @Test + public void testClose() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new InMemoryStore()); + transactionalMap.close(); + assertTrue(transactionalMap.entries().toList().isEmpty()); + assertEquals(0L, transactionalMap.size()); + assertEquals(4, transactionalMap.getAttributes().getAttributes().size()); + } + + @Test + public void testConstructor() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + transactionalStore); + TransactionalStore transactionalStore1 = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalMap actualTransactionalMap = new TransactionalMap<>("Map Name", + transactionalMap, transactionalStore1); + assertEquals("Map Name", actualTransactionalMap.getName()); + assertEquals("Map Name", transactionalMap.getName()); + assertSame(transactionalStore1, actualTransactionalMap.getStore()); + assertSame(transactionalStore, transactionalMap.getStore()); + } + + @Test + public void testConstructor2() { + TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); + TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, + new TransactionalStore<>(null)); + TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, + new TransactionalStore<>(new TransactionalStore<>(null))); + TransactionalMap transactionalMap = new TransactionalMap<>("Map Name", primary2, + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalMap actualTransactionalMap = new TransactionalMap<>("Map Name", + transactionalMap, transactionalStore); + assertTrue(actualTransactionalMap.entries().toList().isEmpty()); + assertEquals(0L, actualTransactionalMap.size()); + assertTrue(actualTransactionalMap.isEmpty()); + assertSame(transactionalStore, actualTransactionalMap.getStore()); + assertEquals("Map Name", actualTransactionalMap.getName()); + assertTrue(transactionalMap.entries().toList().isEmpty()); + } + + @Test + public void testConstructor3() { + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalMap actualTransactionalMap = new TransactionalMap<>("Map Name", null, + transactionalStore); + assertTrue(actualTransactionalMap.entries().toList().isEmpty()); + assertEquals(0L, actualTransactionalMap.size()); + assertTrue(actualTransactionalMap.isEmpty()); + assertSame(transactionalStore, actualTransactionalMap.getStore()); + assertEquals("Map Name", actualTransactionalMap.getName()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalRTreeTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalRTreeTest.java new file mode 100644 index 000000000..024632db3 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalRTreeTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.index.BoundingBox; +import org.dizitart.no2.store.memory.InMemoryRTree; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class TransactionalRTreeTest { + + @Test + public void testAdd2() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new InMemoryRTree<>()); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + transactionalRTree.add(boundingBox, NitriteId.newId()); + verify(boundingBox).getMaxX(); + verify(boundingBox).getMaxY(); + verify(boundingBox).getMinX(); + verify(boundingBox).getMinY(); + assertEquals(1L, transactionalRTree.size()); + } + + @Test + public void testRemove2() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new InMemoryRTree<>()); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + transactionalRTree.remove(boundingBox, NitriteId.newId()); + verify(boundingBox).getMaxX(); + verify(boundingBox).getMaxY(); + verify(boundingBox).getMinX(); + verify(boundingBox).getMinY(); + assertEquals(0L, transactionalRTree.size()); + } + + @Test + public void testFindIntersectingKeys() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new InMemoryRTree<>()); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + assertTrue(transactionalRTree.findIntersectingKeys(boundingBox).toList().isEmpty()); + verify(boundingBox, times(2)).getMaxX(); + verify(boundingBox, times(2)).getMaxY(); + verify(boundingBox, times(2)).getMinX(); + verify(boundingBox, times(2)).getMinY(); + } + + @Test + public void testFindIntersectingKeys2() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new TransactionalRTree<>(new InMemoryRTree<>())); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + assertTrue(transactionalRTree.findIntersectingKeys(boundingBox).toList().isEmpty()); + verify(boundingBox, times(3)).getMaxX(); + verify(boundingBox, times(3)).getMaxY(); + verify(boundingBox, times(3)).getMinX(); + verify(boundingBox, times(3)).getMinY(); + } + + @Test + public void testFindContainedKeys() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new InMemoryRTree<>()); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + assertTrue(transactionalRTree.findContainedKeys(boundingBox).toList().isEmpty()); + verify(boundingBox, times(2)).getMaxX(); + verify(boundingBox, times(2)).getMaxY(); + verify(boundingBox, times(2)).getMinX(); + verify(boundingBox, times(2)).getMinY(); + } + + @Test + public void testFindContainedKeys2() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new TransactionalRTree<>(new InMemoryRTree<>())); + BoundingBox boundingBox = mock(BoundingBox.class); + when(boundingBox.getMaxY()).thenReturn(10.0f); + when(boundingBox.getMinY()).thenReturn(10.0f); + when(boundingBox.getMaxX()).thenReturn(10.0f); + when(boundingBox.getMinX()).thenReturn(10.0f); + assertTrue(transactionalRTree.findContainedKeys(boundingBox).toList().isEmpty()); + verify(boundingBox, times(3)).getMaxX(); + verify(boundingBox, times(3)).getMaxY(); + verify(boundingBox, times(3)).getMinX(); + verify(boundingBox, times(3)).getMinY(); + } + + @Test + public void testSize() { + assertEquals(0L, (new TransactionalRTree<>(new InMemoryRTree<>())).size()); + } + + @Test + public void testClose() { + TransactionalRTree transactionalRTree = new TransactionalRTree<>( + new InMemoryRTree<>()); + transactionalRTree.close(); + assertEquals(0L, transactionalRTree.size()); + } + + @Test + public void testConstructor() { + assertEquals(0L, (new TransactionalRTree<>(new InMemoryRTree<>())).size()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java new file mode 100644 index 000000000..c10328235 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.exceptions.InvalidOperationException; +import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.StoreConfig; +import org.dizitart.no2.store.events.StoreEventListener; +import org.dizitart.no2.store.memory.InMemoryRTree; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class TransactionalStoreTest { + @Test + public void testCommit() { + assertThrows(InvalidOperationException.class, + () -> (new TransactionalStore<>(new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null))))).commit()); + } + + @Test + public void testClose() throws Exception { + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + transactionalStore.close(); + assertNull(transactionalStore.getCatalog()); + } + + @Test + public void testHasMap() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + when(nitriteStore.hasMap(anyString())).thenReturn(true); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(nitriteStore))); + assertTrue(transactionalStore.hasMap("Map Name")); + verify(nitriteStore).hasMap(anyString()); + assertNull(transactionalStore.getStoreVersion()); + } + + @Test + public void testHasMap2() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + when(nitriteStore.hasMap(anyString())).thenReturn(false); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(nitriteStore))); + assertFalse(transactionalStore.hasMap("Map Name")); + verify(nitriteStore).hasMap(anyString()); + assertNull(transactionalStore.getStoreVersion()); + } + + @Test + public void testOpenRTree() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + when(nitriteStore.openRTree(anyString(), any(), any())) + .thenReturn(new InMemoryRTree<>()); + when(nitriteStore.hasMap(anyString())).thenReturn(true); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(nitriteStore))); + Class keyType = Object.class; + assertEquals(0L, transactionalStore.openRTree("R Tree Name", keyType, Object.class).size()); + verify(nitriteStore, times(3)).hasMap(anyString()); + verify(nitriteStore).openRTree(anyString(), any(), any()); + assertNull(transactionalStore.getStoreVersion()); + } + + @Test + public void testOpenRTree2() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + when(nitriteStore.openRTree(anyString(), any(), any())) + .thenReturn(new InMemoryRTree<>()); + when(nitriteStore.hasMap(anyString())).thenReturn(false); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(nitriteStore))); + Class keyType = Object.class; + assertEquals(0L, transactionalStore.openRTree("R Tree Name", keyType, Object.class).size()); + verify(nitriteStore).hasMap(anyString()); + assertNull(transactionalStore.getStoreVersion()); + } + + @Test + public void testGetStoreVersion() { + NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); + when(nitriteStore.getStoreVersion()).thenReturn("foo"); + assertEquals("foo", (new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(nitriteStore)))).getStoreVersion()); + verify(nitriteStore).getStoreVersion(); + } + + @Test + public void testConstructor() { + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); + actualTransactionalStore.initialize(new NitriteConfig()); + actualTransactionalStore.openOrCreate(); + actualTransactionalStore.subscribe(mock(StoreEventListener.class)); + actualTransactionalStore.unsubscribe(mock(StoreEventListener.class)); + assertTrue(transactionalStore.hasUnsavedChanges()); + assertTrue(actualTransactionalStore.hasUnsavedChanges()); + assertFalse(transactionalStore.isClosed()); + assertFalse(actualTransactionalStore.isClosed()); + assertFalse(transactionalStore.isReadOnly()); + assertFalse(actualTransactionalStore.isReadOnly()); + } + + @Test + public void testConstructor2() { + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); + assertNull(actualTransactionalStore.getCatalog()); + assertFalse(actualTransactionalStore.isReadOnly()); + assertFalse(actualTransactionalStore.isClosed()); + assertTrue(actualTransactionalStore.hasUnsavedChanges()); + assertNull(actualTransactionalStore.getStoreConfig()); + assertNull(transactionalStore.getCatalog()); + assertFalse(transactionalStore.isReadOnly()); + assertFalse(transactionalStore.isClosed()); + assertTrue(transactionalStore.hasUnsavedChanges()); + assertNull(transactionalStore.getStoreConfig()); + } +} + diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/UndoEntryTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/UndoEntryTest.java new file mode 100644 index 000000000..4f6c8b4a0 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/UndoEntryTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.transaction; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class UndoEntryTest { + @Test + public void testCanEqual() { + assertFalse((new UndoEntry()).canEqual("Other")); + } + + @Test + public void testCanEqual2() { + UndoEntry undoEntry = new UndoEntry(); + assertTrue(undoEntry.canEqual(new UndoEntry())); + } + + @Test + public void testConstructor() { + UndoEntry actualUndoEntry = new UndoEntry(); + actualUndoEntry.setCollectionName("Collection Name"); + actualUndoEntry.setRollback(mock(Command.class)); + assertEquals("Collection Name", actualUndoEntry.getCollectionName()); + } + + @Test + public void testEquals() { + assertFalse((new UndoEntry()).equals("42")); + } + + @Test + public void testEquals2() { + UndoEntry undoEntry = new UndoEntry(); + assertTrue(undoEntry.equals(new UndoEntry())); + } + + @Test + public void testEquals3() { + UndoEntry undoEntry = new UndoEntry(); + undoEntry.setRollback(mock(Command.class)); + assertFalse(undoEntry.equals(new UndoEntry())); + } + + @Test + public void testEquals4() { + UndoEntry undoEntry = new UndoEntry(); + + UndoEntry undoEntry1 = new UndoEntry(); + undoEntry1.setRollback(mock(Command.class)); + assertFalse(undoEntry.equals(undoEntry1)); + } + + @Test + public void testEquals5() { + UndoEntry undoEntry = new UndoEntry(); + undoEntry.setCollectionName("Collection Name"); + assertFalse(undoEntry.equals(new UndoEntry())); + } + + @Test + public void testEquals6() { + UndoEntry undoEntry = new UndoEntry(); + + UndoEntry undoEntry1 = new UndoEntry(); + undoEntry1.setCollectionName("Collection Name"); + assertFalse(undoEntry.equals(undoEntry1)); + } + + @Test + public void testEquals7() { + UndoEntry undoEntry = new UndoEntry(); + undoEntry.setCollectionName("Collection Name"); + + UndoEntry undoEntry1 = new UndoEntry(); + undoEntry1.setCollectionName("Collection Name"); + assertTrue(undoEntry.equals(undoEntry1)); + } + + @Test + public void testHashCode() { + assertEquals(6061, (new UndoEntry()).hashCode()); + } + + @Test + public void testHashCode3() { + UndoEntry undoEntry = new UndoEntry(); + undoEntry.setCollectionName("Collection Name"); + assertEquals(244972291, undoEntry.hashCode()); + } +} + diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Builder.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Builder.kt index b49dfb100..b8ccac4cd 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Builder.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Builder.kt @@ -19,8 +19,8 @@ package org.dizitart.kno2 import org.dizitart.no2.Nitrite import org.dizitart.no2.NitriteBuilder import org.dizitart.no2.NitriteConfig -import org.dizitart.no2.module.NitriteModule -import org.dizitart.no2.module.NitriteModule.module +import org.dizitart.no2.common.module.NitriteModule +import org.dizitart.no2.common.module.NitriteModule.module import org.dizitart.no2.spatial.SpatialIndexer /** diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt index 2e6faa0be..6e71cdb61 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt @@ -21,8 +21,8 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jdk8.Jdk8Module import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.KotlinModule -import org.dizitart.no2.mapper.JacksonMapper -import org.dizitart.no2.mapper.JacksonExtension +import org.dizitart.no2.common.mapper.JacksonMapper +import org.dizitart.no2.common.mapper.JacksonExtension import org.dizitart.no2.spatial.mapper.GeometryExtension import java.time.ZoneId import java.time.chrono.ChronoPeriod diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt index 2bf24e1f8..c7cce31f1 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt @@ -16,11 +16,10 @@ package org.dizitart.kno2 -import org.dizitart.no2.common.util.Iterables import org.dizitart.no2.common.util.Iterables.setOf -import org.dizitart.no2.mapper.JacksonExtension -import org.dizitart.no2.module.NitriteModule -import org.dizitart.no2.module.NitritePlugin +import org.dizitart.no2.common.mapper.JacksonExtension +import org.dizitart.no2.common.module.NitriteModule +import org.dizitart.no2.common.module.NitritePlugin import org.dizitart.no2.spatial.SpatialIndexer /** diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt index cdb3292da..8a0e5736c 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt @@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule import org.dizitart.no2.index.IndexType import org.dizitart.no2.repository.annotations.Id import org.dizitart.no2.repository.annotations.Index -import org.dizitart.no2.mapper.JacksonExtension +import org.dizitart.no2.common.mapper.JacksonExtension import org.dizitart.no2.mvstore.MVStoreModule import org.junit.Test import org.threeten.bp.LocalDateTime diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt index b4ddfd3ea..472063466 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt @@ -19,11 +19,10 @@ package org.dizitart.kno2 import org.dizitart.no2.exceptions.SecurityException import org.dizitart.no2.index.NitriteTextIndexer import org.dizitart.no2.index.fulltext.UniversalTextTokenizer -import org.dizitart.no2.module.NitriteModule.module +import org.dizitart.no2.common.module.NitriteModule.module import org.dizitart.no2.mvstore.MVStoreModule import org.junit.Assert.* import org.junit.Test -import java.io.File /** * diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt index 4e78dc63d..19e41eb1b 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt @@ -17,7 +17,6 @@ package org.dizitart.kno2 import org.dizitart.kno2.filters.text -import org.dizitart.no2.common.NullOrder import org.dizitart.no2.common.SortOrder import org.dizitart.no2.exceptions.UniqueConstraintException import org.dizitart.no2.index.IndexOptions diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java index 96caf0239..e009b3a3a 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableCursor.java @@ -18,7 +18,6 @@ import io.reactivex.internal.functions.ObjectHelper; import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.repository.Cursor; diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableDocumentCursor.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableDocumentCursor.java index ef9636944..19f4b9124 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableDocumentCursor.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/FlowableDocumentCursor.java @@ -20,7 +20,6 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.NullOrder; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; diff --git a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java index f3d3c67ff..fbff22faa 100644 --- a/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java +++ b/rx-nitrite/src/main/java/org/dizitart/no2/rx/RxObjectRepositoryImpl.java @@ -29,7 +29,7 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import java.util.Collection; diff --git a/rx-nitrite/src/test/java/org/dizitart/no2/rx/RxBaseTest.java b/rx-nitrite/src/test/java/org/dizitart/no2/rx/RxBaseTest.java index 2ba03e12b..a95c448fd 100644 --- a/rx-nitrite/src/test/java/org/dizitart/no2/rx/RxBaseTest.java +++ b/rx-nitrite/src/test/java/org/dizitart/no2/rx/RxBaseTest.java @@ -23,8 +23,8 @@ import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.mapper.Mappable; -import org.dizitart.no2.mapper.NitriteMapper; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.annotations.Id; import org.junit.Before; From 3e7fb6b0c28f2cb9b95135ea0642d76779cf8c17 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Sun, 6 Jun 2021 00:23:16 +0530 Subject: [PATCH 10/13] checkpoint 2 --- .../no2/mapdb/NitriteBuilderTest.java | 6 +- .../no2/mapdb/NitriteStoreFactoryTest.java | 4 +- .../org/dizitart/no2/NitriteBuilderTest.java | 6 +- .../org/dizitart/no2/NitriteSecurityTest.java | 4 +- .../no2/rocksdb/NitriteBuilderTest.java | 6 +- .../no2/rocksdb/NitriteStoreFactoryTest.java | 4 +- .../java/org/dizitart/no2/NitriteBuilder.java | 4 +- .../java/org/dizitart/no2/NitriteConfig.java | 2 +- .../org/dizitart/no2/NitriteDatabase.java | 6 +- .../collection/DefaultNitriteCollection.java | 2 +- .../operation/CollectionOperations.java | 19 ++ .../java/org/dizitart/no2/common/Fields.java | 3 +- .../no2/common/crypto/AESEncryptor.java | 61 +++-- .../dizitart/no2/common/crypto/Encryptor.java | 6 +- .../common/module/NitritePluginFactory.java | 26 --- .../no2/common/module/PluginManager.java | 2 +- .../StringFieldEncryptionProcessor.java | 1 - ...ion.java => NitriteSecurityException.java} | 16 +- .../org/dizitart/no2/index/CompoundIndex.java | 2 + .../no2/store/UserAuthenticationService.java | 14 +- .../no2/transaction/NitriteTransaction.java | 9 +- .../no2/transaction/TransactionalConfig.java | 11 +- .../no2/transaction/TransactionalMap.java | 24 +- .../no2/transaction/TransactionalStore.java | 6 - .../org/dizitart/no2/NitriteBuilderTest.java | 10 +- .../org/dizitart/no2/NitriteConfigTest.java | 3 +- .../org/dizitart/no2/NitriteDatabaseTest.java | 10 +- .../no2/common/crypto/AESEncryptorTest.java | 3 +- .../no2/common/util/SecureStringTest.java | 48 ++-- ...java => NitriteSecurityExceptionTest.java} | 10 +- .../collection/BaseCollectionTest.java | 3 +- .../collection/FieldProcessorTest.java | 212 ++++++++++++++++++ .../repository/FieldProcessorTest.java | 207 +++++++++++++++++ .../repository/data/EncryptedPerson.java | 54 +++++ .../TransactionCollectionTest.java | 4 +- .../TransactionRepositoryTest.java | 4 +- .../store/UserAuthenticationServiceTest.java | 4 +- .../DefaultTransactionalCollectionTest.java | 48 ++-- .../transaction/NitriteTransactionTest.java | 4 +- .../transaction/TransactionalConfigTest.java | 40 ++-- .../transaction/TransactionalStoreTest.java | 8 +- .../kotlin/org/dizitart/kno2/BuilderTest.kt | 6 +- 42 files changed, 721 insertions(+), 201 deletions(-) delete mode 100644 nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java rename nitrite/src/main/java/org/dizitart/no2/exceptions/{SecurityException.java => NitriteSecurityException.java} (65%) rename nitrite/src/test/java/org/dizitart/no2/exceptions/{SecurityExceptionTest.java => NitriteSecurityExceptionTest.java} (69%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java index 67f734265..4b0123c1b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java @@ -27,7 +27,7 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.common.mapper.Mappable; @@ -222,13 +222,13 @@ public void testNitriteMapper() { assertNotNull(config.nitriteMapper()); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullUserId() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate(null, "abcd"); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullPassword() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate("abcd", null); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java index 7eb871223..32289bdda 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java +++ b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java @@ -19,7 +19,7 @@ import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -96,7 +96,7 @@ public void testIssue116() throws IOException { db.close(); try { db = createDb(fileName,"test-user2", "test-password2"); - } catch (SecurityException se) { + } catch (NitriteSecurityException se) { db = createDb(fileName,"test-user", "test-password"); assertNotNull(db); } finally { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 9684f41d6..a42b6daa7 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -24,7 +24,7 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.common.mapper.Mappable; @@ -230,13 +230,13 @@ public void testNitriteMapper() { assertNotNull(config.nitriteMapper()); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullUserId() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate(null, "abcd"); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullPassword() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate("abcd", null); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java index f8901e416..b98480a98 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java @@ -18,7 +18,7 @@ import org.apache.commons.io.FileUtils; import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -95,7 +95,7 @@ public void testIssue116() throws IOException { db.close(); try { db = createDb(fileName,"test-user2", "test-password2"); - } catch (SecurityException se) { + } catch (NitriteSecurityException se) { db = createDb(fileName,"test-user", "test-password"); assertNotNull(db); } finally { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java index e6e8f2bb2..8c0d361bb 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java @@ -28,7 +28,7 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.common.mapper.Mappable; @@ -216,13 +216,13 @@ public void testNitriteMapper() { assertNotNull(config.nitriteMapper()); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullUserId() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate(null, "abcd"); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullPassword() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate("abcd", null); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java index 539524ec2..018da2613 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java @@ -19,7 +19,7 @@ import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -78,7 +78,7 @@ public void testIssue116() throws IOException { db.close(); try { db = TestUtil.createDb(fileName,"test-user2", "test-password2"); - } catch (SecurityException se) { + } catch (NitriteSecurityException se) { db = TestUtil.createDb(fileName,"test-user", "test-password"); assertNotNull(db); } finally { diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java index fd036237c..8262ba811 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteBuilder.java @@ -19,7 +19,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.common.concurrent.ThreadPoolManager; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.common.module.NitriteModule; @@ -128,7 +128,7 @@ public Nitrite openOrCreate() { * @param username the username * @param password the password * @return the nitrite database instance. - * @throws SecurityException if the user credentials are wrong or one of them is empty string. + * @throws NitriteSecurityException if the user credentials are wrong or one of them is empty string. * @throws org.dizitart.no2.exceptions.NitriteIOException if unable to create a new in-memory database. * @throws org.dizitart.no2.exceptions.NitriteIOException if the database is corrupt and recovery fails. * @throws org.dizitart.no2.exceptions.NitriteIOException if the directory does not exist. diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java index 6158c84be..d97c041bf 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteConfig.java @@ -195,7 +195,7 @@ public NitriteStore getNitriteStore() { /** * Initializes this {@link NitriteConfig} instance. */ - void initialize() { + protected void initialize() { this.configured = true; this.pluginManager.initializePlugins(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java index 14834d682..21a79caf7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java +++ b/nitrite/src/main/java/org/dizitart/no2/NitriteDatabase.java @@ -23,7 +23,7 @@ import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.NitriteException; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.migration.MigrationManager; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.RepositoryFactory; @@ -202,10 +202,10 @@ public Session createSession() { private void validateUserCredentials(String username, String password) { if (isNullOrEmpty(username)) { - throw new SecurityException("username cannot be empty"); + throw new NitriteSecurityException("username cannot be empty"); } if (isNullOrEmpty(password)) { - throw new SecurityException("password cannot be empty"); + throw new NitriteSecurityException("password cannot be empty"); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 41c0e514c..119da0e53 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -396,7 +396,7 @@ public void setAttributes(Attributes attributes) { } } - private void closeEventBus() throws Exception { + private void closeEventBus() { if (eventBus != null) { eventBus.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java index 4e2586a36..11c071794 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java @@ -33,6 +33,9 @@ import java.util.Collection; +import static org.dizitart.no2.collection.UpdateOptions.updateOptions; +import static org.dizitart.no2.common.util.DocumentUtils.createUniqueFilter; + /** * The collection operations. * @@ -74,6 +77,7 @@ public CollectionOperations(String collectionName, * @param processor the processor */ public void addProcessor(Processor processor) { + doProcess(processor); processorChain.add(processor); } @@ -84,6 +88,7 @@ public void addProcessor(Processor processor) { */ public void removeProcessor(Processor processor) { processorChain.remove(processor); + undoProcess(processor); } /** @@ -284,4 +289,18 @@ private void dropNitriteMap() { // drop the map nitriteMap.drop(); } + + private void doProcess(Processor processor) { + for (Document document : find(Filter.ALL, null)) { + Document processed = processor.processBeforeWrite(document); + update(createUniqueFilter(document), processed, updateOptions(false)); + } + } + + private void undoProcess(Processor processor) { + for (Document document : find(Filter.ALL, null)) { + Document processed = processor.processAfterRead(document); + update(createUniqueFilter(document), processed, updateOptions(false)); + } + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java index a7da3de9b..e5f380868 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Fields.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Fields.java @@ -1,6 +1,7 @@ package org.dizitart.no2.common; import lombok.AccessLevel; +import lombok.EqualsAndHashCode; import lombok.Setter; import org.dizitart.no2.common.util.StringUtils; @@ -23,13 +24,13 @@ * @author Anindya Chatterjee * @since 4.0 */ +@EqualsAndHashCode public class Fields implements Comparable, Serializable { private static final long serialVersionUID = 1601646404L; /** * The Field names. */ -// order of the given fields matter @Setter(AccessLevel.PACKAGE) protected List fieldNames; diff --git a/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java index 59dcff4de..467a2ab16 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/crypto/AESEncryptor.java @@ -20,7 +20,7 @@ import org.dizitart.no2.common.util.Base64; import org.dizitart.no2.common.util.CryptoUtils; import org.dizitart.no2.common.util.SecureString; -import org.dizitart.no2.exceptions.NitriteException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -40,21 +40,48 @@ * @since 4.0 */ public class AESEncryptor implements Encryptor { - private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding"; - private static final int TAG_LENGTH_BIT = 128; - private static final int IV_LENGTH_BYTE = 12; - private static final int SALT_LENGTH_BYTE = 16; - private static final Charset UTF_8 = StandardCharsets.UTF_8; + private final String encryptAlgo; + private final int tagLengthBit; + private final int ivLengthByte; + private final int saltLengthByte; + private final Charset UTF_8 = StandardCharsets.UTF_8; private final SecureString password; /** - * Instantiates a new Encryptor. + * Instantiates a new {@link AESEncryptor} with these default values + *

    + *

      + *
    • Encryption Algo - AES/GCM/NoPadding
    • + *
    • Tag Length (bit) - 128
    • + *
    • IV Length (byte) - 12
    • + *
    • Salt Length (byte) - 16
    • + *
    + *

    * * @param password the password */ public AESEncryptor(String password) { + this(password, "AES/GCM/NoPadding", 128, 12, 16); + } + + /** + * Instantiates a new {@link AESEncryptor}. + * + * @param password the password + * @param encryptionAlgo the encryption algo + * @param tagLengthBit the tag length bit + * @param ivLengthByte the iv length byte + * @param saltLengthByte the salt length byte + */ + public AESEncryptor(String password, String encryptionAlgo, + Integer tagLengthBit, Integer ivLengthByte, + Integer saltLengthByte) { this.password = new SecureString(password); + this.encryptAlgo = encryptionAlgo; + this.tagLengthBit = tagLengthBit; + this.ivLengthByte = ivLengthByte; + this.saltLengthByte = saltLengthByte; } /** @@ -67,18 +94,18 @@ public AESEncryptor(String password) { public String encrypt(byte[] plainText) { try { // 16 bytes salt - byte[] salt = CryptoUtils.getRandomNonce(SALT_LENGTH_BYTE); + byte[] salt = CryptoUtils.getRandomNonce(saltLengthByte); // GCM recommended 12 bytes iv? - byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE); + byte[] iv = CryptoUtils.getRandomNonce(ivLengthByte); // secret key from password SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); - Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); + Cipher cipher = Cipher.getInstance(encryptAlgo); // ASE-GCM needs GCMParameterSpec - cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(tagLengthBit, iv)); byte[] cipherText = cipher.doFinal(plainText); @@ -92,7 +119,7 @@ public String encrypt(byte[] plainText) { // string representation, base64, send this string to other for decryption. return Base64.encodeToString(cipherTextWithIvSalt, Base64.URL_SAFE); } catch (Exception e) { - throw new SecurityException("failed to encrypt data", e); + throw new NitriteSecurityException("failed to encrypt data", e); } } @@ -112,10 +139,10 @@ public String decrypt(String encryptedText) { // get back the iv and salt from the cipher text ByteBuffer bb = ByteBuffer.wrap(decode); - byte[] iv = new byte[IV_LENGTH_BYTE]; + byte[] iv = new byte[ivLengthByte]; bb.get(iv); - byte[] salt = new byte[SALT_LENGTH_BYTE]; + byte[] salt = new byte[saltLengthByte]; bb.get(salt); byte[] cipherText = new byte[bb.remaining()]; @@ -123,12 +150,12 @@ public String decrypt(String encryptedText) { // get back the aes key from the same password and salt SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.asString().toCharArray(), salt); - Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO); - cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv)); + Cipher cipher = Cipher.getInstance(encryptAlgo); + cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(tagLengthBit, iv)); byte[] plainText = cipher.doFinal(cipherText); return new String(plainText, UTF_8); } catch (Exception e) { - throw new SecurityException("failed to decrypt data", e); + throw new NitriteSecurityException("failed to decrypt data", e); } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java b/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java index 3ca4fc0c7..4d32637f5 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/crypto/Encryptor.java @@ -29,16 +29,14 @@ public interface Encryptor { * * @param plainText the plain text * @return the encrypted string - * @throws Exception the exception */ - String encrypt(byte[] plainText) throws Exception; + String encrypt(byte[] plainText); /** * Returns the decrypted string, encoded by this encryptor. * * @param encryptedText the encrypted text * @return the string - * @throws Exception the exception */ - String decrypt(String encryptedText) throws Exception; + String decrypt(String encryptedText); } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java b/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java deleted file mode 100644 index 5ec301904..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/common/module/NitritePluginFactory.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2017-2021 Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dizitart.no2.common.module; - -/** - * @author Anindya Chatterjee - */ -@FunctionalInterface -public interface NitritePluginFactory { - NitritePlugin createPlugin(); -} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java index bfd825ca4..1b5cc7cfb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java @@ -149,7 +149,7 @@ private synchronized void loadIfIndexer(NitritePlugin plugin) { } } - private void loadInternalPlugins() { + protected void loadInternalPlugins() { if (!indexerMap.containsKey(IndexType.Unique)) { log.debug("Loading default unique indexer"); loadPlugin(new UniqueIndexer()); diff --git a/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java b/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java index 8c146117d..2d702b60b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/processors/StringFieldEncryptionProcessor.java @@ -69,7 +69,6 @@ public void addFields(String... fields){ this.fields.addAll(Arrays.asList(fields)); } - @Override public Document processBeforeWrite(Document document) { try { diff --git a/nitrite/src/main/java/org/dizitart/no2/exceptions/SecurityException.java b/nitrite/src/main/java/org/dizitart/no2/exceptions/NitriteSecurityException.java similarity index 65% rename from nitrite/src/main/java/org/dizitart/no2/exceptions/SecurityException.java rename to nitrite/src/main/java/org/dizitart/no2/exceptions/NitriteSecurityException.java index 4f5106ab8..df5a7b173 100644 --- a/nitrite/src/main/java/org/dizitart/no2/exceptions/SecurityException.java +++ b/nitrite/src/main/java/org/dizitart/no2/exceptions/NitriteSecurityException.java @@ -22,13 +22,23 @@ * @author Anindya Chatterjee. * @since 1.0 */ -public class SecurityException extends NitriteException { +public class NitriteSecurityException extends NitriteException { /** - * Instantiates a new {@link SecurityException}. + * Instantiates a new {@link NitriteSecurityException}. * * @param errorMessage the error message */ - public SecurityException(String errorMessage) { + public NitriteSecurityException(String errorMessage) { super(errorMessage); } + + /** + * Instantiates a new {@link NitriteSecurityException}. + * + * @param errorMessage the error message + * @param cause the cause + */ + public NitriteSecurityException(String errorMessage, Throwable cause) { + super(errorMessage, cause); + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java index c2970147d..656871cf8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java @@ -178,6 +178,8 @@ private void removeIndexElement(NitriteMap> in @SuppressWarnings({"rawtypes", "unchecked"}) private void populateSubMap(NavigableMap subMap, FieldValues fieldValues, int startIndex) { + if (startIndex >= fieldValues.getValues().size()) return; + Pair pair = fieldValues.getValues().get(startIndex); Object value = pair.getSecond(); DBValue dbValue; diff --git a/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java b/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java index bbeea1e9e..9286d86c8 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/UserAuthenticationService.java @@ -19,7 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.common.util.SecureString; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; @@ -79,15 +79,15 @@ public void authenticate(String username, String password, boolean existing) { byte[] expectedHash = userCredential.getPasswordHash(); if (notExpectedPassword(password.toCharArray(), salt, expectedHash)) { - throw new SecurityException("username or password is invalid"); + throw new NitriteSecurityException("username or password is invalid"); } } else { - throw new SecurityException("username or password is invalid"); + throw new NitriteSecurityException("username or password is invalid"); } } } else if (existing) { if (store.hasMap(USER_MAP)) { - throw new SecurityException("username or password is invalid"); + throw new NitriteSecurityException("username or password is invalid"); } } } @@ -113,12 +113,12 @@ public void addOrUpdatePassword(boolean update, String username, byte[] expectedHash = credential.getPasswordHash(); if (notExpectedPassword(oldPassword.asString().toCharArray(), salt, expectedHash)) { - throw new SecurityException("username or password is invalid"); + throw new NitriteSecurityException("username or password is invalid"); } } } else { if (store.hasMap(USER_MAP)) { - throw new SecurityException("cannot add new credentials"); + throw new NitriteSecurityException("cannot add new credentials"); } } @@ -150,7 +150,7 @@ private byte[] hash(char[] password, byte[] salt) { return skf.generateSecret(spec).getEncoded(); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { log.error("Error while hashing password", e); - throw new SecurityException("error while hashing a password: " + throw new NitriteSecurityException("error while hashing a password: " + e.getMessage()); } finally { spec.clearPassword(); diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java b/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java index a24650c56..63fa00a0b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/NitriteTransaction.java @@ -8,6 +8,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.store.NitriteMap; @@ -255,8 +256,12 @@ private void prepare() { NitriteStore nitriteStore = nitrite.getStore(); NitriteConfig nitriteConfig = nitrite.getConfig(); - this.transactionalStore = new TransactionalStore<>(nitriteStore); - this.transactionalConfig = new TransactionalConfig(nitriteConfig, transactionalStore); + this.transactionalConfig = new TransactionalConfig(nitriteConfig); + this.transactionalConfig.loadModule(NitriteModule.module(new TransactionalStore<>(nitriteStore))); + + this.transactionalConfig.autoConfigure(); + this.transactionalConfig.initialize(); + this.transactionalStore = (TransactionalStore) this.transactionalConfig.getNitriteStore(); this.state = State.Active; } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java index 8dfdcee7a..ea9f6b391 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalConfig.java @@ -15,12 +15,10 @@ @Slf4j class TransactionalConfig extends NitriteConfig { private final NitriteConfig config; - private final TransactionalStore transactionalStore; - public TransactionalConfig(NitriteConfig config, TransactionalStore transactionalStore) { + public TransactionalConfig(NitriteConfig config) { super(); this.config = config; - this.transactionalStore = transactionalStore; } @Override @@ -57,6 +55,11 @@ public NitriteMapper nitriteMapper() { @Override public NitriteStore getNitriteStore() { - return transactionalStore; + return pluginManager.getNitriteStore(); + } + + @Override + public void initialize() { + super.initialize(); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java index 4ca11080d..c2bb93b52 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java @@ -7,7 +7,6 @@ import org.dizitart.no2.store.memory.InMemoryMap; import java.util.*; -import java.util.concurrent.ConcurrentSkipListSet; import static org.dizitart.no2.common.util.ObjectUtils.deepCopy; @@ -57,11 +56,11 @@ public V get(K k) { V result = backingMap.get(k); if (result == null) { result = primary.get(k); - if (result instanceof ConcurrentSkipListSet) { - // create a deep copy of the set so that it does not effect the original one - ConcurrentSkipListSet set = deepCopy((ConcurrentSkipListSet) result); - backingMap.put(k, (V) set); - result = (V) set; + if (result instanceof List) { + // create a deep copy of the list so that it does not effect the original one + List list = deepCopy((ArrayList) result); + backingMap.put(k, (V) list); + result = (V) list; } } @@ -90,7 +89,18 @@ public RecordStream values() { return RecordStream.empty(); } - return RecordStream.fromCombined(primary.values(), backingMap.values()); + return RecordStream.fromIterable(() -> new Iterator() { + private final Iterator> entryIterator = entries().iterator(); + @Override + public boolean hasNext() { + return entryIterator.hasNext(); + } + + @Override + public V next() { + return entryIterator.next().getSecond(); + } + }); } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java index 87e151c9f..25253c776 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java @@ -1,6 +1,5 @@ package org.dizitart.no2.transaction; -import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.index.BoundingBox; import org.dizitart.no2.store.*; @@ -137,9 +136,4 @@ public String getStoreVersion() { public T getStoreConfig() { return null; } - - @Override - public void initialize(NitriteConfig nitriteConfig) { - - } } diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java index 5e9319d9d..59d877268 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteBuilderTest.java @@ -27,7 +27,7 @@ import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.common.module.PluginManager; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; import org.dizitart.no2.integration.Retry; @@ -175,7 +175,7 @@ public void testOpenOrCreate3() { assertTrue(((InMemoryConfig) store.getStoreConfig()).eventListeners().isEmpty()); } - @Test + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreate4() { NitriteBuilder builderResult = Nitrite.builder(); builderResult.openOrCreate("", "iloveyou"); @@ -189,7 +189,7 @@ public void testOpenOrCreate4() { assertTrue(((InMemoryConfig) nitriteStore.getStoreConfig()).eventListeners().isEmpty()); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreate5() { NitriteBuilder builderResult = Nitrite.builder(); builderResult.openOrCreate("", "iloveyou"); @@ -254,13 +254,13 @@ public void testNitriteMapper() { assertNotNull(config.nitriteMapper()); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullUserId() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate(null, "abcd"); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testOpenOrCreateNullPassword() { NitriteBuilder builder = Nitrite.builder(); builder.openOrCreate("abcd", null); diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java index e4b4b8281..684d4840e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteConfigTest.java @@ -21,6 +21,7 @@ import org.dizitart.no2.common.module.NitritePlugin; import org.dizitart.no2.common.module.PluginManager; import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.memory.InMemoryConfig; @@ -139,7 +140,7 @@ public void testGetNitriteStore() { assertNull((new NitriteConfig()).getNitriteStore()); } - @Test + @Test(expected = NitriteIOException.class) public void testInitialize() { NitriteConfig nitriteConfig = new NitriteConfig(); nitriteConfig.initialize(); diff --git a/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java b/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java index 5d5f35526..ea64480e6 100644 --- a/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/NitriteDatabaseTest.java @@ -18,7 +18,8 @@ package org.dizitart.no2; import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.store.memory.InMemoryStoreModule; import org.junit.Test; import static org.junit.Assert.assertThrows; @@ -28,18 +29,19 @@ public class NitriteDatabaseTest { @Test public void testConstructor() { NitriteConfig nitriteConfig = new NitriteConfig(); + nitriteConfig.loadModule(new InMemoryStoreModule()); new NitriteDatabase("janedoe", "iloveyou", nitriteConfig); assertTrue(nitriteConfig.configured); } @Test public void testConstructor2() { - assertThrows(SecurityException.class, () -> new NitriteDatabase("", "iloveyou", new NitriteConfig())); + assertThrows(NitriteSecurityException.class, () -> new NitriteDatabase("", "iloveyou", new NitriteConfig())); } @Test public void testConstructor3() { - assertThrows(SecurityException.class, () -> new NitriteDatabase("janedoe", "", new NitriteConfig())); + assertThrows(NitriteSecurityException.class, () -> new NitriteDatabase("janedoe", "", new NitriteConfig())); } @Test @@ -47,7 +49,7 @@ public void testConstructor4() { assertThrows(NitriteIOException.class, () -> new NitriteDatabase("janedoe", "iloveyou", null)); } - @Test + @Test(expected = NitriteIOException.class) public void testConstructor5() { NitriteConfig nitriteConfig = new NitriteConfig(); new NitriteDatabase(nitriteConfig); diff --git a/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java b/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java index 1184e72d9..854bff17b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/crypto/AESEncryptorTest.java @@ -17,6 +17,7 @@ package org.dizitart.no2.common.crypto; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -32,7 +33,7 @@ public void testEncryptDecrypt() throws Exception { assertEquals("iloveyou", aesEncryptor.decrypt(encrypted)); } - @Test(expected = SecurityException.class) + @Test(expected = NitriteSecurityException.class) public void testDecrypt2() { (new AESEncryptor("iloveyou")).decrypt("bad base-64"); } diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java index 6c7a02cc0..fca7eea8c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/SecureStringTest.java @@ -26,69 +26,69 @@ public class SecureStringTest { @Test public void testConstructor() { assertThrows(ArrayIndexOutOfBoundsException.class, () -> new SecureString(1, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + new SecureString(new SecureString(new SecureString(new SecureString("")))))); assertEquals(2, (new SecureString(1, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String("foo"))))))).length()); - assertEquals(2, (new SecureString(1, 3, new String("foo"))).length()); + new SecureString(new SecureString(new SecureString(new SecureString("foo")))))).length()); + assertEquals(2, (new SecureString(1, 3, "foo")).length()); assertThrows(NegativeArraySizeException.class, () -> new SecureString(Integer.MIN_VALUE, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + new SecureString(new SecureString(new SecureString(new SecureString("")))))); assertEquals(0, - (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(new String())))))) + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString("")))))) .length()); assertEquals(1, (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A'))))))) .length()); - assertEquals(0, (new SecureString(new String())).length()); + assertEquals(0, (new SecureString("")).length()); assertEquals(1, (new SecureString(String.valueOf('A'))).length()); assertThrows(ArrayIndexOutOfBoundsException.class, () -> new SecureString(1, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + new SecureString(new SecureString(new SecureString(new SecureString("")))))); assertThrows(ArrayIndexOutOfBoundsException.class, () -> new SecureString(1, 3, new SecureString(new SecureString(new SecureString(Long.toString(1L)))))); assertEquals(2, (new SecureString(1, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String("foo"))))))).length()); - assertEquals(2, (new SecureString(1, 3, new String("foo"))).length()); + new SecureString(new SecureString(new SecureString(new SecureString("foo")))))).length()); + assertEquals(2, (new SecureString(1, 3, "foo")).length()); assertThrows(NegativeArraySizeException.class, () -> new SecureString(Integer.MIN_VALUE, 3, - new SecureString(new SecureString(new SecureString(new SecureString(new String())))))); + new SecureString(new SecureString(new SecureString(new SecureString("")))))); assertEquals(0, - (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(new String())))))) + (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString("")))))) .length()); assertEquals(1, (new SecureString(new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A'))))))) .length()); - assertEquals(0, (new SecureString(new String())).length()); + assertEquals(0, (new SecureString("")).length()); assertEquals(1, (new SecureString(String.valueOf('A'))).length()); } @Test public void testCharAt2() { assertEquals('o', - (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).charAt(1)); + (new SecureString(new SecureString(new SecureString(new SecureString("foo"))))).charAt(1)); } @Test public void testCharAt4() { assertEquals('o', - (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).charAt(1)); + (new SecureString(new SecureString(new SecureString(new SecureString("foo"))))).charAt(1)); } @Test public void testLength() { - assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).length()); - assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).length()); + assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(""))))).length()); + assertEquals(0, (new SecureString(new SecureString(new SecureString(new SecureString(""))))).length()); } @Test public void testSubSequence2() { assertEquals(2, - (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).subSequence(1, 3) + (new SecureString(new SecureString(new SecureString(new SecureString("foo"))))).subSequence(1, 3) .length()); } @Test public void testSubSequence3() { assertThrows(NegativeArraySizeException.class, - () -> (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))) + () -> (new SecureString(new SecureString(new SecureString(new SecureString(""))))) .subSequence(Integer.MIN_VALUE, 3)); } @@ -96,23 +96,23 @@ public void testSubSequence3() { @Test public void testSubSequence5() { assertEquals(2, - (new SecureString(new SecureString(new SecureString(new SecureString(new String("foo")))))).subSequence(1, 3) + (new SecureString(new SecureString(new SecureString(new SecureString("foo"))))).subSequence(1, 3) .length()); } @Test public void testSubSequence6() { assertThrows(NegativeArraySizeException.class, - () -> (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))) + () -> (new SecureString(new SecureString(new SecureString(new SecureString(""))))) .subSequence(Integer.MIN_VALUE, 3)); } @Test public void testAsString() { - assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).asString()); + assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(""))))).asString()); assertEquals("A", (new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A')))))).asString()); - assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).asString()); + assertEquals("", (new SecureString(new SecureString(new SecureString(new SecureString(""))))).asString()); assertEquals("A", (new SecureString(new SecureString(new SecureString(new SecureString(String.valueOf('A')))))).asString()); } @@ -120,9 +120,9 @@ public void testAsString() { @Test public void testToString() { assertEquals("Secure:XXXXX", - (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).toString()); + (new SecureString(new SecureString(new SecureString(new SecureString(""))))).toString()); assertEquals("Secure:XXXXX", - (new SecureString(new SecureString(new SecureString(new SecureString(new String()))))).toString()); + (new SecureString(new SecureString(new SecureString(new SecureString(""))))).toString()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/exceptions/SecurityExceptionTest.java b/nitrite/src/test/java/org/dizitart/no2/exceptions/NitriteSecurityExceptionTest.java similarity index 69% rename from nitrite/src/test/java/org/dizitart/no2/exceptions/SecurityExceptionTest.java rename to nitrite/src/test/java/org/dizitart/no2/exceptions/NitriteSecurityExceptionTest.java index 0ea04bcb7..f4bd0b9cf 100644 --- a/nitrite/src/test/java/org/dizitart/no2/exceptions/SecurityExceptionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/exceptions/NitriteSecurityExceptionTest.java @@ -1,15 +1,15 @@ package org.dizitart.no2.exceptions; +import org.junit.Test; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import org.junit.Test; - -public class SecurityExceptionTest { +public class NitriteSecurityExceptionTest { @Test public void testConstructor() { - SecurityException actualSecurityException = new SecurityException("An error occurred"); - assertEquals("org.dizitart.no2.exceptions.SecurityException: An error occurred", + NitriteSecurityException actualSecurityException = new NitriteSecurityException("An error occurred"); + assertEquals("org.dizitart.no2.exceptions.NitriteSecurityException: An error occurred", actualSecurityException.toString()); assertEquals("An error occurred", actualSecurityException.getLocalizedMessage()); assertNull(actualSecurityException.getCause()); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java index 121068b5f..9dee23797 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java @@ -26,6 +26,7 @@ import org.dizitart.no2.integration.Retry; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -48,7 +49,7 @@ public abstract class BaseCollectionTest { protected Document doc1, doc2, doc3; protected SimpleDateFormat simpleDateFormat; -// @Rule + @Rule public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Secured = {0}") diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java new file mode 100644 index 000000000..0055f97ac --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseCollectionTest { + + private Encryptor encryptor; + private NitriteCollection collection; + private Processor cvvProcessor; + + @Before + public void setUp() { + super.setUp(); + + encryptor = new AESEncryptor("s3k4e8"); + cvvProcessor = new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String cvv = document.get("cvv", String.class); + String encryptedCvv = encryptor.encrypt(cvv.getBytes(StandardCharsets.UTF_8)); + document.put("cvv", encryptedCvv); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCvv = document.get("cvv", String.class); + String cvv = encryptor.decrypt(encryptedCvv); + document.put("cvv", cvv); + return document; + } + }; + StringFieldEncryptionProcessor creditCardProcessor = new StringFieldEncryptionProcessor(encryptor); + creditCardProcessor.addFields("creditCardNumber"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(creditCardProcessor); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.addProcessor(cvvProcessor); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = collection.getStore().openMap("encryption-test", + NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + Document document = collection.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5500960345687452"); + assertEquals(document.get("cvv", String.class), "008"); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5548960345687452"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + Encryptor wrongEncryptor = new AESEncryptor("secret"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testUpdateEncryptedField() { + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "00000000000000") + .put("cvv", "007") + .put("expiryDate", new Date()); + + WriteResult writeResult = collection.update(where("name").eq("John Doe"), document); + assertEquals(writeResult.getAffectedCount(), 1); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "00000000000000"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + collection.createIndex("cvv"); + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testRemoveProcessor() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + + collection.removeProcessor(cvvProcessor); + + document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(document); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java new file mode 100644 index 000000000..be50bff32 --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.integration.repository.data.EncryptedPerson; +import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseObjectRepositoryTest { + private ObjectRepository persons; + private StringFieldEncryptionProcessor fieldProcessor; + + @Before + public void setUp() { + super.setUp(); + persons = db.getRepository(EncryptedPerson.class); + fieldProcessor = new StringFieldEncryptionProcessor("s3k4e8"); + fieldProcessor.addFields("creditCardNumber", "cvv"); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + persons.insert(person); + + persons.addProcessor(fieldProcessor); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + persons.insert(person); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = persons.getDocumentCollection().getStore() + .openMap(findRepositoryName(EncryptedPerson.class, null), NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + EncryptedPerson person = persons.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5500960345687452"); + assertEquals(person.getCvv(), "008"); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5548960345687452"); + assertEquals(person.getCvv(), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + ObjectRepository testPersons = db.getRepository(EncryptedPerson.class, "test"); + + Encryptor encryptor = new AESEncryptor("secret"); + Encryptor wrongEncryptor = new AESEncryptor("secret", "AES/GCM/NoPadding", + 5, 5, 5); + + testPersons.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + testPersons.insert(person); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + testPersons.insert(person); + + testPersons.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testUpdateEncryptedField() { + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("00000000000000"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + WriteResult writeResult = persons.update(where("name").eq("John Doe"), person); + assertEquals(writeResult.getAffectedCount(), 1); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "00000000000000"); + assertEquals(person.getCvv(), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + persons.createIndex("cvv"); + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testRemoveProcessor() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNull(person); + + persons.removeProcessor(fieldProcessor); + + person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNotNull(person); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java new file mode 100644 index 000000000..8b9d4b23b --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Entity; + +import java.util.Date; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity +public class EncryptedPerson implements Mappable { + private String name; + private String creditCardNumber; + private String cvv; + private Date expiryDate; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument("name", name) + .put("creditCardNumber", creditCardNumber) + .put("cvv", cvv) + .put("expiryDate", expiryDate); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + name = document.get("name", String.class); + creditCardNumber = document.get("creditCardNumber", String.class); + cvv = document.get("cvv", String.class); + expiryDate = document.get("expiryDate", Date.class); + } +} diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java index d50157908..7585a4542 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java @@ -489,7 +489,9 @@ public void testCommitSetAttribute() { NitriteCollection txCol = transaction.getCollection("test"); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txCol.setAttributes(attributes); assertNull(collection.getAttributes()); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index 1c8d08e41..c23d64d99 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -515,7 +515,9 @@ public void testCommitSetAttribute() { ObjectRepository txRepo = transaction.getRepository(TxData.class); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txRepo.setAttributes(attributes); assertNull(repository.getAttributes()); diff --git a/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java b/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java index 4d6fbfe8e..aa32c4958 100644 --- a/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/store/UserAuthenticationServiceTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.store; -import org.dizitart.no2.exceptions.SecurityException; +import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; @@ -36,7 +36,7 @@ public void testConstructor() { @Test public void testAuthenticate() { - assertThrows(SecurityException.class, + assertThrows(NitriteSecurityException.class, () -> (new UserAuthenticationService(new InMemoryStore())).authenticate("janedoe", "iloveyou", true)); } diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java index 425e223f0..e1c5386ff 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/DefaultTransactionalCollectionTest.java @@ -17,9 +17,8 @@ package org.dizitart.no2.transaction; -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.store.NitriteStore; -import org.dizitart.no2.store.StoreConfig; +import org.dizitart.no2.exceptions.NotIdentifiableException; +import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; import static org.junit.Assert.*; @@ -28,36 +27,37 @@ public class DefaultTransactionalCollectionTest { @Test public void testConstructor() { - NitriteStore nitriteStore = (NitriteStore) mock(NitriteStore.class); - TransactionalMap primary = new TransactionalMap<>("Map Name", null, null); - TransactionalMap primary1 = new TransactionalMap<>("Map Name", primary, - new TransactionalStore<>(null)); - TransactionalMap primary2 = new TransactionalMap<>("Map Name", primary1, - new TransactionalStore<>(new TransactionalStore<>(null))); - when(nitriteStore.openMap(anyString(), any(), any())) - .thenReturn(new TransactionalMap<>("Map Name", primary2, new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null))))); - when(nitriteStore.hasMap(anyString())).thenReturn(true); - TransactionalStore transactionalStore = new TransactionalStore<>( - new TransactionalStore<>(nitriteStore)); - TransactionalConfig config = new TransactionalConfig(new NitriteConfig(), transactionalStore); + TransactionalConfig transactionalConfig = mock(TransactionalConfig.class); + when(transactionalConfig.getNitriteStore()).thenThrow(new NotIdentifiableException("An error occurred")); TransactionContext transactionContext = new TransactionContext(); - transactionContext.setConfig(config); + transactionContext.setConfig(transactionalConfig); + assertThrows(NotIdentifiableException.class, + () -> new DefaultTransactionalCollection(null, transactionContext, null)); + verify(transactionalConfig).getNitriteStore(); + } + + @Test + public void testConstructor2() { + TransactionalConfig transactionalConfig = mock(TransactionalConfig.class); + TransactionalStore transactionalStore = new TransactionalStore<>( + new TransactionalStore<>(new TransactionalStore<>(new InMemoryStore()))); + + doReturn(transactionalStore).when(transactionalConfig).getNitriteStore(); + TransactionContext transactionContext = new TransactionContext(); + transactionContext.setConfig(transactionalConfig); DefaultTransactionalCollection actualDefaultTransactionalCollection = new DefaultTransactionalCollection(null, - transactionContext, null); + transactionContext, null); assertNull(actualDefaultTransactionalCollection.getCollectionName()); assertFalse(actualDefaultTransactionalCollection.isDropped()); - assertSame(transactionContext, actualDefaultTransactionalCollection.getTransactionContext()); - NitriteStore store = actualDefaultTransactionalCollection.getStore(); - assertSame(transactionalStore, store); + TransactionContext transactionContext1 = actualDefaultTransactionalCollection.getTransactionContext(); + assertSame(transactionContext, transactionContext1); + assertSame(transactionalStore, actualDefaultTransactionalCollection.getStore()); assertNull(actualDefaultTransactionalCollection.getPrimary()); assertNull(actualDefaultTransactionalCollection.getNitrite()); assertNull(actualDefaultTransactionalCollection.getNitriteMap()); assertNull(actualDefaultTransactionalCollection.getCollectionOperations().getAttributes()); - assertNull(store.getStoreVersion()); - verify(nitriteStore, times(2)).hasMap(anyString()); - verify(nitriteStore).openMap(anyString(), any(), any()); + verify(transactionalConfig, times(2)).getNitriteStore(); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java index 7fd397c5d..79e36d5f9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/NitriteTransactionTest.java @@ -20,6 +20,7 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -30,8 +31,7 @@ public class NitriteTransactionTest { public void testConstructor() { Nitrite nitrite = mock(Nitrite.class); when(nitrite.getConfig()).thenReturn(new NitriteConfig()); - doReturn(new TransactionalStore<>(new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null))))).when(nitrite).getStore(); + doReturn(new TransactionalStore<>(new InMemoryStore())).when(nitrite).getStore(); assertEquals(State.Active, (new NitriteTransaction(nitrite, new LockService())).getState()); verify(nitrite).getConfig(); verify(nitrite).getStore(); diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java index b0ac9499f..397a18f91 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalConfigTest.java @@ -20,7 +20,8 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.store.StoreConfig; +import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.store.memory.InMemoryConfig; import org.junit.Test; import java.util.HashSet; @@ -31,50 +32,45 @@ public class TransactionalConfigTest { @Test public void testConstructor() { - NitriteConfig config = new NitriteConfig(); - TransactionalStore transactionalStore = new TransactionalStore<>( - new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null)))); - TransactionalConfig actualTransactionalConfig = new TransactionalConfig(config, transactionalStore); + TransactionalConfig actualTransactionalConfig = new TransactionalConfig(new NitriteConfig()); assertTrue(actualTransactionalConfig.getMigrations().isEmpty()); assertEquals(1, actualTransactionalConfig.getSchemaVersion().intValue()); - assertSame(transactionalStore, actualTransactionalConfig.getNitriteStore()); + assertNull(actualTransactionalConfig.getNitriteStore()); } @Test public void testFindIndexer() { - NitriteConfig config = new NitriteConfig(); assertThrows(IndexingException.class, - () -> (new TransactionalConfig(config, - new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null))))) - .findIndexer("Index Type")); + () -> (new TransactionalConfig(new NitriteConfig())).findIndexer("Index Type")); } @Test public void testLoadModule() { - NitriteConfig config = new NitriteConfig(); - TransactionalConfig transactionalConfig = new TransactionalConfig(config, new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null)))); + TransactionalConfig transactionalConfig = new TransactionalConfig(new NitriteConfig()); NitriteModule nitriteModule = mock(NitriteModule.class); when(nitriteModule.plugins()).thenReturn(new HashSet<>()); assertSame(transactionalConfig, transactionalConfig.loadModule(nitriteModule)); verify(nitriteModule, times(2)).plugins(); } + @Test + public void testAutoConfigure() { + TransactionalConfig transactionalConfig = new TransactionalConfig(new NitriteConfig()); + transactionalConfig.autoConfigure(); + NitriteStore nitriteStore = transactionalConfig.getNitriteStore(); + assertTrue(nitriteStore instanceof org.dizitart.no2.store.memory.InMemoryStore); + assertFalse(nitriteStore.isClosed()); + assertTrue(((InMemoryConfig) nitriteStore.getStoreConfig()).eventListeners().isEmpty()); + } + @Test public void testNitriteMapper() { - NitriteConfig config = new NitriteConfig(); - assertNull((new TransactionalConfig(config, new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null))))).nitriteMapper()); + assertNull((new TransactionalConfig(new NitriteConfig())).nitriteMapper()); } @Test public void testGetNitriteStore() { - NitriteConfig config = new NitriteConfig(); - TransactionalStore transactionalStore = new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null))); - assertSame(transactionalStore, (new TransactionalConfig(config, transactionalStore)).getNitriteStore()); + assertNull((new TransactionalConfig(new NitriteConfig())).getNitriteStore()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java index c10328235..fe632a6ad 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java @@ -22,7 +22,9 @@ import org.dizitart.no2.store.NitriteStore; import org.dizitart.no2.store.StoreConfig; import org.dizitart.no2.store.events.StoreEventListener; +import org.dizitart.no2.store.memory.InMemoryConfig; import org.dizitart.no2.store.memory.InMemoryRTree; +import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; import static org.junit.Assert.*; @@ -107,10 +109,8 @@ public void testGetStoreVersion() { @Test public void testConstructor() { - TransactionalStore transactionalStore = new TransactionalStore<>( - new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null)))); - TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); + TransactionalStore transactionalStore = new TransactionalStore<>(new InMemoryStore()); + TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); actualTransactionalStore.initialize(new NitriteConfig()); actualTransactionalStore.openOrCreate(); actualTransactionalStore.subscribe(mock(StoreEventListener.class)); diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt index 472063466..52a466ff4 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BuilderTest.kt @@ -16,7 +16,7 @@ package org.dizitart.kno2 -import org.dizitart.no2.exceptions.SecurityException +import org.dizitart.no2.exceptions.NitriteSecurityException import org.dizitart.no2.index.NitriteTextIndexer import org.dizitart.no2.index.fulltext.UniversalTextTokenizer import org.dizitart.no2.common.module.NitriteModule.module @@ -64,14 +64,14 @@ class BuilderTest : BaseTest() { assertFalse(db?.isClosed!!) } - @Test(expected = SecurityException::class) + @Test(expected = NitriteSecurityException::class) fun testBuilderNoUser() { db = nitrite("", "password") { loadModule(MVStoreModule(fileName)) } } - @Test(expected = SecurityException::class) + @Test(expected = NitriteSecurityException::class) fun testBuilderNoPassword() { db = nitrite("user", "") { loadModule(MVStoreModule(fileName)) From ff5ccd12d842dc3caf7d1f44abe8703e244df228 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Sun, 6 Jun 2021 23:49:00 +0530 Subject: [PATCH 11/13] checkpoint 3 --- .../no2/repository/AnnotationScanner.java | 12 ++-- .../no2/repository/IndexValidator.java | 14 ++-- .../no2/repository/ObjectIdField.java | 71 ++++++++++++------- .../no2/repository/RepositoryOperations.java | 4 +- .../annotations/{Order.java => Embedded.java} | 5 +- .../no2/repository/annotations/Id.java | 1 + .../ObjectRepositoryNegativeTest.java | 21 ++++++ .../RepositoryCompoundIndexTest.java | 46 ++++++------ .../RepositoryModificationTest.java | 32 +++++++-- .../no2/integration/repository/data/Book.java | 6 +- .../integration/repository/data/BookId.java | 11 ++- .../integration/repository/data/Company.java | 6 +- .../repository/data/WithoutEmbeddedId.java | 65 +++++++++++++++++ 13 files changed, 217 insertions(+), 77 deletions(-) rename nitrite/src/main/java/org/dizitart/no2/repository/annotations/{Order.java => Embedded.java} (92%) create mode 100644 nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java b/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java index 0daab41a4..2fb209025 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/AnnotationScanner.java @@ -20,6 +20,7 @@ import lombok.Getter; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.util.StringUtils; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.repository.annotations.*; @@ -134,13 +135,16 @@ private void scanIdAnnotation() { boolean alreadyIdFound = false; for (Field field : fieldList) { if (field.isAnnotationPresent(Id.class)) { - indexValidator.validate(field.getType(), field.getName(), nitriteMapper); + Id id = field.getAnnotation(Id.class); + String fieldName = StringUtils.isNullOrEmpty(id.fieldName()) ? field.getName() : id.fieldName(); + indexValidator.validate(field.getType(), fieldName, nitriteMapper); if (alreadyIdFound) { throw new NotIdentifiableException("multiple id fields found for the type"); } else { alreadyIdFound = true; objectIdField = new ObjectIdField(); objectIdField.setField(field); + objectIdField.setIdFieldName(fieldName); objectIdField.setEmbedded(isEmbeddedId(field)); } } @@ -152,11 +156,11 @@ private boolean isEmbeddedId(Field field) { if (fields.size() == 0) return false; for (Field f : fields) { - if (!f.isAnnotationPresent(Order.class)) { - return false; + if (f.isAnnotationPresent(Embedded.class)) { + return true; } } - return true; + return false; } private void populateIndex(List indexList) { diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java b/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java index 17200c43d..f18b42e03 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/IndexValidator.java @@ -21,7 +21,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.repository.annotations.Order; +import org.dizitart.no2.repository.annotations.Embedded; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -61,14 +61,20 @@ public void validate(Class fieldType, String field, NitriteMapper nitriteMapp Document document; try { document = skeletonDocument(nitriteMapper, fieldType); - if (document.size() > 1) { + if (document.size() > 0) { // compound index + boolean embeddedFieldFound = false; List fields = reflector.getAllFields(fieldType); for (Field indexField : fields) { - if (!indexField.isAnnotationPresent(Order.class)) { - throw new IndexingException("@Order must be specified for all fields in the embedded id object"); + if (indexField.isAnnotationPresent(Embedded.class)) { + embeddedFieldFound = true; + break; } } + + if (!embeddedFieldFound) { + throw new IndexingException("no embedded field found for object id"); + } } else { if (!Comparable.class.isAssignableFrom(fieldType)) { throw new IndexingException("cannot index on non comparable field " + field); diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java index 04a6e02fc..1061273cd 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/ObjectIdField.java @@ -22,14 +22,15 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.common.util.StringUtils; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.repository.annotations.Order; +import org.dizitart.no2.filters.NitriteFilter; +import org.dizitart.no2.repository.annotations.Embedded; import java.lang.reflect.Field; import java.util.List; import java.util.NavigableMap; -import java.util.Set; import java.util.TreeMap; import static org.dizitart.no2.filters.FluentFilter.where; @@ -40,67 +41,87 @@ class ObjectIdField { private final Reflector reflector; private final IndexValidator indexValidator; - private String[] fieldNames; + private String[] embeddedFieldNames; @Getter @Setter private Field field; + @Getter @Setter private boolean isEmbedded; + @Getter + @Setter + private String idFieldName; + public ObjectIdField() { this.reflector = new Reflector(); this.indexValidator = new IndexValidator(reflector); } public String[] getFieldNames(NitriteMapper nitriteMapper) { - if (fieldNames != null) { - return fieldNames; + if (embeddedFieldNames != null) { + return embeddedFieldNames; } if (!isEmbedded) { - fieldNames = new String[]{field.getName()}; - return fieldNames; + embeddedFieldNames = new String[]{ idFieldName }; + return embeddedFieldNames; } List fieldList = reflector.getAllFields(field.getType()); NavigableMap orderedFieldName = new TreeMap<>(); + + boolean embeddedFieldFound = false; for (Field field : fieldList) { - String name = this.field.getName() + NitriteConfig.getFieldSeparator() + field.getName(); - indexValidator.validate(field.getType(), name, nitriteMapper); + if (field.isAnnotationPresent(Embedded.class)) { + embeddedFieldFound = true; + Embedded embedded = field.getAnnotation(Embedded.class); + int order = embedded.order(); + String fieldName = StringUtils.isNullOrEmpty(embedded.fieldName()) + ? field.getName() : embedded.fieldName(); - int order = getOrder(field); - orderedFieldName.put(order, name); + String name = this.idFieldName + NitriteConfig.getFieldSeparator() + fieldName; + indexValidator.validate(field.getType(), name, nitriteMapper); + + orderedFieldName.put(order, name); + } } - fieldNames = orderedFieldName.values().toArray(new String[0]); - return fieldNames; + if (!embeddedFieldFound) { + throw new IndexingException("no embedded field found for " + field.getName()); + } + + embeddedFieldNames = orderedFieldName.values().toArray(new String[0]); + return embeddedFieldNames; } public Filter createUniqueFilter(Object value, NitriteMapper nitriteMapper) { - if (fieldNames.length == 1) { - return where(field.getName()).eq(value); + if (embeddedFieldNames.length == 1) { + return where(idFieldName).eq(value); } else { Document document = nitriteMapper.convert(value, Document.class); - Set fields = document.getFields(); - Filter[] filters = new Filter[fields.size()]; + Filter[] filters = new Filter[embeddedFieldNames.length]; int index = 0; - for (String field : fields) { - Object fieldValue = document.get(field); + for (String field : embeddedFieldNames) { + String docFieldName = getEmbeddedFieldName(field); + Object fieldValue = document.get(docFieldName); filters[index++] = where(field).eq(fieldValue); } - return Filter.and(filters); + NitriteFilter nitriteFilter = (NitriteFilter) Filter.and(filters); + nitriteFilter.setObjectFilter(true); + return nitriteFilter; } } - private int getOrder(Field field) { - if (field.isAnnotationPresent(Order.class)) { - Order order = field.getAnnotation(Order.class); - return order.value(); + private String getEmbeddedFieldName(String fieldName) { + if (fieldName.contains(NitriteConfig.getFieldSeparator())) { + return fieldName.substring(fieldName.indexOf(NitriteConfig.getFieldSeparator()) + 1); + } else { + return fieldName; } - throw new IndexingException("no order specified for the field " + field.getName()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java index 5e9eb096a..eb4e2703b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/RepositoryOperations.java @@ -127,7 +127,7 @@ public Document toDocument(T object, boolean update) { if (idField.get(object) == null) { NitriteId id = document.getId(); idField.set(object, id); - document.put(idField.getName(), nitriteMapper.convert(id, Comparable.class)); + document.put(objectIdField.getIdFieldName(), nitriteMapper.convert(id, Comparable.class)); } else if (!update) { throw new InvalidIdException("auto generated id should not be set manually"); } @@ -136,7 +136,7 @@ public Document toDocument(T object, boolean update) { } } - Object idValue = document.get(idField.getName()); + Object idValue = document.get(objectIdField.getIdFieldName()); if (idValue == null) { throw new InvalidIdException("id cannot be null"); } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Embedded.java similarity index 92% rename from nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java rename to nitrite/src/main/java/org/dizitart/no2/repository/annotations/Embedded.java index 6e1ae0210..6e4240006 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Order.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Embedded.java @@ -27,6 +27,7 @@ */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) -public @interface Order { - int value(); +public @interface Embedded { + int order(); + String fieldName() default ""; } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Id.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Id.java index a886b94a4..d63c53729 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Id.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Id.java @@ -30,4 +30,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Id { + String fieldName() default ""; } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java index dbba4d63b..91ced7232 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java @@ -203,4 +203,25 @@ public void testExternalNitriteId() { result = repository.update(obj, true); assertNotEquals(id.getIdValue(), result.iterator().next().getIdValue()); } + + @Test(expected = IndexingException.class) + public void testWithoutEmbeddedId() { + ObjectRepository repository = db.getRepository(WithoutEmbeddedId.class); + assertNull(repository); + } + + @Test(expected = InvalidIdException.class) + public void testGetByWrongIdType() { + ObjectRepository repository = db.getRepository(WithPublicField.class); + WithPublicField object = new WithPublicField(); + object.name = "test"; + object.number = 2; + + repository.insert(object); + + NitriteId id = NitriteId.createId("1"); + WithPublicField instance = repository.getById(id); + assertEquals(object.name, instance.name); + assertEquals(object.number, instance.number); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java index 20d3aa784..9431d991e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java @@ -17,36 +17,36 @@ package org.dizitart.no2.integration.repository; -import lombok.val; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.integration.repository.data.DataGenerator; -import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.integration.repository.data.Book; +import org.dizitart.no2.integration.repository.data.BookId; import org.junit.Test; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + /** * @author Anindya Chatterjee */ -public class RepositoryCompoundIndexTest /*extends BaseObjectRepositoryTest*/ { - private Nitrite db; +public class RepositoryCompoundIndexTest extends BaseObjectRepositoryTest { @Test - public void test() { - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator("."); - db = nitriteBuilder.openOrCreate(); - - val bookRepository = db.getRepository(Book.class); - - for (int i = 0; i < 10; i++) { - Book book = DataGenerator.randomBook(); - bookRepository.insert(book); - } - - Cursor bookCursor = bookRepository.find(); - for (Book book : bookCursor) { - System.out.println(book); - } + public void testFindById() { + BookId bookId = new BookId(); + bookId.setAuthor("John Doe"); + bookId.setIsbn("123456"); + bookId.setName("Nitrite Database"); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription("Some random book description"); + book.setPrice(22.56); + book.setPublisher("My Publisher House"); + book.setTags(Arrays.asList("database", "nosql")); + + bookRepository.insert(book); + + Book bookById = bookRepository.getById(bookId); + assertEquals(bookById, book); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index 439f03868..1ad119dfe 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -195,7 +195,7 @@ public void testUpdateWithJustOnceFalse() throws ParseException { @Test public void testUpsertTrue() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -220,7 +220,7 @@ public void testUpsertTrue() { @Test public void testUpsertFalse() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -247,7 +247,7 @@ public void testDeleteFilterAndWithOutOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate)); @@ -261,7 +261,7 @@ public void testDeleteFilterAndWithOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate), true); @@ -280,7 +280,7 @@ public void testEmployeeRecord() { } } - Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); + Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); assertEquals(cursor.size(), occurrence); } @@ -632,4 +632,26 @@ public void testUpdateObjectExistsUpsertFalse() { assertEquals(repo.find().firstOrNull().getId(), 1); assertEquals(repo.find().firstOrNull().getName(), "second"); } + + @Test + public void testNestedUpdate() { + Employee employee = employeeRepository.getById(1L); + assertNotNull(employee); + + Note note = employee.getEmployeeNote(); + String text = note.getText(); + assertNotNull(text); + + Document update = createDocument("employeeNote.text", "some updated text"); + WriteResult writeResult = employeeRepository.update(where("empId").eq(1L), update, true); + assertEquals(1, writeResult.getAffectedCount()); + + employee = employeeRepository.getById(1L); + assertNotNull(employee); + + note = employee.getEmployeeNote(); + assertNotNull(note); + assertNotEquals(text, note.getText()); + assertEquals("some updated text", note.getText()); + } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java index 9e2981c35..3100f9d64 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -40,7 +40,7 @@ @Index(value = { "price", "publisher" }) }) public class Book implements Mappable { - @Id + @Id(fieldName = "book_id") private BookId bookId; private String publisher; @@ -53,7 +53,7 @@ public class Book implements Mappable { @Override public Document write(NitriteMapper mapper) { - return createDocument("bookId", mapper.convert(bookId, Document.class)) + return createDocument("book_id", mapper.convert(bookId, Document.class)) .put("publisher", publisher) .put("price", price) .put("tags", tags) @@ -63,7 +63,7 @@ public Document write(NitriteMapper mapper) { @Override @SuppressWarnings("unchecked") public void read(NitriteMapper mapper, Document document) { - bookId = mapper.convert(document.get("bookId"), BookId.class); + bookId = mapper.convert(document.get("book_id"), BookId.class); publisher = document.get("publisher", String.class); price = document.get("price", Double.class); tags = (List) document.get("tags", List.class); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java index 05cf9ea07..239b493d3 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java @@ -21,7 +21,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Order; +import org.dizitart.no2.repository.annotations.Embedded; import static org.dizitart.no2.collection.Document.createDocument; @@ -30,26 +30,25 @@ */ @Data public class BookId implements Mappable { - @Order(0) + @Embedded(order = 0) private String isbn; - @Order(1) + @Embedded(order = 1, fieldName = "book_name") private String name; - @Order(2) private String author; @Override public Document write(NitriteMapper mapper) { return createDocument("isbn", isbn) - .put("name", name) + .put("book_name", name) .put("author", author); } @Override public void read(NitriteMapper mapper, Document document) { isbn = document.get("isbn", String.class); - name = document.get("name", String.class); + name = document.get("book_name", String.class); author = document.get("author", String.class); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java index 84d76786e..944e17358 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Company.java @@ -40,7 +40,7 @@ @Index(value = "companyName") }) public class Company implements Serializable, Mappable { - @Id + @Id(fieldName = "company_id") @Getter @Setter private Long companyId; @@ -63,7 +63,7 @@ public class Company implements Serializable, Mappable { @Override public Document write(NitriteMapper mapper) { - return Document.createDocument("companyId", companyId) + return Document.createDocument("company_id", companyId) .put("companyName", companyName) .put("dateCreated", dateCreated) .put("departments", departments) @@ -73,7 +73,7 @@ public Document write(NitriteMapper mapper) { @Override @SuppressWarnings("unchecked") public void read(NitriteMapper mapper, Document document) { - companyId = document.get("companyId", Long.class); + companyId = document.get("company_id", Long.class); companyName = document.get("companyName", String.class); dateCreated = document.get("dateCreated", Date.class); departments = document.get("departments", List.class); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java new file mode 100644 index 000000000..9ecb9a68b --- /dev/null +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; + +/** + * @author Anindya Chatterjee + */ +@Data +public class WithoutEmbeddedId implements Mappable { + @Id + private NestedId nestedId; + private String data; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("nestedId", nestedId.write(mapper)) + .put("data", data); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + Document nestedId = document.get("nestedId", Document.class); + this.nestedId = mapper.convert(nestedId, NestedId.class); + this.data = document.get("data", String.class); + } + + + @Data + public static class NestedId implements Mappable { + private Long id; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("id", id); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + id = document.get("id", Long.class); + } + } +} From 6ab4d635bb435924930001c7258f72aeb89682c6 Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Tue, 8 Jun 2021 12:27:29 +0530 Subject: [PATCH 12/13] checkpoint 4 --- .../mapper/JacksonMapperModuleTest.java | 31 ++ .../no2/common/mapper/JacksonMapperTest.java | 311 ++++++++++++++++++ .../extensions/NitriteIdDeserializerTest.java | 35 ++ .../extensions/NitriteIdExtensionTest.java | 29 ++ .../extensions/NitriteIdSerializerTest.java | 33 ++ .../migrate/MigrationTest.java | 38 ++- .../migrate/NewClass.java | 19 +- .../migrate/OldClass.java | 19 +- .../repository}/BaseObjectRepositoryTest.java | 34 +- .../repository/CustomFieldSeparatorTest.java | 163 +++++++++ .../repository/FieldProcessorTest.java | 207 ++++++++++++ .../repository}/InternalClass.java | 7 +- .../repository}/NitriteIdAsIdTest.java | 11 +- .../repository}/ObjectCursorTest.java | 9 +- .../ObjectRepositoryNegativeTest.java | 80 ++++- .../repository}/ObjectRepositoryTest.java | 114 ++++++- .../repository}/ProjectionTest.java | 18 +- .../RepositoryCompoundIndexTest.java | 52 +++ .../repository/RepositoryFactoryTest.java | 247 ++++++++++++++ .../repository}/RepositoryJoinTest.java | 10 +- .../RepositoryModificationTest.java | 174 +++++++++- .../repository}/RepositorySearchTest.java | 88 +++-- .../repository}/Retry.java | 19 +- .../repository}/TestUtil.java | 7 +- .../repository}/UnAnnotatedObjectTest.java | 38 +-- .../UniversalTextTokenizerTest.java | 14 +- .../no2/integration/repository/data/Book.java | 50 +++ .../integration/repository/data/BookId.java | 37 +++ .../repository}/data/ChildClass.java | 7 +- .../repository}/data/ClassA.java | 11 +- .../repository}/data/ClassB.java | 7 +- .../repository}/data/ClassC.java | 7 +- .../repository}/data/Company.java | 27 +- .../repository/data/DataGenerator.java | 117 +++++++ .../repository}/data/ElemMatch.java | 7 +- .../repository}/data/Employee.java | 21 +- .../repository/data/EncryptedPerson.java | 35 ++ .../repository}/data/Note.java | 10 +- .../repository}/data/ParentClass.java | 12 +- .../repository}/data/PersonEntity.java | 14 +- .../repository}/data/ProductScore.java | 7 +- .../repository}/data/RepeatableIndexTest.java | 7 +- .../repository}/data/StressRecord.java | 7 +- .../repository}/data/SubEmployee.java | 7 +- .../repository}/data/SuperDuperClass.java | 7 +- .../data/WithCircularReference.java | 7 +- .../repository}/data/WithClassField.java | 7 +- .../data/WithCustomConstructor.java | 7 +- .../repository}/data/WithDateId.java | 7 +- .../repository}/data/WithEmptyStringId.java | 7 +- .../repository}/data/WithFinalField.java | 7 +- .../repository/data/WithNitriteId.java | 32 ++ .../repository}/data/WithNullId.java | 7 +- .../repository}/data/WithObjectId.java | 7 +- .../repository}/data/WithOutGetterSetter.java | 7 +- .../repository}/data/WithOutId.java | 7 +- .../data/WithPrivateConstructor.java | 7 +- .../repository}/data/WithPublicField.java | 7 +- .../repository}/data/WithTransientField.java | 7 +- .../repository/data/WithoutEmbeddedId.java | 37 +++ .../TransactionRepositoryTest.java | 55 +++- .../transaction/TxData.java | 7 +- .../dizitart/no2/test/data/DataGenerator.java | 144 -------- .../org/dizitart/no2/mapdb/MapDBModule.java | 2 + .../no2/mvstore/NitriteMVRTreeMap.java | 2 +- .../no2/migration/RepositoryInstruction.java | 15 +- .../no2/store/AbstractNitriteStore.java | 4 +- .../transaction/TransactionalStoreTest.java | 16 +- 68 files changed, 2155 insertions(+), 454 deletions(-) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperModuleTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializerTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtensionTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializerTest.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration}/migrate/MigrationTest.java (93%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration}/migrate/NewClass.java (54%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration}/migrate/OldClass.java (56%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/BaseObjectRepositoryTest.java (86%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/InternalClass.java (81%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/NitriteIdAsIdTest.java (91%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/ObjectCursorTest.java (89%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/ObjectRepositoryNegativeTest.java (67%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/ObjectRepositoryTest.java (66%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/ProjectionTest.java (82%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/RepositoryJoinTest.java (95%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/RepositoryModificationTest.java (76%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/RepositorySearchTest.java (86%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/Retry.java (65%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/TestUtil.java (93%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/UnAnnotatedObjectTest.java (63%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/UniversalTextTokenizerTest.java (97%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ChildClass.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ClassA.java (84%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ClassB.java (87%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ClassC.java (86%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/Company.java (80%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ElemMatch.java (81%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/Employee.java (77%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/Note.java (72%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ParentClass.java (78%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/PersonEntity.java (77%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/ProductScore.java (83%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/RepeatableIndexTest.java (85%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/StressRecord.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/SubEmployee.java (84%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/SuperDuperClass.java (83%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithCircularReference.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithClassField.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithCustomConstructor.java (84%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithDateId.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithEmptyStringId.java (81%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithFinalField.java (82%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithNullId.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithObjectId.java (81%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithOutGetterSetter.java (82%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithOutId.java (83%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithPrivateConstructor.java (86%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithPublicField.java (81%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration/repository}/data/WithTransientField.java (82%) create mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration}/transaction/TransactionRepositoryTest.java (94%) rename nitrite-jackson-mapper/src/test/java/org/dizitart/no2/{test => integration}/transaction/TxData.java (83%) delete mode 100644 nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/DataGenerator.java diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperModuleTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperModuleTest.java new file mode 100644 index 000000000..d06ce7466 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperModuleTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.mapper; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JacksonMapperModuleTest { + + @Test + public void testPlugins() { + assertEquals(1, (new JacksonMapperModule()).plugins().size()); + } +} + diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperTest.java new file mode 100644 index 000000000..72eec9f15 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/JacksonMapperTest.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.mapper; + +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.cfg.ContextAttributes; +import com.fasterxml.jackson.databind.introspect.VisibilityChecker; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.BinaryNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.extensions.NitriteIdExtension; +import org.dizitart.no2.exceptions.ObjectMappingException; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; + +import static org.junit.Assert.*; + +public class JacksonMapperTest { + @Test + public void testConstructor() { + ObjectMapper objectMapper = (new JacksonMapper()).getObjectMapper(); + PolymorphicTypeValidator polymorphicTypeValidator = objectMapper.getPolymorphicTypeValidator(); + assertTrue(polymorphicTypeValidator instanceof LaissezFaireSubTypeValidator); + VisibilityChecker visibilityChecker = objectMapper.getVisibilityChecker(); + assertTrue(visibilityChecker instanceof VisibilityChecker.Std); + assertNull(objectMapper.getPropertyNamingStrategy()); + assertTrue(objectMapper + .getDeserializationContext() instanceof com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.Impl); + assertSame(objectMapper.getFactory(), objectMapper.getJsonFactory()); + assertTrue(objectMapper.getSerializerFactory() instanceof com.fasterxml.jackson.databind.ser.BeanSerializerFactory); + assertTrue(objectMapper + .getSerializerProvider() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue(objectMapper + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue( + objectMapper.getSubtypeResolver() instanceof com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver); + DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig(); + assertTrue(deserializationConfig + .getAnnotationIntrospector() instanceof com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector); + assertNull(deserializationConfig.getActiveView()); + assertNull(deserializationConfig.getHandlerInstantiator()); + assertSame(visibilityChecker, deserializationConfig.getDefaultVisibilityChecker()); + assertTrue(deserializationConfig + .getClassIntrospector() instanceof com.fasterxml.jackson.databind.introspect.BasicClassIntrospector); + DateFormat expectedDateFormat = objectMapper.getDateFormat(); + assertSame(expectedDateFormat, deserializationConfig.getDateFormat()); + assertNull(deserializationConfig.getFullRootName()); + JsonNodeFactory expectedNodeFactory = objectMapper.getNodeFactory(); + assertSame(expectedNodeFactory, deserializationConfig.getNodeFactory()); + assertSame(polymorphicTypeValidator, deserializationConfig.getPolymorphicTypeValidator()); + assertNull(deserializationConfig.getDefaultMergeable()); + assertEquals(237020288, deserializationConfig.getDeserializationFeatures()); + assertTrue(deserializationConfig.getAttributes() instanceof ContextAttributes.Impl); + } + + @Test + public void testConstructor2() { + NitriteIdExtension nitriteIdExtension = new NitriteIdExtension(); + NitriteIdExtension nitriteIdExtension1 = new NitriteIdExtension(); + ObjectMapper objectMapper = (new JacksonMapper(nitriteIdExtension, nitriteIdExtension1, new NitriteIdExtension())) + .getObjectMapper(); + PolymorphicTypeValidator polymorphicTypeValidator = objectMapper.getPolymorphicTypeValidator(); + assertTrue(polymorphicTypeValidator instanceof LaissezFaireSubTypeValidator); + VisibilityChecker visibilityChecker = objectMapper.getVisibilityChecker(); + assertTrue(visibilityChecker instanceof VisibilityChecker.Std); + assertNull(objectMapper.getPropertyNamingStrategy()); + assertTrue(objectMapper + .getDeserializationContext() instanceof com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.Impl); + assertSame(objectMapper.getFactory(), objectMapper.getJsonFactory()); + assertTrue(objectMapper.getSerializerFactory() instanceof com.fasterxml.jackson.databind.ser.BeanSerializerFactory); + assertTrue(objectMapper + .getSerializerProvider() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue(objectMapper + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue( + objectMapper.getSubtypeResolver() instanceof com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver); + DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig(); + assertTrue(deserializationConfig + .getAnnotationIntrospector() instanceof com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector); + assertNull(deserializationConfig.getActiveView()); + assertNull(deserializationConfig.getHandlerInstantiator()); + assertSame(visibilityChecker, deserializationConfig.getDefaultVisibilityChecker()); + assertTrue(deserializationConfig + .getClassIntrospector() instanceof com.fasterxml.jackson.databind.introspect.BasicClassIntrospector); + DateFormat expectedDateFormat = objectMapper.getDateFormat(); + assertSame(expectedDateFormat, deserializationConfig.getDateFormat()); + assertNull(deserializationConfig.getFullRootName()); + JsonNodeFactory expectedNodeFactory = objectMapper.getNodeFactory(); + assertSame(expectedNodeFactory, deserializationConfig.getNodeFactory()); + assertSame(polymorphicTypeValidator, deserializationConfig.getPolymorphicTypeValidator()); + assertNull(deserializationConfig.getDefaultMergeable()); + assertEquals(237020288, deserializationConfig.getDeserializationFeatures()); + assertTrue(deserializationConfig.getAttributes() instanceof ContextAttributes.Impl); + } + + @Test + public void testConstructor3() { + ObjectMapper objectMapper = (new JacksonMapper(new NitriteIdExtension())).getObjectMapper(); + PolymorphicTypeValidator polymorphicTypeValidator = objectMapper.getPolymorphicTypeValidator(); + assertTrue(polymorphicTypeValidator instanceof LaissezFaireSubTypeValidator); + VisibilityChecker visibilityChecker = objectMapper.getVisibilityChecker(); + assertTrue(visibilityChecker instanceof VisibilityChecker.Std); + assertNull(objectMapper.getPropertyNamingStrategy()); + assertTrue(objectMapper + .getDeserializationContext() instanceof com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.Impl); + assertSame(objectMapper.getFactory(), objectMapper.getJsonFactory()); + assertTrue(objectMapper.getSerializerFactory() instanceof com.fasterxml.jackson.databind.ser.BeanSerializerFactory); + assertTrue(objectMapper + .getSerializerProvider() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue(objectMapper + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue( + objectMapper.getSubtypeResolver() instanceof com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver); + DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig(); + assertTrue(deserializationConfig + .getAnnotationIntrospector() instanceof com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector); + assertNull(deserializationConfig.getActiveView()); + assertNull(deserializationConfig.getHandlerInstantiator()); + assertSame(visibilityChecker, deserializationConfig.getDefaultVisibilityChecker()); + assertTrue(deserializationConfig + .getClassIntrospector() instanceof com.fasterxml.jackson.databind.introspect.BasicClassIntrospector); + DateFormat expectedDateFormat = objectMapper.getDateFormat(); + assertSame(expectedDateFormat, deserializationConfig.getDateFormat()); + assertNull(deserializationConfig.getFullRootName()); + JsonNodeFactory expectedNodeFactory = objectMapper.getNodeFactory(); + assertSame(expectedNodeFactory, deserializationConfig.getNodeFactory()); + assertSame(polymorphicTypeValidator, deserializationConfig.getPolymorphicTypeValidator()); + assertNull(deserializationConfig.getDefaultMergeable()); + assertEquals(237020288, deserializationConfig.getDeserializationFeatures()); + assertTrue(deserializationConfig.getAttributes() instanceof ContextAttributes.Impl); + } + + @Test + public void testCreateObjectMapper() { + ObjectMapper actualCreateObjectMapperResult = (new JacksonMapper()).createObjectMapper(); + PolymorphicTypeValidator polymorphicTypeValidator = actualCreateObjectMapperResult.getPolymorphicTypeValidator(); + assertTrue(polymorphicTypeValidator instanceof LaissezFaireSubTypeValidator); + VisibilityChecker visibilityChecker = actualCreateObjectMapperResult.getVisibilityChecker(); + assertTrue(visibilityChecker instanceof VisibilityChecker.Std); + assertNull(actualCreateObjectMapperResult.getPropertyNamingStrategy()); + assertTrue(actualCreateObjectMapperResult + .getDeserializationContext() instanceof com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.Impl); + assertSame(actualCreateObjectMapperResult.getFactory(), actualCreateObjectMapperResult.getJsonFactory()); + assertTrue(actualCreateObjectMapperResult + .getSerializerFactory() instanceof com.fasterxml.jackson.databind.ser.BeanSerializerFactory); + assertTrue(actualCreateObjectMapperResult + .getSerializerProvider() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue(actualCreateObjectMapperResult + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + assertTrue(actualCreateObjectMapperResult + .getSubtypeResolver() instanceof com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver); + DeserializationConfig deserializationConfig = actualCreateObjectMapperResult.getDeserializationConfig(); + assertTrue(deserializationConfig.getAttributes() instanceof ContextAttributes.Impl); + assertTrue(deserializationConfig + .getAnnotationIntrospector() instanceof com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector); + assertNull(deserializationConfig.getActiveView()); + assertEquals(237020288, deserializationConfig.getDeserializationFeatures()); + DateFormat expectedDateFormat = actualCreateObjectMapperResult.getDateFormat(); + assertSame(expectedDateFormat, deserializationConfig.getDateFormat()); + assertNull(deserializationConfig.getDefaultMergeable()); + assertSame(visibilityChecker, deserializationConfig.getDefaultVisibilityChecker()); + assertNull(deserializationConfig.getHandlerInstantiator()); + JsonNodeFactory expectedNodeFactory = actualCreateObjectMapperResult.getNodeFactory(); + assertSame(expectedNodeFactory, deserializationConfig.getNodeFactory()); + assertSame(polymorphicTypeValidator, deserializationConfig.getPolymorphicTypeValidator()); + assertTrue(deserializationConfig + .getClassIntrospector() instanceof com.fasterxml.jackson.databind.introspect.BasicClassIntrospector); + assertNull(deserializationConfig.getFullRootName()); + assertNull(deserializationConfig.getProblemHandlers()); + } + + @Test + public void testConvert() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertEquals("Source", jacksonMapper.convert("Source", Object.class)); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } + + @Test + public void testConvert2() { + JacksonMapper jacksonMapper = new JacksonMapper(); + jacksonMapper.addValueType(Object.class); + assertEquals("Source", jacksonMapper.convert("Source", Object.class)); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } + + @Test + public void testConvert3() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertNull(jacksonMapper.convert(null, Object.class)); + } + + @Test + public void testConvert4() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertEquals(0, ((Integer) jacksonMapper.convert(0, Object.class)).intValue()); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } + + @Test + public void testConvert5() { + JacksonMapper jacksonMapper = new JacksonMapper(); + ArrayNode source = new ArrayNode(new JsonNodeFactory(true)); + assertThrows(ObjectMappingException.class, () -> jacksonMapper.convert(source, Object.class)); + } + + @Test + public void testConvert6() throws UnsupportedEncodingException { + JacksonMapper jacksonMapper = new JacksonMapper(); + BinaryNode source = new BinaryNode("AAAAAAAAAAAAAAAAAAAAAAAA".getBytes(StandardCharsets.UTF_8)); + assertNull(jacksonMapper.convert(source, Object.class)); + } + + @Test + public void testIsValueType() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertThrows(ObjectMappingException.class, () -> jacksonMapper.isValueType(Object.class)); + } + + @Test + public void testIsValueType2() { + JacksonMapper jacksonMapper = new JacksonMapper(); + jacksonMapper.addValueType(Object.class); + assertTrue(jacksonMapper.isValueType(Object.class)); + } + + @Test + public void testIsValueType3() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertFalse(jacksonMapper.isValueType(JsonMappingException.class)); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } + + @Test + public void testIsValueType4() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertFalse(jacksonMapper.isValueType(JsonNode.class)); + } + + @Test + public void testIsValueType5() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertFalse(jacksonMapper.isValueType(Document.class)); + } + + @Test + public void testIsValue() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertTrue(jacksonMapper.isValue("Object")); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } + + @Test + public void testIsValue2() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertFalse(jacksonMapper.isValue(new ArrayNode(new JsonNodeFactory(true)))); + } + + @Test + public void testInitialize() { + JacksonMapper jacksonMapper = new JacksonMapper(); + NitriteConfig nitriteConfig = new NitriteConfig(); + jacksonMapper.initialize(nitriteConfig); + assertEquals(1, nitriteConfig.getSchemaVersion().intValue()); + } + + @Test + public void testConvertFromDocument() { + JacksonMapper jacksonMapper = new JacksonMapper(); + assertNull(jacksonMapper.convertFromDocument(null, Object.class)); + } + + @Test + public void testConvertToDocument() { + JacksonMapper jacksonMapper = new JacksonMapper(); + jacksonMapper.convertToDocument("Source"); + assertTrue(jacksonMapper.getObjectMapper() + .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); + } +} + diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializerTest.java new file mode 100644 index 000000000..9aceea44e --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdDeserializerTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.mapper.extensions; + +import org.dizitart.no2.collection.NitriteId; +import org.junit.Test; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +public class NitriteIdDeserializerTest { + @Test + public void testConstructor() { + NitriteIdDeserializer actualNitriteIdDeserializer = new NitriteIdDeserializer(); + assertNull(actualNitriteIdDeserializer.getValueType()); + Class expectedValueClass = NitriteId.class; + assertSame(expectedValueClass, actualNitriteIdDeserializer.getValueClass()); + } +} + diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtensionTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtensionTest.java new file mode 100644 index 000000000..2a02ad524 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdExtensionTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.mapper.extensions; + +import org.junit.Assert; +import org.junit.Test; + +public class NitriteIdExtensionTest { + @Test + public void testGetSupportedTypes() { + Assert.assertEquals(1, (new NitriteIdExtension()).getSupportedTypes().size()); + } +} + diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializerTest.java new file mode 100644 index 000000000..a1b7f61eb --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/common/mapper/extensions/NitriteIdSerializerTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.mapper.extensions; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +public class NitriteIdSerializerTest { + @Test + public void testConstructor() { + NitriteIdSerializer actualNitriteIdSerializer = new NitriteIdSerializer(); + assertNull(actualNitriteIdSerializer.getDelegatee()); + assertFalse(actualNitriteIdSerializer.isUnwrappingSerializer()); + } +} + diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java similarity index 93% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java index 960c629f0..83f257c24 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/MigrationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java @@ -1,20 +1,37 @@ -package org.dizitart.no2.test.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import com.github.javafaker.Faker; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Constants; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.exceptions.MigrationException; -import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.Retry; +import org.dizitart.no2.integration.repository.Retry; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -26,8 +43,9 @@ import java.util.UUID; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.test.BaseObjectRepositoryTest.getRandomTempDbFile; -import static org.dizitart.no2.test.TestUtil.createDb; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.dizitart.no2.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; +import static org.dizitart.no2.integration.repository.TestUtil.createDb; import static org.junit.Assert.*; /** @@ -85,7 +103,7 @@ public void migrate(Instructions instruction) { instruction.forRepository(OldClass.class, "demo1") .renameRepository("new", null) .changeDataType("empId", (TypeConverter) Long::parseLong) - .changeIdField("uuid", "empId") + .changeIdField(Fields.withNames("uuid"), Fields.withNames("empId")) .deleteField("uuid") .renameField("lastName", "familyName") .addField("fullName", document -> document.get("firstName", String.class) + " " @@ -129,8 +147,8 @@ public void testCollectionMigrate() { collection.insert(document); } - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("bloodGroup", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex(indexOptions(IndexType.NonUnique), "bloodGroup"); db.close(); Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @@ -177,7 +195,7 @@ public void migrate(Instructions instructions) { .addField("address") .addField("vehicles", 1) .renameField("age", "ageGroup") - .createIndex("ageGroup", IndexType.NonUnique); + .createIndex(IndexType.NonUnique, "ageGroup"); } }; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/NewClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java similarity index 54% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/NewClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java index 401cbbf77..45b9265a2 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/NewClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.test.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.index.IndexType; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/OldClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java similarity index 56% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/OldClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java index 5f462da3c..78969818e 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/migrate/OldClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.test.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.index.IndexType; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java similarity index 86% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java index ec775dd7e..607403048 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/BaseObjectRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.common.mapper.JacksonMapperModule; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.data.*; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -30,7 +31,6 @@ import org.junit.runners.Parameterized; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; @@ -53,10 +53,13 @@ public abstract class BaseObjectRepositoryTest { @Parameterized.Parameter(value = 4) public boolean isAutoCompact = false; protected Nitrite db; - ObjectRepository companyRepository; - ObjectRepository employeeRepository; - ObjectRepository aObjectRepository; - ObjectRepository cObjectRepository; + + protected ObjectRepository companyRepository; + protected ObjectRepository employeeRepository; + protected ObjectRepository aObjectRepository; + protected ObjectRepository cObjectRepository; + protected ObjectRepository bookRepository; + private final String fileName = getRandomTempDbFile(); @Rule @@ -91,7 +94,7 @@ public static String getRandomTempDbFile() { if (!file.exists()) { assertTrue(file.mkdirs()); } - return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; + return file.getPath() + File.separator + UUID.randomUUID() + ".db"; } @Before @@ -104,6 +107,8 @@ public void setUp() { aObjectRepository = db.getRepository(ClassA.class); cObjectRepository = db.getRepository(ClassC.class); + bookRepository = db.getRepository(Book.class); + for (int i = 0; i < 10; i++) { Company company = DataGenerator.generateCompanyRecord(); companyRepository.insert(company); @@ -113,6 +118,9 @@ public void setUp() { aObjectRepository.insert(ClassA.create(i + 50)); cObjectRepository.insert(ClassC.create(i + 30)); + + Book book = DataGenerator.randomBook(); + bookRepository.insert(book); } } @@ -145,7 +153,7 @@ private void openDb() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (companyRepository != null && !companyRepository.isDropped()) { companyRepository.remove(ALL); } @@ -162,6 +170,10 @@ public void clear() throws IOException { cObjectRepository.remove(ALL); } + if (bookRepository != null && !bookRepository.isDropped()) { + bookRepository.remove(ALL); + } + if (db != null && !db.isClosed()) { db.commit(); db.close(); diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java new file mode 100644 index 000000000..448af1fdb --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.common.mapper.JacksonMapperModule; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.mvstore.MVStoreModule; +import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; +import org.dizitart.no2.repository.annotations.Indices; +import org.dizitart.no2.integration.repository.data.Company; +import org.dizitart.no2.integration.repository.data.Note; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Date; + +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; +import static org.junit.Assert.assertEquals; + +/** + * @author Anindya Chatterjee + */ +public class CustomFieldSeparatorTest { + private Nitrite db; + private ObjectRepository repository; + private final String fileName = getRandomTempDbFile(); + +// @Rule + public Retry retry = new Retry(3); + + @Before + public void setUp() { + db = Nitrite.builder() + .loadModule(new MVStoreModule(fileName)) + .loadModule(new JacksonMapperModule()) + .fieldSeparator(":") + .openOrCreate(); + repository = db.getRepository(EmployeeForCustomSeparator.class); + } + + @After + public void reset() throws IOException { + (new NitriteConfig()).fieldSeparator("."); + if (db != null && !db.isClosed()) { + db.close(); + } + + if (db != null && !db.isClosed()) { + db.commit(); + db.close(); + } + + Files.delete(Paths.get(fileName)); + } + + @Test + public void testFieldSeparator() { + assertEquals(NitriteConfig.getFieldSeparator(), ":"); + } + + @Test + public void testFindByEmbeddedField() { + EmployeeForCustomSeparator employee = new EmployeeForCustomSeparator(); + employee.setCompany(new Company()); + employee.setEmployeeNote(new Note()); + + employee.setEmpId(123L); + employee.setJoinDate(new Date()); + employee.setBlob(new byte[0]); + employee.setAddress("Dummy address"); + + employee.getCompany().setCompanyId(987L); + employee.getCompany().setCompanyName("Dummy Company"); + employee.getCompany().setDateCreated(new Date()); + + employee.getEmployeeNote().setNoteId(567L); + employee.getEmployeeNote().setText("Dummy Note"); + + repository.insert(employee); + + assertEquals(repository.find(where("employeeNote.text").eq("Dummy Note")).size(), 0); + assertEquals(repository.find(where("employeeNote:text").text("Dummy Note")).size(), 1); + + assertEquals(repository.find(where("company.companyName").eq("Dummy Company")).size(), 0); + assertEquals(repository.find(where("company:companyName").eq("Dummy Company")).size(), 1); + } + + @ToString + @EqualsAndHashCode + @Indices({ + @Index(value = "joinDate", type = IndexType.NonUnique), + @Index(value = "address", type = IndexType.Fulltext), + @Index(value = "employeeNote:text", type = IndexType.Fulltext) + }) + public static class EmployeeForCustomSeparator implements Serializable { + @Id + @Getter + @Setter + private Long empId; + + @Getter + @Setter + private Date joinDate; + + @Getter + @Setter + private String address; + + @Getter + @Setter + private Company company; + + @Getter + @Setter + private byte[] blob; + + @Getter + @Setter + private Note employeeNote; + + EmployeeForCustomSeparator() { + } + + public EmployeeForCustomSeparator(EmployeeForCustomSeparator copy) { + empId = copy.empId; + joinDate = copy.joinDate; + address = copy.address; + company = copy.company; + blob = copy.blob; + employeeNote = copy.employeeNote; + } + } + +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java new file mode 100644 index 000000000..397876740 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.store.NitriteMap; +import org.dizitart.no2.integration.repository.data.EncryptedPerson; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseObjectRepositoryTest { + private ObjectRepository persons; + private StringFieldEncryptionProcessor fieldProcessor; + + @Before + public void setUp() { + super.setUp(); + persons = db.getRepository(EncryptedPerson.class); + fieldProcessor = new StringFieldEncryptionProcessor("s3k4e8"); + fieldProcessor.addFields("creditCardNumber", "cvv"); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + persons.insert(person); + + persons.addProcessor(fieldProcessor); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + persons.insert(person); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = persons.getDocumentCollection().getStore() + .openMap(findRepositoryName(EncryptedPerson.class, null), NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + EncryptedPerson person = persons.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5500960345687452"); + assertEquals(person.getCvv(), "008"); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5548960345687452"); + assertEquals(person.getCvv(), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + ObjectRepository testPersons = db.getRepository(EncryptedPerson.class, "test"); + + Encryptor encryptor = new AESEncryptor("secret"); + Encryptor wrongEncryptor = new AESEncryptor("secret", "AES/GCM/NoPadding", + 5, 5, 5); + + testPersons.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + testPersons.insert(person); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + testPersons.insert(person); + + testPersons.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testUpdateEncryptedField() { + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("00000000000000"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + WriteResult writeResult = persons.update(where("name").eq("John Doe"), person); + assertEquals(writeResult.getAffectedCount(), 1); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "00000000000000"); + assertEquals(person.getCvv(), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + persons.createIndex("cvv"); + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testRemoveProcessor() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNull(person); + + persons.removeProcessor(fieldProcessor); + + person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNotNull(person); + } +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/InternalClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java similarity index 81% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/InternalClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java index 8b6127a61..a437f6c1a 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/InternalClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.repository.annotations.Id; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java similarity index 91% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java index f13488a21..a7a42681c 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/NitriteIdAsIdTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.Nitrite; @@ -36,8 +37,8 @@ import java.nio.file.Paths; import static org.dizitart.no2.common.module.NitriteModule.module; -import static org.dizitart.no2.test.BaseObjectRepositoryTest.getRandomTempDbFile; -import static org.dizitart.no2.test.TestUtil.createDb; +import static org.dizitart.no2.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; +import static org.dizitart.no2.integration.repository.TestUtil.createDb; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectCursorTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java similarity index 89% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectCursorTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java index 971a5ff7e..132746f0e 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectCursorTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.test.data.Employee; +import org.dizitart.no2.integration.repository.data.Employee; import org.junit.Test; import java.util.AbstractCollection; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java similarity index 67% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java index 8815c3c03..48307a3bd 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryNegativeTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java @@ -1,41 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.*; import org.dizitart.no2.common.mapper.JacksonMapperModule; +import org.dizitart.no2.exceptions.*; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.data.*; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.locationtech.jts.geom.LineString; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.*; /** * @author Anindya Chatterjee. @@ -114,6 +113,12 @@ public void testWithNullId() { } } + @Test(expected = ValidationException.class) + public void testWithValueTypeRepository() { + ObjectRepository repository = db.getRepository(String.class); + repository.insert("test"); + } + @Test(expected = InvalidOperationException.class) public void testFindResultRemove() { ObjectRepository repository = db.getRepository(Employee.class); @@ -122,7 +127,7 @@ public void testFindResultRemove() { result.iterator().remove(); } - @Test(expected = InvalidOperationException.class) + @Test(expected = IndexingException.class) public void testWithObjectId() { ObjectRepository repository = db.getRepository(WithObjectId.class); WithOutId id = new WithOutId(); @@ -152,7 +157,7 @@ public void testRemoveNoId() { repository.remove(object); } - @Test(expected = ObjectMappingException.class) + @Test(expected = ValidationException.class) public void testProjectionFailedInstantiate() { ObjectRepository repository = db.getRepository(WithOutId.class); WithOutId object = new WithOutId(); @@ -160,8 +165,8 @@ public void testProjectionFailedInstantiate() { object.setNumber(1L); repository.insert(object); - RecordStream project = repository.find().project(LineString.class); - assertNull(project); + RecordStream project = repository.find().project(NitriteId.class); + assertNull(project.toList()); } @Test(expected = ValidationException.class) @@ -169,4 +174,55 @@ public void testNullInsert() { ObjectRepository repository = db.getRepository(WithOutId.class); repository.insert(null); } + + @Test(expected = InvalidIdException.class) + public void testGetByNullId() { + ObjectRepository repository = db.getRepository(WithPublicField.class); + WithPublicField object = new WithPublicField(); + object.name = "test"; + object.number = 2; + + repository.insert(object); + WithPublicField instance = repository.getById(null); + assertEquals(object.name, instance.name); + assertEquals(object.number, instance.number); + } + + @Test + public void testExternalNitriteId() { + ObjectRepository repository = db.getRepository(WithNitriteId.class); + WithNitriteId obj = new WithNitriteId(); + NitriteId id = NitriteId.createId("1"); + obj.setIdField(id); + obj.setName("testExternalNitriteId"); + WriteResult result = repository.update(obj, true); + + obj = new WithNitriteId(); + id = result.iterator().next(); + obj.setIdField(id); + obj.setName("testExternalNitriteId"); + result = repository.update(obj, true); + assertNotEquals(id.getIdValue(), result.iterator().next().getIdValue()); + } + + @Test(expected = IndexingException.class) + public void testWithoutEmbeddedId() { + ObjectRepository repository = db.getRepository(WithoutEmbeddedId.class); + assertNull(repository); + } + + @Test(expected = InvalidIdException.class) + public void testGetByWrongIdType() { + ObjectRepository repository = db.getRepository(WithPublicField.class); + WithPublicField object = new WithPublicField(); + object.name = "test"; + object.number = 2; + + repository.insert(object); + + NitriteId id = NitriteId.createId("1"); + WithPublicField instance = repository.getById(id); + assertEquals(object.name, instance.name); + assertEquals(object.number, instance.number); + } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java similarity index 66% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index 629f71978..8a43d484f 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ObjectRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -1,27 +1,36 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; +import com.github.javafaker.Faker; +import lombok.Data; import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.common.mapper.JacksonMapperModule; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.data.*; +import org.dizitart.no2.repository.annotations.Entity; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -252,13 +261,104 @@ public void testAttributes() { } @Test - public void testIssue217() { + public void testKeyedRepository() { + // an object repository of employees who are managers + ObjectRepository managerRepo = db.getRepository(Employee.class, "managers"); + + // an object repository of all employee ObjectRepository employeeRepo = db.getRepository(Employee.class); + + // and object repository of employees who are developers + ObjectRepository developerRepo = db.getRepository(Employee.class, "developers"); + + Employee manager = new Employee(); + manager.setEmpId(1L); + manager.setAddress("abcd"); + manager.setJoinDate(new Date()); + + Employee developer = new Employee(); + developer.setEmpId(2L); + developer.setAddress("xyz"); + developer.setJoinDate(new Date()); + + managerRepo.insert(manager); + employeeRepo.insert(manager, developer); + developerRepo.insert(developer); + + assertTrue(db.hasRepository(Employee.class)); + assertTrue(db.hasRepository(Employee.class, "managers")); + assertTrue(db.hasRepository(Employee.class, "developers")); + + assertEquals(db.listRepositories().size(), 1); + assertEquals(db.listKeyedRepository().size(), 2); + + assertEquals(employeeRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(employeeRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(managerRepo.find(where("address").text("xyz")).size(), 0); + assertEquals(managerRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(developerRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(developerRepo.find(where("address").text("abcd")).size(), 0); + } + + @Test + public void testEntityRepository() { + ObjectRepository managerRepo = db.getRepository(EmployeeEntity.class, "managers"); + ObjectRepository employeeRepo = db.getRepository(EmployeeEntity.class); + ObjectRepository developerRepo = db.getRepository(EmployeeEntity.class, "developers"); + + managerRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); + employeeRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); + developerRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); + + boolean errored = false; + try { + NitriteCollection collection = db.getCollection("entity.employee"); + } catch (ValidationException e) { + errored = true; + } + assertTrue(errored); + + assertTrue(db.listRepositories().contains("entity.employee")); + assertEquals(db.listKeyedRepository().size(), 2); + assertEquals(db.listCollectionNames().size(), 0); + + assertTrue(managerRepo.hasIndex("firstName")); + assertTrue(managerRepo.hasIndex("lastName")); + assertTrue(employeeRepo.hasIndex("lastName")); + assertTrue(employeeRepo.hasIndex("lastName")); + + managerRepo.drop(); + assertEquals(db.listKeyedRepository().size(), 1); + } + + @Test + public void testIssue217() { + ObjectRepository employeeRepo = db.getRepository(EmployeeEntity.class); AtomicInteger counter = new AtomicInteger(0); employeeRepo.subscribe(eventInfo -> counter.incrementAndGet()); - ObjectRepository employeeRepo2 = db.getRepository(Employee.class); - employeeRepo2.insert(DataGenerator.generateEmployee()); + ObjectRepository employeeRepo2 = db.getRepository(EmployeeEntity.class); + employeeRepo2.insert(new EmployeeEntity()); await().atMost(5, TimeUnit.SECONDS).until(() -> counter.get() == 1); } + + @Data + @Entity(value = "entity.employee", indices = { + @Index(value = "firstName", type = IndexType.NonUnique), + @Index(value = "lastName", type = IndexType.NonUnique), + }) + private static class EmployeeEntity { + private static final Faker faker = new Faker(); + + @Id + private Long id; + private String firstName; + private String lastName; + + public EmployeeEntity() { + id = faker.number().randomNumber(); + firstName = faker.name().firstName(); + lastName = faker.name().lastName(); + } + } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ProjectionTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ProjectionTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java index eddba3950..a384735ad 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/ProjectionTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java @@ -1,28 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.test.data.SubEmployee; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.junit.Test; import java.util.Iterator; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.junit.Assert.*; /** @@ -32,28 +34,28 @@ public class ProjectionTest extends BaseObjectRepositoryTest { @Test public void testHasMore() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertFalse(iterable.isEmpty()); } @Test public void testSize() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertEquals(iterable.size(), 5); } @Test public void testToString() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertNotNull(iterable.toString()); } @Test(expected = InvalidOperationException.class) public void testRemove() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java new file mode 100644 index 000000000..9431d991e --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.integration.repository.data.Book; +import org.dizitart.no2.integration.repository.data.BookId; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryCompoundIndexTest extends BaseObjectRepositoryTest { + + @Test + public void testFindById() { + BookId bookId = new BookId(); + bookId.setAuthor("John Doe"); + bookId.setIsbn("123456"); + bookId.setName("Nitrite Database"); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription("Some random book description"); + book.setPrice(22.56); + book.setPublisher("My Publisher House"); + book.setTags(Arrays.asList("database", "nosql")); + + bookRepository.insert(book); + + Book bookById = bookRepository.getById(bookId); + assertEquals(bookById, book); + } +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java new file mode 100644 index 000000000..2de2e8915 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.*; +import org.dizitart.no2.collection.events.CollectionEventListener; +import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.common.mapper.JacksonMapper; +import org.dizitart.no2.common.module.NitriteModule; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.repository.RepositoryFactory; +import org.dizitart.no2.store.NitriteStore; +import org.dizitart.no2.integration.repository.data.Book; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; + +import java.util.Collection; + +import static org.dizitart.no2.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; +import static org.junit.Assert.assertNotNull; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryFactoryTest { + private final String fileName = getRandomTempDbFile(); + private Nitrite db; + + @Rule + public Retry retry = new Retry(3); + + @Test + public void testRepositoryFactory() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + assertNotNull(factory); + } + + @Test(expected = ValidationException.class) + public void testNullType() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + JacksonMapper mapper = new JacksonMapper(); + db = TestUtil.createDb(fileName, NitriteModule.module(mapper)); + factory.getRepository(db.getConfig(), null, "dummy"); + } + + @Test + public void testNullCollection() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + JacksonMapper mapper = new JacksonMapper(); + db = TestUtil.createDb(fileName, NitriteModule.module(mapper)); + factory.getRepository(db.getConfig(), Book.class, null); + } + + @Test(expected = ValidationException.class) + public void testNullContext() { + RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); + factory.getRepository(null, Book.class, "dummy"); + } + + @After + public void cleanUp() { + if (db != null && !db.isClosed()) { + db.close(); + } + } + + private static class DummyCollection implements NitriteCollection { + + @Override + public WriteResult insert(Document document, Document... documents) { + return null; + } + + @Override + public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { + return null; + } + + @Override + public WriteResult remove(Filter filter, boolean justOne) { + return null; + } + + @Override + public DocumentCursor find() { + return null; + } + + @Override + public DocumentCursor find(Filter filter) { + return null; + } + + @Override + public DocumentCursor find(Filter filter, FindOptions findOptions) { + return null; + } + + @Override + public Document getById(NitriteId nitriteId) { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public void addProcessor(Processor processor) { + + } + + @Override + public void removeProcessor(Processor processor) { + + } + + @Override + public void createIndex(IndexOptions indexOptions, String... fields) { + + } + + @Override + public void rebuildIndex(String... fields) { + + } + + @Override + public Collection listIndices() { + return null; + } + + @Override + public boolean hasIndex(String... fields) { + return false; + } + + @Override + public boolean isIndexing(String... fields) { + return false; + } + + @Override + public void dropIndex(String... fields) { + + } + + @Override + public void dropAllIndices() { + + } + + @Override + public WriteResult insert(Document[] elements) { + return null; + } + + @Override + public WriteResult update(Document element, boolean insertIfAbsent) { + return null; + } + + @Override + public WriteResult remove(Document element) { + return null; + } + + @Override + public void clear() { + + } + + @Override + public void drop() { + + } + + @Override + public boolean isDropped() { + return false; + } + + @Override + public boolean isOpen() { + return false; + } + + @Override + public void close() { + + } + + @Override + public long size() { + return 0; + } + + @Override + public NitriteStore getStore() { + return null; + } + + @Override + public void subscribe(CollectionEventListener listener) { + + } + + @Override + public void unsubscribe(CollectionEventListener listener) { + + } + + @Override + public Attributes getAttributes() { + return null; + } + + @Override + public void setAttributes(Attributes attributes) { + + } + } +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java similarity index 95% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java index 3897fd661..ccd66e1dd 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryJoinTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java @@ -1,24 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; @@ -190,7 +192,7 @@ public void testJoin() { } } - result = personRepository.find().skipLimit(0, 5).join(addressRepository.find(), lookup, + result = personRepository.find(FindOptions.skipBy(0).limit(5)).join(addressRepository.find(), lookup, PersonDetails.class); assertEquals(result.size(), 5); diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java similarity index 76% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index b607e7f5b..e40db2363 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositoryModificationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.UniqueConstraintException; @@ -24,11 +26,9 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.test.data.Company; -import org.dizitart.no2.test.data.DataGenerator; -import org.dizitart.no2.test.data.Employee; -import org.dizitart.no2.test.data.Note; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; import java.text.ParseException; @@ -51,18 +51,19 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); - companyRepository.rebuildIndex("dateCreated", true); - assertTrue(companyRepository.isIndexing("dateCreated")); + companyRepository.rebuildIndex("dateCreated"); + // rebuild is sync + assertFalse(companyRepository.isIndexing("dateCreated")); await().until(() -> !companyRepository.isIndexing("dateCreated")); } @@ -72,7 +73,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } @@ -192,7 +193,7 @@ public void testUpdateWithJustOnceFalse() throws ParseException { @Test public void testUpsertTrue() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -217,7 +218,7 @@ public void testUpsertTrue() { @Test public void testUpsertFalse() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -244,7 +245,7 @@ public void testDeleteFilterAndWithOutOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate)); @@ -258,7 +259,7 @@ public void testDeleteFilterAndWithOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate), true); @@ -277,7 +278,7 @@ public void testEmployeeRecord() { } } - Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); + Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); assertEquals(cursor.size(), occurrence); } @@ -512,4 +513,143 @@ public void testUpdateWithDoc() { WriteResult result = employeeRepository.update(Filter.ALL, document); assertEquals(result.getAffectedCount(), 10); } + + @Test + public void testDeleteIteratorNPE() { + ObjectRepository notes = db.getRepository(Note.class); + Note one = new Note(); + one.setText("Jane"); + one.setNoteId(1L); + Note two = new Note(); + two.setText("Jill"); + two.setNoteId(2L); + + notes.insert(one, two); + + WriteResult writeResult = notes.remove(where("text").eq("Pete")); + for (NitriteId id : writeResult) { + assertNotNull(id); + } + } + + @Test + public void testDelete() { + ObjectRepository repo = db.getRepository(WithNitriteId.class); + WithNitriteId one = new WithNitriteId(); + one.setName("Jane"); + repo.insert(one); + + WithNitriteId note = repo.find().firstOrNull(); + repo.remove(note); + + assertNull(repo.getById(one.idField)); + } + + /* + * Upsert Use Cases + * + * 1. Object does not exists + * a. if upsert true, it will insert + * b. if upsert false, nothing happens + * 2. Object exists + * a. if upsert true, it will update, old id remains same + * b. if upsert false, it will update, old id remains same + * + * */ + + @Test + public void testUpdateObjectNotExistsUpsertTrue() { + ObjectRepository repo = db.getRepository(InternalClass.class); + InternalClass a = new InternalClass(); + a.setId(1); + a.setName("first"); + repo.insert(a); + + a = new InternalClass(); + a.setId(2); + a.setName("second"); + + // it will insert as new object + repo.update(a, true); + assertEquals(repo.size(), 2); + } + + @Test + public void testUpdateObjectNotExistsUpsertFalse() { + ObjectRepository repo = db.getRepository(InternalClass.class); + InternalClass a = new InternalClass(); + a.setId(1); + a.setName("first"); + repo.insert(a); + + a = new InternalClass(); + a.setId(2); + a.setName("second"); + + // no changes will happen to repository + repo.update(a, false); + assertEquals(repo.size(), 1); + assertEquals(repo.find().firstOrNull().getId(), 1); + assertEquals(repo.find().firstOrNull().getName(), "first"); + } + + @Test + public void testUpdateObjectExistsUpsertTrue() { + ObjectRepository repo = db.getRepository(InternalClass.class); + InternalClass a = new InternalClass(); + a.setId(1); + a.setName("first"); + repo.insert(a); + + a = new InternalClass(); + a.setId(1); + a.setName("second"); + + // update existing object, keep id same + repo.update(a, true); + assertEquals(repo.size(), 1); + assertEquals(repo.find().firstOrNull().getId(), 1); + assertEquals(repo.find().firstOrNull().getName(), "second"); + } + + @Test + public void testUpdateObjectExistsUpsertFalse() { + ObjectRepository repo = db.getRepository(InternalClass.class); + InternalClass a = new InternalClass(); + a.setId(1); + a.setName("first"); + repo.insert(a); + + a = new InternalClass(); + a.setId(1); + a.setName("second"); + + // update existing object, keep id same + repo.update(a, false); + assertEquals(repo.size(), 1); + assertEquals(repo.find().firstOrNull().getId(), 1); + assertEquals(repo.find().firstOrNull().getName(), "second"); + } + + @Test + public void testNestedUpdate() { + Employee employee = employeeRepository.getById(1L); + assertNotNull(employee); + + Note note = employee.getEmployeeNote(); + String text = note.getText(); + assertNotNull(text); + + Document update = createDocument("employeeNote.text", "some updated text"); + WriteResult writeResult = employeeRepository.update(where("empId").eq(1L), update, true); + assertEquals(1, writeResult.getAffectedCount()); + + employee = employeeRepository.getById(1L); + assertNotNull(employee); + + note = employee.getEmployeeNote(); + assertNotNull(note); + assertNotEquals(text, note.getText()); + assertEquals("some updated text", note.getText()); + } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositorySearchTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java similarity index 86% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositorySearchTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java index 8fac9d440..d0bb00a1c 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/RepositorySearchTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java @@ -1,30 +1,31 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import lombok.Getter; -import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.data.*; import org.junit.Test; import java.util.Calendar; @@ -32,7 +33,9 @@ import java.util.GregorianCalendar; import java.util.List; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.*; @@ -43,7 +46,7 @@ public class RepositorySearchTest extends BaseObjectRepositoryTest { @Test public void testFindWithOptions() { - Cursor cursor = employeeRepository.find().skipLimit(0, 1); + Cursor cursor = employeeRepository.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); assertNotNull(cursor.firstOrNull()); } @@ -114,11 +117,8 @@ public void testGetByIdNoId() { Note n2 = DataGenerator.randomNote(); Note n3 = DataGenerator.randomNote(); - assert n1 != null; n1.setNoteId(1000000L); - assert n2 != null; n2.setNoteId(2000000L); - assert n3 != null; n3.setNoteId(3000000L); repository.insert(n1, n2, n3); @@ -213,12 +213,14 @@ public void testAndFilter() { String address = emp.getAddress(); Date joinDate = emp.getJoinDate(); - Employee employee = employeeRepository.find( - where("empId").eq(id) - .and( - where("address").regex(address) - .and( - where("joinDate").eq(joinDate)))).firstOrNull(); + Cursor cursor = employeeRepository.find( + and( + where("empId").eq(id), + where("address").regex(address), + where("joinDate").eq(joinDate) + ) + ); + Employee employee = cursor.firstOrNull(); assertEquals(emp, employee); } @@ -229,11 +231,11 @@ public void testOrFilter() { long id = emp.getEmpId(); Employee employee = employeeRepository.find( - where("empId").eq(id) - .or( - where("address").regex("n/a") - .or( - where("joinDate").eq(null)))).firstOrNull(); + or( + where("empId").eq(id), + where("address").text("n/a"), + where("joinDate").eq(null) + )).firstOrNull(); assertEquals(emp, employee); } @@ -250,7 +252,7 @@ public void testNotFilter() { @Test public void testGreaterFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gt(id)) @@ -262,7 +264,7 @@ public void testGreaterFilter() { @Test public void testGreaterEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gte(id)) @@ -274,7 +276,7 @@ public void testGreaterEqualFilter() { @Test public void testLesserThanFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lt(id)) @@ -286,7 +288,7 @@ public void testLesserThanFilter() { @Test public void testLesserEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lte(id)) @@ -309,10 +311,11 @@ public void testTextFilter() { @Test public void testRegexFilter() { - RecordStream employees = employeeRepository.find(); + Cursor employees = employeeRepository.find(); int count = employees.toList().size(); - List employeeList = employeeRepository.find(where("employeeNote.text").regex(".*")) + List employeeList = employeeRepository.find(where("emailAddress") + .regex("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$")) .toList(); assertEquals(employeeList.size(), count); @@ -320,7 +323,7 @@ public void testRegexFilter() { @Test public void testInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").in(id, id - 1, id - 2)) @@ -335,7 +338,7 @@ public void testInFilter() { @Test public void testNotInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").notIn(id, id - 1, id - 2)) @@ -475,7 +478,7 @@ public void testFilterAll() { assertEquals(cursor.size(), 1); } - @Test + @Test(expected = FilterException.class) public void testEqualsOnTextIndex() { PersonEntity p1 = new PersonEntity("jhonny"); PersonEntity p2 = new PersonEntity("jhonny"); @@ -488,21 +491,6 @@ public void testEqualsOnTextIndex() { List sameNamePeople = repository.find(where("name").eq("jhonny")).toList(); assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhonny")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").text("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 3); } @Test @@ -524,12 +512,12 @@ public void testIssue62() { Filter married = where("status").eq("Married"); assertEquals(repository.find(married).size(), 2); - assertEquals(repository.find(married).sort("status", SortOrder.Descending).size(), 2); + assertEquals(repository.find(married, orderBy("status", SortOrder.Descending)).size(), 2); - assertEquals(repository.find().sort("status", SortOrder.Descending).firstOrNull().getStatus(), "Un-Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Descending)).firstOrNull().getStatus(), "Un-Married"); - assertEquals(repository.find().sort("status", SortOrder.Ascending).size(), 3); - assertEquals(repository.find().sort("status", SortOrder.Ascending).firstOrNull().getStatus(), "Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).size(), 3); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).firstOrNull().getStatus(), "Married"); } @Test @@ -550,7 +538,7 @@ public void testRepeatableIndexAnnotation() { @Test public void testIdSet() { - Cursor employees = employeeRepository.find().sort("empId", SortOrder.Ascending); + Cursor employees = employeeRepository.find(orderBy("empId", SortOrder.Ascending)); assertEquals(employees.size(), 10); } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/Retry.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/Retry.java similarity index 65% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/Retry.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/Retry.java index 62d667b49..7c2c065bd 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/Retry.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/Retry.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.test; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; import org.junit.rules.TestRule; import org.junit.runner.Description; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/TestUtil.java similarity index 93% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/TestUtil.java index de6d0e7fd..6967e6289 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/TestUtil.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/TestUtil.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UnAnnotatedObjectTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java similarity index 63% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UnAnnotatedObjectTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java index 10a259194..734a55e29 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UnAnnotatedObjectTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java @@ -1,29 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.test.data.ClassA; -import org.dizitart.no2.test.data.ClassC; +import org.dizitart.no2.integration.repository.data.ClassA; +import org.dizitart.no2.integration.repository.data.ClassC; import org.junit.Test; +import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,16 +35,14 @@ public class UnAnnotatedObjectTest extends BaseObjectRepositoryTest { @Test public void testFind() { - Cursor cursor = aObjectRepository.find(); + Cursor cursor = aObjectRepository.find(); assertEquals(cursor.size(), 10); assertFalse(cursor.isEmpty()); - IndexOptions indexOptions = new IndexOptions(); - indexOptions.setIndexType(IndexType.Unique); - aObjectRepository.createIndex("b.number", indexOptions); + aObjectRepository.createIndex("b.number"); - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Ascending).skipLimit(0, 10); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Ascending).skip(0).limit(10)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -54,8 +52,8 @@ public void testFind() { System.out.println(classA); } - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Descending).skipLimit(2, 7); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -65,12 +63,12 @@ public void testFind() { System.out.println(classA); } - Cursor cursor2 = cObjectRepository.find(where("id").gt(900)). - sort("id", SortOrder.Descending).skipLimit(2, 7); - System.out.println("Available - " + !cursor2.isEmpty()); - System.out.println("Total Size - " + cursor2.size()); + cursor = cObjectRepository.find(where("id").gt(900), + orderBy("id", SortOrder.Descending).skip(2).limit(7)); + System.out.println("Available - " + !cursor.isEmpty()); + System.out.println("Total Size - " + cursor.size()); - Iterable findRecordC = cursor2.project(ClassC.class); + Iterable findRecordC = cursor.project(ClassC.class); for (ClassC classC : findRecordC) { System.out.println(classC); } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java similarity index 97% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index 88957bfb4..d01e74ba7 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/UniversalTextTokenizerTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; +import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.common.mapper.JacksonMapperModule; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.Cursor; @@ -33,13 +34,12 @@ import org.junit.Before; import org.junit.Test; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.common.module.NitriteModule.module; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -82,7 +82,7 @@ public void setUp() { @After @Override - public void clear() throws IOException { + public void clear() throws Exception { if (textRepository != null && !textRepository.isDropped()) { textRepository.remove(ALL); } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java new file mode 100644 index 000000000..da8bb7db7 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Entity; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; + +import java.util.List; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity(value = "books", indices = { + @Index(value = "tags", type = IndexType.NonUnique), + @Index(value = "description", type = IndexType.Fulltext), + @Index(value = { "price", "publisher" }) +}) +public class Book { + @JsonProperty("book_id") + @Id(fieldName = "book_id") + private BookId bookId; + + private String publisher; + + private Double price; + + private List tags; + + private String description; +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java new file mode 100644 index 000000000..988908919 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.dizitart.no2.repository.annotations.Embedded; + +/** + * @author Anindya Chatterjee + */ +@Data +public class BookId { + @Embedded(order = 0) + private String isbn; + + @Embedded(order = 1, fieldName = "book_name") + @JsonProperty("book_name") + private String name; + + private String author; +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ChildClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ChildClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java index 512d73cd1..7df72c261 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ChildClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassA.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java similarity index 84% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassA.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java index cd5a9a1dc..10aa57a6d 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassA.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -28,7 +29,7 @@ public class ClassA { @Getter @Setter - private ClassB classB; + private ClassB b; @Getter @Setter private UUID uid; @@ -42,7 +43,7 @@ public class ClassA { public static ClassA create(int seed) { ClassB classB = ClassB.create(seed); ClassA classA = new ClassA(); - classA.classB = classB; + classA.b = classB; classA.uid = new UUID(seed, seed + 50); classA.string = Integer.toHexString(seed); classA.blob = new byte[]{(byte) seed}; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassB.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java similarity index 87% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassB.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java index 328967d74..567c99244 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassB.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassC.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java similarity index 86% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassC.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java index fb9f2034c..237f3f835 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ClassC.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Company.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Company.java similarity index 80% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Company.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Company.java index 364433bae..4a85b5156 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Company.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Company.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -32,30 +34,19 @@ /** * @author Anindya Chatterjee. */ +@Getter +@Setter @ToString @EqualsAndHashCode @Indices({ @Index(value = "companyName") }) public class Company implements Serializable { - @Id - @Getter - @Setter + @Id(fieldName = "company_id") + @JsonProperty("company_id") private Long companyId; - - @Getter - @Setter private String companyName; - - @Getter - @Setter private Date dateCreated; - - @Getter - @Setter private List departments; - - @Getter - @Setter private Map> employeeRecord; } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java new file mode 100644 index 000000000..26e0dcf4a --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import com.github.javafaker.Faker; +import lombok.val; + +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author Anindya Chatterjee. + */ +public class DataGenerator { + private static final Random random = new Random(System.currentTimeMillis()); + private static final AtomicInteger counter = new AtomicInteger(random.nextInt()); + private static final Faker faker = new Faker(random); + + private DataGenerator() {} + + public static Company generateCompanyRecord() { + Company company = new Company(); + company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); + company.setCompanyName(faker.company().name()); + company.setDateCreated(faker.date().past(10, TimeUnit.DAYS)); + List departments = departments(); + company.setDepartments(departments); + + Map> employeeRecord = new HashMap<>(); + for (String department : departments) { + employeeRecord.put(department, + generateEmployeeRecords(company, random.nextInt(20))); + } + company.setEmployeeRecord(employeeRecord); + return company; + } + + private static List generateEmployeeRecords(Company company, int count) { + List employeeList = new ArrayList<>(); + for (int i = 0; i < count; i++) { + Employee employee = generateEmployee(); + employee.setCompany(company); + employeeList.add(employee); + } + return employeeList; + } + + public static Employee generateEmployee() { + Employee employee = new Employee(); + employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); + employee.setJoinDate(faker.date().birthday()); + employee.setAddress(faker.address().fullAddress()); + + employee.setBlob(faker.lorem().paragraph().getBytes(StandardCharsets.UTF_8)); + employee.setEmployeeNote(randomNote()); + employee.setEmailAddress(faker.internet().emailAddress()); + + return employee; + } + + public static Note randomNote() { + Note note = new Note(); + note.setNoteId(System.nanoTime() + counter.incrementAndGet()); + note.setText(faker.lorem().paragraph()); + return note; + } + + public static Book randomBook() { + BookId bookId = new BookId(); + val bookFaker = faker.book(); + bookId.setIsbn(faker.idNumber().ssnValid()); + bookId.setAuthor(bookFaker.author()); + bookId.setName(bookFaker.title()); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription(faker.backToTheFuture().quote()); + book.setPrice(faker.number().randomDouble(2, 100, 500)); + book.setPublisher(bookFaker.publisher()); + List tags = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + tags.add(bookFaker.genre()); + } + book.setTags(tags); + return book; + } + + private static List departments() { + return new ArrayList() {{ + add("dev"); + add("hr"); + add("qa"); + add("dev-ops"); + add("sales"); + add("marketing"); + add("design"); + add("support"); + }}; + } +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ElemMatch.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java similarity index 81% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ElemMatch.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java index 992fdf906..9de46c3a4 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ElemMatch.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Employee.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java similarity index 77% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Employee.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 7a68458d9..5dfb2a7d3 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Employee.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -23,7 +24,6 @@ import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; import java.io.Serializable; import java.util.Date; @@ -33,11 +33,9 @@ */ @ToString @EqualsAndHashCode -@Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote.text", type = IndexType.Fulltext) -}) +@Index(value = "joinDate", type = IndexType.NonUnique) +@Index(value = "address", type = IndexType.Fulltext) +@Index(value = "employeeNote.text", type = IndexType.Fulltext) public class Employee implements Serializable { @Id @Getter @@ -52,6 +50,10 @@ public class Employee implements Serializable { @Setter private String address; + @Getter + @Setter + private String emailAddress; + @Getter @Setter private transient Company company; @@ -74,5 +76,6 @@ public Employee(Employee copy) { company = copy.company; blob = copy.blob; employeeNote = copy.employeeNote; + emailAddress = copy.emailAddress; } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java new file mode 100644 index 000000000..fcf5e7cd6 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.repository.annotations.Entity; + +import java.util.Date; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity +public class EncryptedPerson { + private String name; + private String creditCardNumber; + private String cvv; + private Date expiryDate; +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Note.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Note.java similarity index 72% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Note.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Note.java index 5eba9a8a9..647776b0f 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/Note.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Note.java @@ -1,24 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import java.io.Serializable; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ParentClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java similarity index 78% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ParentClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java index 4d5a16772..844e39223 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ParentClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java @@ -1,26 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; import java.util.Date; @@ -29,9 +29,7 @@ */ @Getter @Setter -@Indices( - @Index(value = "date") -) +@Index(value = "date") public class ParentClass extends SuperDuperClass { @Id protected Long id; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/PersonEntity.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java similarity index 77% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/PersonEntity.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index 195f5d49b..c70046406 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/PersonEntity.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; import java.util.Date; import java.util.UUID; @@ -29,8 +30,9 @@ * @author Anindya Chatterjee */ @Data -@Indices({ - @Index(value = "name", type = IndexType.Fulltext) +@Entity(value = "MyPerson", indices = { + @Index(value = "name", type = IndexType.Fulltext), + @Index(value = "status", type = IndexType.NonUnique) }) public class PersonEntity { @Id diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ProductScore.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java similarity index 83% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ProductScore.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java index 0faca8005..c796a49d3 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/ProductScore.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/RepeatableIndexTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java similarity index 85% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/RepeatableIndexTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index 1da0b894f..2edc387fb 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/RepeatableIndexTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.index.IndexType; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/StressRecord.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/StressRecord.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java index 3c7e0eebc..9ab3c6d10 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/StressRecord.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SubEmployee.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java similarity index 84% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SubEmployee.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java index 808c2c7de..0b4713a03 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SubEmployee.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SuperDuperClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java similarity index 83% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SuperDuperClass.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index e1bab1eb5..442e00678 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/SuperDuperClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCircularReference.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCircularReference.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java index 15e8e8128..ef9128b30 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCircularReference.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithClassField.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithClassField.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java index 6dbc86332..648f562d0 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithClassField.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCustomConstructor.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java similarity index 84% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCustomConstructor.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java index 843f49c2f..5982ee0e1 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithCustomConstructor.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithDateId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithDateId.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java index de502257d..1ad510072 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithDateId.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithEmptyStringId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java similarity index 81% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithEmptyStringId.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java index d95053ced..cb32a0d84 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithEmptyStringId.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithFinalField.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithFinalField.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java index 2c9c19fe6..43e903151 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithFinalField.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java new file mode 100644 index 000000000..b9b980f70 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.repository.annotations.Id; + +/** + * @author Anindya Chatterjee + */ +@Data +public class WithNitriteId { + @Id + public NitriteId idField; + public String name; +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithNullId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithNullId.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java index 0136adebf..4a7059eaf 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithNullId.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithObjectId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java similarity index 81% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithObjectId.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java index ad71e12a7..ab1009b01 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithObjectId.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutGetterSetter.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutGetterSetter.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java index 41c775390..eebfa6f6f 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutGetterSetter.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java similarity index 83% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutId.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java index 009aadf25..43a6de490 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithOutId.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPrivateConstructor.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java similarity index 86% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPrivateConstructor.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java index 6f782e5f0..2570ebb50 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPrivateConstructor.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPublicField.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java similarity index 81% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPublicField.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java index d6bf5016e..d5fde086b 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithPublicField.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import org.dizitart.no2.repository.annotations.Id; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithTransientField.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java similarity index 82% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithTransientField.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java index 862559e1b..2371e5998 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/WithTransientField.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java new file mode 100644 index 000000000..147513d86 --- /dev/null +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.repository.annotations.Id; + +/** + * @author Anindya Chatterjee + */ +@Data +public class WithoutEmbeddedId { + @Id + private NestedId nestedId; + private String data; + + + @Data + public static class NestedId { + private Long id; + } +} diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TransactionRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java similarity index 94% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TransactionRepositoryTest.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index 87a92087a..b6d9142a3 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TransactionRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.test.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; import org.dizitart.no2.collection.Document; @@ -8,8 +25,8 @@ import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.test.BaseObjectRepositoryTest; -import org.dizitart.no2.test.data.SubEmployee; +import org.dizitart.no2.integration.repository.BaseObjectRepositoryTest; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.dizitart.no2.transaction.Session; import org.dizitart.no2.transaction.Transaction; import org.junit.Test; @@ -56,7 +73,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -116,7 +133,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { ObjectRepository repository = db.getRepository(TxData.class, "rollback"); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(new TxData(1L, "Jane")); try (Session session = db.createSession()) { @@ -180,7 +197,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); TxData txData1 = new TxData(1L, "John"); repository.insert(txData1); @@ -220,7 +237,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -245,7 +262,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -290,7 +307,7 @@ public void testRollbackClear() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -320,7 +337,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -344,7 +361,7 @@ public void testRollbackDropIndex() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -374,7 +391,7 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -398,7 +415,7 @@ public void testRollbackDropAllIndices() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -461,7 +478,7 @@ public void testRollbackDropRepository() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -498,7 +515,9 @@ public void testCommitSetAttribute() { ObjectRepository txRepo = transaction.getRepository(TxData.class); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txRepo.setAttributes(attributes); assertNull(repository.getAttributes()); @@ -513,7 +532,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -551,7 +570,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.NonUnique)); + repository.createIndex(indexOptions(IndexType.NonUnique), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -692,7 +711,7 @@ public void testTransactionOnDifferentRepositoriesAndCollections() { ObjectRepository repo2 = db.getRepository(TxData.class, "2"); ObjectRepository repo3 = db.getRepository(SubEmployee.class); NitriteCollection col1 = db.getCollection("test1"); - col1.createIndex("id", indexOptions(IndexType.Unique)); + col1.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TxData.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TxData.java similarity index 83% rename from nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TxData.java rename to nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TxData.java index 12899009e..57461811e 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/transaction/TxData.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TxData.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.test.transaction; +package org.dizitart.no2.integration.transaction; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/DataGenerator.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/DataGenerator.java deleted file mode 100644 index e3d306bda..000000000 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/test/data/DataGenerator.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.test.data; - -import lombok.experimental.UtilityClass; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author Anindya Chatterjee. - */ -@UtilityClass -public class DataGenerator { - private static Random random = new Random(System.currentTimeMillis()); - private static AtomicInteger counter = new AtomicInteger(random.nextInt()); - - public static Company generateCompanyRecord() { - Company company = new Company(); - company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); - company.setCompanyName(randomCompanyName()); - company.setDateCreated(randomDate()); - List departments = departments(); - company.setDepartments(departments); - - Map> employeeRecord = new HashMap<>(); - for (String department : departments) { - employeeRecord.put(department, - generateEmployeeRecords(company, random.nextInt(20))); - } - company.setEmployeeRecord(employeeRecord); - return company; - } - - private static List generateEmployeeRecords(Company company, int count) { - List employeeList = new ArrayList<>(); - for (int i = 0; i < count; i++) { - Employee employee = generateEmployee(); - employee.setCompany(company); - employeeList.add(employee); - } - return employeeList; - } - - public static Employee generateEmployee() { - Employee employee = new Employee(); - employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); - employee.setJoinDate(randomDate()); - employee.setAddress(UUID.randomUUID().toString().replace('-', ' ')); - - byte[] blob = new byte[random.nextInt(8000)]; - random.nextBytes(blob); - employee.setBlob(blob); - employee.setEmployeeNote(randomNote()); - - return employee; - } - - private static Date randomDate() { - return new Date(-946771200000L + - (Math.abs(random.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000))); - } - - public static Note randomNote() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.text"); - BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); - - String strLine; - long line = random.nextInt(49); - int count = 0; - try { - while ((strLine = br.readLine()) != null) { - if (count == line) { - Note note = new Note(); - note.setNoteId(line); - note.setText(strLine); - return note; - } - count++; - } - } catch (IOException e) { - // ignore - } finally { - try { - br.close(); - } catch (IOException e) { - // ignore - } - } - return null; - } - - private static String randomCompanyName() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("english.stop"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - int line = random.nextInt(570); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - return strLine + System.nanoTime() + " inc."; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; - } - - private static List departments() { - return new ArrayList() {{ - add("dev"); - add("hr"); - add("qa"); - add("dev-ops"); - add("sales"); - add("marketing"); - add("design"); - add("support"); - }}; - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java index 1b996c72f..93c5f10eb 100644 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java +++ b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java @@ -8,6 +8,8 @@ import java.util.Set; +import static org.dizitart.no2.common.util.Iterables.setOf; + /** * @author Anindya Chatterjee */ diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java index 1fd2970a5..1842547cf 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java @@ -92,7 +92,7 @@ public NitriteId next() { } @Override - public void close() throws Exception { + public void close() { //nothing to close } } diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java b/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java index b288aec54..7dd160cac 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/RepositoryInstruction.java @@ -151,14 +151,27 @@ default RepositoryInstruction changeDataType(String fieldName, TypeConverter con default RepositoryInstruction changeIdField(List oldFieldNames, List newFieldNames) { Fields oldFields = Fields.withNames(oldFieldNames.toArray(new String[0])); Fields newFields = Fields.withNames(newFieldNames.toArray(new String[0])); + return changeIdField(oldFields, newFields); + } + /** + * Adds an instruction to change the id field of an entity in the + * {@link org.dizitart.no2.repository.ObjectRepository} + * + * @param oldField the old field names + * @param newField the new field names + * @return the repository instruction + */ + default RepositoryInstruction changeIdField(Fields oldField, Fields newField) { MigrationStep migrationStep = new MigrationStep(); migrationStep.setInstructionType(InstructionType.RepositoryChangeIdField); - migrationStep.setArguments(new Quartet<>(entityName(), key(), oldFields, newFields)); + migrationStep.setArguments(new Quartet<>(entityName(), key(), oldField, newField)); addStep(migrationStep); return this; } + + /** * Adds an instruction to drop an index from the {@link org.dizitart.no2.repository.ObjectRepository}. * diff --git a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java index 3093f3edf..87a4f084b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/AbstractNitriteStore.java @@ -94,11 +94,13 @@ public void unsubscribe(StoreEventListener listener) { @Override public void initialize(NitriteConfig nitriteConfig) { this.nitriteConfig = nitriteConfig; - this.storeCatalog = new StoreCatalog(this); } @Override public StoreCatalog getCatalog() { + if (storeCatalog == null) { + this.storeCatalog = new StoreCatalog(this); + } return storeCatalog; } } diff --git a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java index fe632a6ad..85e413192 100644 --- a/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/transaction/TransactionalStoreTest.java @@ -40,11 +40,11 @@ public void testCommit() { @Test public void testClose() throws Exception { - TransactionalStore transactionalStore = new TransactionalStore<>( + TransactionalStore transactionalStore = new TransactionalStore<>( new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null)))); + new TransactionalStore<>(new TransactionalStore<>(new InMemoryStore())))); transactionalStore.close(); - assertNull(transactionalStore.getCatalog()); + assertNotNull(transactionalStore.getCatalog()); } @Test @@ -125,16 +125,16 @@ public void testConstructor() { @Test public void testConstructor2() { - TransactionalStore transactionalStore = new TransactionalStore<>( + TransactionalStore transactionalStore = new TransactionalStore<>( new TransactionalStore<>( - new TransactionalStore<>(new TransactionalStore<>(null)))); - TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); - assertNull(actualTransactionalStore.getCatalog()); + new TransactionalStore<>(new TransactionalStore<>(new InMemoryStore())))); + TransactionalStore actualTransactionalStore = new TransactionalStore<>(transactionalStore); + assertNotNull(actualTransactionalStore.getCatalog()); assertFalse(actualTransactionalStore.isReadOnly()); assertFalse(actualTransactionalStore.isClosed()); assertTrue(actualTransactionalStore.hasUnsavedChanges()); assertNull(actualTransactionalStore.getStoreConfig()); - assertNull(transactionalStore.getCatalog()); + assertNotNull(transactionalStore.getCatalog()); assertFalse(transactionalStore.isReadOnly()); assertFalse(transactionalStore.isClosed()); assertTrue(transactionalStore.hasUnsavedChanges()); From 77c872dd2885b8d4a24b56903fba5ed771e8ea3d Mon Sep 17 00:00:00 2001 From: Anindya Chatterjee Date: Sun, 27 Jun 2021 00:24:07 +0530 Subject: [PATCH 13/13] checkpoint 5 --- nitrite-bom/build.gradle | 3 +- .../integration/migrate/MigrationTest.java | 6 +- .../no2/integration/migrate/NewClass.java | 6 +- .../no2/integration/migrate/OldClass.java | 8 +- .../repository/CustomFieldSeparatorTest.java | 6 +- .../repository/ObjectRepositoryTest.java | 4 +- .../RepositoryModificationTest.java | 6 +- .../UniversalTextTokenizerTest.java | 2 +- .../no2/integration/repository/data/Book.java | 4 +- .../integration/repository/data/Employee.java | 6 +- .../repository/data/PersonEntity.java | 4 +- .../repository/data/RepeatableIndexTest.java | 4 +- .../repository/data/SuperDuperClass.java | 2 +- .../TransactionRepositoryTest.java | 6 +- nitrite-mapdb-adapter/build.gradle | 132 --- nitrite-mapdb-adapter/lombok.config | 3 - .../org/dizitart/no2/mapdb/MapDBConfig.java | 93 -- .../java/org/dizitart/no2/mapdb/MapDBMap.java | 250 ------ .../org/dizitart/no2/mapdb/MapDBModule.java | 41 - .../no2/mapdb/MapDBModuleBuilder.java | 107 --- .../org/dizitart/no2/mapdb/MapDBStore.java | 158 ---- .../dizitart/no2/mapdb/MapDBStoreType.java | 12 - .../org/dizitart/no2/mapdb/StoreFactory.java | 141 --- .../no2/mapdb/serializers/Serializers.java | 30 - .../no2/mapdb/BaseCollectionTest.java | 140 --- .../no2/mapdb/CollectionFieldIndexTest.java | 105 --- .../dizitart/no2/mapdb/CustomFilterTest.java | 41 - .../no2/mapdb/DbWriteCloseReadTest.java | 58 -- .../dizitart/no2/mapdb/MapDBConfigTest.java | 17 - .../no2/mapdb/MapDBModuleBuilderTest.java | 17 - .../dizitart/no2/mapdb/MapDBModuleTest.java | 26 - .../dizitart/no2/mapdb/MapDBStoreTest.java | 32 - .../no2/mapdb/MapDBStoreTypeTest.java | 18 - .../no2/mapdb/NitriteBuilderNegativeTest.java | 94 -- .../no2/mapdb/NitriteBuilderTest.java | 431 --------- .../dizitart/no2/mapdb/NitriteStressTest.java | 151 ---- .../no2/mapdb/SerializabilityTest.java | 117 --- .../java/org/dizitart/no2/mapdb/TestUtil.java | 160 ---- .../mapdb/collection/CollectionFindTest.java | 850 ------------------ .../operation/DocumentCursorTest.java | 86 -- .../operation/JoinedDocumentStreamTest.java | 76 -- .../no2/mapdb/common/event/EventTest.java | 241 ----- .../mapdb/mapdb/NitriteStoreEventTest.java | 134 --- .../no2/mapdb/migrate/MigrationTest.java | 557 ------------ .../repository/BaseObjectRepositoryTest.java | 136 --- .../repository/CustomFieldSeparatorTest.java | 181 ---- .../repository/RepositorySearchTest.java | 603 ------------- .../UniversalTextTokenizerTest.java | 195 ---- .../no2/mapdb/repository/data/ChildClass.java | 44 - .../mapdb/repository/data/DataGenerator.java | 139 --- .../no2/mapdb/repository/data/ElemMatch.java | 65 -- .../no2/mapdb/repository/data/Employee.java | 101 --- .../mapdb/repository/data/ParentClass.java | 52 -- .../data/WithCustomConstructor.java | 35 - .../mapdb/repository/data/WithFinalField.java | 62 -- .../mapdb/repository/data/WithObjectId.java | 44 - .../repository/data/WithPublicField.java | 43 - .../repository/data/WithTransientField.java | 46 - .../src/test/resources/english.stop | 571 ------------ .../src/test/resources/log4j2.xml | 31 - .../src/test/resources/test.text | 50 -- nitrite-mvstore-adapter/build.gradle | 2 + .../dizitart/no2/mvstore/NitriteMVMap.java | 3 +- .../no2/mvstore/NitriteMVRTreeMap.java | 27 +- .../dizitart/no2/mvstore/NitriteMVStore.java | 15 +- .../no2/mvstore/compat/v3/MigrationUtil.java | 17 +- .../org/dizitart/no2/DbTestOperations.java | 214 ----- .../dizitart/no2/DbWriteCloseReadTest.java | 59 -- .../dizitart/no2/DocumentMetadataTest.java | 69 -- .../org/dizitart/no2/MultiThreadedTest.java | 162 ---- .../dizitart/no2/NitriteCorruptedTest.java | 98 -- .../org/dizitart/no2/NitriteStressTest.java | 150 ---- .../java/org/dizitart/no2/NitriteTest.java | 95 +- .../CollectionDeleteNegativeTest.java | 57 -- .../no2/collection/CollectionDeleteTest.java | 126 --- .../no2/collection/CollectionFactoryTest.java | 50 -- .../CollectionFindByIndexNegativeTest.java | 48 - .../collection/CollectionFindByIndexTest.java | 399 -------- .../CollectionFindNegativeTest.java | 104 --- .../CollectionInsertNegativeTest.java | 36 - .../no2/collection/CollectionInsertTest.java | 54 -- .../no2/collection/CollectionJoinTest.java | 103 --- .../no2/collection/CollectionUpdateTest.java | 268 ------ .../no2/collection/NitriteCollectionTest.java | 55 -- .../event/SampleListenerCollection.java | 39 - .../no2/integration}/CustomFilterTest.java | 10 +- .../no2/integration/DbWriteCloseReadTest.java | 98 +- .../integration}/DocumentMetadataTest.java | 8 +- .../no2/integration}/MultiThreadedTest.java | 29 +- .../NitriteBuilderNegativeTest.java | 12 +- .../{ => integration}/NitriteBuilderTest.java | 20 +- .../integration}/NitriteCorruptedTest.java | 17 +- .../NitriteSecurityNegativeTest.java | 12 +- .../NitriteSecurityTest.java | 26 +- .../no2/integration/NitriteStressTest.java | 170 +++- .../dizitart/no2/{ => integration}/Retry.java | 19 +- .../no2/integration}/SerializabilityTest.java | 23 +- .../no2/{ => integration}/TestUtil.java | 37 +- .../collection/BaseCollectionTest.java | 18 +- .../CollectionCompoundIndexNegativeTest.java | 98 ++ .../CollectionCompoundIndexTest.java | 310 +++++++ .../CollectionDeleteNegativeTest.java | 8 +- .../collection/CollectionDeleteTest.java | 10 +- .../collection}/CollectionFieldIndexTest.java | 16 +- .../CollectionFindByCompoundIndexTest.java | 503 +++++++++++ .../CollectionFindByIndexNegativeTest.java | 12 +- .../CollectionFindBySingleFieldIndexTest.java | 103 ++- .../CollectionFindNegativeTest.java | 23 +- .../collection/CollectionFindTest.java | 222 ++--- .../CollectionIndexNegativeTest.java | 19 +- .../collection/CollectionIndexTest.java | 304 +++++++ .../CollectionInsertNegativeTest.java | 8 +- .../collection/CollectionInsertTest.java | 8 +- .../collection/CollectionJoinTest.java | 8 +- ...ollectionSingleFieldIndexNegativeTest.java | 79 ++ .../CollectionSingleFieldIndexTest.java} | 114 ++- .../collection/CollectionUpdateTest.java | 14 +- .../collection/FieldProcessorTest.java | 212 +++++ .../collection/NitriteCollectionTest.java | 10 +- .../event/EventTest.java | 18 +- .../event/SampleListenerCollection.java | 7 +- .../migrate/MigrationTest.java | 40 +- .../no2/integration}/migrate/NewClass.java | 25 +- .../no2/integration}/migrate/OldClass.java | 27 +- .../mvstore/NitriteMapStressTest.java | 19 +- .../mvstore/NitriteStoreEventTest.java | 19 +- .../repository/BaseObjectRepositoryTest.java | 35 +- .../repository/CustomFieldSeparatorTest.java | 27 +- .../repository/FieldProcessorTest.java | 207 +++++ .../repository/InternalClass.java | 9 +- .../repository/NitriteIdAsIdTest.java | 20 +- .../repository/ObjectCursorTest.java | 9 +- .../ObjectRepositoryNegativeTest.java | 43 +- .../repository/ObjectRepositoryTest.java | 43 +- .../repository/ProjectionTest.java | 18 +- .../RepositoryCompoundIndexTest.java | 52 ++ .../repository/RepositoryFactoryTest.java | 69 +- .../repository/RepositoryJoinTest.java | 20 +- .../RepositoryModificationTest.java | 52 +- .../repository/RepositorySearchTest.java | 87 +- .../repository/UnAnnotatedObjectTest.java | 33 +- .../UniversalTextTokenizerTest.java | 31 +- .../no2/integration/repository/data/Book.java | 72 ++ .../integration/repository/data/BookId.java | 54 ++ .../repository/data/ChildClass.java | 9 +- .../repository/data/ClassA.java | 19 +- .../integration}/repository/data/ClassB.java | 7 +- .../integration}/repository/data/ClassC.java | 9 +- .../repository/data/Company.java | 25 +- .../repository/data/DataGenerator.java | 95 +- .../repository/data/ElemMatch.java | 7 +- .../repository/data/Employee.java | 24 +- .../repository/data/EncryptedPerson.java} | 31 +- .../integration}/repository/data/Note.java | 7 +- .../repository/data/ParentClass.java | 7 +- .../repository/data/PersonEntity.java | 11 +- .../repository/data/ProductScore.java | 7 +- .../repository/data/RepeatableIndexTest.java | 11 +- .../repository/data/StressRecord.java | 7 +- .../repository/data/SubEmployee.java | 7 +- .../repository/data/SuperDuperClass.java | 9 +- .../data/WithCircularReference.java | 7 +- .../repository/data/WithClassField.java | 7 +- .../data/WithCustomConstructor.java | 7 +- .../repository/data/WithDateId.java | 7 +- .../repository/data/WithEmptyStringId.java | 7 +- .../repository/data/WithFinalField.java | 7 +- .../repository/data/WithNitriteId.java | 7 +- .../repository/data/WithNullId.java | 9 +- .../repository/data/WithObjectId.java | 7 +- .../repository/data/WithOutGetterSetter.java | 7 +- .../repository/data/WithOutId.java | 7 +- .../data/WithPrivateConstructor.java | 7 +- .../repository/data/WithPublicField.java | 9 +- .../repository/data/WithTransientField.java | 9 +- .../repository/data/WithoutEmbeddedId.java | 40 +- .../stream}/DocumentCursorTest.java | 15 +- .../stream}/JoinedDocumentStreamTest.java | 15 +- .../TransactionCollectionTest.java | 61 +- .../TransactionRepositoryTest.java | 55 +- .../no2/integration}/transaction/TxData.java | 7 +- .../org/dizitart/no2/migrate/NewClass.java | 67 -- .../org/dizitart/no2/migrate/OldClass.java | 68 -- .../no2/mvstore/MVStoreConfigTest.java | 41 + .../no2/mvstore/MVStoreModuleBuilderTest.java | 94 ++ .../no2/mvstore/MVStoreModuleTest.java | 51 ++ .../no2/mvstore/MVStoreUtilsTest.java | 70 ++ .../no2/mvstore/NitriteMVMapTest.java | 64 ++ .../no2/mvstore/NitriteMVStoreTest.java | 59 ++ .../dizitart/no2/mvstore/RecoveryTest.java | 27 +- .../no2/mvstore/ReverseIteratorTest.java | 54 ++ .../mvstore/compat/v3/MVMapBuilderTest.java | 32 + .../compat/v3/NitriteDataTypeTest.java | 754 ++++++++++++++++ .../no2/repository/ObjectCursorTest.java | 53 -- .../no2/repository/RepositoryFactoryTest.java | 209 ----- .../no2/repository/RepositoryJoinTest.java | 296 ------ .../RepositoryModificationTest.java | 631 ------------- .../repository/RepositoryOperationsTest.java | 399 -------- .../dizitart/no2/repository/data/ClassB.java | 61 -- .../dizitart/no2/repository/data/ClassC.java | 65 -- .../dizitart/no2/repository/data/Note.java | 50 -- .../no2/repository/data/PersonEntity.java | 78 -- .../repository/data/RepeatableIndexTest.java | 51 -- .../no2/repository/data/SubEmployee.java | 59 -- .../repository/data/WithEmptyStringId.java | 44 - .../no2/repository/data/WithOutId.java | 51 -- .../data/WithPrivateConstructor.java | 55 -- .../TransactionCollectionTest.java | 770 ---------------- .../TransactionRepositoryTest.java | 808 ----------------- .../org/dizitart/no2/transaction/TxData.java | 49 - nitrite-rocksdb-adapter/build.gradle | 1 + .../org/dizitart/no2/rocksdb/EntrySet.java | 1 - .../java/org/dizitart/no2/rocksdb/KeySet.java | 1 - .../org/dizitart/no2/rocksdb/RocksDBMap.java | 11 +- .../no2/rocksdb/RocksDBReference.java | 30 +- .../dizitart/no2/rocksdb/RocksDBStore.java | 10 + .../org/dizitart/no2/rocksdb/ValueSet.java | 4 +- .../formatter/KryoObjectFormatter.java | 1 - .../rocksdb/formatter/NitriteSerializers.java | 44 +- .../java/org/dizitart/no2}/NitriteTest.java | 128 +-- .../no2/integration}/CustomFilterTest.java | 11 +- .../DbWriteCloseReadTest.java} | 98 +- .../DocumentMetadataTest.java | 8 +- .../MultiThreadedTest.java | 34 +- .../NitriteBuilderNegativeTest.java | 21 +- .../NitriteBuilderTest.java | 36 +- .../integration}/NitriteCorruptedTest.java | 41 +- .../NitriteSecurityNegativeTest.java | 13 +- .../no2/integration/NitriteSecurityTest.java | 42 +- .../no2/integration/NitriteStressTest.java | 173 +++- .../org/dizitart/no2/integration}/Retry.java | 19 +- .../no2/integration}/SerializabilityTest.java | 19 +- .../{rocksdb => integration}/TestUtil.java | 55 +- .../collection}/BaseCollectionTest.java | 21 +- .../CollectionCompoundIndexNegativeTest.java | 98 ++ .../CollectionCompoundIndexTest.java | 310 +++++++ .../CollectionDeleteNegativeTest.java | 8 +- .../collection/CollectionDeleteTest.java | 10 +- .../collection}/CollectionFieldIndexTest.java | 28 +- .../CollectionFindByCompoundIndexTest.java | 503 +++++++++++ .../CollectionFindByIndexNegativeTest.java | 12 +- .../CollectionFindBySingleFieldIndexTest.java | 102 ++- .../CollectionFindNegativeTest.java | 23 +- .../collection/CollectionFindTest.java | 218 ++--- .../CollectionIndexNegativeTest.java | 20 +- .../collection/CollectionIndexTest.java | 304 +++++++ .../CollectionInsertNegativeTest.java | 8 +- .../collection/CollectionInsertTest.java | 8 +- .../collection/CollectionJoinTest.java | 8 +- ...ollectionSingleFieldIndexNegativeTest.java | 79 ++ .../CollectionSingleFieldIndexTest.java | 120 ++- .../collection/CollectionUpdateTest.java | 14 +- .../collection/FieldProcessorTest.java | 212 +++++ .../collection/NitriteCollectionTest.java | 26 +- .../event/EventTest.java | 37 +- .../event/SampleListenerCollection.java | 7 +- .../migrate/MigrationTest.java | 40 +- .../migrate/NewClass.java | 25 +- .../migrate/OldClass.java | 27 +- .../repository/BaseObjectRepositoryTest.java | 44 +- .../repository/CustomFieldSeparatorTest.java | 34 +- .../repository/FieldProcessorTest.java | 207 +++++ .../repository/InternalClass.java | 7 +- .../repository/NitriteIdAsIdTest.java | 22 +- .../repository/ObjectCursorTest.java | 9 +- .../ObjectRepositoryNegativeTest.java | 44 +- .../repository/ObjectRepositoryTest.java | 47 +- .../repository/ProjectionTest.java | 18 +- .../RepositoryCompoundIndexTest.java | 52 ++ .../repository/RepositoryFactoryTest.java | 70 +- .../repository/RepositoryJoinTest.java | 82 +- .../RepositoryModificationTest.java | 52 +- .../repository/RepositorySearchTest.java | 87 +- .../repository/UnAnnotatedObjectTest.java | 34 +- .../UniversalTextTokenizerTest.java | 27 +- .../no2/integration/repository/data/Book.java | 72 ++ .../integration/repository/data/BookId.java | 54 ++ .../repository/data/ChildClass.java | 7 +- .../integration}/repository/data/ClassA.java | 19 +- .../integration}/repository/data/ClassB.java | 7 +- .../repository/data/ClassC.java | 9 +- .../integration}/repository/data/Company.java | 25 +- .../repository/data/DataGenerator.java | 99 +- .../repository/data/ElemMatch.java | 7 +- .../repository/data/Employee.java | 20 +- .../repository/data/EncryptedPerson.java | 54 ++ .../integration}/repository/data/Note.java | 7 +- .../repository/data/ParentClass.java | 9 +- .../repository/data/PersonEntity.java | 11 +- .../repository/data/ProductScore.java | 7 +- .../repository/data/RepeatableIndexTest.java | 11 +- .../repository/data/StressRecord.java | 7 +- .../repository/data/SubEmployee.java | 7 +- .../repository/data/SuperDuperClass.java | 11 +- .../data/WithCircularReference.java | 7 +- .../repository/data/WithClassField.java | 9 +- .../data/WithCustomConstructor.java | 7 +- .../repository/data/WithDateId.java | 7 +- .../repository/data/WithEmptyStringId.java | 7 +- .../repository/data/WithFinalField.java | 7 +- .../repository/data/WithNitriteId.java | 9 +- .../repository/data/WithNullId.java | 7 +- .../repository/data/WithObjectId.java | 9 +- .../repository/data/WithOutGetterSetter.java | 7 +- .../repository/data/WithOutId.java | 7 +- .../data/WithPrivateConstructor.java | 7 +- .../repository/data/WithPublicField.java | 7 +- .../repository/data/WithTransientField.java | 7 +- .../repository/data/WithoutEmbeddedId.java | 65 ++ .../rocksdb}/NitriteMapStressTest.java | 19 +- .../rocksdb/NitriteStoreEventTest.java | 19 +- .../stream}/DocumentCursorTest.java | 29 +- .../stream}/JoinedDocumentStreamTest.java | 30 +- .../TransactionCollectionTest.java | 61 +- .../TransactionRepositoryTest.java | 55 +- .../transaction/TxData.java | 7 +- .../dizitart/no2/rocksdb/AbstractTest.java | 56 -- .../no2/rocksdb}/CollectionFactoryTest.java | 9 +- .../no2/rocksdb/DbWriteCloseReadTest.java | 59 -- .../dizitart/no2/rocksdb/EntrySetTest.java | 49 + .../org/dizitart/no2/rocksdb/KeySetTest.java | 38 + .../NitriteStoreFactoryNegativeTest.java | 91 -- .../no2/rocksdb/NitriteStoreFactoryTest.java | 98 -- .../no2/rocksdb/NitriteStressTest.java | 152 ---- .../org/dizitart/no2/rocksdb/NitriteTest.java | 411 --------- .../no2/rocksdb/RocksDBConfigTest.java | 34 +- .../dizitart/no2/rocksdb/RocksDBMapTest.java | 34 + .../no2/rocksdb/RocksDBModuleBuilderTest.java | 55 +- .../no2/rocksdb/RocksDBModuleTest.java | 30 +- .../no2/rocksdb/RocksDBReferenceTest.java | 32 +- .../no2/rocksdb/RocksDBStoreTest.java | 52 +- .../no2/rocksdb/RocksDBStoreUtilsTest.java | 40 + .../org/dizitart/no2/rocksdb/RocksDBTest.java | 40 +- .../org/dizitart/no2/rocksdb/StressTest.java | 196 ---- .../dizitart/no2/rocksdb/ValueSetTest.java | 38 + .../collection/CollectionFactoryTest.java | 51 -- .../formatter/KryoObjectFormatterTest.java | 9 +- .../no2/rocksdb/repository/InternalClass.java | 45 - .../rocksdb/repository/NitriteIdAsIdTest.java | 97 -- .../ObjectRepositoryNegativeTest.java | 185 ---- .../repository/ObjectRepositoryTest.java | 357 -------- .../rocksdb/repository/ProjectionTest.java | 64 -- .../repository/UnAnnotatedObjectTest.java | 80 -- .../no2/rocksdb/repository/data/ClassA.java | 74 -- .../no2/rocksdb/repository/data/Company.java | 83 -- .../rocksdb/repository/data/ProductScore.java | 53 -- .../rocksdb/repository/data/StressRecord.java | 56 -- .../repository/data/SuperDuperClass.java | 45 - .../repository/data/WithClassField.java | 47 - .../rocksdb/repository/data/WithNullId.java | 48 - .../repository/data/WithOutGetterSetter.java | 49 - .../rocksdb/rocksdb/NitriteMapStressTest.java | 92 -- .../dizitart/no2/spatial/FluentFilter.java | 39 + .../no2/spatial/IntersectsFilter.java | 10 +- .../org/dizitart/no2/spatial/NearFilter.java | 6 + .../no2/spatial/NitriteBoundingBox.java | 2 + .../dizitart/no2/spatial/SpatialFilter.java | 27 +- .../dizitart/no2/spatial/SpatialIndex.java | 163 ++++ .../dizitart/no2/spatial/SpatialIndexer.java | 105 +-- .../dizitart/no2/spatial/SpatialModule.java | 3 + .../dizitart/no2/spatial/WithinFilter.java | 10 +- .../dizitart/no2/spatial/BaseSpatialTest.java | 110 +++ .../java/org/dizitart/no2/spatial}/Retry.java | 2 +- .../no2/spatial/{test => }/SpatialData.java | 6 +- .../no2/spatial/SpatialIndexNegativeTest.java | 110 +++ .../no2/spatial/SpatialIndexTest.java | 211 +++++ .../dizitart/no2/spatial/SpatialViewer.java | 83 ++ .../org/dizitart/no2/spatial/TestUtil.java | 63 ++ .../org/dizitart/no2/spatial/test/Retry.java | 42 - .../no2/spatial/test/SpatialIndexTest.java | 357 -------- .../no2/support/NitriteJsonImporter.java | 12 +- .../org/dizitart/no2/support/Employee.java | 6 +- .../collection/DefaultNitriteCollection.java | 30 +- .../org/dizitart/no2/collection/FindPlan.java | 8 +- .../operation/CollectionOperations.java | 6 +- .../collection/operation/FindOptimizer.java | 189 +++- .../collection/operation/IndexManager.java | 25 +- .../collection/operation/IndexOperations.java | 19 +- .../collection/operation/ReadOperations.java | 63 +- .../org/dizitart/no2/common/Constants.java | 5 +- .../no2/common/PersistentCollection.java | 5 + .../org/dizitart/no2/common/RecordStream.java | 11 + .../no2/common/module/PluginManager.java | 6 +- .../dizitart/no2/filters/EqualsFilter.java | 2 +- .../dizitart/no2/filters/IndexOnlyFilter.java | 47 + .../dizitart/no2/filters/IndexScanFilter.java | 4 +- .../dizitart/no2/filters/StringFilter.java | 2 +- .../org/dizitart/no2/filters/TextFilter.java | 23 +- .../org/dizitart/no2/index/CompoundIndex.java | 24 +- .../dizitart/no2/index/IndexDescriptor.java | 2 +- .../java/org/dizitart/no2/index/IndexMap.java | 3 +- .../org/dizitart/no2/index/IndexScanner.java | 13 +- .../org/dizitart/no2/index/IndexType.java | 6 +- .../org/dizitart/no2/index/NitriteIndex.java | 5 +- .../no2/index/NitriteTextIndexer.java | 2 +- .../dizitart/no2/index/NonUniqueIndexer.java | 2 +- .../dizitart/no2/index/SingleFieldIndex.java | 22 +- .../org/dizitart/no2/index/TextIndex.java | 33 +- .../org/dizitart/no2/index/UniqueIndexer.java | 2 +- .../no2/migration/commands/ChangeIdField.java | 2 +- .../repository/DefaultObjectRepository.java | 2 +- .../no2/repository/annotations/Index.java | 2 +- .../org/dizitart/no2/store/NitriteRTree.java | 10 + .../org/dizitart/no2/store/NitriteStore.java | 17 +- .../no2/store/memory/InMemoryMap.java | 2 +- .../no2/store/memory/InMemoryRTree.java | 10 + .../no2/store/memory/InMemoryStore.java | 14 + .../DefaultTransactionalCollection.java | 6 +- .../DefaultTransactionalRepository.java | 2 +- .../no2/transaction/TransactionalMap.java | 5 +- .../no2/transaction/TransactionalRTree.java | 10 + .../no2/transaction/TransactionalStore.java | 15 + .../dizitart/no2/collection/FindPlanTest.java | 282 +----- .../operation/DocumentIndexWriterTest.java | 62 +- .../operation/FindOptimizerTest.java | 44 +- .../operation/IndexOperationsTest.java | 250 ------ .../operation/ReadOperationsTest.java | 43 +- .../streams/SortedDocumentStreamTest.java | 4 +- .../no2/filters/IndexScanFilterTest.java | 2 +- .../org/dizitart/no2/index/IndexMapTest.java | 5 +- .../no2/index/NitriteTextIndexerTest.java | 2 +- .../no2/index/NonUniqueIndexerTest.java | 2 +- .../dizitart/no2/index/UniqueIndexerTest.java | 2 +- .../no2/integration/CustomFilterTest.java | 2 +- .../no2/integration/DbTestOperations.java | 4 +- .../no2/integration/MultiThreadedTest.java | 4 +- .../no2/integration/NitriteStressTest.java | 4 +- .../dizitart/no2/integration/NitriteTest.java | 26 +- .../dizitart/no2/integration/StressTest.java | 10 +- .../CollectionCompoundIndexNegativeTest.java | 12 +- .../CollectionCompoundIndexTest.java | 16 +- .../collection/CollectionDeleteTest.java | 2 +- .../CollectionFieldIndexTest.java | 7 +- .../CollectionFindByCompoundIndexTest.java | 2 +- .../CollectionFindByIndexNegativeTest.java | 4 +- .../CollectionFindBySingleFieldIndexTest.java | 30 +- .../collection/CollectionFindTest.java | 35 +- .../CollectionIndexNegativeTest.java | 33 +- .../collection/CollectionIndexTest.java | 110 +-- ...ollectionSingleFieldIndexNegativeTest.java | 12 +- .../CollectionSingleFieldIndexTest.java | 42 +- .../repository/CustomFieldSeparatorTest.java | 6 +- .../repository/ObjectRepositoryTest.java | 4 +- .../RepositoryModificationTest.java | 6 +- .../repository/RepositorySearchTest.java | 15 + .../UniversalTextTokenizerTest.java | 2 +- .../no2/integration/repository/data/Book.java | 4 +- .../integration/repository/data/Employee.java | 6 +- .../repository/data/PersonEntity.java | 4 +- .../repository/data/RepeatableIndexTest.java | 4 +- .../repository/data/SuperDuperClass.java | 2 +- .../TransactionCollectionTest.java | 8 +- .../TransactionRepositoryTest.java | 6 +- .../kotlin/org/dizitart/kno2/Documents.kt | 10 + .../main/kotlin/org/dizitart/kno2/Nitrite.kt | 14 +- .../org/dizitart/kno2/filters/Filters.kt | 125 ++- .../main/kotlin/org/dizitart/kno2/package.md | 3 - .../org/dizitart/kno2/BackportJavaTimeTest.kt | 2 +- .../kotlin/org/dizitart/kno2/FilterTest.kt | 13 +- .../kotlin/org/dizitart/kno2/NitriteTest.kt | 18 +- .../org/dizitart/kno2/ObjectFilterTest.kt | 4 +- settings.gradle | 1 - 462 files changed, 10403 insertions(+), 18964 deletions(-) delete mode 100644 nitrite-mapdb-adapter/build.gradle delete mode 100644 nitrite-mapdb-adapter/lombok.config delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBConfig.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModuleBuilder.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStoreType.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/StoreFactory.java delete mode 100644 nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/serializers/Serializers.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/BaseCollectionTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CollectionFieldIndexTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CustomFilterTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbWriteCloseReadTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBConfigTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleBuilderTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTypeTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderNegativeTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/SerializabilityTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/TestUtil.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/DocumentCursorTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/JoinedDocumentStreamTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/EventTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteStoreEventTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/BaseObjectRepositoryTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/DataGenerator.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCustomConstructor.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java delete mode 100644 nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java delete mode 100644 nitrite-mapdb-adapter/src/test/resources/english.stop delete mode 100644 nitrite-mapdb-adapter/src/test/resources/log4j2.xml delete mode 100644 nitrite-mapdb-adapter/src/test/resources/test.text delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbTestOperations.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbWriteCloseReadTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DocumentMetadataTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/MultiThreadedTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/SampleListenerCollection.java rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/CustomFilterTest.java (79%) rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbTestOperations.java => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java (73%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/DocumentMetadataTest.java (91%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/MultiThreadedTest.java (85%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/NitriteBuilderNegativeTest.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/NitriteBuilderTest.java (97%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/NitriteCorruptedTest.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/NitriteSecurityNegativeTest.java (89%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/NitriteSecurityTest.java (82%) rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java (63%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/Retry.java (66%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/SerializabilityTest.java (86%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/TestUtil.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/collection/BaseCollectionTest.java (92%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionDeleteNegativeTest.java (90%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionDeleteTest.java (93%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection}/CollectionFieldIndexTest.java (88%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionFindByIndexNegativeTest.java (79%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexTest.java => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java (79%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionFindNegativeTest.java (83%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionFindTest.java (80%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/collection/CollectionIndexNegativeTest.java (77%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionInsertNegativeTest.java (85%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionInsertTest.java (90%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionJoinTest.java (94%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{collection/CollectionIndexTest.java => integration/collection/CollectionSingleFieldIndexTest.java} (66%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionUpdateTest.java (95%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/collection/NitriteCollectionTest.java (80%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{common => integration}/event/EventTest.java (95%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/event/SampleListenerCollection.java (87%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/migrate/MigrationTest.java (93%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/migrate/NewClass.java (69%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/migrate/OldClass.java (67%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/mvstore/NitriteMapStressTest.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/mvstore/NitriteStoreEventTest.java (89%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/BaseObjectRepositoryTest.java (84%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/CustomFieldSeparatorTest.java (86%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/InternalClass.java (88%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/NitriteIdAsIdTest.java (86%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/ObjectCursorTest.java (87%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/ObjectRepositoryNegativeTest.java (84%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/ObjectRepositoryTest.java (92%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/ProjectionTest.java (82%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryFactoryTest.java (81%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryJoinTest.java (94%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryModificationTest.java (91%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositorySearchTest.java (88%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/UnAnnotatedObjectTest.java (69%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/UniversalTextTokenizerTest.java (92%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ChildClass.java (87%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ClassA.java (80%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ClassB.java (90%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ClassC.java (89%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/Company.java (77%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/DataGenerator.java (52%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ElemMatch.java (92%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/Employee.java (82%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{repository/data/WithDateId.java => integration/repository/data/EncryptedPerson.java} (58%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/Note.java (89%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ParentClass.java (89%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/PersonEntity.java (89%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/ProductScore.java (89%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/RepeatableIndexTest.java (84%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/StressRecord.java (90%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/SubEmployee.java (90%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/SuperDuperClass.java (84%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithCircularReference.java (81%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithClassField.java (88%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithCustomConstructor.java (83%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithDateId.java (88%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithEmptyStringId.java (87%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithFinalField.java (91%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithNitriteId.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithNullId.java (88%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithObjectId.java (87%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithOutGetterSetter.java (88%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithOutId.java (89%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithPrivateConstructor.java (90%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithPublicField.java (88%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/{ => integration}/repository/data/WithTransientField.java (88%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java (50%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream}/DocumentCursorTest.java (82%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream}/JoinedDocumentStreamTest.java (79%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/transaction/TransactionCollectionTest.java (93%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/transaction/TransactionRepositoryTest.java (94%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration}/transaction/TxData.java (89%) delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreConfigTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleBuilderTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreUtilsTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVMapTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVStoreTest.java rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCircularReference.java => nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/RecoveryTest.java (56%) create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/ReverseIteratorTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/MVMapBuilderTest.java create mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/NitriteDataTypeTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java delete mode 100644 nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2}/NitriteTest.java (84%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/CustomFilterTest.java (79%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb/DbTestOperations.java => integration/DbWriteCloseReadTest.java} (73%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/DocumentMetadataTest.java (91%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/MultiThreadedTest.java (82%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/NitriteBuilderNegativeTest.java (74%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/NitriteBuilderTest.java (94%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/NitriteCorruptedTest.java (75%) rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryNegativeTest.java => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java (89%) rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java (68%) rename nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java (63%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/Retry.java (66%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/SerializabilityTest.java (85%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/TestUtil.java (67%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration/collection}/BaseCollectionTest.java (91%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionDeleteNegativeTest.java (89%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionDeleteTest.java (92%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection}/CollectionFieldIndexTest.java (84%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionFindByIndexNegativeTest.java (79%) rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexTest.java => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java (79%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionFindNegativeTest.java (83%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionFindTest.java (79%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/collection/CollectionIndexNegativeTest.java (75%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionInsertNegativeTest.java (85%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionInsertTest.java (90%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionJoinTest.java (94%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java rename nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java (65%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/collection/CollectionUpdateTest.java (95%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/collection/NitriteCollectionTest.java (63%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb/common => integration}/event/EventTest.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/event/SampleListenerCollection.java (87%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/migrate/MigrationTest.java (93%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/migrate/NewClass.java (69%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/migrate/OldClass.java (67%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/BaseObjectRepositoryTest.java (76%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/CustomFieldSeparatorTest.java (87%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/InternalClass.java (88%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/NitriteIdAsIdTest.java (83%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/ObjectCursorTest.java (87%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/ObjectRepositoryNegativeTest.java (83%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/ObjectRepositoryTest.java (91%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/ProjectionTest.java (82%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryFactoryTest.java (79%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryJoinTest.java (75%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositoryModificationTest.java (91%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/RepositorySearchTest.java (88%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/UnAnnotatedObjectTest.java (69%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/UniversalTextTokenizerTest.java (94%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/ChildClass.java (87%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ClassA.java (80%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ClassB.java (90%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/ClassC.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/Company.java (77%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/DataGenerator.java (52%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ElemMatch.java (92%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/Employee.java (82%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/Note.java (89%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ParentClass.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/PersonEntity.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/ProductScore.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/RepeatableIndexTest.java (84%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/StressRecord.java (90%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/SubEmployee.java (90%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/SuperDuperClass.java (84%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithCircularReference.java (81%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithClassField.java (88%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithCustomConstructor.java (83%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithDateId.java (88%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/WithEmptyStringId.java (87%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithFinalField.java (91%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithNitriteId.java (88%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithNullId.java (88%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2 => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithObjectId.java (87%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithOutGetterSetter.java (88%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/WithOutId.java (89%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/repository/data/WithPrivateConstructor.java (90%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/WithPublicField.java (88%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/repository/data/WithTransientField.java (88%) create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb}/NitriteMapStressTest.java (87%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/rocksdb/NitriteStoreEventTest.java (88%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream}/DocumentCursorTest.java (77%) rename {nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream}/JoinedDocumentStreamTest.java (76%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/transaction/TransactionCollectionTest.java (93%) rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration}/transaction/TransactionRepositoryTest.java (94%) rename nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/{rocksdb => integration}/transaction/TxData.java (89%) delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/AbstractTest.java rename {nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection => nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb}/CollectionFactoryTest.java (88%) delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbWriteCloseReadTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/EntrySetTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/KeySetTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryNegativeTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBMapTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreUtilsTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java create mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/ValueSetTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFactoryTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/NitriteIdAsIdTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryNegativeTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ProjectionTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UnAnnotatedObjectTest.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java delete mode 100644 nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteMapStressTest.java create mode 100644 nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndex.java create mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/BaseSpatialTest.java rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite-spatial/src/test/java/org/dizitart/no2/spatial}/Retry.java (97%) rename nitrite-spatial/src/test/java/org/dizitart/no2/spatial/{test => }/SpatialData.java (85%) create mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexNegativeTest.java create mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexTest.java create mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialViewer.java create mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/TestUtil.java delete mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/Retry.java delete mode 100644 nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java create mode 100644 nitrite/src/main/java/org/dizitart/no2/filters/IndexOnlyFilter.java delete mode 100644 nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java rename nitrite/src/test/java/org/dizitart/no2/integration/{ => collection}/CollectionFieldIndexTest.java (93%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite/src/test/java/org/dizitart/no2/integration}/collection/CollectionIndexNegativeTest.java (66%) rename {nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb => nitrite/src/test/java/org/dizitart/no2/integration}/collection/CollectionIndexTest.java (63%) delete mode 100644 potassium-nitrite/src/main/kotlin/org/dizitart/kno2/package.md diff --git a/nitrite-bom/build.gradle b/nitrite-bom/build.gradle index a2db0e5fc..d3a848cf9 100644 --- a/nitrite-bom/build.gradle +++ b/nitrite-bom/build.gradle @@ -22,7 +22,6 @@ dependencies { api project(":nitrite-mvstore-adapter") api project(":nitrite-rocksdb-adapter") - api project(":nitrite-mapdb-adapter") api "org.slf4j:slf4j-api:1.7.30" api "org.objenesis:objenesis:2.6" @@ -34,7 +33,7 @@ dependencies { api "org.mapdb:mapdb:3.0.8" api "com.h2database:h2-mvstore:1.4.200" api "com.squareup.okhttp3:okhttp:4.9.0" - api "org.rocksdb:rocksdbjni:6.13.3" + api "org.rocksdb:rocksdbjni:6.20.3" api "com.esotericsoftware:kryo:4.0.2" api "org.locationtech.jts:jts-core:1.17.1" api "commons-codec:commons-codec:1.15" diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java index 83f257c24..16b83e0df 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java @@ -147,8 +147,8 @@ public void testCollectionMigrate() { collection.insert(document); } - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "bloodGroup"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "bloodGroup"); db.close(); Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @@ -195,7 +195,7 @@ public void migrate(Instructions instructions) { .addField("address") .addField("vehicles", 1) .renameField("age", "ageGroup") - .createIndex(IndexType.NonUnique, "ageGroup"); + .createIndex(IndexType.NON_UNIQUE, "ageGroup"); } }; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java index 45b9265a2..28f0f15db 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java @@ -28,9 +28,9 @@ */ @Data @Entity(value = "new", indices = { - @Index(value = "familyName", type = IndexType.NonUnique), - @Index(value = "fullName", type = IndexType.NonUnique), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "familyName", type = IndexType.NON_UNIQUE), + @Index(value = "fullName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class NewClass { @Id diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java index 78969818e..32a687c53 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java @@ -28,10 +28,10 @@ */ @Data @Entity(value = "old", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), - @Index(value = "literature.text", type = IndexType.Fulltext), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.text", type = IndexType.FULL_TEXT), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class OldClass { @Id diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java index 448af1fdb..5a60bb6ec 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -117,9 +117,9 @@ public void testFindByEmbeddedField() { @ToString @EqualsAndHashCode @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote:text", type = IndexType.Fulltext) + @Index(value = "joinDate", type = IndexType.NON_UNIQUE), + @Index(value = "address", type = IndexType.FULL_TEXT), + @Index(value = "employeeNote:text", type = IndexType.FULL_TEXT) }) public static class EmployeeForCustomSeparator implements Serializable { @Id diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index 8a43d484f..86ce57e8b 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -344,8 +344,8 @@ public void testIssue217() { @Data @Entity(value = "entity.employee", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), }) private static class EmployeeEntity { private static final Faker faker = new Faker(); diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index e40db2363..26c89c680 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -51,14 +51,14 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); companyRepository.rebuildIndex("dateCreated"); @@ -73,7 +73,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index d01e74ba7..fac81c611 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -181,7 +181,7 @@ public void testUniversalFullTextIndexing() { } @Indices( - @Index(value = "text", type = IndexType.Fulltext) + @Index(value = "text", type = IndexType.FULL_TEXT) ) public static class TextData { public int id; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java index da8bb7db7..5bffe69e8 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -31,8 +31,8 @@ */ @Data @Entity(value = "books", indices = { - @Index(value = "tags", type = IndexType.NonUnique), - @Index(value = "description", type = IndexType.Fulltext), + @Index(value = "tags", type = IndexType.NON_UNIQUE), + @Index(value = "description", type = IndexType.FULL_TEXT), @Index(value = { "price", "publisher" }) }) public class Book { diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 5dfb2a7d3..ed048f2e6 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -33,9 +33,9 @@ */ @ToString @EqualsAndHashCode -@Index(value = "joinDate", type = IndexType.NonUnique) -@Index(value = "address", type = IndexType.Fulltext) -@Index(value = "employeeNote.text", type = IndexType.Fulltext) +@Index(value = "joinDate", type = IndexType.NON_UNIQUE) +@Index(value = "address", type = IndexType.FULL_TEXT) +@Index(value = "employeeNote.text", type = IndexType.FULL_TEXT) public class Employee implements Serializable { @Id @Getter diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index c70046406..cc871a260 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -31,8 +31,8 @@ */ @Data @Entity(value = "MyPerson", indices = { - @Index(value = "name", type = IndexType.Fulltext), - @Index(value = "status", type = IndexType.NonUnique) + @Index(value = "name", type = IndexType.FULL_TEXT), + @Index(value = "status", type = IndexType.NON_UNIQUE) }) public class PersonEntity { @Id diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index 2edc387fb..a56a63b56 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -26,8 +26,8 @@ */ @Data @Index(value = "firstName") -@Index(value = "age", type = IndexType.NonUnique) -@Index(value = "lastName", type = IndexType.Fulltext) +@Index(value = "age", type = IndexType.NON_UNIQUE) +@Index(value = "lastName", type = IndexType.FULL_TEXT) public class RepeatableIndexTest { private String firstName; private Integer age; diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index 442e00678..d39ddf146 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -27,7 +27,7 @@ */ @Getter @Setter -@Index(value = "text", type = IndexType.Fulltext) +@Index(value = "text", type = IndexType.FULL_TEXT) public class SuperDuperClass { private String text; } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index b6d9142a3..50af4f042 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -237,7 +237,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -262,7 +262,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -570,7 +570,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex(indexOptions(IndexType.NonUnique), "name"); + repository.createIndex(indexOptions(IndexType.NON_UNIQUE), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); diff --git a/nitrite-mapdb-adapter/build.gradle b/nitrite-mapdb-adapter/build.gradle deleted file mode 100644 index 9b80a4f98..000000000 --- a/nitrite-mapdb-adapter/build.gradle +++ /dev/null @@ -1,132 +0,0 @@ -plugins { - id 'java-library' - id 'signing' - id 'maven-publish' - id 'com.github.hauner.jarTest' - id 'jacoco' -} - -jar { - archivesBaseName = 'nitrite-mapdb-adapter' -} - -java { - withJavadocJar() - withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} - -compileJava.options.encoding = 'UTF-8' -compileTestJava.options.encoding = 'UTF-8' -javadoc.options.encoding = 'UTF-8' - -repositories { - mavenCentral() -} - -dependencies { - api platform(project(':nitrite-bom')) - api project(':nitrite') - api "org.slf4j:slf4j-api" - api "org.mapdb:mapdb" - - annotationProcessor "org.projectlombok:lombok:1.18.14" - - testAnnotationProcessor "org.projectlombok:lombok:1.18.12" - testImplementation "uk.co.jemos.podam:podam:7.2.5.RELEASE" - testImplementation "com.github.javafaker:javafaker:1.0.2" - testImplementation "junit:junit:4.13.1" - testImplementation "org.apache.lucene:lucene-core:8.6.3" - testImplementation "org.apache.lucene:lucene-analyzers-common:8.6.3" - testImplementation "org.apache.lucene:lucene-queryparser:8.6.3" - testImplementation "org.apache.logging.log4j:log4j-slf4j-impl:2.13.3" - testImplementation "org.apache.logging.log4j:log4j-core:2.13.3" - testImplementation "org.awaitility:awaitility:4.0.3" - testImplementation "joda-time:joda-time:2.10.6" - testImplementation "org.meanbean:meanbean:2.0.3" - testImplementation "com.fasterxml.jackson.core:jackson-databind:2.11.3" - testImplementation "commons-io:commons-io:2.8.0" -} - -test { - testLogging.showStandardStreams = false - testLogging.exceptionFormat = 'full' -} - -jacocoTestReport { - reports { - xml.enabled true - xml.destination file("${buildDir}/reports/jacoco/report.xml") - csv.enabled false - html.destination file("${buildDir}/reports/coverage") - } -} - -check.dependsOn jacocoTestReport - -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = 'nitrite-mapdb-adapter' - from components.java - versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') - } - usage('java-runtime') { - fromResolutionResult() - } - } - pom { - name = 'Nitrite MapDB Storage Engine' - description = 'An in-memory, file-based embedded nosql persistent document store based on mapdb.' - url = 'https://github.com/nitrite/nitrite-java' - licenses { - license { - name = 'The Apache License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - developers { - developer { - id = 'anidotnet' - name = 'Anindya Chatterjee' - email = 'anidotnet@gmail.com' - } - } - scm { - connection = 'scm:git:git@github.com:nitrite/nitrite-java.git' - developerConnection = 'scm:git:git@github.com:nitrite/nitrite-java.git' - url = 'git@github.com:nitrite/nitrite-java.git' - } - } - } - } - repositories { - if (version.endsWith('SNAPSHOT') || project.hasProperty('release')) { - maven { - name = "OSSRH" - def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - credentials { - username System.getenv('MAVEN_USERNAME') - password System.getenv('MAVEN_PASSWORD') - } - - } - } - } -} - -signing { - sign publishing.publications.mavenJava -} - - -javadoc { - if(JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) - } -} \ No newline at end of file diff --git a/nitrite-mapdb-adapter/lombok.config b/nitrite-mapdb-adapter/lombok.config deleted file mode 100644 index 189c0bef9..000000000 --- a/nitrite-mapdb-adapter/lombok.config +++ /dev/null @@ -1,3 +0,0 @@ -# This file is generated by the 'io.freefair.lombok' Gradle plugin -config.stopBubbling = true -lombok.addLombokGeneratedAnnotation = true diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBConfig.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBConfig.java deleted file mode 100644 index 4c698d4c9..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBConfig.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import lombok.experimental.Accessors; -import org.dizitart.no2.store.StoreConfig; -import org.dizitart.no2.store.events.StoreEventListener; -import org.mapdb.serializer.GroupSerializer; -import org.mapdb.volume.Volume; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * @author Anindya Chatterjee - */ -@Accessors(fluent = true) -public class MapDBConfig implements StoreConfig { - @Getter - @Setter(AccessLevel.PACKAGE) - private Set eventListeners; - - @Getter @Setter(AccessLevel.PACKAGE) - private String filePath = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private MapDBStoreType storeType = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Volume volume = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean volumeExists = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Long allocateStartSize = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Long allocateIncrement = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean fileDeleteAfterClose = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean fileDeleteAfterOpen = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean isThreadSafe = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Integer concurrencyScale = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean cleanerHack = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean fileMmapPreclearDisable = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Long fileLockWait = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean fileMmapfIfSupported = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean closeOnJvmShutdown = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean closeOnJvmShutdownWeakReference = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean isReadOnly = false; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean checksumStoreEnable = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Boolean checksumHeaderBypass = null; - - @Getter @Setter(AccessLevel.PACKAGE) - private Map, GroupSerializer> serializerRegistry = null; - - MapDBConfig() { - eventListeners = new HashSet<>(); - } - - @Override - public void addStoreEventListener(StoreEventListener listener) { - eventListeners.add(listener); - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java deleted file mode 100644 index e3701f925..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBMap.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.DBNull; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; -import org.mapdb.BTreeMap; -import org.mapdb.DBException; - -import java.util.Iterator; -import java.util.Map; -import java.util.NavigableMap; - -import static org.dizitart.no2.common.util.ValidationUtils.notNull; - -/** - * @author Anindya Chatterjee - */ -@Slf4j -public class MapDBMap implements NitriteMap { - @Getter(AccessLevel.PACKAGE) - private final BTreeMap bTreeMap; - - @Getter(AccessLevel.PACKAGE) - private final BTreeMap nullEntryMap; - - private final NitriteStore nitriteStore; - private final String mapName; - - - public MapDBMap(String mapName, BTreeMap bTreeMap, - BTreeMap nullEntryMap, NitriteStore nitriteStore) { - this.bTreeMap = bTreeMap; - this.mapName = mapName; - this.nitriteStore = nitriteStore; - this.nullEntryMap = nullEntryMap; - } - - @Override - public boolean containsKey(K k) { - if (k == null) { - return nullEntryMap.containsKey(DBNull.getInstance()); - } - return bTreeMap.containsKey(k); - } - - @Override - public V get(K k) { - if (k == null) { - return nullEntryMap.get(DBNull.getInstance()); - } - - Map.Entry firstEntry = bTreeMap.firstEntry(); - if (firstEntry != null) { - K firstKey = firstEntry.getKey(); - if (firstKey.getClass().equals(k.getClass())) { - return bTreeMap.get(k); - } - } - return null; - } - - @Override - public NitriteStore getStore() { - return nitriteStore; - } - - @Override - public void clear() { - bTreeMap.clear(); - nullEntryMap.clear(); - updateLastModifiedTime(); - } - - @Override - public String getName() { - return mapName; - } - - @Override - public RecordStream values() { - return RecordStream.fromCombined(bTreeMap.values(), nullEntryMap.values()); - } - - @Override - public V remove(K k) { - V value; - if (k == null) { - value = nullEntryMap.remove(DBNull.getInstance()); - } else { - value = bTreeMap.remove(k); - } - updateLastModifiedTime(); - return value; - } - - @Override - public RecordStream keys() { - return RecordStream.fromIterable(() -> new Iterator() { - final Iterator keyIterator = bTreeMap.keyIterator(); - final Iterator nullEntryIterator = nullEntryMap.keyIterator(); - - @Override - public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return keyIterator.hasNext(); - } - return true; - } - - @Override - public K next() { - if (nullEntryIterator.hasNext()) { - return null; - } else { - return keyIterator.next(); - } - } - }); - } - - @Override - public void put(K k, V v) { - notNull(v, "value cannot be null"); - try { - if (k == null) { - nullEntryMap.put(DBNull.getInstance(), v); - } else { - bTreeMap.put(k, v); - } - updateLastModifiedTime(); - } catch (DBException e) { - log.error("Error while writing data", e); - throw new NitriteIOException("failed to write data", e); - } - } - - @Override - public long size() { - return bTreeMap.sizeLong() + nullEntryMap.sizeLong(); - } - - @Override - public V putIfAbsent(K k, V v) { - notNull(v, "value cannot be null"); - - V value; - if (k == null) { - value = nullEntryMap.putIfAbsent(DBNull.getInstance(), v); - } else { - value = bTreeMap.putIfAbsent(k, v); - } - updateLastModifiedTime(); - return value; - } - - @Override - public RecordStream> entries() { - return getStream(bTreeMap, nullEntryMap); - } - - @Override - public RecordStream> reversedEntries() { - return getStream(bTreeMap.descendingMap(), nullEntryMap.descendingMap()); - } - - @Override - public K higherKey(K k) { - if (k == null) { - return null; - } - return bTreeMap.higherKey(k); - } - - @Override - public K ceilingKey(K k) { - if (k == null) { - return null; - } - return bTreeMap.ceilingKey(k); - } - - @Override - public K lowerKey(K k) { - if (k == null) { - return null; - } - return bTreeMap.lowerKey(k); - } - - @Override - public K floorKey(K k) { - if (k == null) { - return null; - } - return bTreeMap.floorKey(k); - } - - @Override - public boolean isEmpty() { - return bTreeMap.isEmpty() && nullEntryMap.isEmpty(); - } - - @Override - public void drop() { - nitriteStore.removeMap(getName()); - } - - @Override - public void close() { - bTreeMap.close(); - nullEntryMap.close(); - } - - private RecordStream> getStream(NavigableMap primaryMap, - NavigableMap nullEntryMap) { - return RecordStream.fromIterable(() -> new Iterator>() { - private final Iterator> entryIterator = - primaryMap.entrySet().iterator(); - private final Iterator> nullEntryIterator = - nullEntryMap.entrySet().iterator(); - - @Override - public boolean hasNext() { - boolean result = nullEntryIterator.hasNext(); - if (!result) { - return entryIterator.hasNext(); - } - return true; - } - - @Override - public Pair next() { - if (nullEntryIterator.hasNext()) { - Map.Entry entry = nullEntryIterator.next(); - return new Pair<>(null, entry.getValue()); - } else { - Map.Entry entry = entryIterator.next(); - return new Pair<>(entry.getKey(), entry.getValue()); - } - } - }); - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java deleted file mode 100644 index 93c5f10eb..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModule.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.AccessLevel; -import lombok.Setter; -import org.dizitart.no2.common.module.NitritePlugin; -import org.dizitart.no2.store.NitriteStore; -import org.dizitart.no2.store.StoreModule; - -import java.util.Set; - -import static org.dizitart.no2.common.util.Iterables.setOf; - -/** - * @author Anindya Chatterjee - */ -public class MapDBModule implements StoreModule { - - @Setter(AccessLevel.PACKAGE) - private MapDBConfig storeConfig; - - public MapDBModule(String path) { - this.storeConfig = new MapDBConfig(); - this.storeConfig.filePath(path); - } - - public static MapDBModuleBuilder withConfig() { - return new MapDBModuleBuilder(); - } - - @Override - public NitriteStore getStore() { - MapDBStore store = new MapDBStore(); - store.setStoreConfig(storeConfig); - return store; - } - - @Override - public Set plugins() { - return setOf(getStore()); - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModuleBuilder.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModuleBuilder.java deleted file mode 100644 index ba4e2ead2..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBModuleBuilder.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import lombok.experimental.Accessors; -import org.dizitart.no2.store.events.StoreEventListener; -import org.mapdb.serializer.GroupSerializer; -import org.mapdb.volume.Volume; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * @author Anindya Chatterjee - */ -@Getter -@Setter -@Accessors(fluent = true) -public class MapDBModuleBuilder { - private String filePath; - private MapDBStoreType storeType = null; - private Volume volume = null; - private Boolean volumeExists = null; - private Long allocateStartSize = null; - private Long allocateIncrement = null; - private Boolean fileDeleteAfterClose = null; - private Boolean fileDeleteAfterOpen = null; - private Boolean isThreadSafe = null; - private Integer concurrencyScale = null; - private Boolean cleanerHack = null; - private Boolean fileMmapPreclearDisable = null; - private Long fileLockWait = null; - private Boolean fileMmapfIfSupported = null; - private Boolean closeOnJvmShutdown = null; - private Boolean closeOnJvmShutdownWeakReference = null; - private Boolean readOnly = false; - private Boolean checksumStoreEnable = null; - private Boolean checksumHeaderBypass = null; - - private MapDBConfig dbConfig; - - @Setter(AccessLevel.NONE) - private final Set eventListeners; - - @Setter(AccessLevel.NONE) - private final Map, GroupSerializer> serializerRegistry; - - MapDBModuleBuilder() { - dbConfig = new MapDBConfig(); - eventListeners = new HashSet<>(); - serializerRegistry = new HashMap<>(); - } - - public MapDBModuleBuilder filePath(File file) { - if (file != null) { - this.filePath = file.getPath(); - } - return this; - } - - public MapDBModuleBuilder filePath(String path) { - this.filePath = path; - return this; - } - - public MapDBModuleBuilder addStoreEventListener(StoreEventListener listener) { - eventListeners.add(listener); - return this; - } - - public void registerSerializer(Class type, GroupSerializer serializer) { - serializerRegistry.put(type, serializer); - } - - public MapDBModule build() { - MapDBModule module = new MapDBModule(filePath()); - - dbConfig.filePath(filePath()); - dbConfig.storeType(storeType()); - dbConfig.volume(volume()); - dbConfig.volumeExists(volumeExists()); - dbConfig.allocateStartSize(allocateStartSize()); - dbConfig.allocateIncrement(allocateIncrement()); - dbConfig.fileDeleteAfterClose(fileDeleteAfterClose()); - dbConfig.fileDeleteAfterOpen(fileDeleteAfterOpen()); - dbConfig.isThreadSafe(isThreadSafe()); - dbConfig.concurrencyScale(concurrencyScale()); - dbConfig.cleanerHack(cleanerHack()); - dbConfig.fileMmapPreclearDisable(fileMmapPreclearDisable()); - dbConfig.fileLockWait(fileLockWait()); - dbConfig.fileMmapfIfSupported(fileMmapfIfSupported()); - dbConfig.closeOnJvmShutdown(closeOnJvmShutdown()); - dbConfig.closeOnJvmShutdownWeakReference(closeOnJvmShutdownWeakReference()); - dbConfig.isReadOnly(readOnly()); - dbConfig.checksumStoreEnable(checksumStoreEnable()); - dbConfig.checksumHeaderBypass(checksumHeaderBypass()); - dbConfig.serializerRegistry(serializerRegistry()); - dbConfig.eventListeners(eventListeners()); - - module.setStoreConfig(dbConfig); - return module; - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java deleted file mode 100644 index dd2276c0b..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStore.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.DBNull; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.index.BoundingBox; -import org.dizitart.no2.mapdb.serializers.Serializers; -import org.dizitart.no2.store.AbstractNitriteStore; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteRTree; -import org.dizitart.no2.store.events.StoreEventListener; -import org.dizitart.no2.store.events.StoreEvents; -import org.mapdb.BTreeMap; -import org.mapdb.DB; -import org.mapdb.serializer.GroupSerializer; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Anindya Chatterjee - */ -@Slf4j -public class MapDBStore extends AbstractNitriteStore { - private DB db; - private final Map> nitriteMapRegistry; - - public MapDBStore() { - super(); - nitriteMapRegistry = new ConcurrentHashMap<>(); - } - - @Override - public void openOrCreate() { - this.db = StoreFactory.open(getStoreConfig()); - initEventBus(); - alert(StoreEvents.Opened); - } - - @Override - public boolean isClosed() { - return db == null || db.isClosed(); - } - - @Override - public boolean hasUnsavedChanges() { - return false; - } - - @Override - public boolean isReadOnly() { - return db.getStore().isReadOnly(); - } - - @Override - public void commit() { - db.commit(); - alert(StoreEvents.Commit); - } - - @Override - public void close() throws Exception { - db.close(); - - for (NitriteMap nitriteMap : nitriteMapRegistry.values()) { - nitriteMap.close(); - } - - alert(StoreEvents.Closed); - } - - @Override - public boolean hasMap(String mapName) { - return db.exists(mapName); - } - - @Override - @SuppressWarnings("unchecked") - public NitriteMap openMap(String mapName, Class keyType, Class valueType) { - if (nitriteMapRegistry.containsKey(mapName)) { - return (MapDBMap) nitriteMapRegistry.get(mapName); - } - - GroupSerializer keySerializer = Serializers.findSerializer(keyType); - GroupSerializer valueSerializer = Serializers.findSerializer(valueType); - - DB.TreeMapMaker treeMapMaker = (DB.TreeMapMaker) db.treeMap(mapName) - .counterEnable() - .valuesOutsideNodesEnable(); - - if (keySerializer != null) { - treeMapMaker.keySerializer(keySerializer); - } - - if (valueSerializer != null) { - treeMapMaker.valueSerializer(valueSerializer); - } - - BTreeMap bTreeMap = treeMapMaker.createOrOpen(); - - // mapdb btreemap does not support null key, so all null key entries are maintained in a separate map - DB.TreeMapMaker nullMapMaker = (DB.TreeMapMaker) db - .treeMap(mapName + "null-map") - .counterEnable() - .valuesOutsideNodesEnable(); - - if (valueSerializer != null) { - nullMapMaker.valueSerializer(valueSerializer); - } - - BTreeMap nullMap = nullMapMaker.createOrOpen(); - - MapDBMap mapDBMap = new MapDBMap<>(mapName, bTreeMap, nullMap, this); - nitriteMapRegistry.put(mapName, mapDBMap); - return mapDBMap; - } - - @Override - public void removeMap(String mapName) { - if (nitriteMapRegistry.containsKey(mapName)) { - MapDBMap mapDb = (MapDBMap) nitriteMapRegistry.get(mapName); - BTreeMap bTreeMap = mapDb.getBTreeMap(); - BTreeMap nullEntryMap = mapDb.getNullEntryMap(); - - bTreeMap.clear(); - nullEntryMap.clear(); - - nitriteMapRegistry.remove(mapName); - } - } - - @Override - public NitriteRTree openRTree(String rTreeName, Class keyType, Class valueType) { - throw new InvalidOperationException("rtree not supported on mapdb store"); - } - - @Override - public void removeRTree(String mapName) { - throw new InvalidOperationException("rtree not supported on mapdb store"); - } - - @Override - public String getStoreVersion() { - return "MapDB/" + getMapDbVersion(); - } - - private void initEventBus() { - if (getStoreConfig().eventListeners() != null) { - for (StoreEventListener eventListener : getStoreConfig().eventListeners()) { - eventBus.register(eventListener); - } - } - } - - private static String getMapDbVersion() { - return "3.0.8"; - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStoreType.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStoreType.java deleted file mode 100644 index b6dc86d98..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/MapDBStoreType.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.dizitart.no2.mapdb; - -/** - * @author Anindya Chatterjee - */ -public enum MapDBStoreType { - ByteArray, - DirectBuffer, - MemoryMappedFile, - RandomAccessFile, - FileChannel, -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/StoreFactory.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/StoreFactory.java deleted file mode 100644 index ebd6b5f7d..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/StoreFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.dizitart.no2.mapdb; - -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.util.StringUtils; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapdb.serializers.Serializers; -import org.mapdb.DB; -import org.mapdb.DBMaker; - -import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; - -/** - * @author Anindya Chatterjee - */ -@Slf4j -class StoreFactory { - private StoreFactory() {} - - public static DB open(MapDBConfig dbConfig) { - DBMaker.StoreType storeType; - boolean defaultConfig = true; - - if (dbConfig.storeType() != null) { - defaultConfig = false; - switch (dbConfig.storeType()) { - case DirectBuffer: - storeType = DBMaker.StoreType.directbuffer; - break; - case MemoryMappedFile: - storeType = DBMaker.StoreType.fileMMap; - break; - case RandomAccessFile: - storeType = DBMaker.StoreType.fileRaf; - break; - case FileChannel: - storeType = DBMaker.StoreType.fileChannel; - break; - default: - storeType = DBMaker.StoreType.bytearray; - break; - } - } else { - if (StringUtils.isNullOrEmpty(dbConfig.filePath())) { - // if no file specified, use on bytearray memory db - storeType = DBMaker.StoreType.bytearray; - } else { - storeType = DBMaker.StoreType.fileRaf; - } - } - - DBMaker.Maker maker = new DBMaker.Maker(storeType, dbConfig.volume(), - dbConfig.volumeExists(), dbConfig.filePath()); - - if (dbConfig.allocateStartSize() != null) { - defaultConfig = false; - maker.allocateStartSize(dbConfig.allocateStartSize()); - } - - if (dbConfig.allocateIncrement() != null) { - defaultConfig = false; - maker.allocateIncrement(dbConfig.allocateIncrement()); - } - - if (dbConfig.fileDeleteAfterClose() != null && dbConfig.fileDeleteAfterClose()) { - maker.fileDeleteAfterClose(); - } - - if (dbConfig.fileDeleteAfterOpen() != null && dbConfig.fileDeleteAfterOpen()) { - maker.fileDeleteAfterOpen(); - } - - if (dbConfig.isThreadSafe() != null && !dbConfig.isThreadSafe()) { - defaultConfig = false; - maker.concurrencyDisable(); - } - - if (dbConfig.concurrencyScale() != null) { - defaultConfig = false; - maker.concurrencyScale(dbConfig.concurrencyScale()); - } - - if (dbConfig.cleanerHack() != null && dbConfig.cleanerHack()) { - defaultConfig = false; - maker.cleanerHackEnable(); - } - - if (dbConfig.fileMmapPreclearDisable() != null && dbConfig.fileMmapPreclearDisable()) { - defaultConfig = false; - maker.fileMmapPreclearDisable(); - } - - if (dbConfig.fileLockWait() != null) { - defaultConfig = false; - maker.fileLockWait(dbConfig.fileLockWait()); - } - - if (dbConfig.fileMmapfIfSupported() != null && dbConfig.fileMmapfIfSupported()) { - defaultConfig = false; - maker.fileMmapEnableIfSupported(); - } - - if (dbConfig.closeOnJvmShutdown() != null && dbConfig.closeOnJvmShutdown()) { - maker.closeOnJvmShutdown(); - } - - if (dbConfig.closeOnJvmShutdownWeakReference() != null && dbConfig.closeOnJvmShutdownWeakReference()) { - maker.closeOnJvmShutdownWeakReference(); - } - - if (dbConfig.isReadOnly() != null && dbConfig.isReadOnly()) { - defaultConfig = false; - if (isNullOrEmpty(dbConfig.filePath())) { - throw new InvalidOperationException("unable create readonly in-memory database"); - } - maker.readOnly(); - } - - if (dbConfig.checksumStoreEnable() != null && dbConfig.checksumStoreEnable()) { - maker.checksumStoreEnable(); - } - - if (dbConfig.checksumHeaderBypass() != null && dbConfig.checksumHeaderBypass()) { - maker.checksumHeaderBypass(); - } - - if (!StringUtils.isNullOrEmpty(dbConfig.filePath()) && defaultConfig) { - maker.fileMmapEnableIfSupported() - .fileMmapPreclearDisable() - .cleanerHackEnable(); - } - - if (dbConfig.serializerRegistry() != null) { - dbConfig.serializerRegistry().forEach(Serializers::registerSerializer); - } - - DB db = maker.make(); - db.getStore().fileLoad(); - - return db; - } -} diff --git a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/serializers/Serializers.java b/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/serializers/Serializers.java deleted file mode 100644 index 6a57e4736..000000000 --- a/nitrite-mapdb-adapter/src/main/java/org/dizitart/no2/mapdb/serializers/Serializers.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dizitart.no2.mapdb.serializers; - -import org.mapdb.serializer.GroupSerializer; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author Anindya Chatterjee - */ -public class Serializers { - private static final Map> serializerRegistry; - private Serializers() { - } - - static { - serializerRegistry = new HashMap<>(); - } - - public static void registerSerializer(Class type, GroupSerializer serializer) { - serializerRegistry.put(type.getName(), serializer); - } - - public static GroupSerializer findSerializer(Class type) { - if (serializerRegistry.containsKey(type.getName())) { - return serializerRegistry.get(type.getName()); - } - return null; - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/BaseCollectionTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/BaseCollectionTest.java deleted file mode 100644 index f561e928e..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/BaseCollectionTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.WriteResult; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Collection; -import java.util.Locale; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; - -@Slf4j -@RunWith(value = Parameterized.class) -public abstract class BaseCollectionTest { - @Parameterized.Parameter - public boolean inMemory = false; - @Parameterized.Parameter(value = 1) - public boolean isSecured = false; - - protected Nitrite db; - protected NitriteCollection collection; - protected Document doc1, doc2, doc3; - protected SimpleDateFormat simpleDateFormat; - private final String fileName = getRandomTempDbFile(); - - @Rule - public Retry retry = new Retry(3); - - @Parameterized.Parameters(name = "InMemory = {0}, Protected = {1}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false, false}, - {false, true}, - {true, false}, - {true, true}, - }); - } - - @Before - public void setUp() { - try { - openDb(); - - simpleDateFormat - = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); - - doc1 = createDocument("firstName", "fn1") - .put("lastName", "ln1") - .put("birthDay", simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) - .put("data", new byte[]{1, 2, 3}) - .put("list", Arrays.asList("one", "two", "three")) - .put("body", "a quick brown fox jump over the lazy dog"); - doc2 = createDocument("firstName", "fn2") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2010-06-12T16:02:48.440Z")) - .put("data", new byte[]{3, 4, 3}) - .put("list", Arrays.asList("three", "four", "three")) - .put("body", "quick hello world from nitrite"); - doc3 = createDocument("firstName", "fn3") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2014-04-17T16:02:48.440Z")) - .put("data", new byte[]{9, 4, 8}) - .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + - "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); - - collection = db.getCollection("test"); - collection.remove(ALL); - } catch (Throwable t) { - log.error("Error while initializing test database", t); - } - } - - @After - public void clear() { - try { - if (collection != null && !collection.isDropped()) { - collection.close(); - } - if (db != null && !db.isClosed()) db.close(); - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } - } catch (Throwable t) { - log.error("Error while clearing test database", t); - } - } - - private void openDb() { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - - if (!inMemory) { - builder.filePath(fileName); - } - - MapDBModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - if (isSecured) { - db = nitriteBuilder.openOrCreate("test-user", "test-password"); - } else { - db = nitriteBuilder.openOrCreate(); - } - } - - protected WriteResult insert() { - return collection.insert(doc1, doc2, doc3); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CollectionFieldIndexTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CollectionFieldIndexTest.java deleted file mode 100644 index e558319bd..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CollectionFieldIndexTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.index.IndexType; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee - */ -public class CollectionFieldIndexTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = createDb(); - } - - @Test - public void testCollection() { - Document doc1 = Document.createDocument("name", "Anindya") - .put("color", new String[]{"red", "green", "blue"}) - .put("books", new Document[]{ - Document.createDocument("name", "Book ABCD") - .put("tag", new String[]{"tag1", "tag2"}), - Document.createDocument("name", "Book EFGH") - .put("tag", new String[]{"tag3", "tag1"}), - Document.createDocument("name", "No Tag") - }); - - Document doc2 = Document.createDocument("name", "Bill") - .put("color", new String[]{"purple", "yellow", "gray"}) - .put("books", new Document[]{ - Document.createDocument("name", "Book abcd") - .put("tag", new String[]{"tag4", "tag5"}), - Document.createDocument("name", "Book wxyz") - .put("tag", new String[]{"tag3", "tag1"}), - Document.createDocument("name", "No Tag 2") - }); - - Document doc3 = Document.createDocument("name", "John") - .put("color", new String[]{"black", "sky", "violet"}) - .put("books", new Document[]{ - Document.createDocument("name", "Book Mnop") - .put("tag", new String[]{"tag6", "tag2"}), - Document.createDocument("name", "Book ghij") - .put("tag", new String[]{"tag3", "tag7"}), - Document.createDocument("name", "No Tag") - }); - - NitriteCollection collection = db.getCollection("test"); - collection.createIndex("color", indexOptions(IndexType.Unique)); - collection.createIndex("books.tag", indexOptions(IndexType.NonUnique)); - collection.createIndex("books.name", indexOptions(IndexType.Fulltext)); - - WriteResult writeResult = collection.insert(doc1, doc2, doc3); - assertEquals(writeResult.getAffectedCount(), 3); - - DocumentCursor documents = collection.find(where("color").eq("red")); - assertTrue(isSimilar(documents.firstOrNull(), doc1, "name", "color", "books")); - - documents = collection.find(where("books.name").text("abcd")); - assertEquals(documents.size(), 2); - - documents = collection.find(where("books.tag").eq("tag2")); - assertEquals(documents.size(), 2); - - documents = collection.find(where("books.tag").eq("tag5")); - assertEquals(documents.size(), 1); - - documents = collection.find(where("books.tag").eq("tag10")); - assertEquals(documents.size(), 0); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CustomFilterTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CustomFilterTest.java deleted file mode 100644 index ae96f5e74..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/CustomFilterTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class CustomFilterTest extends BaseCollectionTest { - - @Test - public void testCustomFilter() { - insert(); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); - DocumentCursor cursor = collection.find(element -> element.getSecond().get("firstName", String.class) - .equalsIgnoreCase("FN1")); - - assertEquals(cursor.size(), 1); - assertEquals(cursor.firstOrNull().get("firstName"), "fn1"); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbWriteCloseReadTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbWriteCloseReadTest.java deleted file mode 100644 index b8a11d845..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbWriteCloseReadTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import java.text.ParseException; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Anindya Chatterjee. - */ -public class DbWriteCloseReadTest { - private final DbTestOperations operations = new DbTestOperations(); - private volatile boolean writeCompleted = false; - -// @Rule -// public Retry retry = new Retry(3); - - @Test - public void testWriteCloseRead() throws Exception { - try { - operations.createDb(); - operations.writeCollection(); - operations.writeIndex(); - operations.insertInCollection(); - } catch (ParseException pe) { - // ignore - } finally { - writeCompleted = true; - } - - try { - assertTrue(writeCompleted); - operations.readCollection(); - } catch (Exception e) { - fail("collection read failed - " + e.getMessage()); - } finally { - operations.deleteDb(); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBConfigTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBConfigTest.java deleted file mode 100644 index 24791976a..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBConfigTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; - -public class MapDBConfigTest { - @Test - public void testConstructor() { - MapDBConfig actualMapDBConfig = new MapDBConfig(); - assertNull(actualMapDBConfig.isThreadSafe()); - assertNull(actualMapDBConfig.volume()); - assertFalse(actualMapDBConfig.isReadOnly()); - } -} - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleBuilderTest.java deleted file mode 100644 index 8d7da0824..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleBuilderTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; - -public class MapDBModuleBuilderTest { - @Test - public void testConstructor() { - MapDBModuleBuilder actualMapDBModuleBuilder = new MapDBModuleBuilder(); - assertNull(actualMapDBModuleBuilder.isThreadSafe()); - assertNull(actualMapDBModuleBuilder.volume()); - assertFalse(actualMapDBModuleBuilder.readOnly()); - } -} - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleTest.java deleted file mode 100644 index 6f39214d9..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBModuleTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.*; - -public class MapDBModuleTest { - @Test - public void testWithConfig() { - MapDBModuleBuilder actualWithConfigResult = MapDBModule.withConfig(); - assertNull(actualWithConfigResult.isThreadSafe()); - assertNull(actualWithConfigResult.volume()); - assertFalse(actualWithConfigResult.readOnly()); - } - - @Test - public void testGetStore() { - assertTrue((new MapDBModule("path")).getStore() instanceof MapDBStore); - } - - @Test - public void testPlugins() { - assertEquals(1, (new MapDBModule("path")).plugins().size()); - } -} - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTest.java deleted file mode 100644 index 5e9be9643..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.*; - -public class MapDBStoreTest { - @Test - public void testConstructor() { - MapDBStore actualMapDBStore = new MapDBStore(); - assertNull(actualMapDBStore.getStoreConfig()); - assertEquals("MapDB/3.0.8", actualMapDBStore.getStoreVersion()); - assertFalse(actualMapDBStore.hasUnsavedChanges()); - assertTrue(actualMapDBStore.isClosed()); - } - - @Test - public void testIsClosed() { - assertTrue((new MapDBStore()).isClosed()); - } - - @Test - public void testHasUnsavedChanges() { - assertFalse((new MapDBStore()).hasUnsavedChanges()); - } - - @Test - public void testGetStoreVersion() { - assertEquals("MapDB/3.0.8", (new MapDBStore()).getStoreVersion()); - } -} - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTypeTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTypeTest.java deleted file mode 100644 index a3e6ec7fb..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MapDBStoreTypeTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.dizitart.no2.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class MapDBStoreTypeTest { - @Test - public void testValueOf() { - assertEquals(MapDBStoreType.ByteArray, MapDBStoreType.valueOf("ByteArray")); - } - - @Test - public void testValues() { - assertEquals(5, MapDBStoreType.values().length); - } -} - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderNegativeTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderNegativeTest.java deleted file mode 100644 index 92ac2bfcf..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderNegativeTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import org.apache.commons.io.FileUtils; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.common.util.StringUtils; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; - -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteBuilderNegativeTest { - private Nitrite db; - private String filePath; - - @Rule - public Retry retry = new Retry(3); - - @Test(expected = NitriteIOException.class) - public void testCreateReadonlyDatabase() { - filePath = getRandomTempDbFile(); - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(filePath) - .readOnly(true) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .openOrCreate(); - db.close(); - } - - @Test(expected = InvalidOperationException.class) - public void testCreateReadonlyInMemoryDatabase() { - MapDBModule storeModule = MapDBModule.withConfig() - .readOnly(true) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .openOrCreate(); - db.close(); - } - - @Test(expected = NitriteIOException.class) - public void testOpenWithLock() { - filePath = getRandomTempDbFile(); - - db = createDb(filePath); - db = createDb(filePath); - } - - @Test(expected = NitriteIOException.class) - public void testInvalidDirectory() { - filePath = "/ytgr/hfurh/frij.db"; - db = createDb(filePath); - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - - if (!StringUtils.isNullOrEmpty(filePath)) { - FileUtils.deleteQuietly(new File(filePath)); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java deleted file mode 100644 index 4b0123c1b..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteBuilderTest.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.FindPlan; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.FieldValues; -import org.dizitart.no2.common.Fields; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.NitriteSecurityException; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.store.StoreConfig; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.LinkedHashSet; -import java.util.Random; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.dizitart.no2.common.module.NitriteModule.module; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteBuilderTest { - private String fakeFile; - private String filePath; - private Nitrite db; - private Nitrite fakeDb; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void startup() { - fakeFile = getRandomTempDbFile(); - filePath = getRandomTempDbFile(); - } - - @After - public void cleanup() throws IOException { - (new NitriteConfig()).fieldSeparator("."); - - if (db != null && !db.isClosed()) { - db.close(); - } - - if (Files.exists(Paths.get(filePath))) { - Files.delete(Paths.get(filePath)); - } - - if (fakeDb != null && !fakeDb.isClosed()){ - fakeDb.close(); - } - - if (Files.exists(Paths.get(fakeFile))) { - Files.delete(Paths.get(fakeFile)); - } - } - - @Test - public void testConfig() throws IOException { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - builder.filePath(filePath); - - NitriteBuilder nitriteBuilder = Nitrite.builder(); - nitriteBuilder.loadModule(module(new CustomIndexer())); - nitriteBuilder.loadModule(builder.build()); - - db = nitriteBuilder.openOrCreate(); - NitriteConfig config = nitriteBuilder.getNitriteConfig(); - MapDBConfig storeConfig = (MapDBConfig) db.getStore().getStoreConfig(); - - assertEquals(config.findIndexer("Custom").getClass(), CustomIndexer.class); - assertFalse(storeConfig.isReadOnly()); - assertFalse(storeConfig.isInMemory()); - assertFalse(isNullOrEmpty(storeConfig.filePath())); - - db.close(); - - builder = MapDBModule.withConfig() - .readOnly(true) - .filePath(filePath); - - db = Nitrite.builder().loadModule(builder.build()).openOrCreate(); - - storeConfig = (MapDBConfig) db.getStore().getStoreConfig(); - assertTrue(storeConfig.isReadOnly()); - db.close(); - - Files.delete(Paths.get(filePath)); - } - - @Test - public void testConfigWithFile() { - File file = new File(filePath); - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(file) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .openOrCreate(); - StoreConfig storeConfig = db.getStore().getStoreConfig(); - - assertFalse(storeConfig.isInMemory()); - assertFalse(isNullOrEmpty(storeConfig.filePath())); - - NitriteCollection test = db.getCollection("test"); - assertNotNull(test); - - db.commit(); - db.close(); - - assertTrue(file.delete()); - } - - @Test - public void testConfigWithFileNull() { - File file = null; - MapDBModule module = MapDBModule.withConfig() - .filePath(file) - .build(); - - db = Nitrite.builder().loadModule(module).openOrCreate(); - StoreConfig storeConfig = db.getStore().getStoreConfig(); - - assertTrue(storeConfig.isInMemory()); - assertTrue(isNullOrEmpty(storeConfig.filePath())); - - NitriteCollection test = db.getCollection("test"); - assertNotNull(test); - - db.commit(); - db.close(); - } - - @Test - public void testPopulateRepositories() { - File file = new File(filePath); - MapDBModule module = MapDBModule.withConfig().filePath(file).build(); - db = Nitrite.builder() - .fieldSeparator(".") - .loadModule(module) - .openOrCreate(); - - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("id1", "value")); - - ObjectRepository repository = db.getRepository(TestObject.class); - repository.insert(new TestObject("test", 1L)); - - ObjectRepository repository2 = db.getRepository(TestObject.class, "key"); - TestObject object = new TestObject(); - object.stringValue = "test2"; - object.longValue = 2L; - repository2.insert(object); - - ObjectRepository repository3 = db.getRepository(TestObject2.class, "key"); - TestObject2 object2 = new TestObject2(); - object2.stringValue = "test2"; - object2.longValue = 2L; - repository3.insert(object2); - - db.commit(); - db.close(); - - db = Nitrite.builder() - .loadModule(module) - .fieldSeparator(".") - .openOrCreate(); - assertTrue(db.hasCollection("test")); - assertTrue(db.hasRepository(TestObject.class)); - assertTrue(db.hasRepository(TestObject.class, "key")); - assertFalse(db.hasRepository(TestObject2.class)); - assertTrue(db.hasRepository(TestObject2.class, "key")); - } - - - @Test - public void testNitriteMapper() { - NitriteBuilder builder = Nitrite.builder(); - builder.loadModule(module(new CustomNitriteMapper())); - NitriteConfig config = builder.getNitriteConfig(); - assertNotNull(config.nitriteMapper()); - } - - @Test(expected = NitriteSecurityException.class) - public void testOpenOrCreateNullUserId() { - NitriteBuilder builder = Nitrite.builder(); - builder.openOrCreate(null, "abcd"); - } - - @Test(expected = NitriteSecurityException.class) - public void testOpenOrCreateNullPassword() { - NitriteBuilder builder = Nitrite.builder(); - builder.openOrCreate("abcd", null); - } - - @Test(expected = NitriteIOException.class) - public void testDbCorruption() throws IOException { - File file = new File(fakeFile); - FileWriter writesToFile; - // Create file writer object - writesToFile = new FileWriter(file); - // Wrap the writer with buffered streams - BufferedWriter writer = new BufferedWriter(writesToFile); - int line; - Random rand = new Random(); - for (int j = 0; j < 10; j++) { - // Randomize an integer and write it to the output file - line = rand.nextInt(50000); - writer.write(line + "\n"); - } - // Close the stream - writer.close(); - - fakeDb = createDb(fakeFile); - assertNull(fakeDb); - } - - @Test(expected = InvalidOperationException.class) - public void testDbInMemoryReadonly() { - MapDBModule module = MapDBModule.withConfig() - .readOnly(true) - .build(); - - fakeDb = Nitrite.builder() - .loadModule(module) - .openOrCreate(); - assertNull(fakeDb); - } - - @Test(expected = NitriteIOException.class) - public void testDbInvalidDirectory() { - fakeFile = System.getProperty("java.io.tmpdir") + File.separator + "fake" + File.separator + "fake.db"; - db = createDb(fakeFile, "test", "test"); - assertNull(db); - } - - @Test - public void testFieldSeparator() { - MapDBModule module = MapDBModule.withConfig() - .filePath(filePath) - .build(); - db = Nitrite.builder() - .loadModule(module) - .fieldSeparator("::") - .openOrCreate(); - - Document document = createDocument("firstName", "John") - .put("colorCodes", new Document[]{createDocument("color", "Red"), createDocument("color", "Green")}) - .put("address", createDocument("street", "ABCD Road")); - - String street = document.get("address::street", String.class); - assertEquals("ABCD Road", street); - - // use default separator, it should return null - street = document.get("address.street", String.class); - assertNull(street); - - assertEquals(document.get("colorCodes::1::color"), "Green"); - } - - @Test(expected = NitriteIOException.class) - public void testInvalidPath() { - MapDBModule module = MapDBModule.withConfig() - .filePath("http://www.localhost.com") - .build(); - - db = Nitrite.builder() - .loadModule(module) - .openOrCreate("test", "test"); - assertNull(db); - } - - private static class CustomIndexer implements NitriteIndexer { - - @Override - public String getIndexType() { - return "Custom"; - } - - @Override - public void validateIndex(Fields fields) { - - } - - @Override - public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - - } - - @Override - public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - - } - - @Override - public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { - - } - - @Override - public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { - return null; - } - - - @Override - public void initialize(NitriteConfig nitriteConfig) { - - } - } - - public static class CustomNitriteMapper implements NitriteMapper { - - @Override - public Target convert(Source source, Class type) { - return null; - } - - @Override - public boolean isValueType(Class type) { - return false; - } - - @Override - public boolean isValue(Object object) { - return false; - } - - @Override - public void initialize(NitriteConfig nitriteConfig) { - - } - } - - @Index(value = "longValue") - private static class TestObject implements Mappable { - private String stringValue; - private Long longValue; - - public TestObject() { - } - - public TestObject(String stringValue, Long longValue) { - this.longValue = longValue; - this.stringValue = stringValue; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - this.stringValue = document.get("stringValue", String.class); - this.longValue = document.get("longValue", Long.class); - } - } - } - - @Index(value = "longValue") - private static class TestObject2 implements Mappable { - private String stringValue; - private Long longValue; - - public TestObject2() { - } - - public TestObject2(String stringValue, Long longValue) { - this.longValue = longValue; - this.stringValue = stringValue; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - this.stringValue = document.get("stringValue", String.class); - this.longValue = document.get("longValue", Long.class); - } - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java deleted file mode 100644 index 8ea0f3ade..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStressTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import lombok.Data; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Id; -import org.junit.Rule; -import org.junit.Test; -import uk.co.jemos.podam.api.PodamFactory; -import uk.co.jemos.podam.api.PodamFactoryImpl; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlSchemaType; -import java.util.ArrayList; -import java.util.List; - -import static org.dizitart.no2.mapdb.TestUtil.createDb; - - -/** - * @author Anindya Chatterjee - */ -public class NitriteStressTest { - private static final int TEST_SET_COUNT = 15000; - private final PodamFactory podamFactory = new PodamFactoryImpl(); - - @Rule - public Retry retry = new Retry(3); - - @Test - public void stressTest() { - Nitrite database = createDb(); - ObjectRepository testRepository = database.getRepository(TestDto.class); - testRepository.createIndex("lastName", IndexOptions.indexOptions(IndexType.Fulltext)); - testRepository.createIndex("birthDate", IndexOptions.indexOptions(IndexType.NonUnique)); - - int counter = 0; - try { - for (TestDto testDto : createTestSet()) { - testRepository.insert(testDto); - counter++; - } - } catch (Throwable t) { - System.err.println("Crashed after " + counter + " records"); - throw t; - } - } - - private List createTestSet() { - List testData = new ArrayList<>(); - for (int i = 0; i < TEST_SET_COUNT; i++) { - TestDto testRecords = podamFactory.manufacturePojo(TestDto.class); - testData.add(testRecords); - } - return testData; - } - - @Data - public static class TestDto implements Mappable { - - @XmlElement( - name = "StudentNumber", - required = true - ) - @Id - protected String studentNumber; - - @XmlElement( - name = "LastName", - required = true - ) - protected String lastName; - - @XmlElement( - name = "Prefixes" - ) - protected String prefixes; - - @XmlElement( - name = "Initials", - required = true - ) - protected String initials; - - @XmlElement( - name = "FirstNames" - ) - protected String firstNames; - @XmlElement( - name = "Nickname" - ) - protected String nickName; - - @XmlElement( - name = "BirthDate", - required = true - ) - @XmlSchemaType( - name = "date" - ) - protected String birthDate; - - - public TestDto() { - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("studentNumber", studentNumber) - .put("lastName", lastName) - .put("prefixes", prefixes) - .put("initials", initials) - .put("firstNames", firstNames) - .put("nickName", nickName) - .put("birthDate", birthDate); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - studentNumber = document.get("studentNumber", String.class); - lastName = document.get("lastName", String.class); - prefixes = document.get("prefixes", String.class); - initials = document.get("initials", String.class); - firstNames = document.get("firstNames", String.class); - nickName = document.get("nickName", String.class); - birthDate = document.get("birthDate", String.class); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/SerializabilityTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/SerializabilityTest.java deleted file mode 100644 index 513ffebe7..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/SerializabilityTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import lombok.Data; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.ValidationException; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; -import java.io.Serializable; - -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee - */ -public class SerializabilityTest { - private NitriteCollection collection; - private File dbFile; - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - dbFile = new File(getRandomTempDbFile()); - db = createDb(dbFile.getPath()); - collection = db.getCollection("test"); - } - - @After - public void tearDown() { - if (db != null && !db.isClosed()) { - db.close(); - } - - if (dbFile.exists()) { - boolean delete = dbFile.delete(); - assertTrue(delete); - } - } - - @Test(expected = ValidationException.class) - public void testSerializabilityValidation() { - for (int i = 0; i < 5; i++) { - Document doc = Document.createDocument(); - doc.put("key", i); - doc.put("data", new NotSerializableClass(Integer.toString(i))); - collection.insert(doc); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Write " + i + " completed"); - } - } - - @Test - public void testSerializablity() { - for (int i = 0; i < 5; i++) { - Document doc = Document.createDocument(); - doc.put("key", i); - doc.put("data", new SerializableClass(Integer.toString(i))); - collection.insert(doc); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Write " + i + " completed"); - } - } - - @Data - public static class NotSerializableClass { - private String myId; - - public NotSerializableClass(String myId) { - this.myId = myId; - } - } - - @Data - public static class SerializableClass implements Serializable { - private String myId; - - public SerializableClass(String myId) { - this.myId = myId; - } - } -} - - diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/TestUtil.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/TestUtil.java deleted file mode 100644 index ec8eafc27..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/TestUtil.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2019-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb; - -import com.fasterxml.jackson.databind.JsonNode; -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; - -import java.io.IOException; -import java.util.*; - -/** - * @author Anindya Chatterjee - */ -@Slf4j -public class TestUtil { - - /** - * Determines whether the supplied `iterable` is sorted. - * - * @param the type parameter - * @param iterable the iterable - * @param ascending a boolean value indicating whether to sort in ascending order - * @return the boolean value indicating if `iterable` is sorted or not. - */ - public static > boolean isSorted(Iterable iterable, boolean ascending) { - Iterator iterator = iterable.iterator(); - if (!iterator.hasNext()) { - return true; - } - T t = iterator.next(); - while (iterator.hasNext()) { - T t2 = iterator.next(); - if (ascending) { - if (t.compareTo(t2) > 0) { - return false; - } - } else { - if (t.compareTo(t2) < 0) { - return false; - } - } - t = t2; - } - return true; - } - - public static Nitrite createDb() { - MapDBModule storeModule = MapDBModule.withConfig() - .build(); - - return Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - } - - public static Nitrite createDb(String user, String password) { - MapDBModule storeModule = MapDBModule.withConfig() - .build(); - - return Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(user, password); - } - - public static Nitrite createDb(String filePath) { - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(filePath) - .build(); - - return Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - } - - public static Nitrite createDb(String filePath, String user, String password) { - return Nitrite.builder() - .loadModule(new MapDBModule(filePath)) - .fieldSeparator(".") - .openOrCreate(user, password); - } - - private static Document loadDocument(JsonNode node) { - Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); - String name = entry.getKey(); - JsonNode value = entry.getValue(); - Object object = loadObject(value); - objectMap.put(name, object); - } - - return Document.createDocument(objectMap); - } - - private static Object loadObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return loadArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return loadDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { - return null; - } - return null; - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static List loadArray(JsonNode array) { - if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(loadObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; - } - return null; - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java deleted file mode 100644 index 465db3503..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindTest.java +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.collection; - -import com.google.common.collect.Lists; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; -import org.joda.time.DateTime; -import org.junit.Test; - -import java.text.Collator; -import java.text.ParseException; -import java.util.*; -import java.util.stream.Collectors; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.Constants.*; -import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.$; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.TestUtil.isSorted; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -public class CollectionFindTest extends BaseCollectionTest { - - private static Document trimMeta(Document document) { - document.remove(DOC_ID); - document.remove(DOC_REVISION); - document.remove(DOC_MODIFIED); - document.remove(DOC_SOURCE); - return document; - } - - @Test - public void testFindAll() { - insert(); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - } - - @Test - public void testFindWithFilter() throws ParseException { - insert(); - - DocumentCursor cursor = collection.find(where("birthDay").gt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").gte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lte( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").lt( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").gt( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").gte( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .and(where("firstName").eq("fn1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12"))); - assertEquals(cursor.size(), 3); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); - assertEquals(cursor.size(), 2); - - - cursor = collection.find(where("data.1").eq((byte) 4)); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").lt(4)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("lastName").in("ln1", "ln2", "ln10")); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("firstName").notIn("fn1", "fn2")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(ALL.not()); - assertEquals(cursor.size(), 0); - } - - @Test - public void testFindWithSkipLimit() { - insert(); - - DocumentCursor cursor = collection.find().skipLimit(0, 1); - assertEquals(cursor.size(), 1); - - cursor = collection.find().skipLimit(1, 3); - assertEquals(cursor.size(), 2); - - cursor = collection.find().skipLimit(0, 30); - assertEquals(cursor.size(), 3); - - cursor = collection.find().skipLimit(2, 3); - assertEquals(cursor.size(), 1); - } - - @Test - public void testFindWithSkip() { - insert(); - - DocumentCursor cursor = collection.find().skip(0); - assertEquals(cursor.size(), 3); - - cursor = collection.find().skip(1); - assertEquals(cursor.size(), 2); - - cursor = collection.find().skip(30); - assertEquals(cursor.size(), 0); - - cursor = collection.find().skip(2); - assertEquals(cursor.size(), 1); - - boolean invalid = false; - try { - cursor = collection.find().skip(-1); - assertEquals(cursor.size(), 1); - } catch (ValidationException e) { - invalid = true; - } - assertTrue(invalid); - } - - @Test - public void testFindWithLimit() { - insert(); - - DocumentCursor cursor = collection.find().limit(0); - assertEquals(cursor.size(), 0); - - cursor = collection.find().limit(1); - assertEquals(cursor.size(), 1); - - boolean invalid = false; - try { - cursor = collection.find().limit(-1); - assertEquals(cursor.size(), 1); - } catch (ValidationException e) { - invalid = true; - } - assertTrue(invalid); - - cursor = collection.find().limit(30); - assertEquals(cursor.size(), 3); - } - - @Test - public void testFindSortAscending() { - insert(); - - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); - assertEquals(cursor.size(), 3); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, true)); - } - - @Test - public void testFindSortDescending() { - insert(); - - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); - assertEquals(cursor.size(), 3); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, false)); - } - - @Test - public void testFindLimitAndSort() { - insert(); - - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, false)); - - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, true)); - - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); - assertEquals(cursor.size(), 3); - List nameList = new ArrayList<>(); - for (Document document : cursor) { - nameList.add(document.get("firstName", String.class)); - } - assertTrue(isSorted(nameList, true)); - } - - @Test - public void testFindSortOnNonExistingField() { - insert(); - DocumentCursor cursor = collection.find().sort("my-value", SortOrder.Descending); - assertEquals(cursor.size(), 3); - } - - @Test - public void testFindInvalidField() { - insert(); - DocumentCursor cursor = collection.find(where("myField").eq("myData")); - assertEquals(cursor.size(), 0); - } - - @Test - public void testFindInvalidFieldWithInvalidAccessor() { - insert(); - DocumentCursor cursor = collection.find(where("myField.0").eq("myData")); - assertEquals(cursor.size(), 0); - } - - @Test - public void testFindLimitAndSortInvalidField() { - insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay2", SortOrder.Descending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - } - - @Test - public void testGetById() { - collection.insert(doc1); - NitriteId id = NitriteId.createId("1"); - Document document = collection.getById(id); - assertNull(document); - - document = collection.find().firstOrNull(); - - assertEquals(document.get(DOC_ID), document.getId().getIdValue()); - assertEquals(document.get("firstName"), "fn1"); - assertEquals(document.get("lastName"), "ln1"); - assertArrayEquals((byte[]) document.get("data"), new byte[]{1, 2, 3}); - assertEquals(document.get("body"), "a quick brown fox jump over the lazy dog"); - } - - @Test - public void testFindWithFilterAndOption() { - insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - } - - @Test - public void testFindTextWithRegex() { - insert(); - DocumentCursor cursor = collection.find(where("body").regex("hello")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("body").regex("test")); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("body").regex("^hello$")); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("body").regex(".*")); - assertEquals(cursor.size(), 3); - } - - @Test - public void testProject() { - insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); - int iteration = 0; - for (Document document : cursor) { - switch (iteration) { - case 0: - assertTrue(isSimilar(document, doc1, "firstName", "lastName", "birthDay", "data", "list", "body")); - break; - case 1: - assertTrue(isSimilar(document, doc2, "firstName", "lastName", "birthDay", "data", "list", "body")); - break; - case 2: - assertTrue(isSimilar(document, doc3, "firstName", "lastName", "birthDay", "data", "list", "body")); - break; - } - iteration++; - } - assertEquals(iteration, 3); - } - - @Test - public void testProjectWithCustomDocument() { - insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); - - Document projection = createDocument("firstName", null) - .put("lastName", null); - - Iterable documents = cursor.project(projection); - int iteration = 0; - for (Document document : documents) { - assertTrue(document.containsKey("firstName")); - assertTrue(document.containsKey("lastName")); - - assertFalse(document.containsKey("_id")); - assertFalse(document.containsKey("birthDay")); - assertFalse(document.containsKey("data")); - assertFalse(document.containsKey("body")); - - switch (iteration) { - case 0: - assertEquals(document.get("firstName"), "fn1"); - assertEquals(document.get("lastName"), "ln1"); - break; - case 1: - assertEquals(document.get("firstName"), "fn2"); - assertEquals(document.get("lastName"), "ln2"); - break; - case 2: - assertEquals(document.get("firstName"), "fn3"); - assertEquals(document.get("lastName"), "ln2"); - break; - } - iteration++; - } - assertEquals(iteration, 3); - } - - @Test - public void testFindWithArrayEqual() { - insert(); - DocumentCursor ids = collection.find(where("data").eq(new byte[]{3, 4, 3})); - assertNotNull(ids); - assertEquals(ids.size(), 1); - } - - @Test - public void testFindWithArrayEqualFailForWrongCardinality() { - insert(); - DocumentCursor ids = collection.find(where("data").eq(new byte[]{4, 3, 3})); - assertNotNull(ids); - assertEquals(ids.size(), 0); - } - - @Test - public void testFindWithIterableEqual() { - insert(); - DocumentCursor ids = collection.find(where("list").eq(Lists.newArrayList("three", "four", "three"))); - assertNotNull(ids); - assertEquals(ids.size(), 1); - } - - @Test - public void testFindWithIterableEqualFailForWrongCardinality() { - insert(); - DocumentCursor ids = collection.find(where("list").eq(Lists.newArrayList("four", "three", "three"))); - assertNotNull(ids); - assertEquals(ids.size(), 0); - } - - @Test - public void testFindInArray() { - insert(); - DocumentCursor ids = collection.find(where("data").elemMatch($.gte(2).and($.lt(5)))); - assertNotNull(ids); - assertEquals(ids.size(), 3); - - ids = collection.find(where("data").elemMatch($.gt(2).or($.lte(5)))); - assertNotNull(ids); - assertEquals(ids.size(), 3); - - ids = collection.find(where("data").elemMatch($.gt(1).and($.lt(4)))); - assertNotNull(ids); - assertEquals(ids.size(), 2); - } - - @Test - public void testFindInList() { - insert(); - DocumentCursor ids = collection.find(where("list").elemMatch($.regex("three"))); - assertNotNull(ids); - assertEquals(ids.size(), 2); - - ids = collection.find(where("list").elemMatch($.regex("hello"))); - assertNotNull(ids); - assertEquals(ids.size(), 0); - - ids = collection.find(where("list").elemMatch($.regex("hello").not())); - assertNotNull(ids); - assertEquals(ids.size(), 2); - } - - @Test - public void testElemMatchFilter() { - Document doc1 = createDocument("productScores", new Document[]{ - createDocument("product", "abc").put("score", 10), - createDocument("product", "xyz").put("score", 5) - }).put("strArray", new String[]{"a", "b"}); - - Document doc2 = createDocument("productScores", new Document[]{ - createDocument("product", "abc").put("score", 8), - createDocument("product", "xyz").put("score", 7) - }).put("strArray", new String[]{"d", "e"}); - - Document doc3 = createDocument("productScores", new Document[]{ - createDocument("product", "abc").put("score", 7), - createDocument("product", "xyz").put("score", 8) - }).put("strArray", new String[]{"a", "f"}); - - NitriteCollection prodCollection = db.getCollection("prodScore"); - prodCollection.insert(doc1, doc2, doc3); - - List documentList = prodCollection.find(where("productScores") - .elemMatch(where("product").eq("xyz").and(where("score").gte(8)))).toList(); - - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").lte(8).not())).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("product").eq("xyz").or(where("score").gte(8)))).toList(); - assertEquals(documentList.size(), 3); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("product").eq("xyz"))).toList(); - assertEquals(documentList.size(), 3); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").gte(10))).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").gt(8))).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").lt(7))).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").lte(7))).toList(); - assertEquals(documentList.size(), 3); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").in(7, 8))).toList(); - assertEquals(documentList.size(), 2); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("score").notIn(7, 8))).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("productScores") - .elemMatch(where("product").regex("xyz"))).toList(); - assertEquals(documentList.size(), 3); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.eq("a"))).toList(); - assertEquals(documentList.size(), 2); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.eq("a").or($.eq("f").or($.eq("b"))).not())).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.gt("e"))).toList(); - assertEquals(documentList.size(), 1); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.gte("e"))).toList(); - assertEquals(documentList.size(), 2); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.lte("b"))).toList(); - assertEquals(documentList.size(), 2); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.lt("a"))).toList(); - assertEquals(documentList.size(), 0); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.in("a", "f"))).toList(); - assertEquals(documentList.size(), 2); - - documentList = prodCollection.find(where("strArray") - .elemMatch($.regex("a"))).toList(); - assertEquals(documentList.size(), 2); - - } - - @Test - public void testNotEqualFilter() { - Document document = createDocument("abc", "123"); - document.put("xyz", null); - - collection.insert(document); - DocumentCursor cursor = collection.find(where("abc").eq("123")); - assertEquals(cursor.size(), 1); - assertEquals(cursor.toList().size(), 1); - - cursor = collection.find(where("xyz").eq(null)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("abc").notEq(null)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("abc").notEq(null).and(where("xyz").eq(null))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("abc").eq(null).and(where("xyz").notEq(null))); - assertEquals(cursor.size(), 0); - - collection.remove(ALL); - - document = createDocument("field", "two"); - document.put(DOC_REVISION, 1482225343161L); - - collection.insert(document); - Document projection = collection.find( - where(DOC_REVISION).gte(1482225343160L) - .and(where(DOC_REVISION).lte(1482225343162L) - .and(where(DOC_REVISION).notEq(null)))) - .firstOrNull(); - - assertNull(projection); - } - - @Test - public void testFilterAll() { - DocumentCursor cursor = collection.find(ALL); - assertNotNull(cursor); - assertEquals(cursor.size(), 0); - - insert(); - cursor = collection.find(ALL); - assertNotNull(cursor); - assertEquals(cursor.size(), 3); - } - - @Test - public void testIssue72() { - NitriteCollection coll = db.getCollection("test"); - coll.createIndex("id", IndexOptions.indexOptions(IndexType.Unique)); - coll.createIndex("group", IndexOptions.indexOptions(IndexType.NonUnique)); - - coll.remove(ALL); - - Document doc = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - doc = createDocument().put("id", "test-2").put("group", "groupA").put("startTime", DateTime.now()); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); - assertEquals(2, cursor.size()); - assertNull(cursor.toList().get(1).get("startTime")); - assertNotNull(cursor.toList().get(0).get("startTime")); - - cursor = coll.find(where("group").eq("groupA")).sort("startTime", SortOrder.Ascending); - assertEquals(2, cursor.size()); - assertNull(cursor.toList().get(0).get("startTime")); - assertNotNull(cursor.toList().get(1).get("startTime")); - } - - @Test - public void testIssue93() { - NitriteCollection coll = db.getCollection("orderByOnNullableColumn2"); - - coll.remove(ALL); - - Document doc = createDocument().put("id", "test-2").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - doc = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); - assertEquals(2, cursor.size()); - } - - @Test - public void testNullOrderWithAllNull() { - NitriteCollection coll = db.getCollection("test"); - - coll.remove(ALL); - - Document doc = createDocument().put("id", "test-2").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - doc = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); - assertEquals(2, cursor.size()); - - DocumentCursor cursor2 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); - assertEquals(2, cursor2.size()); - - assertThat(cursor.toList(), is(cursor2.toList())); - - DocumentCursor cursor3 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(2, cursor3.size()); - - assertThat(cursor.toList(), is(cursor3.toList())); - - DocumentCursor cursor4 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(2, cursor4.size()); - - assertThat(cursor.toList(), is(cursor4.toList())); - - DocumentCursor cursor5 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(2, cursor5.size()); - - assertThat(cursor.toList(), is(cursor5.toList())); - - DocumentCursor cursor6 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(2, cursor6.size()); - - assertThat(cursor.toList(), is(cursor6.toList())); - - DocumentCursor cursor7 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); - assertEquals(2, cursor7.size()); - - assertThat(cursor.toList(), is(cursor7.toList())); - } - - @Test - public void testNullOrder() { - NitriteCollection coll = db.getCollection("test"); - try { - coll.createIndex("startTime", IndexOptions.indexOptions(IndexType.NonUnique)); - } catch (IndexingException e) { - // ignore - } - - coll.remove(ALL); - - Document doc1 = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc1).getAffectedCount()); - - Document doc2 = createDocument().put("id", "test-2").put("group", "groupA").put("startTime", DateTime.now()); - assertEquals(1, coll.insert(doc2).getAffectedCount()); - - Document doc3 = createDocument().put("id", "test-3").put("group", "groupA").put("startTime", DateTime.now().plusMinutes(1)); - assertEquals(1, coll.insert(doc3).getAffectedCount()); - - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc3, doc2), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc2, doc3), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc2, doc3), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc2, doc3, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - } - - @Test - public void testFindFilterInvalidAccessor() { - insert(); - DocumentCursor cursor = collection.find(where("lastName.name").eq("ln2")); - assertEquals(cursor.size(), 0); - } - - @Test - public void testIssue144() { - Document doc1 = createDocument().put("id", "test-1").put("fruit", "Apple"); - Document doc2 = createDocument().put("id", "test-2").put("fruit", "Ôrange"); - Document doc3 = createDocument().put("id", "test-3").put("fruit", "Pineapple"); - - NitriteCollection coll = db.getCollection("test"); - coll.insert(doc1, doc2, doc3); - - DocumentCursor cursor = coll.find().sort("fruit", SortOrder.Ascending, - Collator.getInstance(Locale.FRANCE)); - assertEquals(cursor.toList().get(1).get("fruit"), "Ôrange"); - } - - @Test - public void testIdSet() { - insert(); - DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("lastName").eq("ln1")); - assertEquals(cursor.size(), 1); - - Document byId = cursor.iterator().next(); - assertEquals(byId.get("lastName"), "ln1"); - } - - @Test - public void testCollectionField() { - Document document = createDocument("name", "John") - .put("tags", new Document[]{ - createDocument("type", "example").put("other", "value"), - createDocument("type", "another-example").put("other", "some-other-value") - }); - - NitriteCollection example = db.getCollection("example"); - example.insert(document); - - document = createDocument("name", "Jane") - .put("tags", new Document[]{ - createDocument("type", "example2").put("other", "value2"), - createDocument("type", "another-example2").put("other", "some-other-value2") - }); - example.insert(document); - - DocumentCursor cursor = example.find(where("tags").elemMatch(where("type").eq("example"))); - for (Document doc : cursor) { - assertNotNull(doc); - assertEquals(doc.get("name"), "John"); - } - } - - @Test - public void testBetweenFilter() { - Document doc1 = createDocument("age", 31).put("tag", "one"); - Document doc2 = createDocument("age", 32).put("tag", "two"); - Document doc3 = createDocument("age", 33).put("tag", "three"); - Document doc4 = createDocument("age", 34).put("tag", "four"); - Document doc5 = createDocument("age", 35).put("tag", "five"); - - NitriteCollection collection = db.getCollection("tag"); - collection.insert(doc1, doc2, doc3, doc4, doc5); - collection.createIndex("age", IndexOptions.indexOptions(IndexType.Unique)); - - DocumentCursor cursor = collection.find(where("age").between(31, 35)); - assertEquals(cursor.size(), 5); - - cursor = collection.find(where("age").between(31, 35, false)); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("age").between(31, 35, false, true)); - assertEquals(cursor.size(), 4); - - cursor = collection.find(where("age").between(31, 35, false).not()); - assertEquals(cursor.size(), 2); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/DocumentCursorTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/DocumentCursorTest.java deleted file mode 100644 index c4b02d4a3..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/DocumentCursorTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.collection.operation; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapdb.Retry; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import java.util.Iterator; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee. - */ -public class DocumentCursorTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testFindResult() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("first", "second")); - - DocumentCursor result = collection.find(); - assertNotNull(result); - } - - @Test(expected = InvalidOperationException.class) - public void testIteratorRemove() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("first", "second")); - - DocumentCursor cursor = collection.find(); - Iterator iterator = cursor.iterator(); - if (iterator.hasNext()) { - iterator.next(); - iterator.remove(); - } - } - - @Test - public void testValidateProjection() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("first", "second")); - - Document projection = createDocument("first", createDocument("second", null)); - RecordStream project = collection.find().project(projection); - assertNotNull(project); - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/JoinedDocumentStreamTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/JoinedDocumentStreamTest.java deleted file mode 100644 index 5fbb186c6..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/operation/JoinedDocumentStreamTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.collection.operation; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapdb.Retry; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import java.util.Iterator; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class JoinedDocumentStreamTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testFindResult() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("first", "second")); - - RecordStream result = collection.find().join(collection.find(), new Lookup()); - assertNotNull(result); - } - - @Test(expected = InvalidOperationException.class) - public void testIteratorRemove() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - collection.insert(createDocument("first", "second")); - - RecordStream cursor = collection.find().join(collection.find(), new Lookup()); - assertNotNull(cursor.toString()); - Iterator iterator = cursor.iterator(); - if (iterator.hasNext()) { - iterator.next(); - iterator.remove(); - } - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/EventTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/EventTest.java deleted file mode 100644 index 9098e1119..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/EventTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.common.event; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.collection.events.EventType; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.MapDBModuleBuilder; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.repository.data.Employee; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collection; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -@RunWith(Parameterized.class) -public class EventTest { - @Parameterized.Parameter - public boolean inMemory = false; - @Parameterized.Parameter(value = 1) - public boolean isProtected = false; - - private final String fileName = getRandomTempDbFile(); - private Nitrite db; - private ObjectRepository employeeRepository; - private SampleListenerCollection listener; - - @Rule - public Retry retry = new Retry(3); - - @Parameterized.Parameters(name = "InMemory = {0}, Protected = {1}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false, false}, - {false, true}, - {true, false}, - {true, true}, - }); - } - - @Before - public void setUp() { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - - if (!inMemory) { - builder.filePath(fileName); - } - - MapDBModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - if (isProtected) { - db = nitriteBuilder.openOrCreate("test-user", "test-password"); - } else { - db = nitriteBuilder.openOrCreate(); - } - - employeeRepository = db.getRepository(Employee.class); - listener = new SampleListenerCollection(); - employeeRepository.subscribe(listener); - } - - @Test - public void testInsert() { - Employee employee = new Employee(); - employee.setEmpId(1L); - employeeRepository.insert(employee); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - assertEquals(listener.getAction(), EventType.Insert); - assertNotNull(listener.getItem()); - } - - @Test - public void testUpdate() { - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - employeeRepository.insert(e); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - assertEquals(listener.getAction(), EventType.Insert); - assertNotNull(listener.getItem()); - - e.setAddress("xyz"); - employeeRepository.update(where("empId").eq(1L), e); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Update)); - assertEquals(listener.getAction(), EventType.Update); - assertNotNull(listener.getItem()); - - Employee byId = employeeRepository.getById(1L); - assertEquals(byId.getAddress(), "xyz"); - } - - @Test - public void testUpsert() { - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - - employeeRepository.update(where("empId").eq(1), e, true); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - assertEquals(listener.getAction(), EventType.Insert); - assertNotNull(listener.getItem()); - } - - @Test - public void testDelete() { - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - - employeeRepository.insert(e); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - - employeeRepository.remove(where("empId").eq(1L)); - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Remove)); - - System.out.println("Action - " + listener.getAction()); - assertEquals(listener.getAction(), EventType.Remove); - assertNotNull(listener.getItem()); - } - - @Test - public void testDrop() { - employeeRepository.drop(); - assertNull(listener.getItem()); - } - - @Test - public void testClose() { - if (employeeRepository.isOpen()) { - employeeRepository.close(); - } - assertNull(listener.getItem()); - } - - @Test - public void testDeregister() { - employeeRepository.unsubscribe(listener); - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - - employeeRepository.insert(e); - assertNull(listener.getAction()); - assertNull(listener.getItem()); - } - - @Test - public void testMultipleListeners() { - final AtomicInteger count = new AtomicInteger(0); - employeeRepository.subscribe(changeInfo -> count.incrementAndGet()); - - employeeRepository.subscribe(changeInfo -> count.incrementAndGet()); - - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - employeeRepository.insert(e); - - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - assertEquals(count.get(), 2); - } - - @Test - public void testSingleEventListener() { - final AtomicInteger count = new AtomicInteger(0); - employeeRepository.subscribe(changeInfo -> count.incrementAndGet()); - - employeeRepository = db.getRepository(Employee.class); - Employee e = new Employee(); - e.setEmpId(1L); - e.setAddress("abcd"); - employeeRepository.insert(e); - - await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); - assertEquals(count.get(), 1); - } - - @After - public void clear() throws IOException { - if (employeeRepository != null) { - if (!employeeRepository.isDropped() - && employeeRepository.isOpen()) { - employeeRepository.remove(ALL); - employeeRepository.unsubscribe(listener); - employeeRepository.close(); - } - } - - if (db != null) { - db.commit(); - db.close(); - } - - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } - } - - private Callable listenerPrepared(final EventType action) { - return () -> listener.getAction() == action; - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteStoreEventTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteStoreEventTest.java deleted file mode 100644 index 9a0ed8a0c..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteStoreEventTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2019-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.mapdb; - -import lombok.Data; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.store.events.EventInfo; -import org.dizitart.no2.store.events.StoreEventListener; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.concurrent.TimeUnit; - -import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee - */ -public class NitriteStoreEventTest { - private String dbFile; - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void before() { - dbFile = getRandomTempDbFile(); - } - - @After - public void cleanup() throws IOException { - if (db != null && !db.isClosed()) { - db.close(); - } - - if (Files.exists(Paths.get(dbFile))) { - Files.delete(Paths.get(dbFile)); - } - } - - @Test - public void testStoreEvents() { - TestStoreEventListener listener = new TestStoreEventListener(); - assertFalse(listener.opened); - assertFalse(listener.committed); - assertFalse(listener.closing); - assertFalse(listener.closed); - - MapDBModule module = MapDBModule.withConfig() - .filePath(dbFile) - .addStoreEventListener(listener) - .build(); - - db = Nitrite.builder() - .loadModule(module) - .fieldSeparator(".") - .openOrCreate(); - - await().atMost(1, TimeUnit.SECONDS).until(() -> listener.opened); - assertTrue(listener.opened); - assertFalse(listener.committed); - assertFalse(listener.closing); - assertFalse(listener.closed); - - db.commit(); - - await().atMost(1, TimeUnit.SECONDS).until(() -> listener.committed); - assertTrue(listener.opened); - assertTrue(listener.committed); - assertFalse(listener.closing); - assertFalse(listener.closed); - - db.close(); - - await().atMost(1, TimeUnit.SECONDS).until(() -> listener.closed); - assertTrue(listener.opened); - assertTrue(listener.committed); - assertTrue(listener.closing); - assertTrue(listener.closed); - - db.getStore().unsubscribe(listener); - } - - @Data - private static class TestStoreEventListener implements StoreEventListener { - private boolean opened; - private boolean committed; - private boolean closing; - private boolean closed; - - @Override - public void onEvent(EventInfo eventInfo) { - switch (eventInfo.getEvent()) { - case Opened: - opened = true; - break; - case Commit: - committed = true; - break; - case Closing: - closing = true; - break; - case Closed: - closed = true; - break; - } - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java deleted file mode 100644 index e520f97da..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/MigrationTest.java +++ /dev/null @@ -1,557 +0,0 @@ -package org.dizitart.no2.mapdb.migrate; - -import com.github.javafaker.Faker; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.Constants; -import org.dizitart.no2.exceptions.MigrationException; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.migration.Instructions; -import org.dizitart.no2.migration.Migration; -import org.dizitart.no2.migration.TypeConverter; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.UUID; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -public class MigrationTest { - private final String dbPath = getRandomTempDbFile(); - private Nitrite db; - private Faker faker; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = createDb(dbPath); - faker = new Faker(); - } - - @After - public void cleanUp() throws IOException { - if (!db.isClosed()) { - db.close(); - } - - Files.delete(Paths.get(dbPath)); - } - - @Test - public void testRepositoryMigrate() { - ObjectRepository oldRepo = db.getRepository(OldClass.class, "demo1"); - for (int i = 0; i < 10; i++) { - OldClass old = new OldClass(); - old.setEmpId(String.valueOf(faker.number().randomNumber())); - old.setFirstName(faker.name().firstName()); - old.setLastName(faker.name().lastName()); - old.setUuid(UUID.randomUUID().toString()); - - OldClass.Literature literature = new OldClass.Literature(); - literature.setRatings((float) faker.number().randomDouble(2, 1, 5)); - literature.setText(faker.lorem().paragraph()); - old.setLiterature(literature); - - oldRepo.insert(old); - } - - db.close(); - - Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { - @Override - public void migrate(Instructions instruction) { - instruction.forDatabase() - .addPassword("test-user", "test-password"); - - instruction.forRepository(OldClass.class, "demo1") - .renameRepository("new", null) - .changeDataType("empId", (TypeConverter) Long::parseLong) - .changeIdField("uuid", "empId") - .deleteField("uuid") - .renameField("lastName", "familyName") - .addField("fullName", document -> document.get("firstName", String.class) + " " - + document.get("familyName", String.class)) - .dropIndex("firstName") - .dropIndex("literature.text") - .changeDataType("literature.ratings", (TypeConverter) Math::round); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate("test-user", "test-password"); - - ObjectRepository newRepo = db.getRepository(NewClass.class); - assertEquals(newRepo.size(), 10); - assertTrue(db.listCollectionNames().isEmpty()); - assertTrue(db.listKeyedRepository().isEmpty()); - - assertEquals((int) db.getDatabaseMetaData().getSchemaVersion(), 2); - } - - @Test - public void testCollectionMigrate() { - NitriteCollection collection = db.getCollection("test"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - document.put("bloodGroup", faker.name().bloodGroup()); - document.put("age", faker.number().randomDigit()); - - collection.insert(document); - } - - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("bloodGroup", IndexOptions.indexOptions(IndexType.NonUnique)); - db.close(); - - Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { - @Override - public void migrate(Instructions instruction) { - instruction.forDatabase() - .addPassword("test-user", "test-password"); - - instruction.forCollection("test") - .rename("testCollectionMigrate") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate("test-user", "test-password"); - - collection = db.getCollection("testCollectionMigrate"); - assertTrue(collection.hasIndex("firstName")); - assertEquals(collection.size(), 10); - assertEquals(db.listCollectionNames().size(), 1); - assertEquals((int) db.getDatabaseMetaData().getSchemaVersion(), 2); - db.close(); - - migration = new Migration(2, 3) { - @Override - public void migrate(Instructions instructions) { - instructions.forDatabase() - .changePassword("test-user", "test-password", "password"); - - instructions.forCollection("testCollectionMigrate") - .dropIndex("firstName") - .deleteField("bloodGroup") - .addField("name", document -> faker.name().fullName()) - .addField("address") - .addField("vehicles", 1) - .renameField("age", "ageGroup") - .createIndex("ageGroup", IndexType.NonUnique); - } - }; - - storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(3) - .addMigrations(migration) - .openOrCreate("test-user", "password"); - - collection = db.getCollection("testCollectionMigrate"); - assertEquals(collection.size(), 10); - assertEquals(db.listCollectionNames().size(), 1); - assertEquals((int) db.getDatabaseMetaData().getSchemaVersion(), 3); - - assertFalse(collection.hasIndex("firstName")); - assertTrue(collection.hasIndex("ageGroup")); - assertEquals(collection.find(where("age").notEq(null)).size(), 0); - } - - @Test(expected = MigrationException.class) - public void testOpenWithoutSchemaVersion() { - NitriteCollection collection = db.getCollection("test"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("test") - .rename("testOpenWithoutSchemaVersion") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testOpenWithoutSchemaVersion"); - assertEquals(collection.size(), 10); - db.close(); - - storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - - collection = db.getCollection("testOpenWithoutSchemaVersion"); - assertEquals(collection.size(), 10); - } - - @Test - public void testDescendingSchema() { - NitriteCollection collection = db.getCollection("test"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("test") - .rename("testDescendingSchema") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testDescendingSchema"); - assertEquals(collection.size(), 10); - db.close(); - - migration = new Migration(2, Constants.INITIAL_SCHEMA_VERSION) { - @Override - public void migrate(Instructions instructions) { - - instructions.forCollection("testDescendingSchema") - .rename("test"); - } - }; - - storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(1) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - } - - @Test - public void testMigrationWithoutVersion() { - NitriteCollection collection = db.getCollection("test"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("test") - .rename("testMigrationWithoutVersion") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testMigrationWithoutVersion"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - } - - @Test - public void testWrongSchemaVersionNoMigration() { - NitriteCollection collection = db.getCollection("testWrongSchemaVersionNoMigration"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration = new Migration(1, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("testWrongSchemaVersionNoMigration") - .rename("test") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testWrongSchemaVersionNoMigration"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - - migration = new Migration(2, 3) { - @Override - public void migrate(Instructions instructions) { - instructions.forCollection("test") - .rename("testWrongSchemaVersionNoMigration"); - } - }; - - storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testWrongSchemaVersionNoMigration"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - } - - @Test - public void testReOpenAfterMigration() { - NitriteCollection collection = db.getCollection("testReOpenAfterMigration"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration = new Migration(1, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("testReOpenAfterMigration") - .rename("test") - .deleteField("lastName"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testReOpenAfterMigration"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration) - .openOrCreate(); - - collection = db.getCollection("testReOpenAfterMigration"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - db.close(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .openOrCreate(); - - collection = db.getCollection("testReOpenAfterMigration"); - assertEquals(collection.size(), 0); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - } - - @Test - public void testMultipleMigrations() { - NitriteCollection collection = db.getCollection("testMultipleMigrations"); - for (int i = 0; i < 10; i++) { - Document document = Document.createDocument(); - document.put("firstName", faker.name().firstName()); - document.put("lastName", faker.name().lastName()); - - collection.insert(document); - } - db.close(); - - Migration migration1 = new Migration(1, 2) { - @Override - public void migrate(Instructions instruction) { - - instruction.forCollection("testMultipleMigrations") - .rename("test"); - } - }; - - Migration migration2 = new Migration(2, 3) { - @Override - public void migrate(Instructions instruction) { - instruction.forCollection("test") - .addField("fullName", "Dummy Name"); - } - }; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(2) - .addMigrations(migration1, migration2) - .openOrCreate(); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - assertEquals(collection.find(where("fullName").eq("Dummy Name")).size(), 0); - db.close(); - - Migration migration3 = new Migration(3, 4) { - @Override - public void migrate(Instructions instruction) { - instruction.forCollection("test") - .addField("age", 10); - } - }; - - storeModule = MapDBModule.withConfig() - .filePath(dbPath) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .schemaVersion(4) - .addMigrations(migration1, migration2, migration3) - .openOrCreate(); - - collection = db.getCollection("test"); - assertEquals(collection.size(), 10); - assertEquals(collection.find(where("fullName").eq("Dummy Name")).size(), 10); - assertEquals(collection.find(where("age").eq(10)).size(), 10); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/BaseObjectRepositoryTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/BaseObjectRepositoryTest.java deleted file mode 100644 index 4e33b4b13..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/BaseObjectRepositoryTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.MapDBModuleBuilder; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.repository.data.*; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collection; - -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; - -@RunWith(value = Parameterized.class) -public abstract class BaseObjectRepositoryTest { - @Parameterized.Parameter - public boolean inMemory = false; - @Parameterized.Parameter(value = 1) - public boolean isProtected = false; - - protected Nitrite db; - ObjectRepository companyRepository; - ObjectRepository employeeRepository; - ObjectRepository aObjectRepository; - ObjectRepository cObjectRepository; - private final String fileName = getRandomTempDbFile(); - - @Rule - public Retry retry = new Retry(3); - - @Parameterized.Parameters(name = "InMemory = {0}, Protected = {1}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false, false}, - {false, true}, - {true, false}, - {true, true}, - }); - } - - @Before - public void setUp() { - openDb(); - - companyRepository = db.getRepository(Company.class); - employeeRepository = db.getRepository(Employee.class); - - aObjectRepository = db.getRepository(ClassA.class); - cObjectRepository = db.getRepository(ClassC.class); - - for (int i = 0; i < 10; i++) { - Company company = DataGenerator.generateCompanyRecord(); - companyRepository.insert(company); - Employee employee = DataGenerator.generateEmployee(); - employee.setEmpId((long) i + 1); - employeeRepository.insert(employee); - - aObjectRepository.insert(ClassA.create(i + 50)); - cObjectRepository.insert(ClassC.create(i + 30)); - } - } - - private void openDb() { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - - if (!inMemory) { - builder.filePath(fileName); - } - - MapDBModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - if (isProtected) { - db = nitriteBuilder.openOrCreate("test-user", "test-password"); - } else { - db = nitriteBuilder.openOrCreate(); - } - } - - @After - public void clear() throws IOException { - if (companyRepository != null && !companyRepository.isDropped()) { - companyRepository.remove(ALL); - } - - if (employeeRepository != null && !employeeRepository.isDropped()) { - employeeRepository.remove(ALL); - } - - if (aObjectRepository != null && !aObjectRepository.isDropped()) { - aObjectRepository.remove(ALL); - } - - if (cObjectRepository != null && !cObjectRepository.isDropped()) { - cObjectRepository.remove(ALL); - } - - if (db != null && !db.isClosed()) { - db.commit(); - db.close(); - } - - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java deleted file mode 100644 index 762574c2d..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/CustomFieldSeparatorTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.repository.data.Company; -import org.dizitart.no2.mapdb.repository.data.Note; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.Serializable; -import java.util.Date; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee - */ -public class CustomFieldSeparatorTest { - private Nitrite db; - private ObjectRepository repository; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - MapDBModule module = MapDBModule.withConfig() - .build(); - - db = Nitrite.builder() - .loadModule(module) - .fieldSeparator(":") - .openOrCreate(); - - repository = db.getRepository(EmployeeForCustomSeparator.class); - } - - @After - public void reset() { - (new NitriteConfig()).fieldSeparator("."); - if (db != null && !db.isClosed()) { - db.close(); - } - } - - @Test - public void testFieldSeparator() { - assertEquals(NitriteConfig.getFieldSeparator(), ":"); - } - - @Test - public void testFindByEmbeddedField() { - EmployeeForCustomSeparator employee = new EmployeeForCustomSeparator(); - employee.setCompany(new Company()); - employee.setEmployeeNote(new Note()); - - employee.setEmpId(123L); - employee.setJoinDate(new Date()); - employee.setBlob(new byte[0]); - employee.setAddress("Dummy address"); - - employee.getCompany().setCompanyId(987L); - employee.getCompany().setCompanyName("Dummy Company"); - employee.getCompany().setDateCreated(new Date()); - - employee.getEmployeeNote().setNoteId(567L); - employee.getEmployeeNote().setText("Dummy Note"); - - repository.insert(employee); - - assertEquals(repository.find(where("employeeNote.text").eq("Dummy Note")).size(), 0); - assertEquals(repository.find(where("employeeNote:text").text("Dummy Note")).size(), 1); - - assertEquals(repository.find(where("company.companyName").eq("Dummy Company")).size(), 0); - assertEquals(repository.find(where("company:companyName").eq("Dummy Company")).size(), 1); - } - - @ToString - @EqualsAndHashCode - @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote:text", type = IndexType.Fulltext) - }) - public static class EmployeeForCustomSeparator implements Serializable, Mappable { - @Id - @Getter - @Setter - private Long empId; - - @Getter - @Setter - private Date joinDate; - - @Getter - @Setter - private String address; - - @Getter - @Setter - private Company company; - - @Getter - @Setter - private byte[] blob; - - @Getter - @Setter - private Note employeeNote; - - EmployeeForCustomSeparator() { - } - - public EmployeeForCustomSeparator(EmployeeForCustomSeparator copy) { - empId = copy.empId; - joinDate = copy.joinDate; - address = copy.address; - company = copy.company; - blob = copy.blob; - employeeNote = copy.employeeNote; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument().put("empId", empId) - .put("joinDate", joinDate) - .put("address", address) - .put("blob", blob) - .put("company", company.write(mapper)) - .put("employeeNote", employeeNote.write(mapper)); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - empId = document.get("empId", Long.class); - joinDate = document.get("joinDate", Date.class); - address = document.get("address", String.class); - blob = document.get("blob", byte[].class); - employeeNote = new Note(); - Document doc = document.get("employeeNote", Document.class); - employeeNote.read(mapper, doc); - company = new Company(); - doc = document.get("company", Document.class); - company.read(mapper, doc); - } - } - -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java deleted file mode 100644 index 6b8e165cf..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositorySearchTest.java +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository; - -import lombok.Getter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.exceptions.NotIdentifiableException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.mapdb.repository.data.*; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.Test; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.List; - -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.$; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -public class RepositorySearchTest extends BaseObjectRepositoryTest { - @Test - public void testFindWithOptions() { - Cursor cursor = employeeRepository.find().skipLimit(0, 1); - assertEquals(cursor.size(), 1); - assertNotNull(cursor.firstOrNull()); - } - - @Test - public void testEmployeeProjection() { - List employeeList = employeeRepository.find().toList(); - List subEmployeeList - = employeeRepository.find().project(SubEmployee.class).toList(); - - assertNotNull(employeeList); - assertNotNull(subEmployeeList); - - assertTrue(employeeList.size() > 0); - assertTrue(subEmployeeList.size() > 0); - - assertEquals(employeeList.size(), subEmployeeList.size()); - - for (int i = 0; i < subEmployeeList.size(); i++) { - Employee employee = employeeList.get(i); - SubEmployee subEmployee = subEmployeeList.get(i); - - assertEquals(employee.getEmpId(), subEmployee.getEmpId()); - assertEquals(employee.getJoinDate(), subEmployee.getJoinDate()); - assertEquals(employee.getAddress(), subEmployee.getAddress()); - } - - Cursor cursor = employeeRepository.find(); - assertNotNull(cursor.firstOrNull()); - assertNotNull(cursor.toString()); - assertEquals(cursor.toList().size(), employeeList.size()); - assertNotNull(cursor.firstOrNull()); - assertEquals(cursor.toList().size(), employeeList.size()); - } - - @Test - public void testEmptyResultProjection() { - employeeRepository.remove(ALL); - assertNull(employeeRepository.find().firstOrNull()); - - assertNull(employeeRepository.find(where("empId").eq(-1)) - .firstOrNull()); - } - - @Test - public void testGetById() { - ObjectRepository empRepo = db.getRepository(Employee.class); - Employee e1 = DataGenerator.generateEmployee(); - Employee e2 = DataGenerator.generateEmployee(); - Employee e3 = DataGenerator.generateEmployee(); - Employee e4 = DataGenerator.generateEmployee(); - - e1.setEmpId(1000000L); - e2.setEmpId(2000000L); - e3.setEmpId(3000000L); - e4.setEmpId(4000000L); - - empRepo.insert(e1, e2, e3, e4); - - Employee byId = empRepo.getById(2000000L); - assertEquals(byId, e2); - } - - @Test(expected = NotIdentifiableException.class) - public void testGetByIdNoId() { - ObjectRepository repository = db.getRepository(Note.class); - Note n1 = DataGenerator.randomNote(); - Note n2 = DataGenerator.randomNote(); - Note n3 = DataGenerator.randomNote(); - - assert n1 != null; - n1.setNoteId(1000000L); - assert n2 != null; - n2.setNoteId(2000000L); - assert n3 != null; - n3.setNoteId(3000000L); - - repository.insert(n1, n2, n3); - - repository.getById(2000000L); - } - - @Test(expected = InvalidIdException.class) - public void testGetByIdNullId() { - ObjectRepository empRepo = db.getRepository(Employee.class); - Employee e1 = DataGenerator.generateEmployee(); - Employee e2 = DataGenerator.generateEmployee(); - Employee e3 = DataGenerator.generateEmployee(); - Employee e4 = DataGenerator.generateEmployee(); - - e1.setEmpId(1000000L); - e2.setEmpId(2000000L); - e3.setEmpId(3000000L); - e4.setEmpId(4000000L); - - empRepo.insert(e1, e2, e3, e4); - - empRepo.getById(null); - } - - @Test(expected = InvalidIdException.class) - public void testGetByIdWrongType() { - ObjectRepository empRepo = db.getRepository(Employee.class); - Employee e1 = DataGenerator.generateEmployee(); - Employee e2 = DataGenerator.generateEmployee(); - Employee e3 = DataGenerator.generateEmployee(); - Employee e4 = DataGenerator.generateEmployee(); - - e1.setEmpId(1000000L); - e2.setEmpId(2000000L); - e3.setEmpId(3000000L); - e4.setEmpId(4000000L); - - empRepo.insert(e1, e2, e3, e4); - - Employee byId = empRepo.getById("employee"); - assertNull(byId); - } - - @Test - public void testEqualFilterById() { - Employee employee = employeeRepository.find().firstOrNull(); - long empId = employee.getEmpId(); - Employee emp = employeeRepository.find(where("empId").eq(empId)) - .project(Employee.class).firstOrNull(); - assertEquals(employee, emp); - } - - @Test - public void testEqualFilter() { - Employee employee = employeeRepository.find() - .firstOrNull(); - - Employee emp = employeeRepository.find(where("joinDate").eq(employee.getJoinDate())) - .project(Employee.class) - .firstOrNull(); - assertEquals(employee, emp); - } - - @Test - public void testStringEqualFilter() { - ObjectRepository repository = db.getRepository(ProductScore.class); - - ProductScore object = new ProductScore(); - object.setProduct("test"); - object.setScore(1); - repository.insert(object); - - object = new ProductScore(); - object.setProduct("test"); - object.setScore(2); - repository.insert(object); - - object = new ProductScore(); - object.setProduct("another-test"); - object.setScore(3); - repository.insert(object); - - assertEquals(repository.find(where("product").eq("test")).size(), 2); - } - - @Test - public void testAndFilter() { - Employee emp = employeeRepository.find().firstOrNull(); - - long id = emp.getEmpId(); - String address = emp.getAddress(); - Date joinDate = emp.getJoinDate(); - - Employee employee = employeeRepository.find( - where("empId").eq(id) - .and( - where("address").regex(address) - .and( - where("joinDate").eq(joinDate)))).firstOrNull(); - - assertEquals(emp, employee); - } - - @Test - public void testOrFilter() { - Employee emp = employeeRepository.find().firstOrNull(); - long id = emp.getEmpId(); - - Employee employee = employeeRepository.find( - where("empId").eq(id) - .or( - where("address").regex("n/a") - .or( - where("joinDate").eq(null)))).firstOrNull(); - - assertEquals(emp, employee); - } - - @Test - public void testNotFilter() { - Employee emp = employeeRepository.find().firstOrNull(); - long id = emp.getEmpId(); - - Employee employee = employeeRepository.find( - where("empId").eq(id).not()).firstOrNull(); - assertNotEquals(emp, employee); - } - - @Test - public void testGreaterFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").gt(id)) - .toList(); - - assertFalse(employeeList.contains(emp)); - assertEquals(employeeList.size(), 9); - } - - @Test - public void testGreaterEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").gte(id)) - .toList(); - - assertTrue(employeeList.contains(emp)); - assertEquals(employeeList.size(), 10); - } - - @Test - public void testLesserThanFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").lt(id)) - .toList(); - - assertFalse(employeeList.contains(emp)); - assertEquals(employeeList.size(), 9); - } - - @Test - public void testLesserEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").lte(id)) - .toList(); - - assertTrue(employeeList.contains(emp)); - assertEquals(employeeList.size(), 10); - } - - @Test - public void testTextFilter() { - Employee emp = employeeRepository.find().firstOrNull(); - String text = emp.getEmployeeNote().getText(); - - List employeeList = employeeRepository.find(where("employeeNote.text").text(text)) - .toList(); - - assertTrue(employeeList.contains(emp)); - } - - @Test - public void testRegexFilter() { - RecordStream employees = employeeRepository.find(); - int count = employees.toList().size(); - - List employeeList = employeeRepository.find(where("employeeNote.text").regex(".*")) - .toList(); - - assertEquals(employeeList.size(), count); - } - - @Test - public void testInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").in(id, id - 1, id - 2)) - .toList(); - - assertTrue(employeeList.contains(emp)); - assertEquals(employeeList.size(), 3); - - employeeList = employeeRepository.find(where("empId").in(id - 1, id - 2)).toList(); - assertEquals(employeeList.size(), 2); - } - - @Test - public void testNotInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); - long id = emp.getEmpId(); - - List employeeList = employeeRepository.find(where("empId").notIn(id, id - 1, id - 2)) - .toList(); - - assertFalse(employeeList.contains(emp)); - assertEquals(employeeList.size(), 7); - - employeeList = employeeRepository.find(where("empId").notIn(id - 1, id - 2)).toList(); - assertEquals(employeeList.size(), 8); - } - - @Test - public void testElemMatchFilter() { - final ProductScore score1 = new ProductScore("abc", 10); - final ProductScore score2 = new ProductScore("abc", 8); - final ProductScore score3 = new ProductScore("abc", 7); - final ProductScore score4 = new ProductScore("xyz", 5); - final ProductScore score5 = new ProductScore("xyz", 7); - final ProductScore score6 = new ProductScore("xyz", 8); - - ObjectRepository repository = db.getRepository(ElemMatch.class); - ElemMatch e1 = new ElemMatch(); - e1.setId(1); - e1.setStrArray(new String[]{"a", "b"}); - e1.setProductScores(new ProductScore[]{score1, score4}); - ElemMatch e2 = new ElemMatch(); - e2.setId(2); - e2.setStrArray(new String[]{"d", "e"}); - e2.setProductScores(new ProductScore[]{score2, score5}); - ElemMatch e3 = new ElemMatch(); - e3.setId(3); - e3.setStrArray(new String[]{"a", "f"}); - e3.setProductScores(new ProductScore[]{score3, score6}); - - repository.insert(e1, e2, e3); - - List elements = repository.find( - where("productScores").elemMatch( - where("product").eq("xyz") - .and(where("score").gte(8)))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("score").lte(8).not())).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("product").eq("xyz") - .or(where("score").gte(8)))).toList(); - assertEquals(elements.size(), 3); - - elements = repository.find( - where("productScores").elemMatch( - where("product").eq("xyz"))).toList(); - assertEquals(elements.size(), 3); - - elements = repository.find( - where("productScores").elemMatch( - where("score").gte(10))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("score").gt(8))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("score").lt(7))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("score").lte(7))).toList(); - assertEquals(elements.size(), 3); - - elements = repository.find( - where("productScores").elemMatch( - where("score").in(7, 8))).toList(); - assertEquals(elements.size(), 2); - - elements = repository.find( - where("productScores").elemMatch( - where("score").notIn(7, 8))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find( - where("productScores").elemMatch( - where("product").regex("xyz"))).toList(); - assertEquals(elements.size(), 3); - - elements = repository.find(where("strArray").elemMatch($.eq("a"))).toList(); - assertEquals(elements.size(), 2); - - elements = repository.find( - where("strArray").elemMatch( - $.eq("a") - .or($.eq("f") - .or($.eq("b"))).not())).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find(where("strArray").elemMatch($.gt("e"))).toList(); - assertEquals(elements.size(), 1); - - elements = repository.find(where("strArray").elemMatch($.gte("e"))).toList(); - assertEquals(elements.size(), 2); - - elements = repository.find(where("strArray").elemMatch($.lte("b"))).toList(); - assertEquals(elements.size(), 2); - - elements = repository.find(where("strArray").elemMatch($.lt("a"))).toList(); - assertEquals(elements.size(), 0); - - elements = repository.find(where("strArray").elemMatch($.in("a", "f"))).toList(); - assertEquals(elements.size(), 2); - - elements = repository.find(where("strArray").elemMatch($.regex("a"))).toList(); - assertEquals(elements.size(), 2); - } - - @Test - public void testFilterAll() { - ObjectRepository repository = db.getRepository(ElemMatch.class); - Cursor cursor = repository.find(ALL); - assertNotNull(cursor); - assertEquals(cursor.size(), 0); - - repository.insert(new ElemMatch()); - cursor = repository.find(ALL); - assertNotNull(cursor); - assertEquals(cursor.size(), 1); - } - - @Test - public void testEqualsOnTextIndex() { - PersonEntity p1 = new PersonEntity("jhonny"); - PersonEntity p2 = new PersonEntity("jhonny"); - PersonEntity p3 = new PersonEntity("jhonny"); - - ObjectRepository repository = db.getRepository(PersonEntity.class); - repository.insert(p1); - repository.insert(p2); - repository.insert(p3); - - List sameNamePeople = repository.find(where("name").eq("jhonny")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhonny")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").text("JHONNY")).toList(); - assertEquals(sameNamePeople.size(), 3); - - sameNamePeople = repository.find(where("name").eq("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 0); - - sameNamePeople = repository.find(where("name").text("jhon*")).toList(); - assertEquals(sameNamePeople.size(), 3); - } - - @Test - public void testIssue62() { - PersonEntity p1 = new PersonEntity("abcd"); - p1.setStatus("Married"); - - PersonEntity p2 = new PersonEntity("efgh"); - p2.setStatus("Married"); - - PersonEntity p3 = new PersonEntity("ijkl"); - p3.setStatus("Un-Married"); - - ObjectRepository repository = db.getRepository(PersonEntity.class); - repository.insert(p1); - repository.insert(p2); - repository.insert(p3); - - Filter married = where("status").eq("Married"); - - assertEquals(repository.find(married).size(), 2); - assertEquals(repository.find(married).sort("status", SortOrder.Descending).size(), 2); - - assertEquals(repository.find().sort("status", SortOrder.Descending).firstOrNull().getStatus(), "Un-Married"); - - assertEquals(repository.find().sort("status", SortOrder.Ascending).size(), 3); - assertEquals(repository.find().sort("status", SortOrder.Ascending).firstOrNull().getStatus(), "Married"); - } - - @Test - public void testRepeatableIndexAnnotation() { - ObjectRepository repo = db.getRepository(RepeatableIndexTest.class); - RepeatableIndexTest first = new RepeatableIndexTest(); - first.setAge(12); - first.setFirstName("fName"); - first.setLastName("lName"); - repo.insert(first); - - assertTrue(repo.hasIndex("firstName")); - assertTrue(repo.hasIndex("age")); - assertTrue(repo.hasIndex("lastName")); - - assertEquals(repo.find(where("age").eq(12)).firstOrNull(), first); - } - - @Test - public void testIdSet() { - Cursor employees = employeeRepository.find().sort("empId", SortOrder.Ascending); - assertEquals(employees.size(), 10); - } - - @Test - public void testBetweenFilter() { - @Getter - class TestData implements Mappable { - private Date age; - - public TestData(Date age) { - this.age = age; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("age", age); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - age = document.get("age", Date.class); - } - } - - TestData data1 = new TestData(new GregorianCalendar(2020, Calendar.JANUARY, 11).getTime()); - TestData data2 = new TestData(new GregorianCalendar(2021, Calendar.FEBRUARY, 12).getTime()); - TestData data3 = new TestData(new GregorianCalendar(2022, Calendar.MARCH, 13).getTime()); - TestData data4 = new TestData(new GregorianCalendar(2023, Calendar.APRIL, 14).getTime()); - TestData data5 = new TestData(new GregorianCalendar(2024, Calendar.MAY, 15).getTime()); - TestData data6 = new TestData(new GregorianCalendar(2025, Calendar.JUNE, 16).getTime()); - - ObjectRepository repository = db.getRepository(TestData.class); - repository.insert(data1, data2, data3, data4, data5, data6); - - Cursor cursor = repository.find(where("age").between( - new GregorianCalendar(2020, Calendar.JANUARY, 11).getTime(), - new GregorianCalendar(2025, Calendar.JUNE, 16).getTime())); - assertEquals(cursor.size(), 6); - - cursor = repository.find(where("age").between( - new GregorianCalendar(2020, Calendar.JANUARY, 11).getTime(), - new GregorianCalendar(2025, Calendar.JUNE, 16).getTime(), false)); - assertEquals(cursor.size(), 4); - - cursor = repository.find(where("age").between( - new GregorianCalendar(2020, Calendar.JANUARY, 11).getTime(), - new GregorianCalendar(2025, Calendar.JUNE, 16).getTime(), false, true)); - assertEquals(cursor.size(), 5); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java deleted file mode 100644 index cc8de2f27..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UniversalTextTokenizerTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.index.NitriteTextIndexer; -import org.dizitart.no2.index.fulltext.Languages; -import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.MapDBModuleBuilder; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.common.module.NitriteModule.module; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * @author Anindya Chatterjee - */ -public class UniversalTextTokenizerTest extends BaseObjectRepositoryTest { - private final String fileName = getRandomTempDbFile(); - private ObjectRepository textRepository; - - @Before - @Override - public void setUp() { - openDb(); - - textRepository = db.getRepository(TextData.class); - - for (int i = 0; i < 10; i++) { - TextData data = new TextData(); - data.id = i; - if (i % 2 == 0) { - data.text = "তারা বলল, “এস আমরা আমাদের জন্যে এক বড় শহর বানাই| আর এমন একটি উঁচু স্তম্ভ বানাই " + - "যা আকাশ স্পর্শ করবে| তাহলে আমরা বিখ্যাত হব এবং এটা আমাদের এক সঙ্গে ধরে রাখবে| সারা পৃথিবীতে " + - "আমরা ছড়িয়ে থাকব না|”"; - } else if (i % 3 == 0) { - data.text = "部汁楽示時葉没式将場参右属。覧観将者雄日語山銀玉襲政著約域費。新意虫跡更味株付安署審完顔団。" + - "困更表転定一史賀面政巣迎文学豊税乗。白間接特時京転閉務講封新内。側流効表害場測投活聞秀職探画労。" + - "福川順式極木注美込行警検直性禁遅。土一詳非物質紙姿漢人内池銀周街躍澹二。平討聞述並時全経詳業映回作朝送恵時。"; - } else if (i % 5 == 0) { - data.text = " أقبل لسفن العالم، في أما, بـ بال أملاً الثالث،. الذود بالرّد الثالث، مع" + - " قام, كردة الضغوط الإمداد أن وصل. ٠٨٠٤ عُقر انتباه يكن قد, أن زهاء وفنلندا بال. لان ما يقوم المعاهدات," + - " بـ بخطوط استعملت عدد. صفحة لفشل ولاتّساع لم قام, في مكثّفة الكونجرس جعل, الثالث، واقتصار دون ان.\n"; - } else { - data.text = "Lorem ipsum dolor sit amet, nobis audire perpetua eu sea. Te semper causae " + - "efficiantur per. Qui affert dolorum at. Mel tale constituto interesset in."; - } - textRepository.insert(data); - } - } - - @After - @Override - public void clear() throws IOException { - if (textRepository != null && !textRepository.isDropped()) { - textRepository.remove(ALL); - } - - if (db != null) { - db.commit(); - db.close(); - } - - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } - } - - private void openDb() { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - - if (!inMemory) { - builder.filePath(fileName); - } - - MapDBModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - UniversalTextTokenizer tokenizer; - if (isProtected) { - tokenizer = new UniversalTextTokenizer(Languages.Bengali, Languages.Chinese, Languages.English); - } else { - tokenizer = new UniversalTextTokenizer(Languages.ALL); - } - nitriteBuilder.loadModule(module(new NitriteTextIndexer(tokenizer))); - - if (isProtected) { - db = nitriteBuilder.openOrCreate("test-user", "test-password"); - } else { - db = nitriteBuilder.openOrCreate(); - } - } - - @Test - public void testUniversalFullTextIndexing() { - Cursor cursor = textRepository.find(where("text").text("Lorem")); - assertEquals(cursor.size(), 2); - for (TextData data : cursor) { - System.out.println("Id for English text -> " + data.id); - if (data.id % 2 == 0 || data.id % 3 == 0 || data.id % 5 == 0) { - fail(); - } - } - - cursor = textRepository.find(where("text").text("শহর")); - assertEquals(cursor.size(), 5); - for (TextData data : cursor) { - System.out.println("Id for Bengali text -> " + data.id); - if (data.id % 2 != 0) { - fail(); - } - } - - cursor = textRepository.find(where("text").text("転閉")); - assertEquals(cursor.size(), 0); - cursor = textRepository.find(where("text").text("*転閉*")); - assertEquals(cursor.size(), 2); - for (TextData data : cursor) { - System.out.println("Id for Chinese text -> " + data.id); - if (data.id % 3 != 0) { - fail(); - } - } - - cursor = textRepository.find(where("text").text("أقبل")); - if (isProtected) { - assertEquals(cursor.size(), 1); - for (TextData data : cursor) { - System.out.println("Id for Arabic text -> " + data.id); - if (data.id % 5 != 0) { - fail(); - } - } - } else { - // أقبل eliminated as stop word - assertEquals(cursor.size(), 0); - } - } - - @Indices( - @Index(value = "text", type = IndexType.Fulltext) - ) - public static class TextData implements Mappable { - public int id; - public String text; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("id", id) - .put("text", text); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Integer.class); - text = document.get("text", String.class); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java deleted file mode 100644 index b1c14191d..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ChildClass.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.InheritIndices; - -/** - * @author Anindya Chatterjee - */ -@Getter -@Setter -@InheritIndices -public class ChildClass extends ParentClass { - private String name; - - @Override - public Document write(NitriteMapper mapper) { - return super.write(mapper).put("name", name); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - super.read(mapper, document); - name = document.get("name", String.class); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/DataGenerator.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/DataGenerator.java deleted file mode 100644 index 49b2631be..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/DataGenerator.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import com.google.common.collect.Lists; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author Anindya Chatterjee. - */ -public class DataGenerator { - private DataGenerator() {} - private static final Random random = new Random(System.currentTimeMillis()); - private static final AtomicInteger counter = new AtomicInteger(random.nextInt()); - - public static Company generateCompanyRecord() { - Company company = new Company(); - company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); - company.setCompanyName(randomCompanyName()); - company.setDateCreated(randomDate()); - List departments = departments(); - company.setDepartments(departments); - - Map> employeeRecord = new HashMap<>(); - for (String department : departments) { - employeeRecord.put(department, - generateEmployeeRecords(company, random.nextInt(20))); - } - company.setEmployeeRecord(employeeRecord); - return company; - } - - private static List generateEmployeeRecords(Company company, int count) { - List employeeList = new ArrayList<>(); - for (int i = 0; i < count; i++) { - Employee employee = generateEmployee(); - employee.setCompany(company); - employeeList.add(employee); - } - return employeeList; - } - - public static Employee generateEmployee() { - Employee employee = new Employee(); - employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); - employee.setJoinDate(randomDate()); - employee.setAddress(UUID.randomUUID().toString().replace('-', ' ')); - - byte[] blob = new byte[random.nextInt(8000)]; - random.nextBytes(blob); - employee.setBlob(blob); - employee.setEmployeeNote(randomNote()); - - return employee; - } - - private static Date randomDate() { - return new Date(-946771200000L + - (Math.abs(random.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000))); - } - - public static Note randomNote() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.text"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - long line = random.nextInt(49); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - Note note = new Note(); - note.setNoteId(line); - note.setText(strLine); - return note; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; - } - - private static String randomCompanyName() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("english.stop"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - int line = random.nextInt(570); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - return strLine + System.nanoTime() + " inc."; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; - } - - private static List departments() { - return Lists.newArrayList( - "dev", - "hr", - "qa", - "dev-ops", - "sales", - "marketing", - "design", - "support" - ); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java deleted file mode 100644 index e2ba507bb..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ElemMatch.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Anindya Chatterjee - */ -@Data -public class ElemMatch implements Mappable { - private long id; - private String[] strArray; - private ProductScore[] productScores; - - @Override - public Document write(NitriteMapper mapper) { - List list = new ArrayList<>(); - if (productScores != null) { - for (ProductScore productScore : productScores) { - Document document = productScore.write(mapper); - list.add(document); - } - } - - return Document.createDocument("id", id) - .put("strArray", strArray) - .put("productScores", list); - } - - @Override - @SuppressWarnings("unchecked") - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Long.class); - strArray = document.get("strArray", String[].class); - List list = document.get("productScores", List.class); - if (list != null) { - productScores = new ProductScore[list.size()]; - for (int i = 0; i < list.size(); i++) { - productScores[i] = new ProductScore(); - productScores[i].read(mapper, list.get(i)); - } - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java deleted file mode 100644 index f40062584..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Employee.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; - -import java.io.Serializable; -import java.util.Date; - -/** - * @author Anindya Chatterjee. - */ -@ToString -@EqualsAndHashCode -@Index(value = "joinDate", type = IndexType.NonUnique) -@Index(value = "address", type = IndexType.Fulltext) -@Index(value = "employeeNote.text", type = IndexType.Fulltext) -public class Employee implements Serializable, Mappable { - @Id - @Getter - @Setter - private Long empId; - - @Getter - @Setter - private Date joinDate; - - @Getter - @Setter - private String address; - - @Getter - @Setter - private transient Company company; - - @Getter - @Setter - private byte[] blob; - - @Getter - @Setter - private Note employeeNote; - - public Employee() { - } - - public Employee(Employee copy) { - empId = copy.empId; - joinDate = copy.joinDate; - address = copy.address; - company = copy.company; - blob = copy.blob; - employeeNote = copy.employeeNote; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("empId", empId) - .put("joinDate", joinDate) - .put("address", address) - .put("blob", blob) - .put("employeeNote", employeeNote != null ? employeeNote.write(mapper) : null); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - empId = document.get("empId", Long.class); - joinDate = document.get("joinDate", Date.class); - address = document.get("address", String.class); - blob = document.get("blob", byte[].class); - - if (document.get("employeeNote") != null) { - employeeNote = new Note(); - employeeNote.read(mapper, document.get("employeeNote", Document.class)); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java deleted file mode 100644 index 6b549ff65..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ParentClass.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; - -import java.util.Date; - -/** - * @author Anindya Chatterjee - */ -@Getter -@Setter -@Index(value = "date") -public class ParentClass extends SuperDuperClass { - @Id - protected Long id; - private Date date; - - @Override - public Document write(NitriteMapper mapper) { - return super.write(mapper) - .put("id", id) - .put("date", date); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - super.read(mapper, document); - id = document.get("id", Long.class); - date = document.get("date", Date.class); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCustomConstructor.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCustomConstructor.java deleted file mode 100644 index 93dbb8b55..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCustomConstructor.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithCustomConstructor { - private String name; - private long number; - - public WithCustomConstructor(String name, long number) { - this.name = name; - this.number = number; - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java deleted file mode 100644 index eb9e095a4..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithFinalField.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.exceptions.ObjectMappingException; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - -/** - * @author Anindya Chatterjee. - */ -@Getter -public class WithFinalField implements Mappable { - private final long number; - @Setter - private String name; - - public WithFinalField() { - number = 2; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("name", name) - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - try { - Field field = getClass().getDeclaredField("number"); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - field.set(this, document.get("number", Long.class)); - } catch (Exception e) { - throw new ObjectMappingException("failed to set value"); - } - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java deleted file mode 100644 index 7e4f1f1db..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithObjectId.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithObjectId implements Mappable { - @Id - private WithOutId withOutId; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("withOutId", withOutId); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - withOutId = document.get("withOutId", WithOutId.class); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java deleted file mode 100644 index 19a037250..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPublicField.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -public class WithPublicField implements Mappable { - @Id - public String name; - public long number; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("name", name) - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - number = document.get("number", Long.class); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java b/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java deleted file mode 100644 index 90b8005e3..000000000 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithTransientField.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.mapdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithTransientField implements Mappable { - private transient String name; - @Id - private long number; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - number = document.get("number", Long.class); - } -} diff --git a/nitrite-mapdb-adapter/src/test/resources/english.stop b/nitrite-mapdb-adapter/src/test/resources/english.stop deleted file mode 100644 index 70572ebaa..000000000 --- a/nitrite-mapdb-adapter/src/test/resources/english.stop +++ /dev/null @@ -1,571 +0,0 @@ -a -a's -able -about -above -according -accordingly -across -actually -after -afterwards -again -against -ain't -all -allow -allows -almost -alone -along -already -also -although -always -am -among -amongst -an -and -another -any -anybody -anyhow -anyone -anything -anyway -anyways -anywhere -apart -appear -appreciate -appropriate -are -aren't -around -as -aside -ask -asking -associated -at -available -away -awfully -b -be -became -because -become -becomes -becoming -been -before -beforehand -behind -being -believe -below -beside -besides -best -better -between -beyond -both -brief -but -by -c -c'mon -c's -came -can -can't -cannot -cant -cause -causes -certain -certainly -changes -clearly -co -com -come -comes -concerning -consequently -consider -considering -contain -containing -contains -corresponding -could -couldn't -course -currently -d -definitely -described -despite -did -didn't -different -do -does -doesn't -doing -don't -done -down -downwards -during -e -each -edu -eg -eight -either -else -elsewhere -enough -entirely -especially -et -etc -even -ever -every -everybody -everyone -everything -everywhere -ex -exactly -example -except -f -far -few -fifth -first -five -followed -following -follows -for -former -formerly -forth -four -from -further -furthermore -g -get -gets -getting -given -gives -go -goes -going -gone -got -gotten -greetings -h -had -hadn't -happens -hardly -has -hasn't -have -haven't -having -he -he's -hello -help -hence -her -here -here's -hereafter -hereby -herein -hereupon -hers -herself -hi -him -himself -his -hither -hopefully -how -howbeit -however -i -i'd -i'll -i'm -i've -ie -if -ignored -immediate -in -inasmuch -inc -indeed -indicate -indicated -indicates -inner -insofar -instead -into -inward -is -isn't -it -it'd -it'll -it's -its -itself -j -just -k -keep -keeps -kept -know -knows -known -l -last -lately -later -latter -latterly -least -less -lest -let -let's -like -liked -likely -little -look -looking -looks -ltd -m -mainly -many -may -maybe -me -mean -meanwhile -merely -might -more -moreover -most -mostly -much -must -my -myself -n -name -namely -nd -near -nearly -necessary -need -needs -neither -never -nevertheless -new -next -nine -no -nobody -non -none -noone -nor -normally -not -nothing -novel -now -nowhere -o -obviously -of -off -often -oh -ok -okay -old -on -once -one -ones -only -onto -or -other -others -otherwise -ought -our -ours -ourselves -out -outside -over -overall -own -p -particular -particularly -per -perhaps -placed -please -plus -possible -presumably -probably -provides -q -que -quite -qv -r -rather -rd -re -really -reasonably -regarding -regardless -regards -relatively -respectively -right -s -said -same -saw -say -saying -says -second -secondly -see -seeing -seem -seemed -seeming -seems -seen -self -selves -sensible -sent -serious -seriously -seven -several -shall -she -should -shouldn't -since -six -so -some -somebody -somehow -someone -something -sometime -sometimes -somewhat -somewhere -soon -sorry -specified -specify -specifying -still -sub -such -sup -sure -t -t's -take -taken -tell -tends -th -than -thank -thanks -thanx -that -that's -thats -the -their -theirs -them -themselves -then -thence -there -there's -thereafter -thereby -therefore -therein -theres -thereupon -these -they -they'd -they'll -they're -they've -think -third -this -thorough -thoroughly -those -though -three -through -throughout -thru -thus -to -together -too -took -toward -towards -tried -tries -truly -try -trying -twice -two -u -un -under -unfortunately -unless -unlikely -until -unto -up -upon -us -use -used -useful -uses -using -usually -uucp -v -value -various -very -via -viz -vs -w -want -wants -was -wasn't -way -we -we'd -we'll -we're -we've -welcome -well -went -were -weren't -what -what's -whatever -when -whence -whenever -where -where's -whereafter -whereas -whereby -wherein -whereupon -wherever -whether -which -while -whither -who -who's -whoever -whole -whom -whose -why -will -willing -wish -with -within -without -won't -wonder -would -would -wouldn't -x -y -yes -yet -you -you'd -you'll -you're -you've -your -yours -yourself -yourselves -z -zero \ No newline at end of file diff --git a/nitrite-mapdb-adapter/src/test/resources/log4j2.xml b/nitrite-mapdb-adapter/src/test/resources/log4j2.xml deleted file mode 100644 index ece1f583c..000000000 --- a/nitrite-mapdb-adapter/src/test/resources/log4j2.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/nitrite-mapdb-adapter/src/test/resources/test.text b/nitrite-mapdb-adapter/src/test/resources/test.text deleted file mode 100644 index c940fb50c..000000000 --- a/nitrite-mapdb-adapter/src/test/resources/test.text +++ /dev/null @@ -1,50 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean massa nulla, elementum vitae velit nec, suscipit porttitor urna. Integer volutpat nibh et nisi congue ullamcorper. Cras laoreet consectetur massa a luctus. Etiam non sapien vitae enim semper elementum. Donec ullamcorper nibh quis magna vestibulum, eget faucibus sem posuere. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sed nulla id risus ultricies facilisis. Curabitur scelerisque eros metus, in ultrices libero efficitur sit amet. Vivamus aliquet nec sapien sed vehicula. Praesent a mauris eget tortor consectetur euismod. Suspendisse tempus felis et ante dictum, nec eleifend tellus finibus. -Vivamus felis turpis, pretium id gravida ut, pharetra et massa. Duis lobortis velit in nibh tristique, sit amet tristique neque eleifend. Quisque et faucibus magna. Donec in enim odio. Vestibulum fringilla odio quis libero convallis, sed imperdiet ante scelerisque. Suspendisse rutrum, turpis eget mollis ultricies, purus ante pellentesque arcu, ut gravida libero elit eget odio. Nam quis congue purus. Sed commodo enim lacus, eu tristique nisi pretium id. Nulla diam odio, cursus a eleifend eu, tristique tempus dui. -Suspendisse dictum mollis justo. Aliquam tempus consectetur elit, in euismod erat tempor non. Nullam lacinia eget sapien quis luctus. Praesent odio nisl, dapibus sit amet pharetra ut, consequat et neque. Ut consequat, ligula at lacinia ultrices, erat nisl vehicula urna, at ullamcorper magna urna ut erat. Integer at orci fringilla, congue nibh et, lacinia lorem. Sed aliquet quis felis nec fringilla. Integer egestas vitae neque in consequat. In laoreet nisi risus, a pharetra mi placerat a. Etiam ultricies arcu non est volutpat fringilla. Ut et molestie augue, ac consequat urna. Nulla et egestas mi. Sed tempor tortor et velit lacinia volutpat. Etiam volutpat porta interdum. Aliquam vitae rutrum sem. -Phasellus venenatis nibh mauris, id lobortis lorem dictum quis. Cras at sagittis felis. Proin viverra neque et metus rhoncus suscipit. Nam aliquet aliquet est, eget convallis turpis hendrerit sit amet. Nam eget commodo justo. Morbi pharetra commodo sapien vitae luctus. Integer eu eleifend massa. Integer consectetur sapien nec ligula pellentesque, sit amet tempus lacus venenatis. Aenean efficitur risus sed ligula dapibus pellentesque. Sed consectetur est eget egestas ornare. -Integer sit amet iaculis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec non dignissim nibh, sit amet ornare ipsum. Proin quis felis ut orci condimentum mattis a non urna. Aenean a metus nec lacus fringilla scelerisque sit amet id nisi. Nulla et velit in libero laoreet mollis. Nam malesuada leo non enim hendrerit facilisis a quis enim. -Nullam in diam ut ex mattis aliquet sed et ipsum. Morbi ut nunc et ex mollis convallis. Donec dui velit, iaculis at sapien ullamcorper, dictum maximus nibh. Maecenas porttitor arcu quis ex molestie elementum. Donec scelerisque ut erat at finibus. Nunc nec tempor mauris, sed posuere magna. In hac habitasse platea dictumst. Phasellus elit nisl, pellentesque vestibulum arcu quis, accumsan cursus nisi. Nunc eget orci non felis pretium vestibulum nec in mi. Nulla tincidunt, tortor id bibendum scelerisque, nibh libero lacinia felis, at pretium arcu lectus eu justo. Aenean ac elit id leo finibus vehicula. -Donec sed orci lobortis, posuere purus nec, molestie odio. Mauris elementum libero vel nibh ultrices vehicula. Quisque dignissim ipsum libero, eu elementum quam dignissim a. Mauris magna felis, tincidunt eu dolor vel, sollicitudin porta mi. Integer tempor volutpat leo. Nunc a neque lectus. Nullam pretium tempus congue. -Sed vehicula ipsum ipsum, et maximus augue gravida ut. Nunc augue lorem, volutpat ac volutpat nec, commodo ut ex. Duis dignissim est enim, non dapibus urna pharetra a. Aliquam vitae viverra nibh, ut ullamcorper nulla. Pellentesque ultricies aliquet magna, eget fermentum turpis. Etiam ut urna elementum, laoreet est ut, commodo quam. In quis libero vitae lacus scelerisque dignissim. Phasellus libero ligula, porttitor ac enim sed, ultrices accumsan erat. Quisque cursus tortor sit amet tellus laoreet, eu finibus velit laoreet. Duis luctus massa non nulla luctus, at imperdiet lacus condimentum. Ut nulla metus, elementum sed porta id, fringilla non enim. Fusce id rutrum ipsum. Etiam rhoncus finibus faucibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. -Etiam placerat aliquet nunc, id facilisis metus auctor at. Ut mi lacus, pharetra in egestas in, accumsan nec urna. Donec placerat erat quis enim vehicula, eget sollicitudin elit auctor. Curabitur ac auctor mauris. Nulla facilisi. Nam suscipit commodo mi, ut consequat neque finibus et. Fusce vestibulum porttitor odio, at tincidunt urna consectetur eu. Nullam lobortis risus sed convallis commodo. Cras non nibh vehicula, venenatis eros non, ultricies neque. Pellentesque enim nisl, elementum et libero id, laoreet dapibus odio. Aenean quis erat suscipit, mattis lectus quis, consectetur nibh. Vivamus vel sem egestas, ultricies mauris at, bibendum velit. Phasellus cursus elit erat, ut molestie risus condimentum vitae. Nam sapien mauris, ullamcorper sit amet dui id, accumsan lobortis dolor. Curabitur ultrices metus felis, ac sollicitudin eros vulputate at. Nunc eget tristique eros. -Vestibulum in lobortis nulla. Morbi mattis turpis ut tellus rutrum, at consectetur lacus mollis. Etiam maximus lectus ante, scelerisque aliquet turpis pharetra et. Fusce vulputate efficitur enim, at varius augue sagittis nec. Aenean volutpat volutpat metus, ut faucibus ex posuere dictum. Vivamus est enim, volutpat aliquam mi vel, dictum lobortis leo. Cras luctus fermentum tellus, sodales pellentesque lectus rutrum id. Sed in condimentum leo. Etiam ultricies porttitor ligula, et sodales purus imperdiet ac. Praesent non semper mi. Nullam bibendum auctor mi sit amet malesuada. Maecenas luctus accumsan ante feugiat egestas. Mauris tellus felis, venenatis sit amet risus nec, auctor auctor libero. Suspendisse purus risus, suscipit at lectus ut, maximus convallis nunc. Nulla facilisi. -Quisque commodo diam ut dui tristique luctus. Nam dignissim semper sollicitudin. Aenean condimentum orci ut augue suscipit, vitae ullamcorper urna ultrices. Nunc ac arcu eu massa placerat maximus. Cras ultrices elit id ipsum finibus, sit amet lacinia dui dignissim. Nulla suscipit suscipit libero non posuere. Aenean lobortis cursus metus, eu dignissim ligula pellentesque a. Donec viverra varius luctus. Mauris quis neque erat. Quisque pellentesque volutpat felis ultricies feugiat. -Fusce eu ante bibendum, tincidunt mauris bibendum, vulputate diam. Integer sit amet massa maximus, finibus ipsum in, scelerisque nunc. Quisque sodales neque quis tristique porttitor. Suspendisse molestie sed arcu nec commodo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec gravida nunc at fringilla accumsan. Praesent id elit sem. Sed sagittis sed nunc sit amet volutpat. Suspendisse potenti. Etiam malesuada neque enim, a consectetur justo ultricies ac. -Aenean vel enim a diam aliquet tempor. Phasellus et blandit dui. Nulla facilisi. Vestibulum rhoncus dolor at risus vehicula, ut tincidunt arcu sodales. Duis at massa ut leo suscipit mollis hendrerit nec justo. Nullam ex erat, accumsan eu odio sit amet, ullamcorper hendrerit ligula. Nullam scelerisque ut turpis vitae imperdiet. Pellentesque fermentum urna id ex mollis, vel mattis leo interdum. -Aenean nec est ac est varius elementum. Vestibulum vulputate accumsan pellentesque. Sed pellentesque mi nec ipsum tincidunt, fringilla faucibus urna semper. Pellentesque quis consequat nisl. Sed viverra nulla sagittis ante blandit, nec vulputate purus dapibus. Nullam molestie nisi diam, vitae elementum massa pellentesque eu. Vestibulum lacinia tortor in nisi auctor, ut pharetra dui interdum. Mauris ac ante elit. -Praesent pharetra egestas sapien ut convallis. Pellentesque gravida maximus maximus. Aliquam tristique venenatis arcu, ut bibendum augue lacinia vel. Nulla vulputate sit amet nibh non vestibulum. Pellentesque et imperdiet ex, vel cursus dui. Integer facilisis, est et tincidunt cursus, ligula arcu faucibus tortor, id commodo orci orci in neque. Nam lacinia lectus tempus, finibus libero pretium, tempor nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed massa ipsum, rhoncus pellentesque dui vestibulum, accumsan lacinia risus. Suspendisse ullamcorper enim vel sem blandit aliquet. Pellentesque bibendum erat eget quam pretium, sit amet cursus velit volutpat. Sed eget nunc at odio tristique venenatis. Mauris id sagittis quam, non aliquam magna. Curabitur sit amet neque a odio blandit consequat eu at est. Fusce in bibendum ipsum, quis fringilla justo. Nunc ut arcu non dui pretium vestibulum nec eu ipsum. Morbi ac dictum nulla. Vivamus vitae velit dolor. Duis quis aliquet felis. Praesent eu nulla vitae ex mattis imperdiet. -Aliquam finibus mauris arcu, non pellentesque diam interdum id. Praesent ornare lectus augue, eget lacinia odio venenatis a. Proin vulputate, nisl at feugiat euismod, massa arcu feugiat massa, a vehicula lorem nisi at diam. Aenean mattis, tellus sed hendrerit efficitur, purus purus consectetur nulla, a suscipit ipsum tortor vel magna. Nam sed posuere sem. Aliquam tincidunt in tortor ac cursus. Ut pellentesque urna in purus scelerisque, et imperdiet orci mollis. Fusce ultrices massa nisl, nec facilisis purus scelerisque ut. Pellentesque malesuada scelerisque diam, et dignissim orci ultricies vitae. Proin molestie ac augue at aliquet. Pellentesque fermentum dapibus purus ac porta. Nunc eu augue dui. Proin lacinia, enim at pretium vulputate, arcu arcu egestas ipsum, vel vehicula metus neque sed ex. Suspendisse vitae odio eu sapien pellentesque fermentum in nec leo. -Maecenas accumsan urna eros, id consequat felis maximus ac. Quisque id dictum sapien, et maximus justo. Sed blandit sit amet arcu ac vulputate. Sed bibendum maximus volutpat. Mauris dignissim purus vel leo ultrices aliquet. Aenean vitae sem rhoncus, vehicula sem quis, cursus metus. Duis hendrerit metus a fringilla sollicitudin. Morbi pellentesque velit eget posuere rhoncus. -Maecenas ullamcorper congue egestas. Aliquam maximus ullamcorper velit, vel ultrices ex pulvinar a. Sed convallis, metus eu facilisis lacinia, ex ante sollicitudin ipsum, vitae malesuada nibh nulla quis nulla. Aenean molestie, nulla commodo mattis viverra, purus mi ultrices ligula, ac accumsan libero velit sed est. Praesent cursus tincidunt ipsum nec sodales. Sed aliquet risus et odio lacinia, ac molestie libero posuere. Donec ultrices quam sapien, vel maximus eros malesuada eu. Integer tempor scelerisque laoreet. Vestibulum placerat rhoncus consequat. Nullam hendrerit, eros faucibus dictum faucibus, urna odio lobortis orci, ac suscipit ipsum lorem condimentum odio. Sed sollicitudin at odio sed viverra. Nulla aliquet facilisis ultrices. -Etiam vitae tempor tellus. Suspendisse potenti. Mauris sit amet odio diam. Vivamus at dignissim dui. Cras at nisl ut lorem condimentum vehicula. Cras vel nunc lectus. Morbi consequat dictum aliquet. Sed fermentum elementum ipsum, tempor fringilla libero varius et. -Mauris sed dictum purus, et ullamcorper tortor. Duis quis gravida urna. Integer pellentesque, ipsum at laoreet commodo, arcu dui semper lectus, sit amet consectetur diam nibh ut justo. Nam condimentum tincidunt arcu nec congue. Sed vulputate ligula at quam ultricies, et pretium justo consequat. Aenean nunc nisi, vehicula sed velit ut, pharetra egestas orci. Mauris pharetra erat tincidunt, gravida ipsum vitae, fermentum purus. Pellentesque sodales libero non purus ornare fermentum. Aliquam laoreet dignissim sem, et placerat turpis tincidunt non. -Cras bibendum ornare consequat. Donec non enim blandit, varius lorem sit amet, aliquam nibh. Morbi orci libero, egestas vitae arcu a, mollis interdum ante. Nullam vulputate risus enim, sit amet bibendum risus semper ut. Donec at orci sit amet ante hendrerit iaculis a non massa. Vestibulum nisi velit, dictum quis ullamcorper in, rhoncus sed ipsum. Curabitur sollicitudin diam dictum volutpat suscipit. Curabitur a elit et orci pellentesque venenatis ut rhoncus tellus. Proin nec metus non leo pharetra aliquet. Sed dolor augue, vehicula in odio vitae, cursus tincidunt eros. Praesent tempus luctus metus ac maximus. Phasellus non nibh quis eros rhoncus eleifend quis vitae nisi. -In ante enim, convallis in mollis nec, rutrum a nulla. Sed a urna ac nibh pharetra volutpat sit amet vel tortor. Quisque sodales tincidunt felis, et sollicitudin ligula venenatis vel. Pellentesque non justo eu diam sodales venenatis sed nec lacus. Nulla dignissim, sapien non pharetra scelerisque, risus massa dictum purus, congue convallis ante diam nec erat. Maecenas malesuada efficitur neque, a condimentum erat finibus vitae. Mauris quis dolor cursus nisi eleifend convallis sed id diam. Sed non pellentesque nisi. Praesent ut velit et tellus eleifend lacinia. Sed suscipit rutrum viverra. Pellentesque eget malesuada diam. Ut sed leo egestas, gravida odio aliquam, sodales nulla. In in lobortis nunc. Mauris et ex volutpat, elementum risus a, maximus magna. -Donec at odio sit amet nulla maximus semper at in elit. Vestibulum fringilla a tortor ut tristique. Proin a tristique mi. Cras libero ipsum, blandit ut volutpat non, convallis ac erat. Vivamus condimentum nunc dignissim, vestibulum tellus ut, tempus ante. Suspendisse fringilla nisi id arcu blandit pellentesque. Etiam vel elit velit. Donec ac sem consectetur, pharetra nisi a, facilisis turpis. Integer nec aliquam risus. Nullam posuere ligula eu purus rhoncus, nec fringilla nulla blandit. -Fusce condimentum sapien in elit dictum, ullamcorper vulputate ligula lacinia. Donec placerat elit dignissim mauris pellentesque malesuada. Maecenas semper lectus quis orci varius porta. Cras nec magna vitae ligula gravida bibendum. Pellentesque gravida purus sapien, eu egestas orci cursus sodales. Fusce varius ultrices enim quis faucibus. Aenean vel lobortis ex. Integer scelerisque nulla vel ligula pretium eleifend. Morbi lacus ligula, semper nec aliquet a, pulvinar nec ligula. Duis est orci, varius at ultricies ut, molestie id arcu. Nulla molestie lectus pharetra tortor cursus, eget gravida justo tempor. Fusce non ornare ante. In eu tortor venenatis, aliquet augue a, euismod purus. Duis et nibh venenatis, gravida nisi ut, sodales mi. Ut at ligula pretium, laoreet velit rutrum, sodales neque. Nulla quam nulla, mattis quis erat in, bibendum laoreet sem. -Donec posuere diam et est fringilla, sit amet malesuada lectus auctor. Nulla diam ante, tincidunt eu elementum in, congue vitae ante. Curabitur vulputate, nunc at posuere consectetur, nunc sem sagittis felis, non iaculis elit arcu eu metus. Pellentesque a eros dui. Phasellus commodo risus ante, at placerat augue ultricies a. Mauris in elementum velit. Curabitur quis odio vel tellus lacinia porttitor. Mauris nec mollis est, eget efficitur tellus. -In porttitor vel lectus vel finibus. Nunc quis quam ac nunc fringilla tempor. Pellentesque vel malesuada nunc. Suspendisse interdum pretium turpis, eget pretium tellus facilisis at. Etiam id ipsum eu velit elementum vehicula. Mauris vulputate lacus ac elit semper, a sodales metus varius. In semper ligula non erat vulputate, nec sollicitudin lectus gravida. Suspendisse porttitor sapien quis consectetur euismod. Maecenas consectetur scelerisque augue, eu iaculis dolor vulputate eget. In lobortis tristique mauris eu elementum. Proin lacus libero, suscipit id eleifend tincidunt, tincidunt vel felis. Aenean vulputate leo nec odio vehicula, venenatis tempus purus rutrum. -Curabitur non mauris vitae velit tempor dictum. Morbi id congue nunc. Aliquam imperdiet nec eros vitae pulvinar. Donec ut lobortis mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus pellentesque ante sem, vitae feugiat ante lobortis ut. Aliquam felis est, accumsan eget lacus at, gravida gravida ipsum. Etiam congue est justo, sed elementum erat aliquet quis. Aenean porttitor massa pellentesque, efficitur lacus non, scelerisque justo. Integer commodo turpis nibh, eget tincidunt mauris consequat id. Sed convallis egestas rhoncus. In faucibus mi sit amet dolor tempor, non ullamcorper erat mollis. -Quisque tincidunt feugiat volutpat. Nunc consectetur sapien finibus ipsum tincidunt, sit amet facilisis justo suscipit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque scelerisque massa eros, eget tempor lorem rutrum sit amet. Mauris faucibus libero at est sodales elementum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum dapibus ipsum ac quam placerat, eget lacinia lorem lobortis. Pellentesque eget velit nunc. Integer elementum justo in erat lobortis scelerisque. Sed ultrices dapibus quam quis ullamcorper. Duis auctor commodo placerat. Vivamus sed gravida turpis. Cras et nisl dignissim, pellentesque quam sed, eleifend nibh. Pellentesque et metus vel ipsum interdum bibendum. -Nam porttitor tristique metus eget elementum. Nullam eget risus commodo, malesuada dolor sit amet, tempus leo. Etiam eu iaculis neque, in tristique enim. Sed fringilla convallis leo id eleifend. Donec id purus suscipit, iaculis elit a, luctus felis. Praesent laoreet vulputate mi, eget cursus odio venenatis vitae. Curabitur egestas sem enim, non luctus erat tincidunt consectetur. Sed non viverra tellus. -Donec sodales ex eu neque condimentum feugiat. Integer elementum efficitur ligula quis aliquam. Quisque gravida tincidunt mauris. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque ut vehicula tellus. Maecenas ultricies est ac quam aliquam, eget tincidunt eros bibendum. Curabitur a viverra risus, ut dignissim lacus. Praesent pharetra vulputate porttitor. Suspendisse cursus egestas nisl, in mattis risus imperdiet non. Ut tempus tortor malesuada dapibus tristique. Sed blandit ligula non lacus tincidunt pellentesque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce semper mattis ante, in efficitur ligula egestas sit amet. -Nullam eu dapibus nisi, nec fermentum enim. Duis orci odio, lobortis nec ullamcorper a, faucibus fringilla est. Aenean convallis, lorem non euismod venenatis, sapien ipsum pulvinar ipsum, non auctor arcu massa in nisi. Maecenas tincidunt sapien ante, in consequat dui accumsan eget. Phasellus id tellus ac libero iaculis fermentum. Vestibulum sagittis sapien quis porttitor facilisis. Cras euismod sollicitudin nisi, et pretium sapien hendrerit a. Ut auctor vitae neque id pellentesque. Donec at dui blandit, ultricies orci et, aliquet mauris. Praesent porttitor massa vel diam ultrices, ac convallis tellus tincidunt. Duis molestie condimentum nisl non venenatis. Pellentesque scelerisque odio ut lobortis porttitor. Donec congue interdum dolor, non sagittis tellus mattis vel. Fusce commodo augue fringilla semper gravida. -Sed placerat erat nulla, at commodo enim dapibus id. Integer augue dui, aliquet a eros at, euismod luctus erat. Donec vitae tempus enim. In luctus posuere sollicitudin. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus ultrices a felis tincidunt condimentum. Integer nulla augue, pellentesque eu facilisis id, congue dignissim ligula. Phasellus vestibulum blandit vulputate. Morbi a tempus eros. Maecenas ac metus vehicula massa egestas rhoncus. Nam accumsan porttitor rutrum. Morbi sollicitudin eros vestibulum tortor finibus, nec porta orci eleifend. Curabitur id suscipit quam. -Donec vehicula metus massa, accumsan vulputate dolor bibendum vel. Curabitur tincidunt magna sit amet massa commodo, quis porttitor libero sollicitudin. Aenean sollicitudin vehicula dignissim. Duis rhoncus varius leo, vitae eleifend eros tristique quis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque fermentum nulla purus, nec aliquam nunc ultrices ut. Praesent vestibulum risus eu dolor ultricies eleifend. Nulla vitae hendrerit lorem, a pellentesque eros. Praesent pellentesque sit amet arcu ac hendrerit. -Ut scelerisque, velit eu rhoncus eleifend, dolor dui ultricies dolor, id fermentum lectus nunc nec sem. Donec eget nisi eget augue consequat pretium. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sollicitudin eget magna sed varius. Nam ultricies, eros non dapibus varius, eros elit finibus metus, quis semper lacus lectus in turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Praesent ornare, sapien vel gravida semper, risus risus luctus ligula, in vestibulum nibh arcu ac tortor. In cursus tempus justo eget mollis. Phasellus eget mauris hendrerit, venenatis dolor quis, euismod neque. Suspendisse potenti. -Suspendisse lorem lectus, accumsan eget ipsum ac, commodo luctus velit. Vivamus non ligula enim. In hendrerit turpis ut mauris commodo sagittis. Sed dapibus dolor vel turpis malesuada, id tincidunt ipsum convallis. Nulla in convallis enim, at dignissim mi. Etiam at mauris eget eros viverra malesuada. Etiam malesuada ligula eu libero condimentum pretium. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed eget quam non purus malesuada tristique. -Aenean at arcu felis. Donec consectetur ante a tellus pellentesque sollicitudin. Duis ut arcu sapien. Aenean quis lacus a turpis porttitor egestas ut nec nisi. Aenean viverra nec nunc quis lacinia. Nulla dapibus eros ac placerat blandit. Morbi tincidunt porttitor sapien, eu aliquet ipsum ullamcorper at. Phasellus eleifend lacus et mauris mollis gravida. Nullam vitae luctus mauris. Integer malesuada nec ligula non gravida. Nullam at facilisis neque. Vestibulum ac est a libero sagittis tempor a et urna. Suspendisse ac sollicitudin leo, in aliquet augue. Curabitur non vulputate mi. Ut eget euismod ex, ut placerat leo. Praesent suscipit lectus magna, ac bibendum risus dapibus id. -Cras consequat vel nunc id porttitor. Suspendisse tristique nunc leo, quis fermentum diam ultrices ac. Donec scelerisque mollis porttitor. Maecenas interdum dui orci, ut volutpat purus iaculis ac. Proin sed odio est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum malesuada turpis nunc, nec tincidunt risus ultricies eu. In pellentesque a leo quis aliquam. Suspendisse potenti. Cras volutpat nibh arcu, sit amet molestie purus rhoncus et. -Phasellus mi neque, placerat sed justo laoreet, aliquet sodales sem. Mauris vulputate aliquam sem, ac consectetur dolor iaculis eget. Nunc lobortis sapien lectus, ac consectetur nisi porta ac. In in sem nec massa consequat viverra nec aliquam urna. Proin maximus posuere tellus quis imperdiet. Suspendisse lobortis viverra aliquet. Duis laoreet, sem at ullamcorper consequat, eros orci maximus urna, non laoreet sapien orci ac ante. Quisque vulputate, magna ac venenatis tincidunt, nunc nibh convallis elit, sit amet mattis quam ipsum condimentum sem. Nunc maximus, nibh in lobortis dapibus, est erat lobortis tortor, eu euismod mi leo eu tellus. Praesent sit amet orci at quam porttitor cursus nec vel mauris. Nullam at sagittis tortor. Vivamus fermentum, quam nec egestas lobortis, velit velit molestie quam, in finibus libero mauris a lacus. -Sed nec dolor a lorem semper rutrum nec sit amet est. Vestibulum blandit bibendum nibh at commodo. Aenean sit amet purus dolor. Curabitur consequat volutpat aliquam. Nullam erat lorem, condimentum quis ultrices at, imperdiet at est. Nullam placerat mi sed facilisis rutrum. Proin metus felis, vulputate lacinia urna sit amet, rutrum fringilla felis. Donec quam lectus, porta sed elit et, dignissim luctus libero. -Suspendisse a augue ante. Phasellus hendrerit elit ut maximus consectetur. Aliquam id nisl ac lectus sodales rutrum quis vehicula purus. Vivamus sollicitudin turpis ac felis ullamcorper, id dictum ante iaculis. Fusce a libero est. In bibendum varius enim, gravida ultricies leo placerat et. Nunc ante erat, hendrerit sed sapien ac, molestie semper libero. Sed sagittis, quam non congue imperdiet, tellus leo ullamcorper metus, eget vestibulum tortor dui at dolor. Mauris est sem, tincidunt vel luctus non, tincidunt eu ipsum. Nullam a feugiat dui. Nunc vel velit vel ipsum sollicitudin dictum. Ut cursus imperdiet nibh, et aliquam ligula lacinia ac. -Cras erat felis, commodo ut posuere id, vehicula id neque. Vestibulum urna dolor, gravida vestibulum libero sed, pretium molestie mauris. Nullam in efficitur ipsum. Donec et ipsum finibus, bibendum diam vel, placerat est. Donec vitae gravida felis. Etiam augue justo, finibus id eros nec, consectetur lobortis risus. Aenean varius accumsan quam, ac pulvinar nunc pretium at. Mauris vitae risus maximus, eleifend leo ac, maximus nunc. Cras nibh ante, rhoncus eu eleifend eget, accumsan eget ex. -Vivamus tincidunt fermentum aliquet. Etiam et venenatis diam. Sed scelerisque convallis eros non pulvinar. Ut dignissim justo eros, id rhoncus magna mollis quis. Nullam lobortis odio at placerat feugiat. Morbi feugiat est eu mauris pellentesque efficitur. Praesent posuere arcu urna, eu cursus leo fermentum sit amet. Curabitur sit amet aliquam odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc malesuada nulla est, et varius nulla condimentum sed. Sed sit amet eros felis. Nullam vitae pretium lectus. -Etiam at massa vel urna varius accumsan. Proin non porttitor purus, nec facilisis libero. Quisque tristique, mi ac tristique vulputate, ipsum nibh porta urna, et tempus ex orci eu libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin non pellentesque elit, at vehicula justo. Ut facilisis mi sit amet est faucibus, id lobortis est varius. Nulla placerat justo lorem, quis condimentum nulla dapibus quis. Curabitur blandit non lorem at ultrices. Duis nunc mauris, cursus porttitor mauris mattis, consequat luctus neque. -Duis congue non quam eget dignissim. Etiam molestie metus et arcu sollicitudin cursus. Suspendisse cursus luctus rhoncus. Proin lorem metus, bibendum pharetra auctor vitae, malesuada eget risus. Aenean ac libero quis metus lacinia dignissim nec vitae tellus. Nulla consectetur semper ipsum, sed imperdiet elit lobortis sit amet. Vivamus iaculis arcu ut mattis iaculis. In metus tortor, euismod sit amet ligula eget, tincidunt euismod dolor. Aliquam eget elit at est faucibus aliquet sit amet quis leo. -Praesent lectus dolor, tincidunt et urna eget, consectetur volutpat libero. Quisque placerat vel sem ac accumsan. Nulla facilisi. Praesent facilisis condimentum quam. Vivamus malesuada nibh ut dignissim commodo. Morbi a egestas leo. Sed viverra, purus eu mattis varius, nibh nunc convallis est, et tristique nulla eros ut augue. Curabitur a dui tortor. Pellentesque viverra nisi ut risus laoreet vehicula. -Suspendisse potenti. Quisque et condimentum tellus. Vestibulum mollis sollicitudin risus, ac suscipit ex interdum ac. Vivamus mattis velit non lectus consectetur aliquam. Maecenas commodo iaculis eros ac suscipit. Quisque tempor libero in ultricies luctus. Phasellus dictum, orci in suscipit fringilla, est dui imperdiet purus, vitae tempor tellus odio et est. Vestibulum iaculis id felis in facilisis. Morbi luctus tortor sit amet dui varius iaculis. Sed gravida ipsum lectus, id tincidunt dui dapibus eget. Proin at vestibulum libero, nec ornare sapien. Quisque odio mi, maximus in pretium et, hendrerit at odio. -Nunc ullamcorper mattis laoreet. In dolor justo, imperdiet eget libero id, imperdiet laoreet erat. Donec molestie dictum leo, nec luctus ipsum viverra nec. Maecenas scelerisque metus sed vulputate ullamcorper. Maecenas varius eget felis vel porttitor. Sed sem diam, pellentesque vitae egestas ut, varius at urna. Donec eu metus commodo augue porta eleifend. Maecenas id porta erat. Aenean sed nunc orci. Ut nec tristique ipsum, ut egestas purus. Nullam egestas dictum tristique. Sed lacinia mauris quis cursus tristique. Quisque ac urna id diam elementum vulputate eu eu purus. -Aliquam sit amet purus bibendum, placerat massa quis, malesuada nisl. Nullam orci justo, egestas eget neque maximus, cursus porttitor velit. Donec vel sodales risus. Curabitur lorem dui, finibus id est a, hendrerit luctus velit. Praesent aliquet molestie felis, nec dictum leo tincidunt vel. Cras rutrum tempus egestas. Sed in ex interdum, lobortis nunc a, pharetra diam. Ut sed risus scelerisque purus rutrum rhoncus ut eget urna. Praesent mollis arcu vel auctor luctus. Nullam risus magna, iaculis non condimentum id, maximus sed diam. Integer porttitor ornare metus sed mattis. Nulla facilisi. Proin facilisis vestibulum dolor, sed hendrerit metus convallis a. Cras rutrum est eget mauris laoreet, nec blandit sapien euismod. -Nulla egestas auctor arcu in porttitor. Integer tincidunt ex non laoreet tincidunt. Suspendisse vitae urna ut nibh auctor viverra nec in lacus. In finibus sagittis velit, non rhoncus sapien tristique non. Suspendisse eu urna cursus, varius turpis vel, semper est. Donec orci augue, mollis sed auctor in, eleifend vitae justo. Cras commodo orci interdum turpis suscipit laoreet. Quisque venenatis lacus ut leo molestie pellentesque. Nunc id congue risus. Donec sagittis erat nunc, non consectetur erat euismod eu. Nam at velit nisl. \ No newline at end of file diff --git a/nitrite-mvstore-adapter/build.gradle b/nitrite-mvstore-adapter/build.gradle index 696a49589..00d054e78 100644 --- a/nitrite-mvstore-adapter/build.gradle +++ b/nitrite-mvstore-adapter/build.gradle @@ -52,6 +52,7 @@ dependencies { testImplementation "uk.co.jemos.podam:podam:7.2.5.RELEASE" testImplementation "com.github.javafaker:javafaker:1.0.2" testImplementation "junit:junit:4.13.1" + testImplementation "org.mockito:mockito-core:3.9.0" testImplementation "org.apache.lucene:lucene-core:8.6.3" testImplementation "org.apache.lucene:lucene-analyzers-common:8.6.3" testImplementation "org.apache.lucene:lucene-queryparser:8.6.3" @@ -62,6 +63,7 @@ dependencies { testImplementation "org.meanbean:meanbean:2.0.3" testImplementation "com.fasterxml.jackson.core:jackson-databind:2.11.3" testImplementation "commons-io:commons-io:2.8.0" + testImplementation "com.google.guava:guava:29.0-jre" } test { diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java index 533a9e7a8..480685aab 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVMap.java @@ -153,11 +153,12 @@ public boolean isEmpty() { @Override public void drop() { + nitriteStore.closeMap(getName()); nitriteStore.removeMap(getName()); } @Override public void close() { - // nothing to close + nitriteStore.closeMap(getName()); } } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java index 1842547cf..289a13be4 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVRTreeMap.java @@ -20,6 +20,7 @@ import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.index.BoundingBox; import org.dizitart.no2.store.NitriteRTree; +import org.dizitart.no2.store.NitriteStore; import org.h2.mvstore.rtree.MVRTreeMap; import org.h2.mvstore.rtree.SpatialKey; @@ -31,9 +32,11 @@ */ class NitriteMVRTreeMap implements NitriteRTree { private final MVRTreeMap mvMap; + private final NitriteStore nitriteStore; - NitriteMVRTreeMap(MVRTreeMap mvMap) { + NitriteMVRTreeMap(MVRTreeMap mvMap, NitriteStore nitriteStore) { this.mvMap = mvMap; + this.nitriteStore = nitriteStore; } @Override @@ -72,8 +75,12 @@ public long size() { } private SpatialKey getKey(Key key, long id) { - return new SpatialKey(id, key.getMinX(), - key.getMaxX(), key.getMinY(), key.getMaxY()); + if (key == null) { + return new SpatialKey(id); + } else { + return new SpatialKey(id, key.getMinX(), + key.getMaxX(), key.getMinY(), key.getMaxY()); + } } private RecordStream getRecordStream(MVRTreeMap.RTreeCursor treeCursor) { @@ -93,6 +100,18 @@ public NitriteId next() { @Override public void close() { - //nothing to close + nitriteStore.closeRTree(mvMap.getName()); + } + + @Override + public void clear() { + mvMap.clear(); + } + + @Override + public void drop() { + mvMap.clear(); + nitriteStore.closeRTree(mvMap.getName()); + nitriteStore.removeRTree(mvMap.getName()); } } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java index 90fc6d47f..db963d23d 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/NitriteMVStore.java @@ -90,6 +90,9 @@ public void close() throws Exception { rTree.close(); } + nitriteMapRegistry.clear(); + nitriteRTreeMapRegistry.clear(); + mvStore.close(); alert(StoreEvents.Closed); } @@ -112,6 +115,16 @@ public NitriteMap openMap(String mapName, Class keyT return nitriteMVMap; } + @Override + public void closeMap(String mapName) { + nitriteMapRegistry.remove(mapName); + } + + @Override + public void closeRTree(String rTreeName) { + nitriteRTreeMapRegistry.remove(rTreeName); + } + @Override public void removeMap(String name) { MVMap mvMap = mvStore.openMap(name); @@ -127,7 +140,7 @@ public NitriteRTree openRTree(Strin } MVRTreeMap map = mvStore.openMap(mapName, new MVRTreeMap.Builder<>()); - NitriteMVRTreeMap nitriteMVRTreeMap = new NitriteMVRTreeMap(map); + NitriteMVRTreeMap nitriteMVRTreeMap = new NitriteMVRTreeMap(map, this); nitriteRTreeMapRegistry.put(mapName, nitriteMVRTreeMap); return nitriteMVRTreeMap; } diff --git a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java index 8e549b91c..f6dc0d984 100644 --- a/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java +++ b/nitrite-mvstore-adapter/src/main/java/org/dizitart/no2/mvstore/compat/v3/MigrationUtil.java @@ -32,7 +32,9 @@ import java.util.*; import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.CopyOnWriteArrayList; +import static org.dizitart.no2.common.Constants.INDEX_PREFIX; import static org.dizitart.no2.common.Constants.STORE_INFO; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; @@ -79,7 +81,7 @@ private static void copyData(MVMap oldMap, MVMap newMap) { Object newKey = key; if (key instanceof Compat.NitriteId) { newKey = nitriteId((Compat.NitriteId) key); - } else { + } else if (oldMap.getName().contains(INDEX_PREFIX)) { // index map, wrap with DBValue newKey = newKey == null ? DBNull.getInstance() : new DBValue((Comparable) newKey); } @@ -94,19 +96,26 @@ private static void copyData(MVMap oldMap, MVMap newMap) { private static Object migrateValue(Object value) { if (value != null) { if (value instanceof Compat.UserCredential) { + // old user credentials return credential((Compat.UserCredential) value); } else if (value instanceof Compat.NitriteId) { + // old nitrite id return nitriteId((Compat.NitriteId) value); } else if (value instanceof Compat.Index) { + // old index entry return indexEntry((Compat.Index) value); } else if (value instanceof Compat.IndexMeta) { + // old index meta data return indexMeta((Compat.IndexMeta) value); } else if (value instanceof Compat.Document) { + // old document return document((Compat.Document) value); } else if (value instanceof Compat.Attributes) { + // old attribute return attributes((Compat.Attributes) value); } else if (value instanceof ConcurrentSkipListSet) { - return skipList((ConcurrentSkipListSet) value); + // old index nitrite id list + return arrayList((ConcurrentSkipListSet) value); } else if (value instanceof Iterable) { return iterable((Iterable) value); } else if (value.getClass().isArray()) { @@ -143,8 +152,8 @@ private static Iterable iterable(Iterable value) { return collection; } - private static ConcurrentSkipListSet skipList(ConcurrentSkipListSet value) { - ConcurrentSkipListSet newList = new ConcurrentSkipListSet<>(); + private static CopyOnWriteArrayList arrayList(ConcurrentSkipListSet value) { + CopyOnWriteArrayList newList = new CopyOnWriteArrayList<>(); for (Object object : value) { Object newValue = migrateValue(object); newList.add(newValue); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbTestOperations.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbTestOperations.java deleted file mode 100644 index 669ee0310..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbTestOperations.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.index.IndexType; -import org.junit.Rule; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; - -import static org.dizitart.no2.TestUtil.isSorted; -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee. - */ -public class DbTestOperations { - private final String fileName = getRandomTempDbFile(); - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - public static String getRandomTempDbFile() { - String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; - File file = new File(dataDir); - if (!file.exists()) { - assertTrue(file.mkdirs()); - } - return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; - } - - void createDb() { - db = TestUtil.createDb(fileName); - db.close(); - } - - void writeCollection() { - NitriteCollection collection; - - db = TestUtil.createDb(fileName); - - collection = db.getCollection("test"); - collection.remove(ALL); - db.close(); - } - - void writeIndex() { - NitriteCollection collection; - - db = TestUtil.createDb(fileName); - - collection = db.getCollection("test"); - collection.remove(ALL); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); - db.close(); - } - - void insertInCollection() throws ParseException { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); - - Document doc1 = createDocument("firstName", "fn1") - .put("lastName", "ln1") - .put("birthDay", simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) - .put("data", new byte[]{1, 2, 3}) - .put("body", "a quick brown fox jump over the lazy dog"); - Document doc2 = createDocument("firstName", "fn2") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2010-06-12T16:02:48.440Z")) - .put("data", new byte[]{3, 4, 3}) - .put("body", "quick hello world from nitrite"); - Document doc3 = createDocument("firstName", "fn3") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2014-04-17T16:02:48.440Z")) - .put("data", new byte[]{9, 4, 8}) - .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + - "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); - - NitriteCollection collection; - - db = TestUtil.createDb(fileName); - - collection = db.getCollection("test"); - - WriteResult result = collection.insert(doc1, doc2, doc3); - assertEquals(result.getAffectedCount(), 3); - - db.commit(); - db.close(); - } - - void readCollection() throws ParseException { - NitriteCollection collection; - - db = TestUtil.createDb(fileName); - - collection = db.getCollection("test"); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").gt(simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").gte(simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lt(simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte(simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lte(new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").lt(new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").gt(new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").gte(new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").lte(new Date()).and(where("firstName").eq("fn1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte(new Date()).or(where("firstName").eq("fn12"))); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")) - .not()); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").eq((byte) 4)); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").lt(4)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("lastName").in("ln1", "ln2", "ln10")); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("firstName").notIn("fn1", "fn2")); - assertEquals(cursor.size(), 1); - - collection.createIndex("birthDay", indexOptions(IndexType.Unique)); - cursor = collection.find().sort("birthDay", SortOrder.Descending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, false)); - - cursor = collection.find(where("body").text("Lorem")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("body").text("quick")); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("body").text("nosql")); - assertEquals(cursor.size(), 0); - - db.close(); - } - - void deleteDb() throws IOException { - if (db != null && !db.isClosed()) { - db.close(); - } - Files.delete(Paths.get(fileName)); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbWriteCloseReadTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbWriteCloseReadTest.java deleted file mode 100644 index 5a3a8b10c..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DbWriteCloseReadTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.junit.Rule; -import org.junit.Test; - -import java.text.ParseException; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Anindya Chatterjee. - */ -public class DbWriteCloseReadTest { - private final DbTestOperations operations = new DbTestOperations(); - private volatile boolean writeCompleted = false; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testWriteCloseRead() throws Exception { - try { - operations.createDb(); - operations.writeCollection(); - operations.writeIndex(); - operations.insertInCollection(); - } catch (ParseException pe) { - // ignore - } finally { - writeCompleted = true; - } - - try { - assertTrue(writeCompleted); - operations.readCollection(); - } catch (Exception e) { - fail("collection read failed - " + e.getMessage()); - } finally { - operations.deleteDb(); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DocumentMetadataTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DocumentMetadataTest.java deleted file mode 100644 index 3a912de78..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/DocumentMetadataTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.BaseCollectionTest; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.events.EventType; -import org.junit.Test; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee. - */ -public class DocumentMetadataTest extends BaseCollectionTest { - @Test - public void testTimeStamp() { - Document document = createDocument("test_key", "test_value"); - assertEquals(document.getRevision().intValue(), 0); - assertEquals(document.getLastModifiedSinceEpoch().longValue(), 0L); - - collection.insert(document); - document = collection.find().firstOrNull(); - - assertEquals(document.getRevision().intValue(), 1); - assertTrue(document.getLastModifiedSinceEpoch() > 0); - - long previous = document.getRevision(); - - DocumentCursor cursor = collection.find(where("test_key").eq("test_value")); - document = cursor.firstOrNull(); - document.put("another_key", "another_value"); - - collection.update(document); - cursor = collection.find(where("test_key").eq("test_value")); - document = cursor.firstOrNull(); - - assertTrue(document.getRevision() > previous); - - final long time = document.getRevision(); - final Document removed = document; - - collection.subscribe(changeInfo -> { - if (changeInfo.getEventType() == EventType.Remove) { - assertTrue(removed.getRevision() > time); - } - }); - - collection.remove(document); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/MultiThreadedTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/MultiThreadedTest.java deleted file mode 100644 index 3bdc5de9e..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/MultiThreadedTest.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.concurrent.ThreadPoolManager; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.File; -import java.util.*; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - - -/** - * @author Anindya Chatterjee. - */ -@RunWith(Parameterized.class) -public class MultiThreadedTest { - private static final String fileName = getRandomTempDbFile(); - @Parameterized.Parameter - public boolean inMemory = false; - private NitriteCollection collection; - private final int threadCount = 20; - private final CountDownLatch latch = new CountDownLatch(threadCount); - private final int iterationCount = 100; - private final Random generator = new Random(); - private final AtomicInteger docCounter = new AtomicInteger(0); - private ExecutorService executor = ThreadPoolManager.getThreadPool(threadCount, "MultiThreadedTest"); - private Nitrite db; - - @Parameterized.Parameters(name = "InMemory = {0}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false}, - {true} - }); - } - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testOperations() throws InterruptedException { - db = inMemory ? createDb() : createDb(fileName); - - collection = db.getCollection("test"); - collection.remove(Filter.ALL); - collection.createIndex("unixTime", IndexOptions.indexOptions(IndexType.Unique)); - db.commit(); - - for (int i = 0; i < threadCount; i++) { - executor.submit(() -> { - for (int j = 0; j < iterationCount; j++) { - try { - Document document = generate(); - collection.insert(document); - - if (j == iterationCount / 2 - && !collection.hasIndex("text") - && !collection.hasIndex("date")) { - collection.createIndex("text", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("date", IndexOptions.indexOptions(IndexType.NonUnique)); - } - - long unixTime = (long) document.get("unixTime"); - DocumentCursor cursor = collection.find(where("unixTime").eq(unixTime)); - assertTrue(cursor.size() >= 0); - - if (collection.hasIndex("text") && !collection.isIndexing("text")) { - String textData = (String) document.get("text"); - cursor = collection.find(where("text").text(textData)); - assertTrue(cursor.size() >= 0); - } - - assertTrue(collection.hasIndex("unixTime")); - } catch (Throwable e) { - System.out.println("Exception at thread " + - Thread.currentThread().getName() + " with iteration " + j); - e.printStackTrace(); - } - } - latch.countDown(); - }); - } - - latch.await(); - - db.commit(); - - assertTrue(collection.hasIndex("text")); - assertTrue(collection.hasIndex("date")); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), docCounter.get()); - - cursor = collection.find(where("unixTime").gt(1L)); - assertEquals(cursor.size(), docCounter.get()); - - db.close(); - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - - if (!inMemory) { - File dbFile = new File(fileName); - long fileSize = dbFile.length(); - assertTrue(fileSize > 0); - dbFile.delete(); - } - - if (executor != null && !executor.isShutdown()) { - executor.shutdown(); - executor = null; - } - } - - private synchronized Document generate() { - Document document = createDocument("unixTime", System.nanoTime() + docCounter.incrementAndGet()); - byte[] blob = new byte[1024]; - generator.nextBytes(blob); - document.put("blob", blob); - document.put("text", UUID.randomUUID().toString().replaceAll("-", " ")); - document.put("date", new Date()); - return document; - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java deleted file mode 100644 index a68214245..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteCorruptedTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.concurrent.ThreadPoolManager; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.concurrent.ExecutorService; - -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee - */ -public class NitriteCorruptedTest { - private Nitrite db; - private NitriteCollection collection; - private final String fileName = getRandomTempDbFile(); - private Thread thread; - private final ExecutorService dbPool = ThreadPoolManager.getThreadPool(Runtime.getRuntime().availableProcessors(), - "NitriteCorruptedTest"); - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = createDb(fileName); - - collection = db.getCollection("test"); - collection.remove(ALL); - - thread = new Thread(() -> { - for (int i = 0; i < 50000; i++) { - - // Interruption Guard - if (Thread.interrupted()) { - break; - } - - Document doc1 = createDocument(String.valueOf(System.currentTimeMillis()), "fn1") - .put("lastName", "ln1") - .put("data", new byte[]{1, 2, 3}) - .put("body", "a quick brown fox jump over the lazy dog"); - - // Separate user thread from Db write thread - dbPool.submit(() -> collection.insert(doc1)); - } - }); - } - - @After - public void tearDown() throws IOException { - if (collection.isOpen()) { - collection.remove(ALL); - collection.close(); - } - db.close(); - Files.delete(Paths.get(fileName)); - } - - @Test(timeout = 10000) - public void issue118() throws InterruptedException { - thread.start(); - Thread.sleep(10); - thread.interrupt(); - Thread.sleep(500); - assertTrue(collection.isOpen()); - assertFalse(db.isClosed()); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java deleted file mode 100644 index 4cdc786f3..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteStressTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Id; -import org.junit.Rule; -import org.junit.Test; -import uk.co.jemos.podam.api.PodamFactory; -import uk.co.jemos.podam.api.PodamFactoryImpl; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlSchemaType; -import java.util.ArrayList; -import java.util.List; - -import static org.dizitart.no2.TestUtil.createDb; - - -/** - * @author Anindya Chatterjee - */ -public class NitriteStressTest { - private static final int TEST_SET_COUNT = 15000; - private final PodamFactory podamFactory = new PodamFactoryImpl(); - - @Rule - public Retry retry = new Retry(3); - - @Test - public void stressTest() { - Nitrite database = createDb(); - ObjectRepository testRepository = database.getRepository(TestDto.class); - testRepository.createIndex("lastName", IndexOptions.indexOptions(IndexType.Fulltext)); - testRepository.createIndex("birthDate", IndexOptions.indexOptions(IndexType.NonUnique)); - - int counter = 0; - try { - for (TestDto testDto : createTestSet()) { - testRepository.insert(testDto); - counter++; - } - } catch (Throwable t) { - System.err.println("Crashed after " + counter + " records"); - throw t; - } - } - - private List createTestSet() { - List testData = new ArrayList<>(); - for (int i = 0; i < TEST_SET_COUNT; i++) { - TestDto testRecords = podamFactory.manufacturePojo(TestDto.class); - testData.add(testRecords); - } - return testData; - } - - @Data - public static class TestDto implements Mappable { - - @XmlElement( - name = "StudentNumber", - required = true - ) - @Id - protected String studentNumber; - - @XmlElement( - name = "LastName", - required = true - ) - protected String lastName; - - @XmlElement( - name = "Prefixes" - ) - protected String prefixes; - - @XmlElement( - name = "Initials", - required = true - ) - protected String initials; - - @XmlElement( - name = "FirstNames" - ) - protected String firstNames; - @XmlElement( - name = "Nickname" - ) - protected String nickName; - - @XmlElement( - name = "BirthDate", - required = true - ) - @XmlSchemaType( - name = "date" - ) - protected String birthDate; - - - public TestDto() { - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("studentNumber", studentNumber) - .put("lastName", lastName) - .put("prefixes", prefixes) - .put("initials", initials) - .put("firstNames", firstNames) - .put("nickName", nickName) - .put("birthDate", birthDate); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - studentNumber = document.get("studentNumber", String.class); - lastName = document.get("lastName", String.class); - prefixes = document.get("prefixes", String.class); - initials = document.get("initials", String.class); - firstNames = document.get("firstNames", String.class); - nickName = document.get("nickName", String.class); - birthDate = document.get("birthDate", String.class); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java index 6df77e7f0..d49a599cf 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteTest.java @@ -1,17 +1,18 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2; @@ -20,16 +21,20 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.UpdateOptions; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.ThreadPoolManager; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; @@ -49,21 +54,18 @@ import java.nio.file.Paths; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.List; -import java.util.Locale; -import java.util.Random; -import java.util.Set; +import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; -import static java.nio.file.Paths.get; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; import static org.dizitart.no2.common.Constants.META_MAP_NAME; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.Filter.and; import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -104,13 +106,13 @@ public void setUp() throws ParseException { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); collection.insert(doc1, doc2, doc3); } @After - public void tearDown() throws IOException { + public void tearDown() { if (collection.isOpen()) { collection.remove(ALL); collection.close(); @@ -121,7 +123,7 @@ public void tearDown() throws IOException { } catch (NitriteIOException ignore) { } } - Files.delete(get(fileName)); + deleteDb(fileName); } @Test @@ -357,8 +359,8 @@ public void testIssue185() throws InterruptedException { }).start(); for (int i = 0; i < 1000; ++i) { - repository.find(where("status").eq(Receipt.Status.COMPLETED).not()) - .sort("createdTimestamp", SortOrder.Descending).toList(); + repository.find(where("status").eq(Receipt.Status.COMPLETED).not(), + FindOptions.orderBy("createdTimestamp", SortOrder.Descending)).toList(); try { Thread.sleep(50); } catch (InterruptedException ignored) { @@ -495,14 +497,14 @@ public void testIssue212() { Document doc = createDocument("fifth_key", "fifth_key"); if (!collection.hasIndex("key")) { - collection.createIndex("key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "key"); } if (!collection.hasIndex("second_key")) { - collection.createIndex("second_key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "second_key"); } collection.insert(doc1, doc2); - collection.update(and(where("key").eq("key"), where("second_key").eq("second_key")), + collection.update(where("key").eq("key").and(where("second_key").eq("second_key")), doc, UpdateOptions.updateOptions(true)); for (Document document : collection.find()) { @@ -510,6 +512,56 @@ public void testIssue212() { } } + @Test + public void testIssue245() throws Exception { + class ThreadRunner implements Runnable { + @Override + public void run() { + try { + long id = Thread.currentThread().getId(); + NitriteCollection collection = db.getCollection("testIssue245"); + + for (int i = 0; i < 5; i++) { + + System.out.println("Thread ID = " + id + " Inserting doc " + i); + Document doc = Document.createDocument(UUID.randomUUID().toString(), UUID.randomUUID().toString()); + + WriteResult result = collection.insert(doc);//db.commit(); + System.out.println("Result of insert = " + result.getAffectedCount()); + System.out.println("Thread id = " + id + " --> count = " + collection.size()); + + Thread.sleep(10); + + }//for closing + + collection.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + + Thread t0 = new Thread(new ThreadRunner()); + Thread t1 = new Thread(new ThreadRunner()); + Thread t2 = new Thread(new ThreadRunner()); + + t0.start(); + t1.start(); + t2.start(); + + Thread.sleep(10 * 1000); + + t0.join(); + t1.join(); + t2.join(); + + NitriteCollection collection = db.getCollection("testIssue245"); + System.out.println("No of Documents = " + collection.size()); + collection.close(); + db.close(); + } + @Data @AllArgsConstructor @NoArgsConstructor @@ -534,13 +586,13 @@ public void read(NitriteMapper mapper, Document document) { @NoArgsConstructor @AllArgsConstructor @Indices({ - @Index(value = "synced", type = IndexType.NonUnique) + @Index(value = "synced", type = IndexType.NON_UNIQUE) }) public static class Receipt implements Mappable { - private Status status; @Id private String clientRef; private Boolean synced; + private Status status; private Long createdTimestamp = System.currentTimeMillis(); @Override @@ -565,6 +617,7 @@ public void read(NitriteMapper mapper, Document document) { this.createdTimestamp = document.get("createdTimestamp", Long.class); } } + public enum Status { COMPLETED, PREPARING, diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java deleted file mode 100644 index 61ac96fc5..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteNegativeTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.ValidationException; -import org.junit.Test; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class CollectionDeleteNegativeTest extends BaseCollectionTest { - @Test(expected = NitriteIOException.class) - public void testDrop() { - collection.drop(); - insert(); - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - } - - @Test(expected = FilterException.class) - public void testDeleteWithInvalidFilter() { - insert(); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - - WriteResult writeResult = collection.remove(where("lastName").gt(null)); - assertEquals(writeResult.getAffectedCount(), 0); - } - - @Test(expected = ValidationException.class) - public void testDeleteNullDocument() { - insert(); - - collection.remove((Document) null); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java deleted file mode 100644 index 32a513827..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionDeleteTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class CollectionDeleteTest extends BaseCollectionTest { - - @Test - public void testDelete() { - insert(); - - WriteResult writeResult = collection.remove(where("lastName").notEq(null)); - assertEquals(writeResult.getAffectedCount(), 3); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 0); - } - - @Test - public void testDeleteWithOptions() { - insert(); - - WriteResult writeResult = collection.remove(where("lastName").notEq(null), true); - assertEquals(writeResult.getAffectedCount(), 1); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 2); - } - - @Test - public void testDeleteWithNonMatchingFilter() { - insert(); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - - WriteResult writeResult = collection.remove(where("lastName").eq("a")); - assertEquals(writeResult.getAffectedCount(), 0); - } - - @Test - public void testDeleteInEmptyCollection() { - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 0); - - WriteResult writeResult = collection.remove(where("lastName").notEq(null)); - assertEquals(writeResult.getAffectedCount(), 0); - } - - @Test - public void testClear() { - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - insert(); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - assertTrue(collection.hasIndex("firstName")); - - boolean uniqueError = false; - try { - collection.insert(doc1); - } catch (Exception e) { - uniqueError = true; - } finally { - assertTrue(uniqueError); - } - - collection.remove(Filter.ALL); - - cursor = collection.find(); - assertEquals(cursor.size(), 0); - assertTrue(collection.hasIndex("firstName")); - - collection.insert(doc1); - cursor = collection.find(); - assertEquals(cursor.size(), 1); - assertTrue(collection.hasIndex("firstName")); - } - - @Test - public void testRemoveAll() { - insert(); - WriteResult writeResult = collection.remove((Filter) null); - assertEquals(writeResult.getAffectedCount(), 3); - } - - @Test - public void testRemoveDocument() { - insert(); - - WriteResult writeResult = collection.remove(where("firstName").eq("fn1")); - assertEquals(writeResult.getAffectedCount(), 1); - assertEquals(collection.size(), 2); - - writeResult = collection.remove(where("firstName").eq("fn2")); - assertEquals(writeResult.getAffectedCount(), 1); - assertEquals(collection.size(), 1); - - assertEquals(collection.find(where("firstName").eq("fn1")).size(), 0); - assertEquals(collection.find(where("firstName").eq("fn2")).size(), 0); - assertEquals(collection.find(where("firstName").eq("fn3")).size(), 1); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java deleted file mode 100644 index 47677200a..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFactoryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.Retry; -import org.dizitart.no2.common.concurrent.LockService; -import org.dizitart.no2.exceptions.ValidationException; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class CollectionFactoryTest { - - @Rule - public Retry retry = new Retry(3); - - @Test(expected = ValidationException.class) - public void testGetCollectionMapStoreNull() { - CollectionFactory factory = new CollectionFactory(new LockService()); - assertNotNull(factory); - - NitriteConfig config = new NitriteConfig(); - factory.getCollection(null, config, true); - } - - @Test(expected = ValidationException.class) - public void testGetCollectionContextNull() { - CollectionFactory factory = new CollectionFactory(new LockService()); - factory.getCollection("test", null, false); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java deleted file mode 100644 index feb80b76b..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexNegativeTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class CollectionFindByIndexNegativeTest extends BaseCollectionTest { - @Test(expected = FilterException.class) - public void testFindTextWithWildCardMultipleWord() { - insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - - DocumentCursor cursor = collection.find(where("body").text("*ipsum dolor*")); - assertEquals(cursor.size(), 1); - } - - @Test(expected = FilterException.class) - public void testFindTextWithOnlyWildCard() { - insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - - DocumentCursor cursor = collection.find(where("body").text("*")); - assertEquals(cursor.size(), 1); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java deleted file mode 100644 index ab1df95a3..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindByIndexTest.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import com.github.javafaker.Faker; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import static org.dizitart.no2.TestUtil.isSorted; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Anindya Chatterjee. - */ -public class CollectionFindByIndexTest extends BaseCollectionTest { - - @Test - public void testFindByUniqueIndex() throws ParseException { - insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("firstName").eq("fn10")); - assertEquals(cursor.size(), 0); - - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); - cursor = collection.find(where("birthDay").gt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").gte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lte( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").lt( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").gt( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").gte( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .and(where("firstName").eq("fn1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12"))); - assertEquals(cursor.size(), 3); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").eq((byte) 4)); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").lt(4)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("lastName").in("ln1", "ln2", "ln10")); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("firstName").notIn("fn1", "fn2")); - assertEquals(cursor.size(), 1); - } - - @Test - public void testFindByNonUniqueIndex() throws ParseException { - insert(); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.NonUnique)); - - DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("lastName").eq("ln20")); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").gt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").gte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lt( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("birthDay").lte( - simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("birthDay").lte( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").lt( - new Date())); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("birthDay").gt( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("birthDay").gte( - new Date())); - assertEquals(cursor.size(), 0); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .and(where("firstName").eq("fn1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12"))); - assertEquals(cursor.size(), 3); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); - assertEquals(cursor.size(), 1); - - cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").eq((byte) 4)); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("data.1").lt(4)); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("lastName").in("ln1", "ln2", "ln10")); - assertEquals(cursor.size(), 3); - - cursor = collection.find(where("firstName").notIn("fn1", "fn2")); - assertEquals(cursor.size(), 1); - } - - @Test - public void testFindByFullTextIndexAfterInsert() { - insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - assertTrue(collection.hasIndex("body")); - - DocumentCursor cursor = collection.find(where("body").text("Lorem")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("body").text("nosql")); - assertEquals(cursor.size(), 0); - - collection.dropIndex("body"); - boolean filterException = false; - try { - collection.find(where("body").text("Lorem")).toList(); - } catch (FilterException fe) { - filterException = true; - } finally { - assertTrue(filterException); - } - } - - @Test - public void testFindByFullTextIndexBeforeInsert() { - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - assertTrue(collection.hasIndex("body")); - insert(); - - DocumentCursor cursor = collection.find(where("body").text("Lorem")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("body").text("quick brown")); - assertEquals(cursor.size(), 2); - - cursor = collection.find(where("body").text("nosql")); - assertEquals(cursor.size(), 0); - - collection.dropIndex("body"); - boolean filterException = false; - try { - collection.find(where("body").text("Lorem")).toList(); - } catch (FilterException fe) { - filterException = true; - } finally { - assertTrue(filterException); - } - } - - @Test - public void testFindByIndexSortAscending() { - insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); - - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); - assertEquals(cursor.size(), 3); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, true)); - } - - @Test - public void testFindByIndexSortDescending() { - insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); - - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); - assertEquals(cursor.size(), 3); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, false)); - } - - @Test - public void testFindByIndexLimitAndSort() { - insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); - - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - List dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, false)); - - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); - assertEquals(cursor.size(), 2); - dateList = new ArrayList<>(); - for (Document document : cursor) { - dateList.add(document.get("birthDay", Date.class)); - } - assertTrue(isSorted(dateList, true)); - - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); - assertEquals(cursor.size(), 3); - List nameList = new ArrayList<>(); - for (Document document : cursor) { - nameList.add(document.get("firstName", String.class)); - } - assertTrue(isSorted(nameList, true)); - } - - @Test - public void testFindAfterDroppedIndex() { - insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - - collection.dropIndex("firstName"); - cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - } - - @Test - public void testFindTextWithWildCard() { - insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - - DocumentCursor cursor = collection.find(where("body").text("Lo")); - assertEquals(cursor.size(), 0); - - cursor = collection.find(where("body").text("Lo*")); - assertEquals(cursor.size(), 1); // Lorem - - cursor = collection.find(where("body").text("*rem")); - assertEquals(cursor.size(), 1); // lorem - - cursor = collection.find(where("body").text("*or*")); - assertEquals(cursor.size(), 2); - } - - @Test - public void testFindTextWithEmptyString() { - insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - - DocumentCursor cursor = collection.find(where("body").text("")); - assertEquals(cursor.size(), 0); - } - - @Test - public void testFindWithOrIndexed() { - NitriteCollection collection = db.getCollection("testFindWithOrIndexed"); - Document doc1 = Document.createDocument("firstName", "John").put("lastName", "Doe"); - Document doc2 = Document.createDocument("firstName", "Jane").put("lastName", "Doe"); - Document doc3 = Document.createDocument("firstName", "Jonas").put("lastName", "Doe"); - Document doc4 = Document.createDocument("firstName", "Johan").put("lastName", "Day"); - - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); - - collection.insert(doc1, doc2, doc3, doc4); - - DocumentCursor cursor = collection.find(where("firstName").eq("John").or(where("lastName").eq("Day"))); - assertEquals(cursor.size(), 2); - - List list = cursor.toList(); - assertEquals(list.size(), 2); - } - - @Test - public void testIssue45() { - NitriteCollection collection = db.getCollection("testIssue45"); - Faker faker = new Faker(); - String text1 = faker.lorem().paragraph() + " quick brown"; - String text2 = faker.lorem().paragraph() + " fox jump"; - String text3 = faker.lorem().paragraph() + " over lazy"; - String text4 = faker.lorem().paragraph() + " dog"; - - List list1 = Arrays.asList(text1, text2); - List list2 = Arrays.asList(text1, text2, text3); - List list3 = Arrays.asList(text2, text3); - List list4 = Arrays.asList(text1, text2, text3, text4); - - Document doc1 = Document.createDocument("firstName", "John").put("notes", list1); - Document doc2 = Document.createDocument("firstName", "Jane").put("notes", list2); - Document doc3 = Document.createDocument("firstName", "Jonas").put("notes", list3); - Document doc4 = Document.createDocument("firstName", "Johan").put("notes", list4); - - collection.createIndex("notes", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.insert(doc1, doc2, doc3, doc4); - - DocumentCursor cursor = collection.find(where("notes").text("fox")); - assertEquals(cursor.size(), 4); - - cursor = collection.find(where("notes").text("dog")); - assertEquals(cursor.size(), 1); - - cursor = collection.find(where("notes").text("lazy")); - assertEquals(cursor.size(), 3); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java deleted file mode 100644 index cf85610fe..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindNegativeTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.ValidationException; -import org.junit.Test; - -import java.util.Date; -import java.util.List; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class CollectionFindNegativeTest extends BaseCollectionTest { - @Test(expected = ValidationException.class) - public void testFindFilterInvalidIndex() { - insert(); - collection.find(where("data.9").eq(4)).toList(); - } - - @Test(expected = ValidationException.class) - public void testFindOptionsNegativeOffset() { - insert(); - collection.find().skipLimit(-1, 1); - } - - @Test(expected = ValidationException.class) - public void testFindOptionsNegativeSize() { - insert(); - collection.find().skipLimit(0, -1); - } - - public void testFindOptionsInvalidOffset() { - insert(); - assertEquals(collection.find().skipLimit(10, 1).size(), 0); - } - - @Test(expected = ValidationException.class) - public void testFindInvalidSort() { - insert(); - collection.find().sort("data", SortOrder.Descending).toList(); - } - - @Test(expected = FilterException.class) - public void testFindTextFilterNonIndexed() { - insert(); - collection.find(where("body").text("Lorem")).toList(); - } - - @Test(expected = FilterException.class) - public void testFindWithRegexInvalidValue() { - insert(); - DocumentCursor cursor = collection.find(where("birthDay").regex("hello")); - assertEquals(cursor.size(), 1); - } - - @Test(expected = ValidationException.class) - public void testInvalidProjection() { - insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); - - Document projection = createDocument("firstName", null) - .put("lastName", "ln2"); - - cursor.project(projection); - } - - @Test(expected = UnsupportedOperationException.class) - public void testToListAdd() { - insert(); - DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); - List documents = cursor.toList(); - documents.add(createDocument()); - } - - @Test(expected = UnsupportedOperationException.class) - public void testToListRemove() { - insert(); - DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); - List documents = cursor.toList(); - documents.clear(); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java deleted file mode 100644 index 90c1ba0ef..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertNegativeTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class CollectionInsertNegativeTest extends BaseCollectionTest { - @Test(expected = UniqueConstraintException.class) - public void testMultipleInsert() { - WriteResult result = collection.insert(doc1, doc2, doc3); - assertEquals(result.getAffectedCount(), 3); - Document document = collection.find().firstOrNull(); - collection.insert(document); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java deleted file mode 100644 index f7d538c31..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionInsertTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.WriteResult; -import org.junit.Test; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.Constants.DOC_ID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class CollectionInsertTest extends BaseCollectionTest { - - @Test - public void testInsert() { - WriteResult result = collection.insert(doc1, doc2, doc3); - assertEquals(result.getAffectedCount(), 3); - - DocumentCursor cursor = collection.find(); - assertEquals(cursor.size(), 3); - - for (Document document : cursor) { - assertNotNull(document.get("firstName")); - assertNotNull(document.get("lastName")); - assertNotNull(document.get("birthDay")); - assertNotNull(document.get("data")); - assertNotNull(document.get("body")); - assertNotNull(document.get(DOC_ID)); - } - } - - @Test - public void testInsertHeteroDocs() { - Document document = createDocument("test", "Nitrite Test"); - - WriteResult result = collection.insert(doc1, doc2, doc3, document); - assertEquals(result.getAffectedCount(), 4); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java deleted file mode 100644 index 2d8ef5ac5..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionJoinTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.RecordStream; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -@Slf4j -public class CollectionJoinTest extends BaseCollectionTest { - private NitriteCollection foreignCollection; - - @Before - @Override - public void setUp() { - try { - super.setUp(); - foreignCollection = db.getCollection("foreign"); - foreignCollection.remove(ALL); - - Document fdoc1 = createDocument("fName", "fn1") - .put("address", "ABCD Street") - .put("telephone", "123456789"); - - Document fdoc2 = createDocument("fName", "fn2") - .put("address", "XYZ Street") - .put("telephone", "000000000"); - - Document fdoc3 = createDocument("fName", "fn2") - .put("address", "Some other Street") - .put("telephone", "7893141321"); - - foreignCollection.insert(fdoc1, fdoc2, fdoc3); - } catch (Throwable t) { - log.error("Error while initializing test database", t); - } - } - - @Test - @SuppressWarnings("unchecked") - public void testJoinAll() { - insert(); - - Lookup lookup = new Lookup(); - lookup.setLocalField("firstName"); - lookup.setForeignField("fName"); - lookup.setTargetField("personalDetails"); - - RecordStream result = collection.find().join(foreignCollection.find(), lookup); - assertEquals(result.size(), 3); - - for (Document document : result) { - if (document.get("firstName") == "fn1") { - Collection personalDetails = (Collection) document.get("personalDetails"); - assertNotNull(personalDetails); - assertEquals(personalDetails.size(), 1); - Object[] details = personalDetails.toArray(); - assertEquals(((Document) details[0]).get("telephone"), "123456789"); - } else if (document.get("firstName") == "fn2") { - Collection personalDetails = (Collection) document.get("personalDetails"); - assertNotNull(personalDetails); - assertEquals(personalDetails.size(), 2); - Object[] details = personalDetails.toArray(); - for (Object o : details) { - Document d = (Document) o; - if (d.get("address").equals("XYZ Street")) { - assertEquals(d.get("telephone"), "000000000"); - } else { - assertEquals(d.get("telephone"), "7893141321"); - } - } - } else if (document.get("firstName") == "fn3") { - assertNull(document.get("personalDetails")); - } - System.out.println(document); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java deleted file mode 100644 index aa1c3cee7..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionUpdateTest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.NotIdentifiableException; -import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.*; - -public class CollectionUpdateTest extends BaseCollectionTest { - - @Test - public void testUpdate() { - insert(); - - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertEquals(document.get("lastName"), "ln1"); - } - - WriteResult updateResult = collection.update(where("firstName").eq("fn1"), - createDocument("lastName", "new-last-name")); - assertEquals(updateResult.getAffectedCount(), 1); - - cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertEquals(document.get("lastName"), "new-last-name"); - } - } - - @Test(expected = NotIdentifiableException.class) - public void testUpsertWithoutId() { - insert(); - Document update = createDocument("lastName", "ln4"); - WriteResult writeResult = collection.update(update, false); - assertEquals(writeResult.getAffectedCount(), 0); - assertEquals(collection.size(), 3); - } - - @Test - public void testUpsert() { - insert(); - assertEquals(collection.size(), 3); - - Document update = createDocument("lastName", "ln4"); - WriteResult writeResult = collection.update(update, true); - assertEquals(writeResult.getAffectedCount(), 1); - assertEquals(collection.size(), 4); - - Document document = collection.find(where("lastName").eq("ln4")) - .firstOrNull(); - assertTrue(isSimilar(document, update, "lastName")); - } - - @Test - public void testOptionUpsert() { - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - - WriteResult updateResult = collection.update(where("firstName").eq("fn1"), - doc1, UpdateOptions.updateOptions(true)); - assertEquals(updateResult.getAffectedCount(), 1); - - cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertTrue(isSimilar(document, doc1, "firstName", "lastName", "birthDay", "data", "list", "body")); - } - } - - @Test - public void testUpdateMultiple() { - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - - insert(); - - Document document = createDocument("lastName", "newLastName1"); - WriteResult updateResult = collection.update(where("firstName").eq("fn1").not(), - document); - assertEquals(updateResult.getAffectedCount(), 2); - - cursor = collection.find(where("lastName").eq("newLastName1")); - assertEquals(cursor.size(), 2); - } - - @Test - public void testUpdateWithOptionsUpsertFalse() { - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - - UpdateOptions updateOptions = new UpdateOptions(); - updateOptions.setInsertIfAbsent(false); - - WriteResult updateResult = collection.update(where("firstName").eq("fn1"), - doc1, updateOptions); - assertEquals(updateResult.getAffectedCount(), 0); - - cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - } - - @Test - public void testUpdateMultipleWithJustOnceFalse() { - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - - insert(); - - UpdateOptions updateOptions = new UpdateOptions(); - updateOptions.setJustOnce(false); - - Document document = createDocument("lastName", "newLastName1"); - WriteResult updateResult = collection.update(where("firstName").eq("fn1").not(), - document, updateOptions); - assertEquals(updateResult.getAffectedCount(), 2); - - cursor = collection.find(where("lastName").eq("newLastName1")); - assertEquals(cursor.size(), 2); - } - - @Test - public void testUpdateMultipleWithJustOnceTrue() { - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 0); - - insert(); - - UpdateOptions updateOptions = new UpdateOptions(); - updateOptions.setJustOnce(true); - - Document document = createDocument("lastName", "newLastName1"); - collection.update(where("firstName").eq("fn1").not(), - document, updateOptions); - } - - @Test - public void testUpdateWithNewField() { - insert(); - - DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertEquals(document.get("lastName"), "ln1"); - } - - WriteResult updateResult = collection.update(where("firstName").eq("fn1"), - createDocument("new-value", "new-value-value")); - assertEquals(updateResult.getAffectedCount(), 1); - - cursor = collection.find(where("firstName").eq("fn1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertEquals(document.get("new-value"), "new-value-value"); - } - } - - @Test - public void testUpdateInvalidFilter() { - insert(); - - DocumentCursor cursor = collection.find(where("lastName").eq("ln1")); - assertEquals(cursor.size(), 1); - for (Document document : cursor) { - assertEquals(document.get("firstName"), "fn1"); - } - - // to check if NitriteId is valid. - WriteResult updateResult = collection.update(where("some-value").eq("some-value"), - createDocument("lastName", "new-last-name")); - assertEquals(updateResult.getAffectedCount(), 0); - } - - @Test - public void updateAfterAttributeRemoval() { - NitriteCollection coll = db.getCollection("test_updateAfterAttributeRemoval"); - coll.remove(Filter.ALL); - - Document doc = createDocument().put("id", "test-1").put("group", "groupA"); - assertEquals(1, coll.insert(doc).getAffectedCount()); - - Document savedDoc1 = coll.find().firstOrNull(); - assertNotNull(savedDoc1); - - Document clonedDoc1 = savedDoc1.clone(); - assertEquals(savedDoc1, clonedDoc1); - - clonedDoc1.put("group", null); -// clonedDoc1.remove("group"); - assertEquals(1, coll.update(clonedDoc1).getAffectedCount()); - - Document savedDoc2 = coll.find(Filter.ALL).firstOrNull(); - assertNotNull(savedDoc2); - assertNull(savedDoc2.get("group")); - } - - @Test(expected = NotIdentifiableException.class) - public void testUpdateWithoutId() { - NitriteCollection collection = db.getCollection("test"); - Document document = createDocument("test", "test123"); - collection.update(document); - } - - @Test(expected = NotIdentifiableException.class) - public void testRemoveWithoutId() { - NitriteCollection collection = db.getCollection("test"); - Document document = createDocument("test", "test123"); - collection.remove(document); - } - - @Test(expected = NitriteIOException.class) - public void testRegisterListenerAfterDrop() { - NitriteCollection collection = db.getCollection("test"); - collection.drop(); - collection.subscribe(changeInfo -> fail("should not happen")); - } - - @Test(expected = NitriteIOException.class) - public void testRegisterListenerAfterClose() { - NitriteCollection collection = db.getCollection("test"); - collection.close(); - collection.subscribe(changeInfo -> fail("should not happen")); - } - - @Test(expected = UniqueConstraintException.class) - public void testIssue151() { - Document doc1 = createDocument().put("id", "test-1").put("fruit", "Apple"); - Document doc2 = createDocument().put("id", "test-2").put("fruit", "Ôrange"); - NitriteCollection coll = db.getCollection("test"); - coll.insert(doc1, doc2); - - coll.createIndex("fruit", indexOptions(IndexType.Unique)); - - assertEquals(coll.find(where("fruit").eq("Apple")).size(), 1); - - Document doc3 = coll.find(where("id").eq("test-2")).firstOrNull(); - - doc3.put("fruit", "Apple"); - coll.update(doc3); - - assertEquals(coll.find(where("fruit").eq("Apple")).size(), 1); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java deleted file mode 100644 index 120ed4b8e..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/NitriteCollectionTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.collection; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.collection.meta.Attributes; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import static org.dizitart.no2.TestUtil.createDb; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee - */ -public class NitriteCollectionTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testAttributes() { - db = createDb(); - NitriteCollection collection = db.getCollection("test"); - - Attributes attributes = new Attributes("test"); - collection.setAttributes(attributes); - - assertEquals(collection.getAttributes(), attributes); - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/SampleListenerCollection.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/SampleListenerCollection.java deleted file mode 100644 index debd67fee..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/SampleListenerCollection.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.common.event; - -import lombok.Getter; -import org.dizitart.no2.collection.events.CollectionEventInfo; -import org.dizitart.no2.collection.events.CollectionEventListener; -import org.dizitart.no2.collection.events.EventType; - -/** - * @author Anindya Chatterjee. - */ -@Getter -class SampleListenerCollection implements CollectionEventListener { - private EventType action; - private Object item; - - @Override - public void onEvent(CollectionEventInfo eventInfo) { - if (eventInfo != null) { - this.action = eventInfo.getEventType(); - this.item = eventInfo.getItem(); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CustomFilterTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java similarity index 79% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CustomFilterTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java index 6e905a7a2..75a15f156 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CustomFilterTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.index.IndexType; import org.junit.Test; @@ -31,7 +33,7 @@ public class CustomFilterTest extends BaseCollectionTest { @Test public void testCustomFilter() { insert(); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); DocumentCursor cursor = collection.find(element -> element.getSecond().get("firstName", String.class) .equalsIgnoreCase("FN1")); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbTestOperations.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java similarity index 73% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbTestOperations.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java index a5592d420..ccf825dfe 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DbTestOperations.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -24,40 +25,54 @@ import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.index.IndexType; import org.junit.Rule; +import org.junit.Test; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.dizitart.no2.mapdb.TestUtil.isSorted; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author Anindya Chatterjee. */ -public class DbTestOperations { - private final String fileName = getRandomTempDbFile(); +public class DbWriteCloseReadTest { + private final String fileName = TestUtil.getRandomTempDbFile(); private Nitrite db; + private volatile boolean writeCompleted = false; @Rule public Retry retry = new Retry(3); - public static String getRandomTempDbFile() { - String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; - File file = new File(dataDir); - if (!file.exists()) { - assertTrue(file.mkdirs()); + @Test + public void testWriteCloseRead() throws Exception { + try { + createDb(); + writeCollection(); + writeIndex(); + insertInCollection(); + } catch (ParseException pe) { + // ignore + } finally { + writeCompleted = true; + } + + try { + assertTrue(writeCompleted); + readCollection(); + } catch (Exception e) { + fail("collection read failed - " + e.getMessage()); + } finally { + deleteDb(); } - return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; } void createDb() { @@ -82,13 +97,13 @@ void writeIndex() { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); db.close(); } - void insertInCollection() throws ParseException { + void insertInCollection() throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); Document doc1 = createDocument("firstName", "fn1") @@ -121,7 +136,7 @@ void insertInCollection() throws ParseException { db.close(); } - void readCollection() throws ParseException { + void readCollection() throws Exception { NitriteCollection collection; db = TestUtil.createDb(fileName); @@ -162,15 +177,24 @@ void readCollection() throws ParseException { cursor = collection.find(where("birthDay").lte(new Date()).or(where("firstName").eq("fn12"))); assertEquals(cursor.size(), 3); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")) - .not()); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -185,14 +209,14 @@ void readCollection() throws ParseException { cursor = collection.find(where("firstName").notIn("fn1", "fn2")); assertEquals(cursor.size(), 1); - collection.createIndex("birthDay", indexOptions(IndexType.Unique)); - cursor = collection.find().sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + collection.createIndex("birthDay"); + cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { dateList.add(document.get("birthDay", Date.class)); } - assertTrue(isSorted(dateList, false)); + assertTrue(TestUtil.isSorted(dateList, false)); cursor = collection.find(where("body").text("Lorem")); assertEquals(cursor.size(), 1); @@ -206,10 +230,10 @@ void readCollection() throws ParseException { db.close(); } - void deleteDb() throws IOException { + void deleteDb() { if (db != null && !db.isClosed()) { db.close(); } - Files.delete(Paths.get(fileName)); + TestUtil.deleteDb(fileName); } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DocumentMetadataTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java similarity index 91% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DocumentMetadataTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java index 29a571830..15d01451f 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/DocumentMetadataTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.events.EventType; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MultiThreadedTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java similarity index 85% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MultiThreadedTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java index 562698815..11a7b35bf 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/MultiThreadedTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -25,6 +26,7 @@ import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -38,8 +40,6 @@ import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -49,7 +49,7 @@ */ @RunWith(Parameterized.class) public class MultiThreadedTest { - private static final String fileName = getRandomTempDbFile(); + private static final String fileName = TestUtil.getRandomTempDbFile(); @Parameterized.Parameter public boolean inMemory = false; private NitriteCollection collection; @@ -58,7 +58,7 @@ public class MultiThreadedTest { private final int iterationCount = 100; private final Random generator = new Random(); private final AtomicInteger docCounter = new AtomicInteger(0); - private ExecutorService executor = ThreadPoolManager.getThreadPool(threadCount, "MultiThreadedTest"); + private ExecutorService executor; private Nitrite db; @Parameterized.Parameters(name = "InMemory = {0}") @@ -72,13 +72,18 @@ public static Collection data() { @Rule public Retry retry = new Retry(3); + @Before + public void setUp() { + executor = ThreadPoolManager.getThreadPool(threadCount, "MultiThreadedTest"); + } + @Test public void testOperations() throws InterruptedException { - db = inMemory ? createDb() : createDb(fileName); + db = inMemory ? TestUtil.createDb() : TestUtil.createDb(fileName); collection = db.getCollection("test"); collection.remove(Filter.ALL); - collection.createIndex("unixTime", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("unixTime"); db.commit(); for (int i = 0; i < threadCount; i++) { @@ -91,8 +96,8 @@ public void testOperations() throws InterruptedException { if (j == iterationCount / 2 && !collection.hasIndex("text") && !collection.hasIndex("date")) { - collection.createIndex("text", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("date", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "text"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "date"); } long unixTime = (long) document.get("unixTime"); @@ -133,7 +138,7 @@ public void testOperations() throws InterruptedException { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java index b93aea6fd..036e480ce 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.common.util.StringUtils; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; @@ -27,8 +29,8 @@ import java.io.File; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java similarity index 97% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java index a42b6daa7..fc5457ee5 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteBuilderTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java @@ -1,34 +1,38 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.NitriteBuilder; +import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreConfig; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; @@ -49,11 +53,11 @@ import java.util.LinkedHashSet; import java.util.Random; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; import static org.dizitart.no2.common.module.NitriteModule.module; +import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteCorruptedTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteCorruptedTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java index 4dcfdf1ca..72e18a326 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteCorruptedTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -25,12 +26,12 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.util.concurrent.ExecutorService; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -50,7 +51,7 @@ public class NitriteCorruptedTest { @Before public void setUp() { - db = TestUtil.createDb(fileName); + db = createDb(fileName); collection = db.getCollection("test"); collection.remove(ALL); @@ -75,7 +76,7 @@ public void setUp() { } @After - public void tearDown() throws IOException { + public void tearDown() throws Exception { if (collection.isOpen()) { collection.remove(ALL); collection.close(); @@ -83,7 +84,7 @@ public void tearDown() throws IOException { if (db != null && !db.isClosed()) { db.close(); } - TestUtil.deleteFile(fileName); + TestUtil.deleteDb(fileName); } @Test(timeout = 10000) diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java similarity index 89% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java index f7a28104e..222038b62 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.exceptions.NitriteException; import org.junit.After; @@ -25,9 +27,9 @@ import java.io.File; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; /** diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java similarity index 82% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java index b98480a98..a21a9c541 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/NitriteSecurityTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.exceptions.NitriteSecurityException; import org.junit.After; @@ -24,13 +26,9 @@ import org.junit.Test; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -45,7 +43,7 @@ public class NitriteSecurityTest { public Retry retry = new Retry(3); @Test - public void testSecured() throws IOException { + public void testSecured() { db = createDb(fileName, "test-user", "test-password"); NitriteCollection dbCollection = db.getCollection("test"); dbCollection.insert(createDocument("test", "test")); @@ -56,11 +54,11 @@ public void testSecured() throws IOException { dbCollection = db.getCollection("test"); assertEquals(dbCollection.find().size(), 1); db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } @Test - public void testUnsecured() throws IOException { + public void testUnsecured() { db = createDb(fileName); NitriteCollection dbCollection = db.getCollection("test"); dbCollection.insert(createDocument("test", "test")); @@ -71,7 +69,7 @@ public void testUnsecured() throws IOException { dbCollection = db.getCollection("test"); assertEquals(dbCollection.find().size(), 1); db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } @Test @@ -90,7 +88,7 @@ public void testInMemory() { } @Test - public void testIssue116() throws IOException { + public void testIssue116() { db = createDb(fileName, "test-user", "test-password"); db.close(); try { @@ -100,7 +98,7 @@ public void testIssue116() throws IOException { assertNotNull(db); } finally { db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java similarity index 63% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index 401db2ef4..90b15b3a1 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/StressTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -1,32 +1,34 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; import org.junit.After; @@ -36,22 +38,24 @@ import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; + /** * @author Anindya Chatterjee */ -public class StressTest { +public class NitriteStressTest { + private static final int TEST_SET_COUNT = 15000; + private final PodamFactory podamFactory = new PodamFactoryImpl(); private final String fileName = getRandomTempDbFile(); private Nitrite db; private NitriteCollection collection; @@ -61,24 +65,48 @@ public class StressTest { @Before public void before() { - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(fileName) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - + db = createDb(fileName); collection = db.getCollection("test"); System.out.println(fileName); } + @After + public void cleanUp() { + if (db != null && !db.isClosed()) { + long start = System.currentTimeMillis(); + db.close(); + System.out.println("Time to compact and close - " + (System.currentTimeMillis() - start) / 1000 + " seconds"); + } + + deleteDb(fileName); + } + + @Test + public void stressTest() { + ObjectRepository testRepository = db.getRepository(TestDto.class); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "lastName"); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDate"); + + int counter = 0; + try { + for (TestDto testDto : createTestSet()) { + testRepository.insert(testDto); + counter++; + } + } catch (Throwable t) { + System.err.println("Crashed after " + counter + " records"); + throw t; + } + + int size = testRepository.find().toList().size(); + assertEquals(counter, size); + } + @Test public void testIssue41() { - collection.createIndex("number", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("name", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("counter", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "number"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "name"); + collection.createIndex("counter"); Random random = new Random(); AtomicLong counter = new AtomicLong(System.currentTimeMillis()); @@ -118,16 +146,6 @@ public void testIssue41() { System.out.println("Iteration completed in " + ((System.currentTimeMillis() - start) / (1000)) + " seconds"); } - @After - public void clear() throws IOException { - if (db != null && !db.isClosed()) { - long start = System.currentTimeMillis(); - db.close(); - System.out.println("Time to compact and close - " + (System.currentTimeMillis() - start) / 1000 + " seconds"); - } - Files.delete(Paths.get(fileName)); - } - @Test public void testRepoPerformanceWithIndex() { // warm-up @@ -182,6 +200,15 @@ public void testRepoPerformanceWithoutIndex() { System.out.println("Time take to remove 10000 non-indexed items - " + diff + "ms"); } + private List createTestSet() { + List testData = new ArrayList<>(); + for (int i = 0; i < TEST_SET_COUNT; i++) { + TestDto testRecords = podamFactory.manufacturePojo(TestDto.class); + testData.add(testRecords); + } + return testData; + } + private List getItems(Class type) { PodamFactory generator = new PodamFactoryImpl(); List items = new ArrayList<>(); @@ -192,6 +219,79 @@ private List getItems(Class type) { return items; } + @Data + public static class TestDto implements Mappable { + + @XmlElement( + name = "StudentNumber", + required = true + ) + @Id + protected String studentNumber; + + @XmlElement( + name = "LastName", + required = true + ) + protected String lastName; + + @XmlElement( + name = "Prefixes" + ) + protected String prefixes; + + @XmlElement( + name = "Initials", + required = true + ) + protected String initials; + + @XmlElement( + name = "FirstNames" + ) + protected String firstNames; + @XmlElement( + name = "Nickname" + ) + protected String nickName; + + @XmlElement( + name = "BirthDate", + required = true + ) + @XmlSchemaType( + name = "date" + ) + protected String birthDate; + + + public TestDto() { + } + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("studentNumber", studentNumber) + .put("lastName", lastName) + .put("prefixes", prefixes) + .put("initials", initials) + .put("firstNames", firstNames) + .put("nickName", nickName) + .put("birthDate", birthDate); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + studentNumber = document.get("studentNumber", String.class); + lastName = document.get("lastName", String.class); + prefixes = document.get("prefixes", String.class); + initials = document.get("initials", String.class); + firstNames = document.get("firstNames", String.class); + nickName = document.get("nickName", String.class); + birthDate = document.get("birthDate", String.class); + } + } + @Data public static class PerfTest implements Mappable { private String firstName; @@ -219,9 +319,9 @@ public void read(NitriteMapper mapper, Document document) { } @Indices({ - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "age", type = IndexType.NonUnique), - @Index(value = "text", type = IndexType.Fulltext), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "age", type = IndexType.NON_UNIQUE), + @Index(value = "text", type = IndexType.FULL_TEXT), }) private static class PerfTestIndexed extends PerfTest { } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/Retry.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/Retry.java similarity index 66% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/Retry.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/Retry.java index b9706d1a0..3d6a27d11 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/Retry.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/Retry.java @@ -1,4 +1,21 @@ -package org.dizitart.no2; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration; import org.junit.rules.TestRule; import org.junit.runner.Description; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/SerializabilityTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java similarity index 86% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/SerializabilityTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java index 3783e957d..09ca50080 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/SerializabilityTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; import lombok.Data; import org.dizitart.no2.Nitrite; @@ -27,34 +28,34 @@ import org.junit.Test; import java.io.File; -import java.io.IOException; import java.io.Serializable; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; - /** * @author Anindya Chatterjee */ public class SerializabilityTest { - private Nitrite db; private NitriteCollection collection; private File dbFile; + private Nitrite db; @Rule public Retry retry = new Retry(3); @Before public void setUp() { - dbFile = new File(getRandomTempDbFile()); + dbFile = new File(TestUtil.getRandomTempDbFile()); db = TestUtil.createDb(dbFile.getPath()); collection = db.getCollection("test"); } @After - public void tearDown() throws IOException { - db.close(); + public void tearDown() { + if (db != null && !db.isClosed()) { + db.close(); + } + if (dbFile.exists()) { - TestUtil.deleteFile(dbFile.getPath()); + TestUtil.deleteDb(dbFile.getPath()); } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/TestUtil.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/TestUtil.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java index d95b25961..4a0034399 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/TestUtil.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -1,48 +1,62 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.mvstore.MVStoreModule; +import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; +import static org.junit.Assert.assertTrue; + /** * @author Anindya Chatterjee */ @Slf4j public class TestUtil { - /** - * Determines whether the supplied `iterable` is sorted. - * - * @param the type parameter - * @param iterable the iterable - * @param ascending a boolean value indicating whether to sort in ascending order - * @return the boolean value indicating if `iterable` is sorted or not. - */ + public static String getRandomTempDbFile() { + String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; + File file = new File(dataDir); + if (!file.exists()) { + assertTrue(file.mkdirs()); + } + return file.getPath() + File.separator + UUID.randomUUID() + ".db"; + } + + @SneakyThrows + public static void deleteDb(String filePath) { + Files.delete(Paths.get(filePath)); + } + public static > boolean isSorted(Iterable iterable, boolean ascending) { Iterator iterator = iterable.iterator(); if (!iterator.hasNext()) { @@ -180,7 +194,6 @@ private static List loadArray(JsonNode array) { return null; } - private static ObjectMapper createObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility( diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java similarity index 92% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java index 8b59d4a1c..6898e1169 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/BaseCollectionTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java @@ -1,26 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.junit.After; @@ -29,16 +32,15 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.nio.file.Files; -import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Locale; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; @Slf4j @RunWith(value = Parameterized.class) @@ -126,7 +128,7 @@ public void clear() { } if (db != null && !db.isClosed()) db.close(); if (!inMemory) { - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } catch (Throwable t) { log.error("Error while clearing test database", t); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java new file mode 100644 index 000000000..746fe397b --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Date; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexNegativeTest extends BaseCollectionTest { + + @Test(expected = UniqueConstraintException.class) + public void testCreateInvalidUniqueIndex() { + doc1 = createDocument("firstName", "fn3") + .put("lastName", "ln2") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", Arrays.asList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + + collection.createIndex("lastName", "firstName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateUniqueMultiKeyIndexOnArray() { + collection.createIndex("data", "lastName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateOnInvalidField() { + insert(); + // multiple null value will be created + collection.createIndex( "my-value", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testDropIndexOnNonIndexedField() { + collection.dropIndex("data", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testRebuildIndexInvalid() { + collection.rebuildIndex("unknown", "firstName"); + } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameFields() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testIndexAlreadyExists() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateCompoundTextIndex() { + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateMultiKeyIndexSecondField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "data"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } +} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java new file mode 100644 index 000000000..8d37792ed --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import com.google.common.collect.Lists; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.Date; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.awaitility.Awaitility.await; +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexTest extends BaseCollectionTest { + @Test + public void testCreateAndCheckIndex() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertFalse(collection.hasIndex("firstName", "lastName", "birthDay")); + assertFalse(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testCreateMultiKeyIndexFirstField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "data", "lastName"); + assertTrue(collection.hasIndex("data")); + assertTrue(collection.hasIndex("data", "lastName")); + assertFalse(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testListIndexes() { + assertEquals(collection.listIndices().size(), 0); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertEquals(collection.listIndices().size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + assertEquals(collection.listIndices().size(), 2); + } + + @Test + public void testDropIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + collection.dropIndex("firstName", "lastName"); + assertFalse(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertFalse(collection.hasIndex("firstName")); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testHasIndex() { + assertFalse(collection.hasIndex("lastName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + assertTrue(collection.hasIndex("lastName")); + } + + @Test + public void testDropAllIndexes() { + collection.dropAllIndices(); + + collection.createIndex("firstName", "lastName"); + collection.createIndex("firstName"); + assertEquals(collection.listIndices().size(), 2); + + collection.dropAllIndices(); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testRebuildIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + insert(); + collection.rebuildIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + } + + @Test + public void testDeleteWithIndex() { + collection.createIndex("firstName", "lastName"); + + insert(); + + WriteResult result = collection.remove(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + assertEquals(result.getAffectedCount(), 1); + + result = collection.remove(and(where("firstName").eq("fn2"), + where("birthDay").gte(new Date()))); + assertEquals(result.getAffectedCount(), 0); + } + + @Test + public void testRebuildIndexOnRunningIndex() { + insert(); + db.getStore().subscribe(System.out::println); + + collection.createIndex("firstName", "lastName"); + collection.rebuildIndex("firstName", "lastName"); + + assertTrue(collection.hasIndex("firstName", "lastName")); + } + + @Test + public void testNullValuesInIndexedFields() { + collection.createIndex("firstName", "lastName"); + collection.createIndex("birthDay", "lastName"); + Document document = createDocument("firstName", null) + .put("lastName", "ln1") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", Lists.newArrayList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + + insert(); + collection.insert(document); + + DocumentCursor cursor = collection.find(where("fistName").eq(null)); + assertEquals("ln1", cursor.firstOrNull().get("lastName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + document = createDocument("firstName", "fn4") + .put("lastName", null) + .put("birthDay", null) + .put("data", new byte[]{1, 2, 3}) + .put("list", Lists.newArrayList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + collection.insert(document); + + cursor = collection.find(where("lastName").eq(null)); + assertEquals("fn4", cursor.firstOrNull().get("firstName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + cursor = collection.find(and(where("lastName").eq(null), where("birthDay").eq(null))); + assertNull(cursor.firstOrNull().get("lastName", String.class)); + } + + @Test + public void testDropAllAndCreateIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + + DocumentCursor cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + FindPlan findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + + collection.dropAllIndices(); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + + collection.createIndex("firstName", "lastName"); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + } + + @Test + public void testIssue178() { + collection.dropAllIndices(); + collection.remove(Filter.ALL); + + Document doc1 = createDocument("field1", 5); + Document doc2 = createDocument("field1", 4.3).put("field2", 3.5); + Document doc3 = createDocument("field1", 0.03).put("field2", 5); + Document doc4 = createDocument("field1", 4).put("field2", 4.5); + Document doc5 = createDocument("field1", 5.0).put("field2", 5.0); + + collection.insert(doc1, doc2, doc3, doc4, doc5); + + DocumentCursor cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + + collection.createIndex("field1", "field2"); + cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + } + + @Test + public void testIndexEvent() { + NitriteCollection collection = db.getCollection("index-test"); + Random random = new Random(); + for (int i = 0; i < 10000; i++) { + Document document = createDocument("first", random.nextInt()) + .put("second", random.nextDouble()); + collection.insert(document); + } + + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); + collection.subscribe(eventInfo -> { + switch (eventInfo.getEventType()) { + case Insert: + case Remove: + case Update: + failed.set(true); + break; + case IndexStart: + case IndexEnd: + completed.set(true); + break; + } + }); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first", "second"); + assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); + } + + @Test + public void testIndexAndSearchOnNullValues() { + NitriteCollection collection = db.getCollection("index-on-null"); + collection.insert(createDocument("first", null).put("second", 123).put("third", new Integer[]{1, 2, null})); + collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); + collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); + + collection.createIndex("third", "first"); + assertEquals(collection.find(where("first").eq(null)).size(), 1); + + assertEquals(collection.find(where("third").eq(null)).size(), 2); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java index d541d3523..9c9d9bd6a 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -22,7 +23,6 @@ import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java similarity index 93% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java index 799c4d169..ca1660599 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionDeleteTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java @@ -1,27 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; @@ -74,7 +74,7 @@ public void testDeleteInEmptyCollection() { @Test public void testClear() { - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); insert(); DocumentCursor cursor = collection.find(); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFieldIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFieldIndexTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java index 76dc2edd4..358e83a39 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFieldIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -32,8 +33,7 @@ /** * @author Anindya Chatterjee */ -public class CollectionFieldIndexTest extends AbstractTest { - +public class CollectionFieldIndexTest extends BaseCollectionTest { @Test public void testCollection() { Document doc1 = Document.createDocument("name", "Anindya") @@ -67,9 +67,9 @@ public void testCollection() { }); NitriteCollection collection = db.getCollection("test"); - collection.createIndex("color", indexOptions(IndexType.Unique)); - collection.createIndex("books.tag", indexOptions(IndexType.NonUnique)); - collection.createIndex("books.name", indexOptions(IndexType.Fulltext)); + collection.createIndex("color"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "books.tag"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "books.name"); WriteResult writeResult = collection.insert(doc1, doc2, doc3); assertEquals(writeResult.getAffectedCount(), 3); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java new file mode 100644 index 000000000..8fd30693e --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.AndFilter; +import org.dizitart.no2.filters.IndexScanFilter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.text.ParseException; +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionFindByCompoundIndexTest extends BaseCollectionTest { + + @Test + public void testFindByAndFilter() { + insert(); + collection.createIndex("list", "lastName", "firstName"); + DocumentCursor cursor = collection.find(and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1"), + where("list").eq("four") + )); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(findPlan.getIndexDescriptor(), collection.listIndices().toArray()[0]); + + IndexScanFilter indexScanFilter = findPlan.getIndexScanFilter(); + assertEquals(indexScanFilter.getFilters().get(0), where("list").eq("four")); + assertEquals(indexScanFilter.getFilters().get(1), where("lastName").eq("ln2")); + assertEquals(indexScanFilter.getFilters().get(2), where("firstName").notEq("fn1")); + + List documents = cursor.toList(); + assertEquals(documents.size(), 1); + assertEquals(documents.get(0).get("body", String.class), "quick hello world from nitrite"); + } + + @Test + public void testFindByOrFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + or( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getSubPlans()); + + assertEquals(2, findPlan.getSubPlans().size()); + assertNotNull(findPlan.getSubPlans().get(0).getIndexScanFilter()); + assertNotNull(findPlan.getSubPlans().get(1).getIndexScanFilter()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn2") + && d.get("lastName", String.class).equals("ln2")).count()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn3") + && d.get("lastName", String.class).equals("ln2")).count()); + } + + @Test + public void testFindByAndFilterOrFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ), findPlan.getCollectionScanFilter()); + } + + @Test + public void testFindByAndFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(1, cursor.size()); + FindPlan findPlan = cursor.getFindPlan(); + + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(collection.listIndices().toArray()[0], findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getIndexScanFilter()); + assertEquals(findPlan.getIndexScanFilter().getFilters(), + ((AndFilter) and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + )).getFilters()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(where("firstName").eq("fn3"), findPlan.getCollectionScanFilter()); + + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(cursor.toList().get(0).get("firstName", String.class), "fn3"); + } + + @Test + public void testFindByOrFilter() throws ParseException { + // all or clause has index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + collection.createIndex("birthDay"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(3, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindOrNoIndex() throws ParseException { + // on of the or clause has no index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(0, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindAndNoIndex() throws ParseException { + // index at second field + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + where("firstName").notEq("fn1"), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(0, cursor.size()); + } + + @Test + public void testSortByIndex() throws ParseException { + // multiple field sort in both direction + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } + + @Test + public void testBlockingSort() throws ParseException { + // multiple field sort in memory + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortNotCoveredByIndex() throws ParseException { + // some field sort by index, some by memory + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortByIndexPrefix() throws ParseException { + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + // duplicate birthday will have natural sort order - ascending + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + } + + @Test + public void testLimitAndSkip() throws ParseException { + // test skip and limit + + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + .skip(2) + .limit(1) + ); + + List documents = cursor.toList(); + assertEquals(1, documents.size()); + + Document document = documents.get(0); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + assertEquals(2L, (long)findPlan.getSkip()); + assertEquals(1L, (long)findPlan.getLimit()); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java similarity index 79% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java index ab5a86e65..76b84a0e6 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java @@ -1,26 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; @@ -33,7 +33,7 @@ public class CollectionFindByIndexNegativeTest extends BaseCollectionTest { @Test(expected = FilterException.class) public void testFindTextWithWildCardMultipleWord() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*ipsum dolor*")); assertEquals(cursor.size(), 1); @@ -42,7 +42,7 @@ public void testFindTextWithWildCardMultipleWord() { @Test(expected = FilterException.class) public void testFindTextWithOnlyWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*")); assertEquals(cursor.size(), 1); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java similarity index 79% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java index b4f659e12..cbef67e26 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import com.github.javafaker.Faker; import org.dizitart.no2.collection.Document; @@ -24,7 +25,6 @@ import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import java.text.ParseException; @@ -33,27 +33,30 @@ import java.util.Date; import java.util.List; +import static org.dizitart.no2.integration.TestUtil.isSorted; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.TestUtil.isSorted; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Anindya Chatterjee. */ -public class CollectionFindByIndexTest extends BaseCollectionTest { +public class CollectionFindBySingleFieldIndexTest extends BaseCollectionTest { @Test public void testFindByUniqueIndex() throws ParseException { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); cursor = collection.find(where("firstName").eq("fn10")); assertEquals(cursor.size(), 0); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); cursor = collection.find(where("birthDay").gt( simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); assertEquals(cursor.size(), 1); @@ -72,7 +75,6 @@ public void testFindByUniqueIndex() throws ParseException { cursor = collection.find(where("birthDay").lte( new Date())); - assertEquals(cursor.size(), 3); cursor = collection.find(where("birthDay").lt( @@ -98,15 +100,23 @@ public void testFindByUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -125,8 +135,8 @@ public void testFindByUniqueIndex() throws ParseException { @Test public void testFindByNonUniqueIndex() throws ParseException { insert(); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDay"); DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); assertEquals(cursor.size(), 2); @@ -177,15 +187,23 @@ public void testFindByNonUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -204,7 +222,7 @@ public void testFindByNonUniqueIndex() throws ParseException { @Test public void testFindByFullTextIndexAfterInsert() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); DocumentCursor cursor = collection.find(where("body").text("Lorem")); @@ -226,7 +244,7 @@ public void testFindByFullTextIndexAfterInsert() { @Test public void testFindByFullTextIndexBeforeInsert() { - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); insert(); @@ -253,9 +271,9 @@ public void testFindByFullTextIndexBeforeInsert() { @Test public void testFindByIndexSortAscending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -267,9 +285,9 @@ public void testFindByIndexSortAscending() { @Test public void testFindByIndexSortDescending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -281,10 +299,13 @@ public void testFindByIndexSortDescending() { @Test public void testFindByIndexLimitAndSort() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find( + orderBy("birthDay", SortOrder.Descending) + .skip(1) + .limit(2) + ); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -292,8 +313,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -301,8 +321,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -314,7 +333,7 @@ public void testFindByIndexLimitAndSort() { @Test public void testFindAfterDroppedIndex() { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); @@ -326,7 +345,7 @@ public void testFindAfterDroppedIndex() { @Test public void testFindTextWithWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("Lo")); assertEquals(cursor.size(), 0); @@ -344,7 +363,7 @@ public void testFindTextWithWildCard() { @Test public void testFindTextWithEmptyString() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("")); assertEquals(cursor.size(), 0); @@ -358,8 +377,8 @@ public void testFindWithOrIndexed() { Document doc3 = Document.createDocument("firstName", "Jonas").put("lastName", "Doe"); Document doc4 = Document.createDocument("firstName", "Johan").put("lastName", "Day"); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); collection.insert(doc1, doc2, doc3, doc4); @@ -389,7 +408,7 @@ public void testIssue45() { Document doc3 = Document.createDocument("firstName", "Jonas").put("notes", list3); Document doc4 = Document.createDocument("firstName", "Johan").put("notes", list4); - collection.createIndex("notes", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "notes"); collection.insert(doc1, doc2, doc3, doc4); DocumentCursor cursor = collection.find(where("notes").text("fox")); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java similarity index 83% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java index 6791e75b9..8d446cf0f 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java @@ -1,33 +1,35 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import java.util.Date; import java.util.List; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; @@ -44,24 +46,25 @@ public void testFindFilterInvalidIndex() { @Test(expected = ValidationException.class) public void testFindOptionsNegativeOffset() { insert(); - collection.find().skipLimit(-1, 1); + collection.find(skipBy(-1).limit(1)); } @Test(expected = ValidationException.class) public void testFindOptionsNegativeSize() { insert(); - collection.find().skipLimit(0, -1); + collection.find(skipBy(0).limit(-1)); } + @Test public void testFindOptionsInvalidOffset() { insert(); - assertEquals(collection.find().skipLimit(10, 1).size(), 0); + assertEquals(collection.find(skipBy(10).limit(1)).size(), 0); } @Test(expected = ValidationException.class) public void testFindInvalidSort() { insert(); - collection.find().sort("data", SortOrder.Descending).toList(); + collection.find(orderBy("data", SortOrder.Descending)).toList(); } @Test(expected = FilterException.class) @@ -80,8 +83,8 @@ public void testFindWithRegexInvalidValue() { @Test(expected = ValidationException.class) public void testInvalidProjection() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", "ln2"); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java similarity index 80% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java index 49dae5f27..f5e5a2c04 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionFindTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java @@ -1,21 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.ValidationException; @@ -29,16 +34,17 @@ import java.util.*; import java.util.stream.Collectors; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.*; import static org.dizitart.no2.common.Constants.*; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.TestUtil.isSorted; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.*; public class CollectionFindTest extends BaseCollectionTest { @@ -105,18 +111,25 @@ public void testFindWithFilter() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); - cursor = collection.find(where("data.1").eq((byte) 4)); assertEquals(cursor.size(), 2); @@ -137,16 +150,16 @@ public void testFindWithFilter() throws ParseException { public void testFindWithSkipLimit() { insert(); - DocumentCursor cursor = collection.find().skipLimit(0, 1); + DocumentCursor cursor = collection.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); - cursor = collection.find().skipLimit(1, 3); + cursor = collection.find(skipBy(1).limit(3)); assertEquals(cursor.size(), 2); - cursor = collection.find().skipLimit(0, 30); + cursor = collection.find(skipBy(0).limit(30)); assertEquals(cursor.size(), 3); - cursor = collection.find().skipLimit(2, 3); + cursor = collection.find(skipBy(2).limit(3)); assertEquals(cursor.size(), 1); } @@ -154,21 +167,21 @@ public void testFindWithSkipLimit() { public void testFindWithSkip() { insert(); - DocumentCursor cursor = collection.find().skip(0); + DocumentCursor cursor = collection.find(skipBy(0)); assertEquals(cursor.size(), 3); - cursor = collection.find().skip(1); + cursor = collection.find(skipBy(1)); assertEquals(cursor.size(), 2); - cursor = collection.find().skip(30); + cursor = collection.find(skipBy(30)); assertEquals(cursor.size(), 0); - cursor = collection.find().skip(2); + cursor = collection.find(skipBy(2)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().skip(-1); + cursor = collection.find(skipBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; @@ -180,22 +193,22 @@ public void testFindWithSkip() { public void testFindWithLimit() { insert(); - DocumentCursor cursor = collection.find().limit(0); + DocumentCursor cursor = collection.find(limitBy(0)); assertEquals(cursor.size(), 0); - cursor = collection.find().limit(1); + cursor = collection.find(limitBy(1)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().limit(-1); + cursor = collection.find(limitBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; } assertTrue(invalid); - cursor = collection.find().limit(30); + cursor = collection.find(limitBy(30)); assertEquals(cursor.size(), 3); } @@ -203,7 +216,7 @@ public void testFindWithLimit() { public void testFindSortAscending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -216,7 +229,7 @@ public void testFindSortAscending() { public void testFindSortDescending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -229,8 +242,7 @@ public void testFindSortDescending() { public void testFindLimitAndSort() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -238,8 +250,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -247,8 +258,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -260,7 +270,7 @@ public void testFindLimitAndSort() { @Test public void testFindSortOnNonExistingField() { insert(); - DocumentCursor cursor = collection.find().sort("my-value", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("my-value", SortOrder.Descending)); assertEquals(cursor.size(), 3); } @@ -281,8 +291,7 @@ public void testFindInvalidFieldWithInvalidAccessor() { @Test public void testFindLimitAndSortInvalidField() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay2", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay2", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -305,8 +314,8 @@ public void testGetById() { @Test public void testFindWithFilterAndOption() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -329,8 +338,8 @@ public void testFindTextWithRegex() { @Test public void testProject() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); int iteration = 0; for (Document document : cursor) { switch (iteration) { @@ -352,8 +361,8 @@ public void testProject() { @Test public void testProjectWithCustomDocument() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", null); @@ -613,8 +622,8 @@ public void testFilterAll() { @Test public void testIssue72() { NitriteCollection coll = db.getCollection("test"); - coll.createIndex("id", IndexOptions.indexOptions(IndexType.Unique)); - coll.createIndex("group", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "id"); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "group"); coll.remove(ALL); @@ -624,13 +633,14 @@ public void testIssue72() { doc = createDocument().put("id", "test-2").put("group", "groupA").put("startTime", DateTime.now()); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(1).get("startTime")); assertNotNull(cursor.toList().get(0).get("startTime")); - cursor = coll.find(where("group").eq("groupA")).sort("startTime", SortOrder.Ascending); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(0).get("startTime")); assertNotNull(cursor.toList().get(1).get("startTime")); @@ -648,8 +658,8 @@ public void testIssue93() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); } @@ -665,52 +675,16 @@ public void testNullOrderWithAllNull() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); - - DocumentCursor cursor2 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); - assertEquals(2, cursor2.size()); - - assertThat(cursor.toList(), is(cursor2.toList())); - - DocumentCursor cursor3 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(2, cursor3.size()); - - assertThat(cursor.toList(), is(cursor3.toList())); - - DocumentCursor cursor4 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(2, cursor4.size()); - - assertThat(cursor.toList(), is(cursor4.toList())); - - DocumentCursor cursor5 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(2, cursor5.size()); - - assertThat(cursor.toList(), is(cursor5.toList())); - - DocumentCursor cursor6 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(2, cursor6.size()); - - assertThat(cursor.toList(), is(cursor6.toList())); - - DocumentCursor cursor7 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); - assertEquals(2, cursor7.size()); - - assertThat(cursor.toList(), is(cursor7.toList())); } @Test - public void testNullOrder() { + public void testDefaultNullOrder() { NitriteCollection coll = db.getCollection("test"); try { - coll.createIndex("startTime", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "startTime"); } catch (IndexingException e) { // ignore } @@ -726,47 +700,18 @@ public void testNullOrder() { Document doc3 = createDocument().put("id", "test-3").put("group", "groupA").put("startTime", DateTime.now().plusMinutes(1)); assertEquals(1, coll.insert(doc3).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc3, doc2), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc2, doc3), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc2, doc3), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc2, doc3, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); } @Test @@ -785,8 +730,8 @@ public void testIssue144() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2, doc3); - DocumentCursor cursor = coll.find().sort("fruit", SortOrder.Ascending, - Collator.getInstance(Locale.FRANCE)); + DocumentCursor cursor = coll.find(orderBy("fruit", SortOrder.Ascending) + .collator(Collator.getInstance(Locale.FRANCE))); assertEquals(cursor.toList().get(1).get("fruit"), "Ôrange"); } @@ -838,7 +783,7 @@ public void testBetweenFilter() { NitriteCollection collection = db.getCollection("tag"); collection.insert(doc1, doc2, doc3, doc4, doc5); - collection.createIndex("age", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "age"); DocumentCursor cursor = collection.find(where("age").between(31, 35)); assertEquals(cursor.size(), 5); @@ -852,4 +797,29 @@ public void testBetweenFilter() { cursor = collection.find(where("age").between(31, 35, false).not()); assertEquals(cursor.size(), 2); } + + @Test + public void testByIdFilter() { + Document doc1 = createDocument("age", 31).put("tag", "one"); + Document doc2 = createDocument("age", 32).put("tag", "two"); + Document doc3 = createDocument("age", 33).put("tag", "three"); + Document doc4 = createDocument("age", 34).put("tag", "four"); + Document doc5 = createDocument("age", 35).put("tag", "five"); + + NitriteCollection collection = db.getCollection("tag"); + collection.insert(doc1, doc2, doc3, doc4, doc5); + + List documentList = collection.find().toList(); + Document document = documentList.get(0); + NitriteId nitriteId = document.getId(); + + Document result = collection.find(byId(nitriteId)).firstOrNull(); + assertEquals(document, result); + + result = collection.find(and(byId(nitriteId), where("age").notEq(null))).firstOrNull(); + assertEquals(document, result); + + result = collection.find(or(byId(nitriteId), where("tag").eq(document.get("tag")))).firstOrNull(); + assertEquals(document, result); + } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java similarity index 77% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java index 3c0828520..f6ce8612e 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; @@ -31,30 +32,30 @@ public class CollectionIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("lastName"); assertTrue(collection.hasIndex("lastName")); insert(); } @Test(expected = UniqueConstraintException.class) public void testCreateIndexOnArray() { - collection.createIndex("data", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("data"); assertTrue(collection.hasIndex("data")); // data array field has repetition, so unique constraint exception insert(); } - @Test + @Test(expected = UniqueConstraintException.class) public void testCreateOnInvalidField() { insert(); - collection.createIndex("my-value", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("my-value"); assertTrue(collection.hasIndex("my-value")); } @Test(expected = IndexingException.class) public void testCreateFullTextOnNonTextField() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "birthDay"); assertTrue(collection.hasIndex("birthDay")); } @@ -65,6 +66,6 @@ public void testDropIndexOnNonIndexedField() { @Test(expected = IndexingException.class) public void testRebuildIndexInvalid() { - collection.rebuildIndex("unknown", true); + collection.rebuildIndex("unknown"); } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java new file mode 100644 index 000000000..247a1705a --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; +import java.util.concurrent.Callable; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee. + */ +public class CollectionIndexTest extends BaseCollectionTest { + + @Test + public void testCollection() { + Document doc1 = Document.createDocument("name", "Anindya") + .put("color", new String[]{"red", "green", "blue"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book ABCD") + .put("tag", new String[]{"tag1", "tag2"}), + Document.createDocument("name", "Book EFGH") + .put("tag", new String[]{"tag3", "tag1"}), + Document.createDocument("name", "No Tag") + }); + + Document doc2 = Document.createDocument("name", "Bill") + .put("color", new String[]{"purple", "yellow", "gray"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book abcd") + .put("tag", new String[]{"tag4", "tag5"}), + Document.createDocument("name", "Book wxyz") + .put("tag", new String[]{"tag3", "tag1"}), + Document.createDocument("name", "No Tag 2") + }); + + Document doc3 = Document.createDocument("name", "John") + .put("color", new String[]{"black", "sky", "violet"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book Mnop") + .put("tag", new String[]{"tag6", "tag2"}), + Document.createDocument("name", "Book ghij") + .put("tag", new String[]{"tag3", "tag7"}), + Document.createDocument("name", "No Tag") + }); + + NitriteCollection collection = db.getCollection("test"); + collection.createIndex("color"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "books.tag"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "books.name"); + + WriteResult writeResult = collection.insert(doc1, doc2, doc3); + assertEquals(writeResult.getAffectedCount(), 3); + + DocumentCursor documents = collection.find(where("color").eq("red")); + assertTrue(isSimilar(documents.firstOrNull(), doc1, "name", "color", "books")); + + documents = collection.find(where("books.name").text("abcd")); + assertEquals(documents.size(), 2); + + documents = collection.find(where("books.tag").eq("tag2")); + assertEquals(documents.size(), 2); + + documents = collection.find(where("books.tag").eq("tag5")); + assertEquals(documents.size(), 1); + + documents = collection.find(where("books.tag").eq("tag10")); + assertEquals(documents.size(), 0); + } + + @Test + public void testCreateIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + + collection.createIndex("birthDay", null); + assertTrue(collection.hasIndex("birthDay")); + + insert(); + } + + @Test + public void testListIndexes() { + assertEquals(collection.listIndices().size(), 0); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + + assertEquals(collection.listIndices().size(), 3); + } + + @Test + public void testDropIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertFalse(collection.hasIndex("firstName")); + } + + @Test + public void testDropAllIndexes() { + collection.dropAllIndices(); + + testCreateIndex(); + assertEquals(collection.listIndices().size(), 4); + + collection.dropAllIndices(); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testHasIndex() { + assertFalse(collection.hasIndex("lastName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + assertFalse(collection.hasIndex("body")); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + } + + @Test + public void testDeleteWithIndex() { + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + + insert(); + + WriteResult result = collection.remove(where("firstName").eq("fn1")); + assertEquals(result.getAffectedCount(), 1); + + DocumentCursor cursor = collection.find(); + assertEquals(cursor.size(), 2); + + result = collection.remove(where("body").text("Lorem")); + assertEquals(result.getAffectedCount(), 1); + + cursor = collection.find(); + assertEquals(cursor.size(), 1); + } + + @Test + public void testRebuildIndex() { + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + insert(); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); + } + } + + private Callable bodyIndexingCompleted() { + return () -> !collection.isIndexing("body"); + } + + @Test + public void testNullValueInIndexedField() { + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); + insert(); + + Document document = createDocument("firstName", null) + .put("lastName", "ln1") + .put("birthDay", null) + .put("data", new byte[]{1, 2, 3}) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) + .put("body", "a quick brown fox jump over the lazy dog"); + + collection.insert(document); + } + + @Test + public void testDropAllAndCreateIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + collection.dropAllIndices(); + assertFalse(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection = db.getCollection("test"); + assertTrue(collection.hasIndex("firstName")); + } + + @Test + public void testIssue178() { + collection.dropAllIndices(); + collection.remove(Filter.ALL); + + Document doc1 = createDocument("field", 5); + Document doc2 = createDocument("field", 4.3); + Document doc3 = createDocument("field", 0.03); + Document doc4 = createDocument("field", 4); + Document doc5 = createDocument("field", 5.0); + + collection.insert(doc1, doc2, doc3, doc4, doc5); + + DocumentCursor cursor = collection.find(where("field").eq(5)); + assertEquals(cursor.size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); + + cursor = collection.find(where("field").eq(5)); + assertEquals(cursor.size(), 1); + } + + @Test + public void testIndexEvent() { + NitriteCollection collection = db.getCollection("index-test"); + Random random = new Random(); + for (int i = 0; i < 10000; i++) { + Document document = createDocument("first", random.nextInt()) + .put("second", random.nextDouble()); + collection.insert(document); + } + + collection.subscribe(eventInfo -> { + switch (eventInfo.getEventType()) { + case Insert: + fail("wrong event Insert"); + break; + case Update: + fail("wrong event Update"); + break; + case Remove: + fail("wrong event Remove"); + break; + case IndexStart: + case IndexEnd: + break; + } + assertTrue(eventInfo.getItem() instanceof String); + System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); + }); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); + assertEquals(collection.find().size(), 10000); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); + assertEquals(collection.find().size(), 10000); + } + + @Test + public void testIndexAndSearchOnNullValues() { + NitriteCollection collection = db.getCollection("index-on-null"); + collection.insert(createDocument("first", null).put("second", 123).put("third", new Integer[]{1, 2, null})); + collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); + collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); + + collection.createIndex("first"); + assertEquals(collection.find(where("first").eq(null)).size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); + assertEquals(collection.find(where("third").eq(null)).size(), 2); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java similarity index 85% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java index 5d455e93d..02358caf6 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java index cbfdfa471..cd9558946 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionInsertTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.collection.Document.createDocument; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionJoinTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java similarity index 94% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionJoinTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java index a2220b271..caff44d61 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionJoinTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java @@ -1,27 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Before; import org.junit.Test; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java new file mode 100644 index 000000000..b459e469b --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee. + */ +public class CollectionSingleFieldIndexNegativeTest extends BaseCollectionTest { + + @Test(expected = UniqueConstraintException.class) + public void testCreateInvalidUniqueIndex() { + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateIndexOnArray() { + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "data"); + assertTrue(collection.hasIndex("data")); + // data array field has repetition, so unique constraint exception + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateOnInvalidField() { + insert(); + // multiple null value will be created + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "my-value"); + assertTrue(collection.hasIndex("my-value")); + } + + @Test(expected = IndexingException.class) + public void testCreateFullTextOnNonTextField() { + insert(); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "birthDay"); + assertTrue(collection.hasIndex("birthDay")); + } + + @Test(expected = IndexingException.class) + public void testDropIndexOnNonIndexedField() { + collection.dropIndex("data"); + } + + @Test(expected = IndexingException.class) + public void testRebuildIndexInvalid() { + collection.rebuildIndex("unknown"); + } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameField() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + } +} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java similarity index 66% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java index 774338f70..fe37845e1 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/CollectionIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java @@ -1,21 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection; +package org.dizitart.no2.integration.collection; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; @@ -27,6 +31,7 @@ import java.util.Collection; import java.util.Random; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; import static org.awaitility.Awaitility.await; import static org.dizitart.no2.collection.Document.createDocument; @@ -37,20 +42,20 @@ /** * @author Anindya Chatterjee. */ -public class CollectionIndexTest extends BaseCollectionTest { +public class CollectionSingleFieldIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); - collection.createIndex("birthDay", null); + collection.createIndex("birthDay"); assertTrue(collection.hasIndex("birthDay")); insert(); @@ -60,13 +65,13 @@ public void testCreateIndex() { public void testListIndexes() { assertEquals(collection.listIndices().size(), 0); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); assertEquals(collection.listIndices().size(), 3); @@ -74,7 +79,7 @@ public void testListIndexes() { @Test public void testDropIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropIndex("firstName"); @@ -95,18 +100,18 @@ public void testDropAllIndexes() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); assertFalse(collection.hasIndex("body")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); } @Test public void testDeleteWithIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); @@ -123,53 +128,29 @@ public void testDeleteWithIndex() { assertEquals(cursor.size(), 1); } - @Test - public void testCreateIndexAsync() { - insert(); - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); - assertTrue(collection.isIndexing("body")); - - await().until(bodyIndexingCompleted()); - } - @Test public void testRebuildIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - insert(); - Collection indices = collection.listIndices(); - for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), false); - } - } - - @Test - public void testRebuildIndexAsync() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); - await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), true); - await().until(bodyIndexingCompleted()); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); } } @Test public void testRebuildIndexOnRunningIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexDescriptor idx = indices.iterator().next(); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex("body"); boolean error = false; try { - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex("body"); } catch (IndexingException ie) { error = true; } finally { - assertTrue(error); + assertFalse(error); await().until(bodyIndexingCompleted()); } } @@ -180,8 +161,8 @@ private Callable bodyIndexingCompleted() { @Test public void testNullValueInIndexedField() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("birthDay", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); insert(); Document document = createDocument("firstName", null) @@ -200,12 +181,12 @@ public void testNullValueInIndexedField() { @Test public void testDropAllAndCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropAllIndices(); assertFalse(collection.hasIndex("firstName")); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection = db.getCollection("test"); @@ -228,7 +209,7 @@ public void testIssue178() { DocumentCursor cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); - collection.createIndex("field", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); @@ -244,30 +225,30 @@ public void testIndexEvent() { collection.insert(document); } + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); collection.subscribe(eventInfo -> { switch (eventInfo.getEventType()) { case Insert: - fail("wrong event Insert"); - break; - case Update: - fail("wrong event Update"); - break; case Remove: - fail("wrong event Remove"); + case Update: + failed.set(true); break; case IndexStart: case IndexEnd: + completed.set(true); break; } - assertTrue(eventInfo.getItem() instanceof String); - System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); }); - collection.createIndex("first", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); assertEquals(collection.find().size(), 10000); - collection.createIndex("second", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); } @Test @@ -277,10 +258,17 @@ public void testIndexAndSearchOnNullValues() { collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); - collection.createIndex("first", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "first"); assertEquals(collection.find(where("first").eq(null)).size(), 1); - collection.createIndex("third", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } + + @Test + public void testCreateCompoundAndSingleFieldIndexOnSameField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionUpdateTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java similarity index 95% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionUpdateTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java index 5691999cc..86bff59b5 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionUpdateTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -25,14 +26,11 @@ import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; import static org.junit.Assert.*; public class CollectionUpdateTest extends BaseCollectionTest { @@ -246,7 +244,7 @@ public void testRegisterListenerAfterDrop() { } @Test(expected = NitriteIOException.class) - public void testRegisterListenerAfterClose() { + public void testRegisterListenerAfterClose() throws Exception { NitriteCollection collection = db.getCollection("test"); collection.close(); collection.subscribe(changeInfo -> fail("should not happen")); @@ -259,7 +257,7 @@ public void testIssue151() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2); - coll.createIndex("fruit", indexOptions(IndexType.Unique)); + coll.createIndex("fruit"); assertEquals(coll.find(where("fruit").eq("Apple")).size(), 1); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java new file mode 100644 index 000000000..0055f97ac --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseCollectionTest { + + private Encryptor encryptor; + private NitriteCollection collection; + private Processor cvvProcessor; + + @Before + public void setUp() { + super.setUp(); + + encryptor = new AESEncryptor("s3k4e8"); + cvvProcessor = new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String cvv = document.get("cvv", String.class); + String encryptedCvv = encryptor.encrypt(cvv.getBytes(StandardCharsets.UTF_8)); + document.put("cvv", encryptedCvv); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCvv = document.get("cvv", String.class); + String cvv = encryptor.decrypt(encryptedCvv); + document.put("cvv", cvv); + return document; + } + }; + StringFieldEncryptionProcessor creditCardProcessor = new StringFieldEncryptionProcessor(encryptor); + creditCardProcessor.addFields("creditCardNumber"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(creditCardProcessor); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.addProcessor(cvvProcessor); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = collection.getStore().openMap("encryption-test", + NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + Document document = collection.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5500960345687452"); + assertEquals(document.get("cvv", String.class), "008"); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5548960345687452"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + Encryptor wrongEncryptor = new AESEncryptor("secret"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testUpdateEncryptedField() { + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "00000000000000") + .put("cvv", "007") + .put("expiryDate", new Date()); + + WriteResult writeResult = collection.update(where("name").eq("John Doe"), document); + assertEquals(writeResult.getAffectedCount(), 1); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "00000000000000"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + collection.createIndex("cvv"); + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testRemoveProcessor() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + + collection.removeProcessor(cvvProcessor); + + document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(document); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/NitriteCollectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java similarity index 80% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/NitriteCollectionTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java index 8c48d8f48..ad3534435 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/NitriteCollectionTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java @@ -1,24 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.rocksdb.AbstractTest; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -26,7 +26,7 @@ /** * @author Anindya Chatterjee */ -public class NitriteCollectionTest extends AbstractTest { +public class NitriteCollectionTest extends BaseCollectionTest { @Test public void testAttributes() { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/EventTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java similarity index 95% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/EventTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java index 9ad63d60f..813a36503 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/common/event/EventTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java @@ -1,29 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.common.event; +package org.dizitart.no2.integration.event; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.Employee; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.data.Employee; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -32,8 +33,6 @@ import org.junit.runners.Parameterized; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.Callable; @@ -41,9 +40,10 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -256,7 +256,7 @@ public void clear() throws IOException { } if (!inMemory) { - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/SampleListenerCollection.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/SampleListenerCollection.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java index b4938756c..6297ecbc1 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/SampleListenerCollection.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.common.event; +package org.dizitart.no2.integration.event; import lombok.Getter; import org.dizitart.no2.collection.events.CollectionEventInfo; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java similarity index 93% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java index 162474d9c..9b4eeab29 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/MigrationTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java @@ -1,11 +1,29 @@ -package org.dizitart.no2.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import com.github.javafaker.Faker; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Constants; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; @@ -19,14 +37,10 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.UUID; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.*; /** @@ -47,12 +61,12 @@ public void setUp() { } @After - public void cleanUp() throws IOException { + public void cleanUp() { if (!db.isClosed()) { db.close(); } - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } @Test @@ -84,7 +98,7 @@ public void migrate(Instructions instruction) { instruction.forRepository(OldClass.class, "demo1") .renameRepository("new", null) .changeDataType("empId", (TypeConverter) Long::parseLong) - .changeIdField("uuid", "empId") + .changeIdField(Fields.withNames("uuid"), Fields.withNames("empId")) .deleteField("uuid") .renameField("lastName", "familyName") .addField("fullName", document -> document.get("firstName", String.class) + " " @@ -128,8 +142,8 @@ public void testCollectionMigrate() { collection.insert(document); } - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("bloodGroup", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "bloodGroup"); db.close(); Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @@ -176,7 +190,7 @@ public void migrate(Instructions instructions) { .addField("address") .addField("vehicles", 1) .renameField("age", "ageGroup") - .createIndex("ageGroup", IndexType.NonUnique); + .createIndex(IndexType.NON_UNIQUE, "ageGroup"); } }; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java similarity index 69% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java index e10997fa2..56ef25c22 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/NewClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.mapdb.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -14,9 +31,9 @@ */ @Data @Entity(value = "new", indices = { - @Index(value = "familyName", type = IndexType.NonUnique), - @Index(value = "fullName", type = IndexType.NonUnique), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "familyName", type = IndexType.NON_UNIQUE), + @Index(value = "fullName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class NewClass implements Mappable { @Id diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java similarity index 67% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java index cd0ea75bf..3bbb09b4e 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/migrate/OldClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.mapdb.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -14,10 +31,10 @@ */ @Data @Entity(value = "old", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), - @Index(value = "literature.text", type = IndexType.Fulltext), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.text", type = IndexType.FULL_TEXT), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class OldClass implements Mappable { @Id diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMapStressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteMapStressTest.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMapStressTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteMapStressTest.java index e7671aa6f..82986a8c7 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMapStressTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteMapStressTest.java @@ -1,23 +1,24 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mvstore; +package org.dizitart.no2.integration.mvstore; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.ValidationException; @@ -27,13 +28,9 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.UUID; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -113,10 +110,10 @@ public void testNullPutIfAbsent() { } @After - public void tearDown() throws IOException { + public void tearDown() { if (db != null && !db.isClosed()) { db.close(); } - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteStoreEventTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteStoreEventTest.java similarity index 89% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteStoreEventTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteStoreEventTest.java index 6e66f2ce1..f9d66266c 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteStoreEventTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/mvstore/NitriteStoreEventTest.java @@ -1,24 +1,26 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mvstore; +package org.dizitart.no2.integration.mvstore; import lombok.Data; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.store.events.EventInfo; import org.dizitart.no2.store.events.StoreEventListener; import org.junit.After; @@ -27,12 +29,11 @@ import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -57,9 +58,7 @@ public void cleanup() throws IOException { db.close(); } - if (Files.exists(Paths.get(dbFile))) { - Files.delete(Paths.get(dbFile)); - } + deleteDb(dbFile); } @Test diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java similarity index 84% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java index 6c2150ed2..2d33d0c43 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/BaseObjectRepositoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java @@ -1,41 +1,41 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; @RunWith(value = Parameterized.class) public abstract class BaseObjectRepositoryTest { @@ -53,6 +53,8 @@ public abstract class BaseObjectRepositoryTest { protected ObjectRepository employeeRepository; protected ObjectRepository aObjectRepository; protected ObjectRepository cObjectRepository; + protected ObjectRepository bookRepository; + private final String fileName = getRandomTempDbFile(); @Rule @@ -91,6 +93,8 @@ public void setUp() { aObjectRepository = db.getRepository(ClassA.class); cObjectRepository = db.getRepository(ClassC.class); + bookRepository = db.getRepository(Book.class); + for (int i = 0; i < 10; i++) { Company company = DataGenerator.generateCompanyRecord(); companyRepository.insert(company); @@ -100,10 +104,13 @@ public void setUp() { aObjectRepository.insert(ClassA.create(i + 50)); cObjectRepository.insert(ClassC.create(i + 30)); + + Book book = DataGenerator.randomBook(); + bookRepository.insert(book); } } - private void openDb() { + protected void openDb() { MVStoreModuleBuilder builder = MVStoreModule.withConfig(); if (isCompressed) { @@ -131,7 +138,7 @@ private void openDb() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (companyRepository != null && !companyRepository.isDropped()) { companyRepository.remove(ALL); } @@ -148,13 +155,17 @@ public void clear() throws IOException { cObjectRepository.remove(ALL); } + if (bookRepository != null && !bookRepository.isDropped()) { + bookRepository.remove(ALL); + } + if (db != null && !db.isClosed()) { db.commit(); db.close(); } if (!inMemory) { - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java similarity index 86% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java index 073d511b8..965a8d8ab 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/CustomFieldSeparatorTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -1,38 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.Company; +import org.dizitart.no2.integration.repository.data.Note; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.dizitart.no2.repository.data.Company; -import org.dizitart.no2.repository.data.Note; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -42,14 +44,17 @@ import java.util.Date; import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; /** * @author Anindya Chatterjee */ public class CustomFieldSeparatorTest { - private Nitrite db; + private final String fileName = getRandomTempDbFile(); private ObjectRepository repository; + private Nitrite db; @Rule public Retry retry = new Retry(3); @@ -57,6 +62,7 @@ public class CustomFieldSeparatorTest { @Before public void setUp() { MVStoreModule module = MVStoreModule.withConfig() + .filePath(fileName) .compress(true) .build(); @@ -73,6 +79,7 @@ public void reset() { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { db.close(); + deleteDb(fileName); } } @@ -111,9 +118,9 @@ public void testFindByEmbeddedField() { @ToString @EqualsAndHashCode @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote:text", type = IndexType.Fulltext) + @Index(value = "joinDate", type = IndexType.NON_UNIQUE), + @Index(value = "address", type = IndexType.FULL_TEXT), + @Index(value = "employeeNote:text", type = IndexType.FULL_TEXT) }) public static class EmployeeForCustomSeparator implements Serializable, Mappable { @Id diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java new file mode 100644 index 000000000..73a093082 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.integration.repository.data.EncryptedPerson; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseObjectRepositoryTest { + private ObjectRepository persons; + private StringFieldEncryptionProcessor fieldProcessor; + + @Before + public void setUp() { + super.setUp(); + persons = db.getRepository(EncryptedPerson.class); + fieldProcessor = new StringFieldEncryptionProcessor("s3k4e8"); + fieldProcessor.addFields("creditCardNumber", "cvv"); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + persons.insert(person); + + persons.addProcessor(fieldProcessor); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + persons.insert(person); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = persons.getDocumentCollection().getStore() + .openMap(findRepositoryName(EncryptedPerson.class, null), NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + EncryptedPerson person = persons.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5500960345687452"); + assertEquals(person.getCvv(), "008"); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5548960345687452"); + assertEquals(person.getCvv(), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + ObjectRepository testPersons = db.getRepository(EncryptedPerson.class, "test"); + + Encryptor encryptor = new AESEncryptor("secret"); + Encryptor wrongEncryptor = new AESEncryptor("secret", "AES/GCM/NoPadding", + 5, 5, 5); + + testPersons.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + testPersons.insert(person); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + testPersons.insert(person); + + testPersons.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testUpdateEncryptedField() { + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("00000000000000"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + WriteResult writeResult = persons.update(where("name").eq("John Doe"), person); + assertEquals(writeResult.getAffectedCount(), 1); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "00000000000000"); + assertEquals(person.getCvv(), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + persons.createIndex("cvv"); + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testRemoveProcessor() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNull(person); + + persons.removeProcessor(fieldProcessor); + + person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNotNull(person); + } +} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java index 1c9fda1da..1a52708ce 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/InternalClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/NitriteIdAsIdTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java similarity index 86% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/NitriteIdAsIdTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java index 994e24b93..dedd5e256 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/NitriteIdAsIdTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java @@ -1,29 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.WithNitriteId; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.util.Iterables; import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.TestUtil; -import org.dizitart.no2.mapdb.repository.data.WithNitriteId; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; @@ -32,10 +33,9 @@ import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -59,7 +59,7 @@ public void before() { @After public void after() throws IOException { db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } @Test diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectCursorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectCursorTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java index cc8a4a123..5be20ded7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectCursorTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java @@ -1,23 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.Employee; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.rocksdb.repository.data.Employee; import org.dizitart.no2.repository.Cursor; import org.junit.Test; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryNegativeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java similarity index 84% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryNegativeTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java index 968d9bd97..e070d485d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryNegativeTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java @@ -1,29 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.*; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.TestUtil; -import org.dizitart.no2.mapdb.repository.data.*; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; @@ -31,10 +32,9 @@ import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -56,7 +56,7 @@ public void setUp() { public void close() throws IOException { db.close(); db = null; - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } @Test(expected = ObjectMappingException.class) @@ -132,7 +132,7 @@ public void testFindResultRemove() { result.iterator().remove(); } - @Test(expected = InvalidOperationException.class) + @Test(expected = IndexingException.class) public void testWithObjectId() { ObjectRepository repository = db.getRepository(WithObjectId.class); WithOutId id = new WithOutId(); @@ -209,4 +209,25 @@ public void testExternalNitriteId() { result = repository.update(obj, true); assertNotEquals(id.getIdValue(), result.iterator().next().getIdValue()); } + + @Test(expected = IndexingException.class) + public void testWithoutEmbeddedId() { + ObjectRepository repository = db.getRepository(WithoutEmbeddedId.class); + assertNull(repository); + } + + @Test(expected = InvalidIdException.class) + public void testGetByWrongIdType() { + ObjectRepository repository = db.getRepository(WithPublicField.class); + WithPublicField object = new WithPublicField(); + object.name = "test"; + object.number = 2; + + repository.insert(object); + + NitriteId id = NitriteId.createId("1"); + WithPublicField instance = repository.getById(id); + assertEquals(object.name, instance.name); + assertEquals(object.number, instance.number); + } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java similarity index 92% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index 0492685cf..16455e07d 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -1,55 +1,57 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import com.github.javafaker.Faker; import lombok.Data; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexType; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.MappableMapper; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.index.IndexType; import org.dizitart.no2.mvstore.MVStoreModule; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.data.*; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Date; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.common.module.NitriteModule.module; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -80,7 +82,7 @@ public void setUp() { public void close() throws IOException { db.close(); db = null; - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } @Test @@ -180,6 +182,7 @@ public void testWriteThousandRecords() { Cursor cursor = repository.find(where("failed").eq(false)); + for (StressRecord record : cursor) { record.setProcessed(true); repository.update(where("firstName").eq(record.getFirstName()), record); @@ -305,12 +308,12 @@ public void testKeyedRepository() { assertEquals(db.listRepositories().size(), 1); assertEquals(db.listKeyedRepository().size(), 2); - assertEquals(employeeRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(employeeRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(managerRepo.find(where("address").eq("xyz")).size(), 0); - assertEquals(managerRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("abcd")).size(), 0); + assertEquals(employeeRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(employeeRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(managerRepo.find(where("address").text("xyz")).size(), 0); + assertEquals(managerRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(developerRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(developerRepo.find(where("address").text("abcd")).size(), 0); } @Test @@ -357,8 +360,8 @@ public void testIssue217() { @Data @Entity(value = "entity.employee", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), }) private static class EmployeeEntity implements Mappable { private static final Faker faker = new Faker(); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ProjectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java similarity index 82% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ProjectionTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java index b510b088e..c6a85b0a3 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ProjectionTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java @@ -1,28 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapdb.repository.data.SubEmployee; import org.junit.Test; import java.util.Iterator; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.junit.Assert.*; /** @@ -32,28 +34,28 @@ public class ProjectionTest extends BaseObjectRepositoryTest { @Test public void testHasMore() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertFalse(iterable.isEmpty()); } @Test public void testSize() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertEquals(iterable.size(), 5); } @Test public void testToString() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertNotNull(iterable.toString()); } @Test(expected = InvalidOperationException.class) public void testRemove() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java new file mode 100644 index 000000000..9431d991e --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.integration.repository.data.Book; +import org.dizitart.no2.integration.repository.data.BookId; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryCompoundIndexTest extends BaseObjectRepositoryTest { + + @Test + public void testFindById() { + BookId bookId = new BookId(); + bookId.setAuthor("John Doe"); + bookId.setIsbn("123456"); + bookId.setName("Nitrite Database"); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription("Some random book description"); + book.setPrice(22.56); + book.setPublisher("My Publisher House"); + book.setTags(Arrays.asList("database", "nosql")); + + bookRepository.insert(book); + + Book bookById = bookRepository.getById(bookId); + assertEquals(bookById, book); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java similarity index 81% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java index 248f13df7..d617767c0 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryFactoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java @@ -1,44 +1,45 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.repository.RepositoryFactory; -import org.dizitart.no2.rocksdb.DbTestOperations; -import org.dizitart.no2.rocksdb.Retry; -import org.dizitart.no2.rocksdb.TestUtil; import org.dizitart.no2.store.NitriteStore; import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.util.Collection; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertNotNull; /** @@ -46,11 +47,16 @@ */ public class RepositoryFactoryTest { private Nitrite db; - private final String fileName = DbTestOperations.getRandomTempDbFile(); + private final String fileName = getRandomTempDbFile(); @Rule public Retry retry = new Retry(3); + @Before + public void setUp() { + db = TestUtil.createDb(fileName); + } + @Test public void testRepositoryFactory() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); @@ -60,14 +66,12 @@ public void testRepositoryFactory() { @Test(expected = ValidationException.class) public void testNullType() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(fileName); factory.getRepository(db.getConfig(), null, "dummy"); } @Test public void testNullCollection() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(fileName); factory.getRepository(db.getConfig(), DummyCollection.class, null); } @@ -78,11 +82,11 @@ public void testNullContext() { } @After - public void cleanUp() throws IOException { + public void cleanUp() { if (db != null && !db.isClosed()) { db.close(); } - TestUtil.deleteFile(fileName); + TestUtil.deleteDb(fileName); } private static class DummyCollection implements NitriteCollection { @@ -102,6 +106,16 @@ public WriteResult remove(Filter filter, boolean justOne) { return null; } + @Override + public DocumentCursor find() { + return null; + } + + @Override + public DocumentCursor find(Filter filter) { + return null; + } + @Override public DocumentCursor find(Filter filter, FindOptions findOptions) { return null; @@ -118,22 +132,22 @@ public String getName() { } @Override - public void createIndex(String field, IndexOptions indexOptions) { + public void addProcessor(Processor processor) { } @Override - public void createIndex(Fields fields, IndexOptions indexOptions) { + public void removeProcessor(Processor processor) { } @Override - public void rebuildIndex(String field) { + public void createIndex(IndexOptions indexOptions, String... fields) { } @Override - public void rebuildIndex(Fields fields) { + public void rebuildIndex(String... fields) { } @@ -143,32 +157,17 @@ public Collection listIndices() { } @Override - public boolean hasIndex(String field) { + public boolean hasIndex(String... fields) { return false; } @Override - public boolean hasIndex(Fields fields) { + public boolean isIndexing(String... fields) { return false; } @Override - public boolean isIndexing(String field) { - return false; - } - - @Override - public boolean isIndexing(Fields fields) { - return false; - } - - @Override - public void dropIndex(String field) { - - } - - @Override - public void dropIndex(Fields fields) { + public void dropIndex(String... fields) { } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java similarity index 94% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java index dc7fe6c87..4dacdbff8 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryJoinTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java @@ -1,42 +1,43 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.Filter.ALL; import static org.junit.Assert.*; @@ -75,7 +76,7 @@ public void setUp() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (personRepository != null && !personRepository.isDropped()) { personRepository.remove(ALL); } @@ -84,11 +85,6 @@ public void clear() throws IOException { addressRepository.remove(ALL); } - if (db != null) { - db.commit(); - db.close(); - } - super.clear(); } @@ -114,7 +110,7 @@ public void testJoin() { } } - result = personRepository.find().skipLimit(0, 5).join(addressRepository.find(), lookup, + result = personRepository.find(skipBy(0).limit(5)).join(addressRepository.find(), lookup, PersonDetails.class); assertEquals(result.size(), 5); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java similarity index 91% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index 723d6f0ef..d5bd0f5cb 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositoryModificationTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; @@ -25,7 +27,6 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.repository.data.*; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; @@ -52,18 +53,19 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); - companyRepository.rebuildIndex("dateCreated", true); - assertTrue(companyRepository.isIndexing("dateCreated")); + companyRepository.rebuildIndex("dateCreated"); + // rebuild is sync + assertFalse(companyRepository.isIndexing("dateCreated")); await().until(() -> !companyRepository.isIndexing("dateCreated")); } @@ -73,7 +75,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } @@ -193,7 +195,7 @@ public void testUpdateWithJustOnceFalse() throws ParseException { @Test public void testUpsertTrue() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -218,7 +220,7 @@ public void testUpsertTrue() { @Test public void testUpsertFalse() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -245,7 +247,7 @@ public void testDeleteFilterAndWithOutOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate)); @@ -259,7 +261,7 @@ public void testDeleteFilterAndWithOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate), true); @@ -278,7 +280,7 @@ public void testEmployeeRecord() { } } - Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); + Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); assertEquals(cursor.size(), occurrence); } @@ -630,4 +632,26 @@ public void testUpdateObjectExistsUpsertFalse() { assertEquals(repo.find().firstOrNull().getId(), 1); assertEquals(repo.find().firstOrNull().getName(), "second"); } + + @Test + public void testNestedUpdate() { + Employee employee = employeeRepository.getById(1L); + assertNotNull(employee); + + Note note = employee.getEmployeeNote(); + String text = note.getText(); + assertNotNull(text); + + Document update = createDocument("employeeNote.text", "some updated text"); + WriteResult writeResult = employeeRepository.update(where("empId").eq(1L), update, true); + assertEquals(1, writeResult.getAffectedCount()); + + employee = employeeRepository.getById(1L); + assertNotNull(employee); + + note = employee.getEmployeeNote(); + assertNotNull(note); + assertNotEquals(text, note.getText()); + assertEquals("some updated text", note.getText()); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java index ac8bdf37c..68015c9f3 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/RepositorySearchTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java @@ -1,31 +1,32 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import lombok.Getter; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.rocksdb.repository.data.*; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; @@ -35,7 +36,9 @@ import java.util.GregorianCalendar; import java.util.List; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.*; @@ -46,7 +49,7 @@ public class RepositorySearchTest extends BaseObjectRepositoryTest { @Test public void testFindWithOptions() { - Cursor cursor = employeeRepository.find().skipLimit(0, 1); + Cursor cursor = employeeRepository.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); assertNotNull(cursor.firstOrNull()); } @@ -117,11 +120,8 @@ public void testGetByIdNoId() { Note n2 = DataGenerator.randomNote(); Note n3 = DataGenerator.randomNote(); - assert n1 != null; n1.setNoteId(1000000L); - assert n2 != null; n2.setNoteId(2000000L); - assert n3 != null; n3.setNoteId(3000000L); repository.insert(n1, n2, n3); @@ -216,12 +216,14 @@ public void testAndFilter() { String address = emp.getAddress(); Date joinDate = emp.getJoinDate(); - Employee employee = employeeRepository.find( - where("empId").eq(id) - .and( - where("address").regex(address) - .and( - where("joinDate").eq(joinDate)))).firstOrNull(); + Cursor cursor = employeeRepository.find( + and( + where("empId").eq(id), + where("address").regex(address), + where("joinDate").eq(joinDate) + ) + ); + Employee employee = cursor.firstOrNull(); assertEquals(emp, employee); } @@ -232,11 +234,11 @@ public void testOrFilter() { long id = emp.getEmpId(); Employee employee = employeeRepository.find( - where("empId").eq(id) - .or( - where("address").regex("n/a") - .or( - where("joinDate").eq(null)))).firstOrNull(); + or( + where("empId").eq(id), + where("address").text("n/a"), + where("joinDate").eq(null) + )).firstOrNull(); assertEquals(emp, employee); } @@ -253,7 +255,7 @@ public void testNotFilter() { @Test public void testGreaterFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gt(id)) @@ -265,7 +267,7 @@ public void testGreaterFilter() { @Test public void testGreaterEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gte(id)) @@ -277,7 +279,7 @@ public void testGreaterEqualFilter() { @Test public void testLesserThanFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lt(id)) @@ -289,9 +291,7 @@ public void testLesserThanFilter() { @Test public void testLesserEqualFilter() { - employeeRepository = db.getRepository(Employee.class); - - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lte(id)) @@ -314,10 +314,11 @@ public void testTextFilter() { @Test public void testRegexFilter() { - RecordStream employees = employeeRepository.find(); + Cursor employees = employeeRepository.find(); int count = employees.toList().size(); - List employeeList = employeeRepository.find(where("employeeNote.text").regex(".*")) + List employeeList = employeeRepository.find(where("emailAddress") + .regex("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$")) .toList(); assertEquals(employeeList.size(), count); @@ -325,7 +326,7 @@ public void testRegexFilter() { @Test public void testInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").in(id, id - 1, id - 2)) @@ -340,7 +341,7 @@ public void testInFilter() { @Test public void testNotInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").notIn(id, id - 1, id - 2)) @@ -480,7 +481,7 @@ public void testFilterAll() { assertEquals(cursor.size(), 1); } - @Test + @Test(expected = FilterException.class) public void testEqualsOnTextIndex() { PersonEntity p1 = new PersonEntity("jhonny"); PersonEntity p2 = new PersonEntity("jhonny"); @@ -529,12 +530,12 @@ public void testIssue62() { Filter married = where("status").eq("Married"); assertEquals(repository.find(married).size(), 2); - assertEquals(repository.find(married).sort("status", SortOrder.Descending).size(), 2); + assertEquals(repository.find(married, orderBy("status", SortOrder.Descending)).size(), 2); - assertEquals(repository.find().sort("status", SortOrder.Descending).firstOrNull().getStatus(), "Un-Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Descending)).firstOrNull().getStatus(), "Un-Married"); - assertEquals(repository.find().sort("status", SortOrder.Ascending).size(), 3); - assertEquals(repository.find().sort("status", SortOrder.Ascending).firstOrNull().getStatus(), "Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).size(), 3); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).firstOrNull().getStatus(), "Married"); } @Test @@ -555,7 +556,7 @@ public void testRepeatableIndexAnnotation() { @Test public void testIdSet() { - Cursor employees = employeeRepository.find().sort("empId", SortOrder.Ascending); + Cursor employees = employeeRepository.find(orderBy("empId", SortOrder.Ascending)); assertEquals(employees.size(), 10); } @@ -563,11 +564,11 @@ public void testIdSet() { public void testBetweenFilter() { @Getter class TestData implements Mappable { - private Date age; + private Date age; - public TestData(Date age) { - this.age = age; - } + public TestData(Date age) { + this.age = age; + } @Override public Document write(NitriteMapper mapper) { diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UnAnnotatedObjectTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java similarity index 69% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UnAnnotatedObjectTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java index b6ce0f421..cf793fb10 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/UnAnnotatedObjectTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java @@ -1,30 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.ClassA; +import org.dizitart.no2.integration.repository.data.ClassC; import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.repository.data.ClassA; -import org.dizitart.no2.mapdb.repository.data.ClassC; import org.dizitart.no2.repository.Cursor; import org.junit.Test; +import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,18 +35,15 @@ public class UnAnnotatedObjectTest extends BaseObjectRepositoryTest { @Test - @SuppressWarnings("unchecked") public void testFind() { - Cursor cursor = aObjectRepository.find(); + Cursor cursor = aObjectRepository.find(); assertEquals(cursor.size(), 10); assertFalse(cursor.isEmpty()); - IndexOptions indexOptions = new IndexOptions(); - indexOptions.setIndexType(IndexType.Unique); - aObjectRepository.createIndex("b.number", indexOptions); + aObjectRepository.createIndex("b.number"); - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Ascending).skipLimit(0, 10); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Ascending).skip(0).limit(10)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -56,8 +53,8 @@ public void testFind() { System.out.println(classA); } - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Descending).skipLimit(2, 7); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -67,8 +64,8 @@ public void testFind() { System.out.println(classA); } - cursor = cObjectRepository.find(where("id").gt(900)). - sort("id", SortOrder.Descending).skipLimit(2, 7); + cursor = cObjectRepository.find(where("id").gt(900), + orderBy("id", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java similarity index 92% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index db6100a23..057a0b78e 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UniversalTextTokenizerTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -1,46 +1,46 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.mvstore.MVStoreModuleBuilder; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.common.module.NitriteModule.module; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -83,7 +83,7 @@ public void setUp() { @After @Override - public void clear() throws IOException { + public void clear() throws Exception { if (textRepository != null && !textRepository.isDropped()) { textRepository.remove(ALL); } @@ -94,11 +94,12 @@ public void clear() throws IOException { } if (!inMemory) { - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } - private void openDb() { + @Override + protected void openDb() { MVStoreModuleBuilder builder = MVStoreModule.withConfig(); if (isCompressed) { @@ -180,7 +181,7 @@ public void testUniversalFullTextIndexing() { } @Indices( - @Index(value = "text", type = IndexType.Fulltext) + @Index(value = "text", type = IndexType.FULL_TEXT) ) public static class TextData implements Mappable { public int id; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java new file mode 100644 index 000000000..5a147769c --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Entity; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; + +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity(value = "books", indices = { + @Index(value = "tags", type = IndexType.NON_UNIQUE), + @Index(value = "description", type = IndexType.FULL_TEXT), + @Index(value = { "price", "publisher" }) +}) +public class Book implements Mappable { + @Id(fieldName = "book_id") + private BookId bookId; + + private String publisher; + + private Double price; + + private List tags; + + private String description; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("book_id", mapper.convert(bookId, Document.class)) + .put("publisher", publisher) + .put("price", price) + .put("tags", tags) + .put("description", description); + } + + @Override + @SuppressWarnings("unchecked") + public void read(NitriteMapper mapper, Document document) { + bookId = mapper.convert(document.get("book_id"), BookId.class); + publisher = document.get("publisher", String.class); + price = document.get("price", Double.class); + tags = (List) document.get("tags", List.class); + description = document.get("description", String.class); + } +} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java new file mode 100644 index 000000000..239b493d3 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Embedded; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +public class BookId implements Mappable { + @Embedded(order = 0) + private String isbn; + + @Embedded(order = 1, fieldName = "book_name") + private String name; + + private String author; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("isbn", isbn) + .put("book_name", name) + .put("author", author); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + isbn = document.get("isbn", String.class); + name = document.get("book_name", String.class); + author = document.get("author", String.class); + } +} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java similarity index 87% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java index 3940aaa69..d3c2ba644 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ChildClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.InheritIndices; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.InheritIndices; /** * @author Anindya Chatterjee diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java similarity index 80% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java index 47efd01f1..a8161c4e2 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassA.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -31,7 +32,7 @@ public class ClassA implements Mappable { @Getter @Setter - private ClassB classB; + private ClassB b; @Getter @Setter private UUID uid; @@ -45,7 +46,7 @@ public class ClassA implements Mappable { public static ClassA create(int seed) { ClassB classB = ClassB.create(seed); ClassA classA = new ClassA(); - classA.classB = classB; + classA.b = classB; classA.uid = new UUID(seed, seed + 50); classA.string = Integer.toHexString(seed); classA.blob = new byte[]{(byte) seed}; @@ -55,7 +56,7 @@ public static ClassA create(int seed) { @Override public Document write(NitriteMapper mapper) { return Document.createDocument() - .put("classB", classB != null ? classB.write(mapper) : null) + .put("b", b != null ? b.write(mapper) : null) .put("uid", uid) .put("string", string) .put("blob", blob); @@ -63,9 +64,9 @@ public Document write(NitriteMapper mapper) { @Override public void read(NitriteMapper mapper, Document document) { - if (document.get("classB") != null) { - classB = new ClassB(); - classB.read(mapper, document.get("classB", Document.class)); + if (document.get("b") != null) { + b = new ClassB(); + b.read(mapper, document.get("b", Document.class)); } uid = document.get("uid", UUID.class); string = document.get("string", String.class); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java similarity index 90% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java index 9f4d2e171..a546b91e2 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassB.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java index beb96231b..860fe1e93 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassC.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -39,7 +40,7 @@ public class ClassC implements Mappable { public static ClassC create(int seed) { ClassC classC = new ClassC(); - classC.id = seed * 5000; + classC.id = seed * 5000L; classC.digit = seed * 69.65; classC.parent = ClassA.create(seed); return classC; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java similarity index 77% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java index 635cad5a9..944e17358 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Company.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; -import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; @@ -35,13 +35,12 @@ /** * @author Anindya Chatterjee. */ -@ToString @EqualsAndHashCode @Indices({ @Index(value = "companyName") }) public class Company implements Serializable, Mappable { - @Id + @Id(fieldName = "company_id") @Getter @Setter private Long companyId; @@ -64,7 +63,7 @@ public class Company implements Serializable, Mappable { @Override public Document write(NitriteMapper mapper) { - return Document.createDocument("companyId", companyId) + return Document.createDocument("company_id", companyId) .put("companyName", companyName) .put("dateCreated", dateCreated) .put("departments", departments) @@ -74,10 +73,20 @@ public Document write(NitriteMapper mapper) { @Override @SuppressWarnings("unchecked") public void read(NitriteMapper mapper, Document document) { - companyId = document.get("companyId", Long.class); + companyId = document.get("company_id", Long.class); companyName = document.get("companyName", String.class); dateCreated = document.get("dateCreated", Date.class); departments = document.get("departments", List.class); employeeRecord = document.get("employeeRecord", Map.class); } + + @Override + public String toString() { + return "Company{" + + "companyId=" + companyId + + ", companyName='" + companyName + '\'' + + ", dateCreated=" + dateCreated + + ", departments=" + departments + + '}'; + } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java similarity index 52% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java index c0a0352be..26e0dcf4a 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/DataGenerator.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java @@ -1,26 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; + +import com.github.javafaker.Faker; +import lombok.val; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** @@ -29,14 +31,15 @@ public class DataGenerator { private static final Random random = new Random(System.currentTimeMillis()); private static final AtomicInteger counter = new AtomicInteger(random.nextInt()); + private static final Faker faker = new Faker(random); private DataGenerator() {} public static Company generateCompanyRecord() { Company company = new Company(); company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); - company.setCompanyName(randomCompanyName()); - company.setDateCreated(randomDate()); + company.setCompanyName(faker.company().name()); + company.setDateCreated(faker.date().past(10, TimeUnit.DAYS)); List departments = departments(); company.setDepartments(departments); @@ -62,65 +65,41 @@ private static List generateEmployeeRecords(Company company, int count public static Employee generateEmployee() { Employee employee = new Employee(); employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); - employee.setJoinDate(randomDate()); - employee.setAddress(UUID.randomUUID().toString().replace('-', ' ')); + employee.setJoinDate(faker.date().birthday()); + employee.setAddress(faker.address().fullAddress()); - byte[] blob = new byte[random.nextInt(8000)]; - random.nextBytes(blob); - employee.setBlob(blob); + employee.setBlob(faker.lorem().paragraph().getBytes(StandardCharsets.UTF_8)); employee.setEmployeeNote(randomNote()); + employee.setEmailAddress(faker.internet().emailAddress()); return employee; } - private static Date randomDate() { - return new Date(-946771200000L + - (Math.abs(random.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000))); - } - public static Note randomNote() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.text"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - long line = random.nextInt(49); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - Note note = new Note(); - note.setNoteId(line); - note.setText(strLine); - return note; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; + Note note = new Note(); + note.setNoteId(System.nanoTime() + counter.incrementAndGet()); + note.setText(faker.lorem().paragraph()); + return note; } - private static String randomCompanyName() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("english.stop"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - int line = random.nextInt(570); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - return strLine + System.nanoTime() + " inc."; - } - count++; - } - } catch (IOException e) { - // ignore + public static Book randomBook() { + BookId bookId = new BookId(); + val bookFaker = faker.book(); + bookId.setIsbn(faker.idNumber().ssnValid()); + bookId.setAuthor(bookFaker.author()); + bookId.setName(bookFaker.title()); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription(faker.backToTheFuture().quote()); + book.setPrice(faker.number().randomDouble(2, 100, 500)); + book.setPublisher(bookFaker.publisher()); + List tags = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + tags.add(bookFaker.genre()); } - // ignore - return null; + book.setTags(tags); + return book; } private static List departments() { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java similarity index 92% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java index b8b4aee2e..cb5304e29 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ElemMatch.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java similarity index 82% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 02a5b378b..7204f5654 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Employee.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,10 +23,10 @@ import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; import java.io.Serializable; import java.util.Date; @@ -35,9 +36,9 @@ */ @ToString @EqualsAndHashCode -@Index(value = "joinDate", type = IndexType.NonUnique) -@Index(value = "address", type = IndexType.Fulltext) -@Index(value = "employeeNote.text", type = IndexType.Fulltext) +@Index(value = "joinDate", type = IndexType.NON_UNIQUE) +@Index(value = "address", type = IndexType.FULL_TEXT) +@Index(value = "employeeNote.text", type = IndexType.FULL_TEXT) public class Employee implements Serializable, Mappable { @Id @Getter @@ -52,6 +53,10 @@ public class Employee implements Serializable, Mappable { @Setter private String address; + @Getter + @Setter + private String emailAddress; + @Getter @Setter private transient Company company; @@ -74,6 +79,7 @@ public Employee(Employee copy) { company = copy.company; blob = copy.blob; employeeNote = copy.employeeNote; + emailAddress = copy.emailAddress; } @Override @@ -83,6 +89,7 @@ public Document write(NitriteMapper mapper) { .put("joinDate", joinDate) .put("address", address) .put("blob", blob) + .put("emailAddress", emailAddress) .put("employeeNote", employeeNote != null ? employeeNote.write(mapper) : null); } @@ -92,6 +99,7 @@ public void read(NitriteMapper mapper, Document document) { joinDate = document.get("joinDate", Date.class); address = document.get("address", String.class); blob = document.get("blob", byte[].class); + emailAddress = document.get("emailAddress", String.class); if (document.get("employeeNote") != null) { employeeNote = new Note(); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java similarity index 58% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java index c0072e655..8b9d4b23b 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithDateId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java @@ -1,49 +1,54 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Entity; import java.util.Date; /** * @author Anindya Chatterjee */ -@Getter -@Setter -@EqualsAndHashCode -public class WithDateId implements Mappable { - private Date id; +@Data +@Entity +public class EncryptedPerson implements Mappable { private String name; + private String creditCardNumber; + private String cvv; + private Date expiryDate; @Override public Document write(NitriteMapper mapper) { return Document.createDocument("name", name) - .put("id", id); + .put("creditCardNumber", creditCardNumber) + .put("cvv", cvv) + .put("expiryDate", expiryDate); } @Override public void read(NitriteMapper mapper, Document document) { name = document.get("name", String.class); - id = document.get("id", Date.class); + creditCardNumber = document.get("creditCardNumber", String.class); + cvv = document.get("cvv", String.class); + expiryDate = document.get("expiryDate", Date.class); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java index 7b0686118..67dc307d1 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Note.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java index 8c4227abc..bc2514543 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ParentClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index 116b2dd77..2b90075fa 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/PersonEntity.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -33,8 +34,8 @@ */ @Data @Entity(value = "MyPerson", indices = { - @Index(value = "name", type = IndexType.Fulltext), - @Index(value = "status", type = IndexType.NonUnique) + @Index(value = "name", type = IndexType.FULL_TEXT), + @Index(value = "status", type = IndexType.NON_UNIQUE) }) public class PersonEntity implements Mappable { @Id diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java similarity index 89% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java index 06fab6a78..65550d182 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ProductScore.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java similarity index 84% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index 352100cb4..1ecadb243 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/RepeatableIndexTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -28,8 +29,8 @@ */ @Data @Index(value = "firstName") -@Index(value = "age", type = IndexType.NonUnique) -@Index(value = "lastName", type = IndexType.Fulltext) +@Index(value = "age", type = IndexType.NON_UNIQUE) +@Index(value = "lastName", type = IndexType.FULL_TEXT) public class RepeatableIndexTest implements Mappable { private String firstName; private Integer age; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java index 602d2c54f..d1cb199c4 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/StressRecord.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java similarity index 90% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java index 7c03e0cc3..8eaa3faf1 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SubEmployee.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java similarity index 84% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index 5fc701968..198f16d0c 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SuperDuperClass.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; @@ -29,7 +30,7 @@ */ @Getter @Setter -@Index(value = "text", type = IndexType.Fulltext) +@Index(value = "text", type = IndexType.FULL_TEXT) public class SuperDuperClass implements Mappable { private String text; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCircularReference.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java similarity index 81% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCircularReference.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java index a08a0ac76..efbb6766a 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithCircularReference.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java index e34d7e6dc..79cafe0dc 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithClassField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCustomConstructor.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java similarity index 83% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCustomConstructor.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java index 46d035652..bea5dabe9 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCustomConstructor.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java index 5790e25d0..229f1aaf7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithDateId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java similarity index 87% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java index 1e84a020d..a0048a6bb 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithEmptyStringId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java similarity index 91% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java index 48a9ae966..05afc21e8 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithFinalField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java index f6ade0d57..2364be76d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNitriteId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java index 5f8f87c3e..0dc3fb68b 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNullId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java index 31b02d3cc..5f00f97d4 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithObjectId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java index 56bdbd241..a7a2c56c9 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutGetterSetter.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java index e110c24f5..09b63c2c2 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java similarity index 90% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java index 3b9fc622a..a425209fb 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPrivateConstructor.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java index 2f643c251..793388231 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPublicField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java @@ -1,25 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java index 6294a5783..9c1ade657 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithTransientField.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java similarity index 50% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java index c4d120fee..9ecb9a68b 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNitriteId.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java @@ -1,24 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; @@ -27,21 +27,39 @@ * @author Anindya Chatterjee */ @Data -public class WithNitriteId implements Mappable { +public class WithoutEmbeddedId implements Mappable { @Id - public NitriteId idField; - public String name; + private NestedId nestedId; + private String data; @Override public Document write(NitriteMapper mapper) { return Document.createDocument() - .put("idField", idField) - .put("name", name); + .put("nestedId", nestedId.write(mapper)) + .put("data", data); } @Override public void read(NitriteMapper mapper, Document document) { - idField = document.get("idField", NitriteId.class); - name = document.get("name", String.class); + Document nestedId = document.get("nestedId", Document.class); + this.nestedId = mapper.convert(nestedId, NestedId.class); + this.data = document.get("data", String.class); + } + + + @Data + public static class NestedId implements Mappable { + private Long id; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("id", id); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + id = document.get("id", Long.class); + } } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/DocumentCursorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java similarity index 82% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/DocumentCursorTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java index 8a76bd180..de377b162 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/DocumentCursorTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java @@ -1,38 +1,41 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection.operation; +package org.dizitart.no2.integration.stream; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.DocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.rocksdb.AbstractTest; import org.junit.Test; import java.util.Iterator; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * @author Anindya Chatterjee. */ -public class DocumentCursorTest extends AbstractTest { +public class DocumentCursorTest extends BaseCollectionTest { @Test public void testFindResult() { @@ -40,7 +43,7 @@ public void testFindResult() { collection.insert(createDocument("first", "second")); DocumentCursor result = collection.find(); - assertNotNull(result); + assertTrue(result instanceof DocumentStream); } @Test(expected = InvalidOperationException.class) diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/JoinedDocumentStreamTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java similarity index 79% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/JoinedDocumentStreamTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java index 40d94df00..00923c738 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/operation/JoinedDocumentStreamTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java @@ -1,38 +1,41 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection.operation; +package org.dizitart.no2.integration.stream; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.JoinedDocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.rocksdb.AbstractTest; import org.junit.Test; import java.util.Iterator; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * @author Anindya Chatterjee */ -public class JoinedDocumentStreamTest extends AbstractTest { +public class JoinedDocumentStreamTest extends BaseCollectionTest { @Test public void testFindResult() { @@ -40,7 +43,7 @@ public void testFindResult() { collection.insert(createDocument("first", "second")); RecordStream result = collection.find().join(collection.find(), new Lookup()); - assertNotNull(result); + assertTrue(result instanceof JoinedDocumentStream); } @Test(expected = InvalidOperationException.class) diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionCollectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java similarity index 93% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionCollectionTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java index 897985bfa..05a2b095b 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionCollectionTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java @@ -1,13 +1,30 @@ -package org.dizitart.no2.rocksdb.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.dizitart.no2.transaction.Session; import org.dizitart.no2.transaction.Transaction; import org.junit.Test; @@ -50,7 +67,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -104,7 +121,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); collection.insert(createDocument("firstName", "Jane")); try (Session session = db.createSession()) { @@ -160,7 +177,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -198,7 +215,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Fulltext)); + txCol.createIndex(indexOptions(IndexType.FULL_TEXT), "firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -222,7 +239,7 @@ public void testRollbackCreateIndex() { transaction = session.beginTransaction(); NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Unique)); + txCol.createIndex("firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -263,7 +280,7 @@ public void testCommitClear() { @Test public void testRollbackClear() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); Document document2 = createDocument("firstName", "Jane"); collection.insert(document); @@ -295,7 +312,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -317,8 +334,8 @@ public void testRollbackDropIndex() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -348,8 +365,8 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); + collection.createIndex("lastName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -373,8 +390,8 @@ public void testCommitDropAllIndices() { public void testRollbackDropAllIndices() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -435,7 +452,7 @@ public void testCommitDropCollection() { @Test public void testRollbackDropCollection() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -472,7 +489,9 @@ public void testCommitSetAttribute() { NitriteCollection txCol = transaction.getCollection("test"); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txCol.setAttributes(attributes); assertNull(collection.getAttributes()); @@ -486,7 +505,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -524,8 +543,8 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { NitriteCollection collection = db.getCollection("test"); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); - collection.createIndex("id", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex("id"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -669,7 +688,7 @@ public void testTransactionOnDifferentCollections() { NitriteCollection col1 = db.getCollection("test1"); NitriteCollection col2 = db.getCollection("test2"); NitriteCollection col3 = db.getCollection("test3"); - col3.createIndex("id", indexOptions(IndexType.Unique)); + col3.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionRepositoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java similarity index 94% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionRepositoryTest.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index 23d05aa3c..5e93303ed 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TransactionRepositoryTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -1,6 +1,25 @@ -package org.dizitart.no2.rocksdb.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; +import org.dizitart.no2.integration.repository.BaseObjectRepositoryTest; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; @@ -8,8 +27,6 @@ import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.rocksdb.repository.BaseObjectRepositoryTest; -import org.dizitart.no2.rocksdb.repository.data.SubEmployee; import org.dizitart.no2.transaction.Session; import org.dizitart.no2.transaction.Transaction; import org.junit.Test; @@ -56,7 +73,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -116,7 +133,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { ObjectRepository repository = db.getRepository(TxData.class, "rollback"); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(new TxData(1L, "Jane")); try (Session session = db.createSession()) { @@ -180,7 +197,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); TxData txData1 = new TxData(1L, "John"); repository.insert(txData1); @@ -220,7 +237,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -245,7 +262,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -290,7 +307,7 @@ public void testRollbackClear() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -320,7 +337,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -344,7 +361,7 @@ public void testRollbackDropIndex() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -374,7 +391,7 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -398,7 +415,7 @@ public void testRollbackDropAllIndices() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -461,7 +478,7 @@ public void testRollbackDropRepository() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -498,7 +515,9 @@ public void testCommitSetAttribute() { ObjectRepository txRepo = transaction.getRepository(TxData.class); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txRepo.setAttributes(attributes); assertNull(repository.getAttributes()); @@ -513,7 +532,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -551,7 +570,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.NonUnique)); + repository.createIndex(indexOptions(IndexType.NON_UNIQUE), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -692,7 +711,7 @@ public void testTransactionOnDifferentRepositoriesAndCollections() { ObjectRepository repo2 = db.getRepository(TxData.class, "2"); ObjectRepository repo3 = db.getRepository(SubEmployee.class); NitriteCollection col1 = db.getCollection("test1"); - col1.createIndex("id", indexOptions(IndexType.Unique)); + col1.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java index 024b9f184..1e5ed7ca6 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TxData.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.transaction; +package org.dizitart.no2.integration.transaction; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java deleted file mode 100644 index c8a982000..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/NewClass.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.dizitart.no2.migrate; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Entity; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; - -/** - * @author Anindya Chatterjee - */ -@Data -@Entity(value = "new", indices = { - @Index(value = "familyName", type = IndexType.NonUnique), - @Index(value = "fullName", type = IndexType.NonUnique), - @Index(value = "literature.ratings", type = IndexType.NonUnique), -}) -public class NewClass implements Mappable { - @Id - private Long empId; - private String firstName; - private String familyName; - private String fullName; - private Literature literature; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("empId", empId) - .put("firstName", firstName) - .put("familyName", familyName) - .put("fullName", fullName) - .put("literature", literature.write(mapper)); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - empId = document.get("empId", Long.class); - firstName = document.get("firstName", String.class); - familyName = document.get("familyName", String.class); - fullName = document.get("fullName", String.class); - - Document doc = document.get("literature", Document.class); - literature = new Literature(); - literature.read(mapper, doc); - } - - @Data - public static class Literature implements Mappable { - private String text; - private Integer ratings; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("text", text) - .put("ratings", ratings); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - text = document.get("text", String.class); - ratings = document.get("ratings", Integer.class); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java deleted file mode 100644 index cf7a597ed..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/migrate/OldClass.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.dizitart.no2.migrate; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Entity; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; - -/** - * @author Anindya Chatterjee - */ -@Data -@Entity(value = "old", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), - @Index(value = "literature.text", type = IndexType.Fulltext), - @Index(value = "literature.ratings", type = IndexType.NonUnique), -}) -public class OldClass implements Mappable { - @Id - private String uuid; - private String empId; - private String firstName; - private String lastName; - private Literature literature; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("empId", empId) - .put("uuid", uuid) - .put("firstName", firstName) - .put("lastName", lastName) - .put("literature", literature.write(mapper)); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - empId = document.get("empId", String.class); - uuid = document.get("uuid", String.class); - firstName = document.get("firstName", String.class); - lastName = document.get("lastName", String.class); - - Document doc = document.get("literature", Document.class); - literature = new Literature(); - literature.read(mapper, doc); - } - - @Data - public static class Literature implements Mappable { - private String text; - private Float ratings; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("text", text) - .put("ratings", ratings); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - text = document.get("text", String.class); - ratings = document.get("ratings", Float.class); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreConfigTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreConfigTest.java new file mode 100644 index 000000000..b38fafab8 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreConfigTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.dizitart.no2.store.events.StoreEventListener; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class MVStoreConfigTest { + @Test + public void testConstructor() { + MVStoreConfig actualMvStoreConfig = new MVStoreConfig(); + assertFalse(actualMvStoreConfig.isReadOnly()); + assertTrue(actualMvStoreConfig.eventListeners().isEmpty()); + } + + @Test + public void testAddStoreEventListener() { + MVStoreConfig mvStoreConfig = new MVStoreConfig(); + mvStoreConfig.addStoreEventListener(mock(StoreEventListener.class)); + assertEquals(1, mvStoreConfig.eventListeners().size()); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleBuilderTest.java new file mode 100644 index 000000000..0f4d3087d --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleBuilderTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.dizitart.no2.store.events.StoreEventListener; +import org.junit.Test; + +import java.nio.file.Paths; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class MVStoreModuleBuilderTest { + @Test + public void testConstructor() { + MVStoreModuleBuilder actualMvStoreModuleBuilder = new MVStoreModuleBuilder(); + MVStoreModuleBuilder actualFilePathResult = actualMvStoreModuleBuilder.filePath("Path"); + assertTrue(actualMvStoreModuleBuilder.autoCommit()); + assertFalse(actualMvStoreModuleBuilder.recoveryMode()); + assertFalse(actualMvStoreModuleBuilder.readOnly()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.pageSplitSize()); + assertNull(actualMvStoreModuleBuilder.fileStore()); + assertEquals("Path", actualMvStoreModuleBuilder.filePath()); + assertTrue(actualMvStoreModuleBuilder.eventListeners().isEmpty()); + assertNull(actualMvStoreModuleBuilder.encryptionKey()); + assertFalse(actualMvStoreModuleBuilder.compressHigh()); + assertEquals(1024, actualMvStoreModuleBuilder.autoCommitBufferSize()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.cacheSize()); + assertFalse(actualMvStoreModuleBuilder.compress()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.cacheConcurrency()); + MVStoreConfig dbConfigResult = actualMvStoreModuleBuilder.dbConfig(); + assertNull(dbConfigResult.filePath()); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + assertNull(dbConfigResult.encryptionKey()); + assertFalse(dbConfigResult.compressHigh()); + assertFalse(dbConfigResult.compress()); + assertEquals(0, dbConfigResult.cacheSize()); + assertEquals(0, dbConfigResult.cacheConcurrency()); + assertFalse(dbConfigResult.autoCompact()); + assertEquals(0, dbConfigResult.autoCommitBufferSize()); + assertFalse(dbConfigResult.autoCommit()); + assertEquals(0, dbConfigResult.pageSplitSize()); + assertFalse(dbConfigResult.recoveryMode()); + assertNull(dbConfigResult.fileStore()); + assertFalse(dbConfigResult.isReadOnly()); + assertSame(actualMvStoreModuleBuilder, actualFilePathResult); + } + + @Test + public void testConstructor2() { + MVStoreModuleBuilder actualMvStoreModuleBuilder = new MVStoreModuleBuilder(); + assertTrue(actualMvStoreModuleBuilder.autoCommit()); + assertFalse(actualMvStoreModuleBuilder.recoveryMode()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.pageSplitSize()); + assertTrue(actualMvStoreModuleBuilder.eventListeners().isEmpty()); + assertEquals(1024, actualMvStoreModuleBuilder.autoCommitBufferSize()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.cacheSize()); + assertEquals(Short.SIZE, actualMvStoreModuleBuilder.cacheConcurrency()); + MVStoreConfig dbConfigResult = actualMvStoreModuleBuilder.dbConfig(); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + assertFalse(dbConfigResult.isReadOnly()); + } + + @Test + public void testFilePath() { + MVStoreModuleBuilder withConfigResult = MVStoreModule.withConfig(); + MVStoreModuleBuilder actualFilePathResult = withConfigResult + .filePath(Paths.get(System.getProperty("java.io.tmpdir"), "test.txt").toFile()); + assertSame(withConfigResult, actualFilePathResult); + assertEquals("/tmp/test.txt", actualFilePathResult.filePath()); + } + + @Test + public void testAddStoreEventListener() { + MVStoreModuleBuilder withConfigResult = MVStoreModule.withConfig(); + assertSame(withConfigResult, withConfigResult.addStoreEventListener(mock(StoreEventListener.class))); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleTest.java new file mode 100644 index 000000000..13a55b031 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreModuleTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class MVStoreModuleTest { + @Test + public void testPlugins() { + Assert.assertEquals(1, (new MVStoreModule("Path")).plugins().size()); + } + + @Test + public void testWithConfig() { + MVStoreModuleBuilder actualWithConfigResult = MVStoreModule.withConfig(); + assertTrue(actualWithConfigResult.autoCommit()); + assertFalse(actualWithConfigResult.recoveryMode()); + assertEquals(Short.SIZE, actualWithConfigResult.pageSplitSize()); + assertTrue(actualWithConfigResult.eventListeners().isEmpty()); + assertEquals(1024, actualWithConfigResult.autoCommitBufferSize()); + assertEquals(Short.SIZE, actualWithConfigResult.cacheSize()); + assertEquals(Short.SIZE, actualWithConfigResult.cacheConcurrency()); + MVStoreConfig dbConfigResult = actualWithConfigResult.dbConfig(); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + assertFalse(dbConfigResult.isReadOnly()); + } + + @Test + public void testGetStore() { + assertTrue((new MVStoreModule("Path")).getStore() instanceof NitriteMVStore); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreUtilsTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreUtilsTest.java new file mode 100644 index 000000000..af170ebd4 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/MVStoreUtilsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.dizitart.no2.store.events.StoreEventListener; +import org.h2.mvstore.MVStore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class MVStoreUtilsTest { + @Test + public void testOpenOrCreate() { + MVStore actualOpenOrCreateResult = MVStoreUtils.openOrCreate(new MVStoreConfig()); + assertFalse(actualOpenOrCreateResult.isReadOnly()); + assertEquals(0L, actualOpenOrCreateResult.getVersionsToKeep()); + assertEquals(0.0, actualOpenOrCreateResult.getUpdateFailureRatio(), 0.0); + assertEquals(0, actualOpenOrCreateResult.getUnsavedMemory()); + assertEquals(0, actualOpenOrCreateResult.getStoreVersion()); + assertTrue(actualOpenOrCreateResult.getStoreHeader().isEmpty()); + assertTrue(actualOpenOrCreateResult.getReuseSpace()); + assertEquals(0, actualOpenOrCreateResult.getRetentionTime()); + assertEquals(48, actualOpenOrCreateResult.getPageSplitSize()); + assertEquals(2, actualOpenOrCreateResult.getMetaMap().size()); + assertEquals(Long.MAX_VALUE, actualOpenOrCreateResult.getMaxPageSize()); + assertEquals(1, actualOpenOrCreateResult.getMapNames().size()); + assertEquals(48, actualOpenOrCreateResult.getKeysPerPage()); + assertEquals(100, actualOpenOrCreateResult.getChunksFillRate()); + assertEquals(0, actualOpenOrCreateResult.getAutoCommitMemory()); + } + + @Test + public void testOpenOrCreate2() { + MVStoreConfig mvStoreConfig = new MVStoreConfig(); + mvStoreConfig.addStoreEventListener(mock(StoreEventListener.class)); + MVStore actualOpenOrCreateResult = MVStoreUtils.openOrCreate(mvStoreConfig); + assertFalse(actualOpenOrCreateResult.isReadOnly()); + assertEquals(0L, actualOpenOrCreateResult.getVersionsToKeep()); + assertEquals(0.0, actualOpenOrCreateResult.getUpdateFailureRatio(), 0.0); + assertEquals(0, actualOpenOrCreateResult.getUnsavedMemory()); + assertEquals(0, actualOpenOrCreateResult.getStoreVersion()); + assertTrue(actualOpenOrCreateResult.getStoreHeader().isEmpty()); + assertTrue(actualOpenOrCreateResult.getReuseSpace()); + assertEquals(0, actualOpenOrCreateResult.getRetentionTime()); + assertEquals(48, actualOpenOrCreateResult.getPageSplitSize()); + assertEquals(2, actualOpenOrCreateResult.getMetaMap().size()); + assertEquals(Long.MAX_VALUE, actualOpenOrCreateResult.getMaxPageSize()); + assertEquals(1, actualOpenOrCreateResult.getMapNames().size()); + assertEquals(48, actualOpenOrCreateResult.getKeysPerPage()); + assertEquals(100, actualOpenOrCreateResult.getChunksFillRate()); + assertEquals(0, actualOpenOrCreateResult.getAutoCommitMemory()); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVMapTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVMapTest.java new file mode 100644 index 000000000..3116ee8b5 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVMapTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.h2.mvstore.MVMap; +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class NitriteMVMapTest { + @Test + public void testValues() { + NitriteMVMap nitriteMVMap = new NitriteMVMap<>( + (MVMap) mock(MVMap.class), null); + assertTrue(nitriteMVMap.values().toList().isEmpty()); + assertFalse(nitriteMVMap.isEmpty()); + } + + @Test + public void testKeys() { + MVMap objectObjectMap = (MVMap) mock(MVMap.class); + when(objectObjectMap.keySet()).thenReturn(new HashSet<>()); + NitriteMVMap nitriteMVMap = new NitriteMVMap<>(objectObjectMap, null); + assertTrue(nitriteMVMap.keys().toList().isEmpty()); + verify(objectObjectMap).keySet(); + assertFalse(nitriteMVMap.isEmpty()); + } + + @Test(expected = NullPointerException.class) + public void testConstructor() { + NitriteMVMap actualNitriteMVMap = new NitriteMVMap<>( + (MVMap) mock(MVMap.class), null); + actualNitriteMVMap.close(); + assertFalse(actualNitriteMVMap.isEmpty()); + } + + @Test + public void testIsEmpty() { + MVMap objectObjectMap = (MVMap) mock(MVMap.class); + when(objectObjectMap.isEmpty()).thenReturn(true); + assertTrue((new NitriteMVMap<>(objectObjectMap, null)).isEmpty()); + verify(objectObjectMap).isEmpty(); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVStoreTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVStoreTest.java new file mode 100644 index 000000000..99968fe49 --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/NitriteMVStoreTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class NitriteMVStoreTest { + @Test + public void testConstructor() { + NitriteMVStore actualNitriteMVStore = new NitriteMVStore(); + assertNull(actualNitriteMVStore.getStoreConfig()); + assertTrue(actualNitriteMVStore.isClosed()); + assertFalse(actualNitriteMVStore.hasUnsavedChanges()); + assertNotNull(actualNitriteMVStore.getStoreVersion()); + } + + @Test + public void testOpenOrCreate() { + NitriteMVStore nitriteMVStore = new NitriteMVStore(); + nitriteMVStore.setStoreConfig(new MVStoreConfig()); + nitriteMVStore.openOrCreate(); + assertFalse(nitriteMVStore.isReadOnly()); + assertFalse(nitriteMVStore.isClosed()); + assertTrue(nitriteMVStore.hasUnsavedChanges()); + } + + @Test + public void testIsClosed() { + assertTrue((new NitriteMVStore()).isClosed()); + } + + @Test + public void testHasUnsavedChanges() { + assertFalse((new NitriteMVStore()).hasUnsavedChanges()); + } + + @Test + public void testGetStoreVersion() { + assertNotNull((new NitriteMVStore()).getStoreVersion()); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCircularReference.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/RecoveryTest.java similarity index 56% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCircularReference.java rename to nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/RecoveryTest.java index a7f6c3a74..26c919907 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithCircularReference.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/RecoveryTest.java @@ -1,30 +1,31 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.mvstore; -import lombok.Getter; -import lombok.Setter; +import org.junit.Test; -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithCircularReference { - private String name; - private WithCircularReference parent; +import static org.junit.Assert.assertFalse; + +public class RecoveryTest { + @Test + public void testRecover() { + assertFalse(Recovery.recover("foo.txt")); + assertFalse(Recovery.recover("File not found: ")); + } } + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/ReverseIteratorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/ReverseIteratorTest.java new file mode 100644 index 000000000..551091b4b --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/ReverseIteratorTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore; + +import org.dizitart.no2.common.tuples.Pair; +import org.h2.mvstore.MVMap; +import org.junit.Test; + +import java.util.NoSuchElementException; + +import static org.mockito.Mockito.*; + +public class ReverseIteratorTest { + + @Test(expected = NoSuchElementException.class) + public void testConstructor() { + MVMap objectObjectMap = (MVMap) mock(MVMap.class); + when(objectObjectMap.getRoot()).thenThrow(new NoSuchElementException("foo")); + new ReverseIterator<>(objectObjectMap); + verify(objectObjectMap).getRoot(); + } + + @Test + public void testHasNext() { + ReverseIterator reverseIterator = (ReverseIterator) mock(ReverseIterator.class); + when(reverseIterator.hasNext()).thenReturn(true); + reverseIterator.hasNext(); + verify(reverseIterator).hasNext(); + } + + @Test + public void testNext() { + ReverseIterator reverseIterator = (ReverseIterator) mock(ReverseIterator.class); + when(reverseIterator.next()).thenReturn(new Pair<>()); + reverseIterator.next(); + verify(reverseIterator).next(); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/MVMapBuilderTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/MVMapBuilderTest.java new file mode 100644 index 000000000..9488930dc --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/MVMapBuilderTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore.compat.v3; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class MVMapBuilderTest { + @Test + public void testConstructor() { + MVMapBuilder actualMvMapBuilder = new MVMapBuilder<>(); + assertTrue(actualMvMapBuilder.getKeyType() instanceof NitriteDataType); + assertTrue(actualMvMapBuilder.getValueType() instanceof NitriteDataType); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/NitriteDataTypeTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/NitriteDataTypeTest.java new file mode 100644 index 000000000..35b31ccff --- /dev/null +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/mvstore/compat/v3/NitriteDataTypeTest.java @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.mvstore.compat.v3; + +import org.h2.mvstore.WriteBuffer; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.UUID; + +import static org.junit.Assert.*; + +public class NitriteDataTypeTest { + @Test + public void testAutoDetectDataTypeGetType() { + assertTrue((new NitriteDataType.BigDecimalType(new NitriteDataType())) + .getType("42") instanceof NitriteDataType.StringType); + assertEquals(4, + (new NitriteDataType.BigDecimalType(new NitriteDataType())).getType(0).typeId); + } + + @Test + public void testBigDecimalTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.BigDecimalType actualBigDecimalType = new NitriteDataType.BigDecimalType(nitriteDataType); + assertEquals(9, actualBigDecimalType.typeId); + assertSame(actualBigDecimalType.base, nitriteDataType); + } + + @Test + public void testBigIntegerTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.BigIntegerType actualBigIntegerType = new NitriteDataType.BigIntegerType(nitriteDataType); + assertEquals(6, actualBigIntegerType.typeId); + assertSame(actualBigIntegerType.base, nitriteDataType); + } + + @Test + public void testBooleanTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.BooleanType actualBooleanType = new NitriteDataType.BooleanType(nitriteDataType); + assertEquals(1, actualBooleanType.typeId); + assertSame(actualBooleanType.base, nitriteDataType); + } + + @Test + public void testByteTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.ByteType actualByteType = new NitriteDataType.ByteType(nitriteDataType); + assertEquals(2, actualByteType.typeId); + assertSame(actualByteType.base, nitriteDataType); + } + + @Test + public void testCharacterTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.CharacterType actualCharacterType = new NitriteDataType.CharacterType(nitriteDataType); + assertEquals(10, actualCharacterType.typeId); + assertSame(actualCharacterType.base, nitriteDataType); + } + + @Test + public void testDateTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.DateType actualDateType = new NitriteDataType.DateType(nitriteDataType); + assertEquals(13, actualDateType.typeId); + assertSame(actualDateType.base, nitriteDataType); + } + + @Test + public void testDoubleTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.DoubleType actualDoubleType = new NitriteDataType.DoubleType(nitriteDataType); + assertEquals(8, actualDoubleType.typeId); + assertSame(actualDoubleType.base, nitriteDataType); + } + + @Test + public void testFloatTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.FloatType actualFloatType = new NitriteDataType.FloatType(nitriteDataType); + assertEquals(7, actualFloatType.typeId); + assertSame(actualFloatType.base, nitriteDataType); + } + + @Test + public void testIntegerTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.IntegerType actualIntegerType = new NitriteDataType.IntegerType(nitriteDataType); + assertEquals(4, actualIntegerType.typeId); + assertSame(actualIntegerType.base, nitriteDataType); + } + + @Test + public void testIsBigInteger() { + assertFalse(NitriteDataType.isBigInteger("Obj")); + assertFalse(NitriteDataType.isBigInteger(null)); + } + + @Test + public void testIsBigDecimal() { + assertFalse(NitriteDataType.isBigDecimal("Obj")); + assertFalse(NitriteDataType.isBigDecimal(null)); + } + + @Test + public void testIsDate() { + assertFalse(NitriteDataType.isDate("Obj")); + assertFalse(NitriteDataType.isDate(null)); + } + + @Test + public void testIsArray() { + assertFalse(NitriteDataType.isArray("Obj")); + assertFalse(NitriteDataType.isArray(null)); + } + + @Test + public void testGetCommonClassId() { + assertEquals(8, NitriteDataType.getCommonClassId(Object.class).intValue()); + assertNull(NitriteDataType.getCommonClassId(null)); + } + + @Test + public void testLongTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.LongType actualLongType = new NitriteDataType.LongType(nitriteDataType); + assertEquals(5, actualLongType.typeId); + assertSame(actualLongType.base, nitriteDataType); + } + + @Test + public void testNullTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.NullType actualNullType = new NitriteDataType.NullType(nitriteDataType); + assertEquals(0, actualNullType.typeId); + assertSame(actualNullType.base, nitriteDataType); + } + + @Test + public void testObjectArrayTypeConstructor() { + assertEquals(14, (new NitriteDataType.ObjectArrayType(new NitriteDataType())).typeId); + } + + @Test + public void testSerialize() { + byte[] actualSerializeResult = NitriteDataType.serialize("Obj"); + assertEquals(10, actualSerializeResult.length); + assertEquals((byte) 0, actualSerializeResult[2]); + assertEquals((byte) 5, actualSerializeResult[3]); + assertEquals('t', actualSerializeResult[4]); + assertEquals((byte) 0, actualSerializeResult[5]); + assertEquals((byte) 3, actualSerializeResult[6]); + assertEquals('O', actualSerializeResult[7]); + assertEquals('b', actualSerializeResult[8]); + assertEquals('j', actualSerializeResult[9]); + } + + @Test + public void testCompareNotNull() throws UnsupportedEncodingException { + byte[] data1 = "AAAAAAAA".getBytes("UTF-8"); + assertEquals(0, NitriteDataType.compareNotNull(data1, "AAAAAAAA".getBytes("UTF-8"))); + } + + @Test + public void testCompareNotNull2() throws UnsupportedEncodingException { + assertEquals(-1, + NitriteDataType.compareNotNull(new byte[]{0, 'A', 'A', 'A', 'A', 'A', 'A', 'A'}, "AAAAAAAA".getBytes("UTF-8"))); + } + + @Test + public void testCompareNotNull3() throws UnsupportedEncodingException { + byte[] data1 = "￿AAAAAAA".getBytes("UTF-8"); + assertEquals(1, NitriteDataType.compareNotNull(data1, "AAAAAAAA".getBytes("UTF-8"))); + } + + @Test + public void testAutoDetectDataTypeCompare() { + assertEquals(-1, (new NitriteDataType.BigDecimalType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.BigDecimalType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testBigDecimalTypeCompare() { + assertEquals(-1, (new NitriteDataType.BigDecimalType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.BigDecimalType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testBigIntegerTypeCompare() { + assertEquals(-1, (new NitriteDataType.BigIntegerType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.BigIntegerType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testBooleanTypeCompare() { + assertEquals(-1, (new NitriteDataType.BooleanType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.BooleanType(new NitriteDataType())).compare(true, "B Obj")); + assertEquals(0, (new NitriteDataType.BooleanType(new NitriteDataType())).compare(true, true)); + } + + @Test + public void testByteTypeCompare() { + assertEquals(-1, (new NitriteDataType.ByteType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.ByteType(new NitriteDataType())).compare((byte) 'A', "B Obj")); + assertEquals(0, (new NitriteDataType.ByteType(new NitriteDataType())).compare((byte) 'A', (byte) 'A')); + } + + @Test + public void testCharacterTypeCompare() { + assertEquals(-1, (new NitriteDataType.CharacterType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.CharacterType(new NitriteDataType())).compare('\u0000', "B Obj")); + assertEquals(0, (new NitriteDataType.CharacterType(new NitriteDataType())).compare('\u0000', '\u0000')); + } + + @Test + public void testCompare() { + assertEquals(0, (new NitriteDataType()).compare("42", "42")); + assertEquals(-1, (new NitriteDataType()).compare(0, "42")); + assertEquals(1, (new NitriteDataType()).compare("42", 0)); + assertEquals(0, (new NitriteDataType()).compare(0, 0)); + } + + @Test + public void testDateTypeCompare() { + assertEquals(-1, (new NitriteDataType.DateType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.DateType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testDoubleTypeCompare() { + assertEquals(-1, (new NitriteDataType.DoubleType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.DoubleType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(-1, (new NitriteDataType.DoubleType(new NitriteDataType())).compare(10.0, "B Obj")); + assertEquals(0, (new NitriteDataType.DoubleType(new NitriteDataType())).compare(10.0, 10.0)); + } + + @Test + public void testFloatTypeCompare() { + assertEquals(-1, (new NitriteDataType.FloatType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.FloatType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(-1, (new NitriteDataType.FloatType(new NitriteDataType())).compare(10.0f, "B Obj")); + assertEquals(0, (new NitriteDataType.FloatType(new NitriteDataType())).compare(10.0f, 10.0f)); + } + + @Test + public void testIntegerTypeCompare() { + assertEquals(-1, (new NitriteDataType.IntegerType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.IntegerType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(0, (new NitriteDataType.IntegerType(new NitriteDataType())).compare(0, 0)); + } + + @Test + public void testLongTypeCompare() { + assertEquals(-1, (new NitriteDataType.LongType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.LongType(new NitriteDataType())).compare(0L, "B Obj")); + assertEquals(0, (new NitriteDataType.LongType(new NitriteDataType())).compare(0L, 0L)); + } + + @Test + public void testNullTypeCompare() { + assertEquals(-1, (new NitriteDataType.NullType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.NullType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(-1, (new NitriteDataType.NullType(new NitriteDataType())).compare(null, "B Obj")); + assertEquals(1, (new NitriteDataType.NullType(new NitriteDataType())).compare("A Obj", null)); + assertEquals(0, (new NitriteDataType.NullType(new NitriteDataType())).compare(null, null)); + } + + @Test + public void testObjectArrayTypeCompare() { + assertEquals(-1, (new NitriteDataType.ObjectArrayType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.ObjectArrayType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testSerializedObjectTypeCompare() { + assertEquals(-1, (new NitriteDataType.SerializedObjectType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.SerializedObjectType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(0, (new NitriteDataType.SerializedObjectType(new NitriteDataType())).compare(0, 0)); + } + + @Test + public void testShortTypeCompare() { + assertEquals(-1, (new NitriteDataType.ShortType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.ShortType(new NitriteDataType())).compare((short) 0, "B Obj")); + assertEquals(0, (new NitriteDataType.ShortType(new NitriteDataType())).compare((short) 0, (short) 0)); + } + + @Test + public void testStringTypeCompare() { + assertEquals(-1, (new NitriteDataType.StringType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.StringType(new NitriteDataType())).compare(0, "B Obj")); + assertEquals(1, (new NitriteDataType.StringType(new NitriteDataType())).compare("A Obj", 0)); + assertEquals(-1, (new NitriteDataType.StringType(new NitriteDataType())).compare(4, "B Obj")); + assertEquals(0, (new NitriteDataType.StringType(new NitriteDataType())).compare(0, 0)); + } + + @Test + public void testUUIDTypeCompare() { + assertEquals(-1, (new NitriteDataType.UUIDType(new NitriteDataType())).compare("A Obj", "B Obj")); + assertEquals(-1, (new NitriteDataType.UUIDType(new NitriteDataType())).compare(0, "B Obj")); + } + + @Test + public void testUUIDTypeCompare2() { + NitriteDataType.UUIDType uuidType = new NitriteDataType.UUIDType(new NitriteDataType()); + assertEquals(1, uuidType.compare(UUID.randomUUID(), "B Obj")); + } + + @Test + public void testAutoDetectDataTypeGetMemory() { + assertEquals(28, (new NitriteDataType.BigDecimalType(new NitriteDataType())).getMemory("42")); + assertEquals(24, (new NitriteDataType.BigDecimalType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testBigDecimalTypeGetMemory() { + assertEquals(30, (new NitriteDataType.BigDecimalType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.BigDecimalType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testBigDecimalTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, (new NitriteDataType.BigDecimalType(nitriteDataType)).getMemory("Obj")); + } + + @Test + public void testBigIntegerTypeGetMemory() { + assertEquals(30, (new NitriteDataType.BigIntegerType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.BigIntegerType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testBigIntegerTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, (new NitriteDataType.BigIntegerType(nitriteDataType)).getMemory("Obj")); + } + + @Test + public void testBooleanTypeGetMemory() { + assertEquals(30, (new NitriteDataType.BooleanType(new NitriteDataType())).getMemory("Obj")); + assertEquals(0, (new NitriteDataType.BooleanType(new NitriteDataType())).getMemory(true)); + assertEquals(24, (new NitriteDataType.BooleanType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testByteTypeGetMemory() { + assertEquals(30, (new NitriteDataType.ByteType(new NitriteDataType())).getMemory("Obj")); + assertEquals(0, (new NitriteDataType.ByteType(new NitriteDataType())).getMemory((byte) 'A')); + assertEquals(24, (new NitriteDataType.ByteType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testCharacterTypeGetMemory() { + assertEquals(30, (new NitriteDataType.CharacterType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.CharacterType(new NitriteDataType())).getMemory('\u0000')); + assertEquals(24, (new NitriteDataType.CharacterType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testDateTypeGetMemory() { + assertEquals(30, (new NitriteDataType.DateType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.DateType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testDateTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, (new NitriteDataType.DateType(nitriteDataType)).getMemory("Obj")); + } + + @Test + public void testDoubleTypeGetMemory() { + assertEquals(30, (new NitriteDataType.DoubleType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.DoubleType(new NitriteDataType())).getMemory(0)); + assertEquals(30, (new NitriteDataType.DoubleType(new NitriteDataType())).getMemory(10.0)); + } + + @Test + public void testFloatTypeGetMemory() { + assertEquals(30, (new NitriteDataType.FloatType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.FloatType(new NitriteDataType())).getMemory(0)); + assertEquals(24, (new NitriteDataType.FloatType(new NitriteDataType())).getMemory(10.0f)); + } + + @Test + public void testGetMemory() { + assertEquals(30, (new NitriteDataType()).getMemory("Obj")); + assertEquals(24, (new NitriteDataType()).getMemory(0)); + } + + @Test + public void testGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, nitriteDataType.getMemory("Obj")); + } + + @Test + public void testIntegerTypeGetMemory() { + assertEquals(30, (new NitriteDataType.IntegerType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.IntegerType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testIntegerTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, (new NitriteDataType.IntegerType(nitriteDataType)).getMemory("Obj")); + } + + @Test + public void testLongTypeGetMemory() { + assertEquals(30, (new NitriteDataType.LongType(new NitriteDataType())).getMemory("Obj")); + assertEquals(30, (new NitriteDataType.LongType(new NitriteDataType())).getMemory(0L)); + assertEquals(24, (new NitriteDataType.LongType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testNullTypeGetMemory() { + assertEquals(30, (new NitriteDataType.NullType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.NullType(new NitriteDataType())).getMemory(0)); + assertEquals(0, (new NitriteDataType.NullType(new NitriteDataType())).getMemory(null)); + } + + @Test + public void testObjectArrayTypeGetMemory() { + assertEquals(30, (new NitriteDataType.ObjectArrayType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.ObjectArrayType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testObjectArrayTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(30, (new NitriteDataType.ObjectArrayType(nitriteDataType)).getMemory("Obj")); + } + + @Test + public void testSerializedObjectTypeGetMemory() { + assertEquals(30, (new NitriteDataType.SerializedObjectType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.SerializedObjectType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testSerializedObjectTypeGetMemory2() { + NitriteDataType.SerializedObjectType serializedObjectType = new NitriteDataType.SerializedObjectType( + new NitriteDataType()); + serializedObjectType.write(new WriteBuffer(), 19088743); + assertEquals(30, serializedObjectType.getMemory("Obj")); + } + + @Test + public void testShortTypeGetMemory() { + assertEquals(30, (new NitriteDataType.ShortType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.ShortType(new NitriteDataType())).getMemory((short) 0)); + assertEquals(24, (new NitriteDataType.ShortType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testStringTypeGetMemory() { + assertEquals(30, (new NitriteDataType.StringType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.StringType(new NitriteDataType())).getMemory(0)); + assertEquals(24, (new NitriteDataType.StringType(new NitriteDataType())).getMemory(4)); + } + + @Test + public void testStringTypeGetMemory2() { + NitriteDataType nitriteDataType = new NitriteDataType(); + nitriteDataType.switchType(1); + assertEquals(24, (new NitriteDataType.StringType(nitriteDataType)).getMemory(0)); + } + + @Test + public void testUUIDTypeGetMemory() { + assertEquals(30, (new NitriteDataType.UUIDType(new NitriteDataType())).getMemory("Obj")); + assertEquals(24, (new NitriteDataType.UUIDType(new NitriteDataType())).getMemory(0)); + } + + @Test + public void testUUIDTypeGetMemory2() { + NitriteDataType.UUIDType uuidType = new NitriteDataType.UUIDType(new NitriteDataType()); + assertEquals(40, uuidType.getMemory(UUID.randomUUID())); + } + + @Test + public void testBigDecimalTypeRead() { + Object actualReadResult = (new NitriteDataType.BigDecimalType(new NitriteDataType())).read(null, 46); + assertSame(((BigDecimal) actualReadResult).ZERO, actualReadResult); + } + + @Test + public void testBigDecimalTypeRead2() { + Object actualReadResult = (new NitriteDataType.BigDecimalType(new NitriteDataType())).read(null, 47); + assertSame(((BigDecimal) actualReadResult).ONE, actualReadResult); + } + + @Test + public void testBigIntegerTypeRead() { + Object actualReadResult = (new NitriteDataType.BigIntegerType(new NitriteDataType())).read(null, 37); + assertSame(((BigInteger) actualReadResult).ZERO, actualReadResult); + } + + @Test + public void testBigIntegerTypeRead2() { + Object actualReadResult = (new NitriteDataType.BigIntegerType(new NitriteDataType())).read(null, 38); + assertSame(((BigInteger) actualReadResult).ONE, actualReadResult); + } + + @Test + public void testNullTypeRead() { + assertNull((new NitriteDataType.NullType(new NitriteDataType())).read(null, 1)); + } + + @Test + public void testStringTypeRead2() { + assertEquals("", (new NitriteDataType.StringType(new NitriteDataType())).read(null, 88)); + } + + @Test + public void testAutoDetectDataTypeWrite() { + NitriteDataType.BigDecimalType bigDecimalType = new NitriteDataType.BigDecimalType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + bigDecimalType.write(writeBuffer, "42"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testAutoDetectDataTypeWrite2() { + NitriteDataType.BigDecimalType bigDecimalType = new NitriteDataType.BigDecimalType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + bigDecimalType.write(writeBuffer, new Object[]{"42", "42", "42"}, 3, true); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testAutoDetectDataTypeWrite3() { + NitriteDataType.BigDecimalType bigDecimalType = new NitriteDataType.BigDecimalType(null); + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> bigDecimalType.write(new WriteBuffer(), new Object[]{}, 3, true)); + } + + @Test + public void testBigDecimalTypeWrite() { + NitriteDataType.BigDecimalType bigDecimalType = new NitriteDataType.BigDecimalType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + bigDecimalType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testBigIntegerTypeWrite() { + NitriteDataType.BigIntegerType bigIntegerType = new NitriteDataType.BigIntegerType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + bigIntegerType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testBooleanTypeWrite() { + NitriteDataType.BooleanType booleanType = new NitriteDataType.BooleanType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + booleanType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testByteTypeWrite() { + NitriteDataType.ByteType byteType = new NitriteDataType.ByteType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + byteType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testCharacterTypeWrite() { + NitriteDataType.CharacterType characterType = new NitriteDataType.CharacterType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + characterType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testDateTypeWrite() { + NitriteDataType.DateType dateType = new NitriteDataType.DateType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + dateType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testDoubleTypeWrite() { + NitriteDataType.DoubleType doubleType = new NitriteDataType.DoubleType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + doubleType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testFloatTypeWrite() { + NitriteDataType.FloatType floatType = new NitriteDataType.FloatType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + floatType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testIntegerTypeWrite() { + NitriteDataType.IntegerType integerType = new NitriteDataType.IntegerType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + integerType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testLongTypeWrite() { + NitriteDataType.LongType longType = new NitriteDataType.LongType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + longType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testNullTypeWrite() { + NitriteDataType.NullType nullType = new NitriteDataType.NullType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + nullType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testObjectArrayTypeWrite() { + NitriteDataType.ObjectArrayType objectArrayType = new NitriteDataType.ObjectArrayType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + objectArrayType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testSerializedObjectTypeWrite() { + NitriteDataType.SerializedObjectType serializedObjectType = new NitriteDataType.SerializedObjectType( + new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + serializedObjectType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testShortTypeWrite() { + NitriteDataType.ShortType shortType = new NitriteDataType.ShortType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + shortType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testStringTypeWrite() { + NitriteDataType.StringType stringType = new NitriteDataType.StringType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + stringType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testUUIDTypeWrite() { + NitriteDataType.UUIDType uuidType = new NitriteDataType.UUIDType(new NitriteDataType()); + WriteBuffer writeBuffer = new WriteBuffer(); + uuidType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testSerializedObjectTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.SerializedObjectType actualSerializedObjectType = new NitriteDataType.SerializedObjectType( + nitriteDataType); + assertEquals(19, actualSerializedObjectType.typeId); + assertSame(actualSerializedObjectType.base, nitriteDataType); + } + + @Test + public void testShortTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.ShortType actualShortType = new NitriteDataType.ShortType(nitriteDataType); + assertEquals(3, actualShortType.typeId); + assertSame(actualShortType.base, nitriteDataType); + } + + @Test + public void testStringTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.StringType actualStringType = new NitriteDataType.StringType(nitriteDataType); + assertEquals(11, actualStringType.typeId); + assertSame(actualStringType.base, nitriteDataType); + } + + @Test + public void testUUIDTypeConstructor() { + NitriteDataType nitriteDataType = new NitriteDataType(); + NitriteDataType.UUIDType actualUuidType = new NitriteDataType.UUIDType(nitriteDataType); + assertEquals(12, actualUuidType.typeId); + assertSame(actualUuidType.base, nitriteDataType); + } + + @Test + public void testWrite() { + NitriteDataType nitriteDataType = new NitriteDataType(); + WriteBuffer writeBuffer = new WriteBuffer(); + nitriteDataType.write(writeBuffer, "Obj"); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testWrite4() { + NitriteDataType nitriteDataType = new NitriteDataType(); + WriteBuffer writeBuffer = new WriteBuffer(); + nitriteDataType.write(writeBuffer, new Object[]{"42", "42", "42"}, 3, true); + assertEquals(1048576, writeBuffer.capacity()); + } + + @Test + public void testWrite5() { + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> (new NitriteDataType()).write(null, new Object[]{}, 3, true)); + } + + @Test + public void testSwitchType() { + assertTrue((new NitriteDataType()).switchType("Obj") instanceof NitriteDataType.StringType); + assertEquals(4, (new NitriteDataType()).switchType(0).typeId); + } +} + diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java deleted file mode 100644 index b5b17c593..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository; - -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.repository.data.Employee; -import org.junit.Test; - -import java.util.AbstractCollection; - -/** - * @author Anindya Chatterjee - */ -public class ObjectCursorTest extends BaseObjectRepositoryTest { - - @Test(expected = ValidationException.class) - public void testProjectForInterface() { - Cursor cursor = employeeRepository.find(); - cursor.project(Comparable.class); - } - - @Test(expected = ValidationException.class) - public void testProjectForPrimitive() { - Cursor cursor = employeeRepository.find(); - cursor.project(int.class); - } - - @Test(expected = ValidationException.class) - public void testProjectForArray() { - Cursor cursor = employeeRepository.find(); - cursor.project(String[].class); - } - - @Test(expected = ValidationException.class) - public void testProjectForAbstractClass() { - Cursor cursor = employeeRepository.find(); - cursor.project(AbstractCollection.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java deleted file mode 100644 index 080a6de79..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryFactoryTest.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; -import org.dizitart.no2.collection.*; -import org.dizitart.no2.collection.events.CollectionEventListener; -import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.common.concurrent.LockService; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.store.NitriteStore; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import java.util.Collection; - -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class RepositoryFactoryTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testRepositoryFactory() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - assertNotNull(factory); - } - - @Test(expected = ValidationException.class) - public void testNullType() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); - factory.getRepository(db.getConfig(), null, "dummy"); - } - - @Test - public void testNullCollection() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); - factory.getRepository(db.getConfig(), DummyCollection.class, null); - } - - @Test(expected = ValidationException.class) - public void testNullContext() { - RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - factory.getRepository(null, DummyCollection.class, "dummy"); - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } - - private static class DummyCollection implements NitriteCollection { - - @Override - public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { - return null; - } - - @Override - public WriteResult remove(Filter filter, boolean justOne) { - return null; - } - - @Override - public DocumentCursor find(Filter filter, FindOptions findOptions) { - return null; - } - - @Override - public Document getById(NitriteId nitriteId) { - return null; - } - - @Override - public String getName() { - return null; - } - - @Override - public void createIndex(String field, IndexOptions indexOptions) { - - } - - @Override - public Collection listIndices() { - return null; - } - - @Override - public boolean hasIndex(String field) { - return false; - } - - @Override - public boolean isIndexing(String field) { - return false; - } - - @Override - public void dropIndex(String field) { - - } - - @Override - public void dropAllIndices() { - - } - - @Override - public WriteResult insert(Document[] elements) { - return null; - } - - @Override - public WriteResult update(Document element, boolean insertIfAbsent) { - return null; - } - - @Override - public WriteResult remove(Document element) { - return null; - } - - @Override - public void clear() { - - } - - @Override - public void drop() { - - } - - @Override - public boolean isDropped() { - return false; - } - - @Override - public boolean isOpen() { - return false; - } - - @Override - public void close() { - - } - - @Override - public long size() { - return 0; - } - - @Override - public NitriteStore getStore() { - return null; - } - - @Override - public void subscribe(CollectionEventListener listener) { - - } - - @Override - public void unsubscribe(CollectionEventListener listener) { - - } - - @Override - public Attributes getAttributes() { - return null; - } - - @Override - public void setAttributes(Attributes attributes) { - - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java deleted file mode 100644 index 2f5670810..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryJoinTest.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository; - -import lombok.Data; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; -import org.dizitart.no2.Retry; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.Lookup; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.mvstore.MVStoreModule; -import org.dizitart.no2.mvstore.MVStoreModuleBuilder; -import org.dizitart.no2.repository.annotations.Id; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; - -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -@RunWith(value = Parameterized.class) -public class RepositoryJoinTest { - @Parameterized.Parameter - public boolean inMemory = false; - @Parameterized.Parameter(value = 1) - public boolean isProtected = false; - @Parameterized.Parameter(value = 2) - public boolean isCompressed = false; - @Parameterized.Parameter(value = 3) - public boolean isAutoCommit = false; - - protected Nitrite db; - private final String fileName = getRandomTempDbFile(); - private ObjectRepository personRepository; - private ObjectRepository
    addressRepository; - - @Rule - public Retry retry = new Retry(3); - - @Parameterized.Parameters(name = "InMemory = {0}, Protected = {1}, " + - "Compressed = {2}, AutoCommit = {3}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false, false, false, false}, - {false, false, false, true}, - {false, false, true, false}, - {false, false, true, true}, - {false, true, false, false}, - {false, true, false, true}, - {false, true, true, false}, - {false, true, true, true}, - {true, false, false, false}, - {true, false, false, true}, - {true, false, true, false}, - {true, false, true, true}, - {true, true, false, false}, - {true, true, false, true}, - {true, true, true, false}, - {true, true, true, true}, - }); - } - - @Before - public void setUp() { - openDb(); - - personRepository = db.getRepository(Person.class); - addressRepository = db.getRepository(Address.class); - - for (int i = 0; i < 10; i++) { - Person person = new Person(); - person.setId(Integer.toString(i)); - person.setName("Person " + i); - personRepository.insert(person); - - Address address = new Address(); - address.setPersonId(Integer.toString(i)); - address.setStreet("Street address " + i); - addressRepository.insert(address); - - if (i == 5) { - Address address2 = new Address(); - address2.setPersonId(Integer.toString(i)); - address2.setStreet("Street address 2nd " + i); - addressRepository.insert(address2); - } - } - } - - private void openDb() { - MVStoreModuleBuilder builder = MVStoreModule.withConfig(); - - if (isCompressed) { - builder.compress(true); - } - - if (!isAutoCommit) { - builder.autoCommit(false); - } - - if (!inMemory) { - builder.filePath(fileName); - } - - MVStoreModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - if (isProtected) { - db = nitriteBuilder.openOrCreate("test-user1", "test-password1"); - } else { - db = nitriteBuilder.openOrCreate(); - } - } - - @After - public void clear() throws IOException { - if (personRepository != null && !personRepository.isDropped()) { - personRepository.remove(ALL); - } - - if (addressRepository != null && !addressRepository.isDropped()) { - addressRepository.remove(ALL); - } - - if (db != null) { - db.commit(); - db.close(); - } - - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } - } - - @Test - public void testJoin() { - Lookup lookup = new Lookup(); - lookup.setLocalField("id"); - lookup.setForeignField("personId"); - lookup.setTargetField("addresses"); - - RecordStream result - = personRepository.find().join(addressRepository.find(), lookup, - PersonDetails.class); - assertEquals(result.size(), 10); - - for (PersonDetails personDetails : result) { - Address[] addresses = personDetails.addresses.toArray(new Address[0]); - if (personDetails.id.equals("5")) { - assertEquals(addresses.length, 2); - } else { - assertEquals(addresses.length, 1); - assertEquals(addresses[0].personId, personDetails.getId()); - } - } - - result = personRepository.find().skipLimit(0, 5).join(addressRepository.find(), lookup, - PersonDetails.class); - - assertEquals(result.size(), 5); - assertFalse(result.isEmpty()); - assertNotNull(result.toString()); - } - - @Test(expected = InvalidOperationException.class) - public void testRemove() { - Lookup lookup = new Lookup(); - lookup.setLocalField("id"); - lookup.setForeignField("personId"); - lookup.setTargetField("addresses"); - - RecordStream result - = personRepository.find().join(addressRepository.find(), lookup, - PersonDetails.class); - assertEquals(result.size(), 10); - - Iterator iterator = result.iterator(); - if (iterator.hasNext()) { - iterator.next(); - iterator.remove(); - } - } - - @Data - public static class Person implements Mappable { - @Id - private NitriteId nitriteId; - private String id; - private String name; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("nitriteId", nitriteId) - .put("id", id) - .put("name", name); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - nitriteId = document.get("nitriteId", NitriteId.class); - id = document.get("id", String.class); - name = document.get("name", String.class); - } - } - - @Data - public static class Address implements Mappable { - @Id - private NitriteId nitriteId; - private String personId; - private String street; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("nitriteId", nitriteId) - .put("personId", personId) - .put("street", street); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - nitriteId = document.get("nitriteId", NitriteId.class); - personId = document.get("personId", String.class); - street = document.get("street", String.class); - } - } - - @Data - public static class PersonDetails implements Mappable { - @Id - private NitriteId nitriteId; - private String id; - private String name; - private List
    addresses; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("nitriteId", nitriteId) - .put("personId", id) - .put("street", name) - .put("addresses", addresses); - } - - @Override - @SuppressWarnings("unchecked") - public void read(NitriteMapper mapper, Document document) { - nitriteId = document.get("nitriteId", NitriteId.class); - id = document.get("id", String.class); - name = document.get("name", String.class); - Set documents = document.get("addresses", Set.class); - this.addresses = new ArrayList<>(); - for (Document doc : documents) { - Address address = new Address(); - address.read(mapper, doc); - addresses.add(address); - } - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java deleted file mode 100644 index 3c259a8a8..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryModificationTest.java +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.data.*; -import org.junit.Test; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Date; -import java.util.Locale; - -import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.*; - - -/** - * @author Anindya Chatterjee. - */ -public class RepositoryModificationTest extends BaseObjectRepositoryTest { - - @Test - public void testCreateIndex() { - assertTrue(companyRepository.hasIndex("companyName")); - assertFalse(companyRepository.hasIndex("dateCreated")); - - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); - assertTrue(companyRepository.hasIndex("dateCreated")); - assertFalse(companyRepository.isIndexing("dateCreated")); - } - - @Test - public void testRebuildIndex() { - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); - assertFalse(companyRepository.isIndexing("dateCreated")); - - companyRepository.rebuildIndex("dateCreated", true); - assertTrue(companyRepository.isIndexing("dateCreated")); - - await().until(() -> !companyRepository.isIndexing("dateCreated")); - } - - @Test - public void testListIndexes() { - Collection indices = companyRepository.listIndices(); - assertEquals(indices.size(), 2); - - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); - indices = companyRepository.listIndices(); - assertEquals(indices.size(), 3); - } - - @Test - public void testDropIndex() { - testListIndexes(); - companyRepository.dropIndex("dateCreated"); - Collection indices = companyRepository.listIndices(); - assertEquals(indices.size(), 2); - } - - @Test - public void testDropAllIndex() { - testListIndexes(); - companyRepository.dropAllIndices(); - Collection indices = companyRepository.listIndices(); - assertEquals(indices.size(), 0); - } - - @Test - public void testCompanyRecord() { - Cursor cursor = companyRepository.find(); - assertEquals(cursor.size(), 10); - assertFalse(cursor.isEmpty()); - } - - @Test - public void testInsert() { - Company company = DataGenerator.generateCompanyRecord(); - Cursor cursor = companyRepository.find(); - assertEquals(cursor.size(), 10); - - companyRepository.insert(company); - cursor = companyRepository.find(); - assertEquals(cursor.size(), 11); - - Company company1 = DataGenerator.generateCompanyRecord(); - Company company2 = DataGenerator.generateCompanyRecord(); - companyRepository.insert(new Company[]{company1, company2}); - cursor = companyRepository.find(); - assertEquals(cursor.size(), 13); - } - - @Test - public void testUpdateWithFilter() { - employeeRepository.remove(Filter.ALL); - - Employee employee = new Employee(); - employee.setCompany(null); - employee.setAddress("abcd road"); - employee.setBlob(new byte[]{1, 2, 125}); - employee.setEmpId(12L); - employee.setJoinDate(new Date()); - Note empNote = new Note(); - empNote.setNoteId(23L); - empNote.setText("sample text note"); - employee.setEmployeeNote(empNote); - - employeeRepository.insert(employee); - Cursor result = employeeRepository.find(); - assertEquals(result.size(), 1); - for (Employee e : result) { - assertEquals(e.getAddress(), "abcd road"); - } - - Employee updated = new Employee(employee); - updated.setAddress("xyz road"); - WriteResult writeResult = employeeRepository.update(where("empId").eq(12L), updated); - assertEquals(writeResult.getAffectedCount(), 1); - result = employeeRepository.find(); - assertEquals(result.size(), 1); - for (Employee e : result) { - assertEquals(e.getAddress(), "xyz road"); - } - } - - @Test - public void testUpdateWithJustOnceFalse() throws ParseException { - Date joiningDate = new Date(); - prepareUpdateWithOptions(joiningDate); - - SimpleDateFormat simpleDateFormat - = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); - Date newJoiningDate = simpleDateFormat.parse("2012-07-01T16:02:48.440Z"); - - Document updated1 = createDocument(); - updated1.put("joinDate", newJoiningDate); - - WriteResult writeResult - = employeeRepository.update(where("empId").eq(12L), updated1, false); - assertEquals(writeResult.getAffectedCount(), 1); - - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 1); - result = employeeRepository.find(where("joinDate").eq(newJoiningDate)); - assertEquals(result.size(), 1); - - employeeRepository.remove(Filter.ALL); - prepareUpdateWithOptions(joiningDate); - result = employeeRepository.find(); - assertEquals(result.size(), 2); - - Document update = createDocument(); - update.put("joinDate", newJoiningDate); - - writeResult = employeeRepository.update(where("joinDate").eq(joiningDate), update, false); - assertEquals(writeResult.getAffectedCount(), 2); - - result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 0); - - result = employeeRepository.find(where("joinDate").eq(newJoiningDate)); - assertEquals(result.size(), 2); - } - - @Test - public void testUpsertTrue() { - Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 0); - - Employee employee = new Employee(); - employee.setCompany(null); - employee.setAddress("some road"); - employee.setBlob(new byte[]{1, 2, 125}); - employee.setEmpId(12L); - employee.setJoinDate(joiningDate); - Note empNote1 = new Note(); - empNote1.setNoteId(23L); - empNote1.setText("sample text note"); - employee.setEmployeeNote(empNote1); - - WriteResult writeResult - = employeeRepository.update(where("empId").eq(12), employee, true); - assertEquals(writeResult.getAffectedCount(), 1); - - result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 1); - } - - @Test - public void testUpsertFalse() { - Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 0); - - Employee employee = new Employee(); - employee.setCompany(null); - employee.setAddress("some road"); - employee.setBlob(new byte[]{1, 2, 125}); - employee.setEmpId(12L); - employee.setJoinDate(joiningDate); - Note empNote1 = new Note(); - empNote1.setNoteId(23L); - empNote1.setText("sample text note"); - employee.setEmployeeNote(empNote1); - - WriteResult writeResult - = employeeRepository.update(where("empId").eq(12), employee, false); - assertEquals(writeResult.getAffectedCount(), 0); - - result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 0); - } - - @Test - public void testDeleteFilterAndWithOutOption() { - Date joiningDate = new Date(); - prepareUpdateWithOptions(joiningDate); - - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 2); - - WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate)); - assertEquals(writeResult.getAffectedCount(), 2); - result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 0); - } - - @Test - public void testDeleteFilterAndWithOption() { - Date joiningDate = new Date(); - prepareUpdateWithOptions(joiningDate); - - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 2); - - WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate), true); - assertEquals(writeResult.getAffectedCount(), 1); - result = employeeRepository.find(where("joinDate").eq(joiningDate)); - assertEquals(result.size(), 1); - } - - @Test - public void testEmployeeRecord() { - Iterable totalResult = employeeRepository.find(); - int occurrence = 0; - for (Employee employee : totalResult) { - if (employee.getEmployeeNote().getText().toLowerCase().contains("class aptent")) { - occurrence++; - } - } - - Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); - assertEquals(cursor.size(), occurrence); - } - - @Test - public void testUpdateWithOptions() { - Employee employee = employeeRepository.find().firstOrNull(); - - Document update = createDocument(); - update.put("address", "new address"); - - WriteResult writeResult - = employeeRepository.update(where("empId").eq(employee.getEmpId()), update, false); - assertEquals(writeResult.getAffectedCount(), 1); - - Employee byId = employeeRepository.getById(employee.getEmpId()); - assertEquals(byId.getAddress(), "new address"); - assertEquals(byId.getEmpId(), employee.getEmpId()); - - update.put("address", "another address"); - employeeRepository.update(where("empId").eq(employee.getEmpId()), update); - - byId = employeeRepository.getById(employee.getEmpId()); - assertEquals(byId.getAddress(), "another address"); - assertEquals(byId.getEmpId(), employee.getEmpId()); - } - - @Test(expected = InvalidIdException.class) - public void testMultiUpdateWithObject() { - employeeRepository.remove(Filter.ALL); - - Date now = new Date(); - Employee employee1 = new Employee(); - employee1.setEmpId(1L); - employee1.setAddress("abcd"); - employee1.setJoinDate(now); - - Employee employee2 = new Employee(); - employee2.setEmpId(2L); - employee2.setAddress("xyz"); - employee2.setJoinDate(now); - employeeRepository.insert(employee1, employee2); - - Employee update = new Employee(); - update.setAddress("new address"); - - WriteResult writeResult - = employeeRepository.update(where("joinDate").eq(now), update, false); - assertEquals(writeResult.getAffectedCount(), 0); - } - - @Test - public void testUpdateNull() { - Employee employee = employeeRepository.find().firstOrNull(); - Employee newEmployee = new Employee(employee); - newEmployee.setJoinDate(null); - - Employee result = employeeRepository.find(where("empId").eq(employee.getEmpId())).firstOrNull(); - assertNotNull(result.getJoinDate()); - - WriteResult writeResult = employeeRepository.update(newEmployee, false); - assertEquals(writeResult.getAffectedCount(), 1); - - result = employeeRepository.find(where("empId").eq(employee.getEmpId())).firstOrNull(); - assertNull(result.getJoinDate()); - - // update with object filter and item and set id different - } - - @Test - public void testUpdateWithChangedId() { - Employee employee = employeeRepository.find().firstOrNull(); - Long oldId = employee.getEmpId(); - long count = employeeRepository.size(); - - Employee newEmployee = new Employee(employee); - newEmployee.setEmpId(50L); - - Employee result = employeeRepository.find(where("empId").eq(oldId)).firstOrNull(); - assertNotNull(result.getJoinDate()); - - WriteResult writeResult = employeeRepository.update(where("empId").eq(oldId), newEmployee, false); - assertEquals(writeResult.getAffectedCount(), 1); - - assertEquals(count, employeeRepository.size()); - Cursor cursor = employeeRepository.find(where("empId").eq(oldId)); - assertEquals(cursor.size(), 0); - } - - @Test(expected = InvalidIdException.class) - public void testUpdateWithNullId() { - Employee employee = employeeRepository.find().firstOrNull(); - Long oldId = employee.getEmpId(); - - Employee newEmployee = new Employee(employee); - newEmployee.setEmpId(null); - - Employee result = employeeRepository.find(where("empId").eq(oldId)).firstOrNull(); - assertNotNull(result.getJoinDate()); - - WriteResult writeResult = employeeRepository.update(where("empId").eq(oldId), newEmployee, false); - assertEquals(writeResult.getAffectedCount(), 1); - } - - @Test(expected = UniqueConstraintException.class) - public void testUpdateWithDuplicateId() { - Employee employee = employeeRepository.find().firstOrNull(); - Long oldId = employee.getEmpId(); - long count = employeeRepository.size(); - - Employee newEmployee = new Employee(employee); - newEmployee.setEmpId(5L); - - Employee result = employeeRepository.find(where("empId").eq(oldId)).firstOrNull(); - assertNotNull(result.getJoinDate()); - - WriteResult writeResult = employeeRepository.update(where("empId").eq(oldId), newEmployee, false); - assertEquals(writeResult.getAffectedCount(), 1); - - assertEquals(count, employeeRepository.size()); - Cursor cursor = employeeRepository.find(where("empId").eq(oldId)); - assertEquals(cursor.size(), 0); - } - - @Test - public void testUpdateWithObject() { - Employee employee = employeeRepository.find().firstOrNull(); - Employee newEmployee = new Employee(employee); - - Long id = employee.getEmpId(); - String address = employee.getAddress(); - newEmployee.setAddress("new address"); - - WriteResult writeResult = employeeRepository.update(newEmployee); - assertEquals(writeResult.getAffectedCount(), 1); - - Employee emp = employeeRepository.find(where("empId").eq(id)).firstOrNull(); - assertNotEquals(address, emp.getAddress()); - assertEquals(employee.getEmpId(), emp.getEmpId()); - assertEquals(employee.getJoinDate(), emp.getJoinDate()); - assertArrayEquals(employee.getBlob(), emp.getBlob()); - } - - @Test - public void testUpsertWithObject() { - Employee employee = new Employee(); - employee.setCompany(null); - employee.setAddress("some road"); - employee.setBlob(new byte[]{1, 2, 125}); - employee.setEmpId(12L); - employee.setJoinDate(new Date()); - Note empNote = new Note(); - empNote.setNoteId(23L); - empNote.setText("sample text note"); - employee.setEmployeeNote(empNote); - - WriteResult writeResult = employeeRepository.update(employee, false); - assertEquals(writeResult.getAffectedCount(), 0); - writeResult = employeeRepository.update(employee, true); - assertEquals(writeResult.getAffectedCount(), 1); - - Employee emp = employeeRepository.find(where("empId").eq(12L)).firstOrNull(); - assertEquals(emp, employee); - } - - @Test - public void testRemoveObject() { - Employee employee = new Employee(); - employee.setCompany(null); - employee.setAddress("some road"); - employee.setBlob(new byte[]{1, 2, 125}); - employee.setEmpId(12L); - employee.setJoinDate(new Date()); - Note empNote = new Note(); - empNote.setNoteId(23L); - empNote.setText("sample text note"); - employee.setEmployeeNote(empNote); - - long size = employeeRepository.size(); - - employeeRepository.insert(employee); - assertEquals(employeeRepository.size(), size + 1); - - employeeRepository.remove(employee); - assertEquals(employeeRepository.size(), size); - - Employee emp = employeeRepository.find(where("empId").eq(12L)).firstOrNull(); - assertNull(emp); - } - - private void prepareUpdateWithOptions(Date joiningDate) { - employeeRepository.remove(Filter.ALL); - - Employee employee1 = new Employee(); - employee1.setCompany(null); - employee1.setAddress("some road"); - employee1.setBlob(new byte[]{1, 2, 125}); - employee1.setEmpId(12L); - employee1.setJoinDate(joiningDate); - Note empNote1 = new Note(); - empNote1.setNoteId(23L); - empNote1.setText("sample text note"); - employee1.setEmployeeNote(empNote1); - - Employee employee2 = new Employee(); - employee2.setCompany(null); - employee2.setAddress("other road"); - employee2.setBlob(new byte[]{10, 12, 25}); - employee2.setEmpId(2L); - employee2.setJoinDate(joiningDate); - Note empNote2 = new Note(); - empNote2.setNoteId(2L); - empNote2.setText("some random note"); - employee2.setEmployeeNote(empNote2); - - employeeRepository.insert(employee1, employee2); - Cursor result = employeeRepository.find(); - assertEquals(result.size(), 2); - for (Employee e : result.project(Employee.class)) { - assertEquals(e.getJoinDate(), joiningDate); - } - } - - @Test - public void testUpdateWithDoc() { - Note note = new Note(); - note.setNoteId(10L); - note.setText("some note text"); - - Document document = createDocument("address", "some address") - .put("employeeNote", note); - - WriteResult result = employeeRepository.update(Filter.ALL, document); - assertEquals(result.getAffectedCount(), 10); - } - - @Test - public void testDeleteIteratorNPE() { - ObjectRepository notes = db.getRepository(Note.class); - Note one = new Note(); - one.setText("Jane"); - one.setNoteId(1L); - Note two = new Note(); - two.setText("Jill"); - two.setNoteId(2L); - - notes.insert(one, two); - - WriteResult writeResult = notes.remove(where("text").eq("Pete")); - for (NitriteId id : writeResult) { - assertNotNull(id); - } - } - - @Test - public void testDelete() { - ObjectRepository repo = db.getRepository(WithNitriteId.class); - WithNitriteId one = new WithNitriteId(); - one.setName("Jane"); - repo.insert(one); - - WithNitriteId note = repo.find().firstOrNull(); - repo.remove(note); - - assertNull(repo.getById(one.idField)); - } - - /* - * Upsert Use Cases - * - * 1. Object does not exists - * a. if upsert true, it will insert - * b. if upsert false, nothing happens - * 2. Object exists - * a. if upsert true, it will update, old id remains same - * b. if upsert false, it will update, old id remains same - * - * */ - - @Test - public void testUpdateObjectNotExistsUpsertTrue() { - ObjectRepository repo = db.getRepository(InternalClass.class); - InternalClass a = new InternalClass(); - a.setId(1); - a.setName("first"); - repo.insert(a); - - a = new InternalClass(); - a.setId(2); - a.setName("second"); - - // it will insert as new object - repo.update(a, true); - assertEquals(repo.size(), 2); - } - - @Test - public void testUpdateObjectNotExistsUpsertFalse() { - ObjectRepository repo = db.getRepository(InternalClass.class); - InternalClass a = new InternalClass(); - a.setId(1); - a.setName("first"); - repo.insert(a); - - a = new InternalClass(); - a.setId(2); - a.setName("second"); - - // no changes will happen to repository - repo.update(a, false); - assertEquals(repo.size(), 1); - assertEquals(repo.find().firstOrNull().getId(), 1); - assertEquals(repo.find().firstOrNull().getName(), "first"); - } - - @Test - public void testUpdateObjectExistsUpsertTrue() { - ObjectRepository repo = db.getRepository(InternalClass.class); - InternalClass a = new InternalClass(); - a.setId(1); - a.setName("first"); - repo.insert(a); - - a = new InternalClass(); - a.setId(1); - a.setName("second"); - - // update existing object, keep id same - repo.update(a, true); - assertEquals(repo.size(), 1); - assertEquals(repo.find().firstOrNull().getId(), 1); - assertEquals(repo.find().firstOrNull().getName(), "second"); - } - - @Test - public void testUpdateObjectExistsUpsertFalse() { - ObjectRepository repo = db.getRepository(InternalClass.class); - InternalClass a = new InternalClass(); - a.setId(1); - a.setName("first"); - repo.insert(a); - - a = new InternalClass(); - a.setId(1); - a.setName("second"); - - // update existing object, keep id same - repo.update(a, false); - assertEquals(repo.size(), 1); - assertEquals(repo.find().firstOrNull().getId(), 1); - assertEquals(repo.find().firstOrNull().getName(), "second"); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java deleted file mode 100644 index 98426b521..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositoryOperationsTest.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository; - -import lombok.Getter; -import org.dizitart.no2.DbTestOperations; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.exceptions.NotIdentifiableException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.InheritIndices; -import org.dizitart.no2.repository.data.Employee; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.Iterator; -import java.util.Set; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * @author Anindya Chatterjee - */ -public class RepositoryOperationsTest { - private RepositoryOperations operations; - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = TestUtil.createDb(); - } - - @Test - public void testIndexes() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(TestObjectWithIndex.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - Set indexes = operations.extractIndices(TestObjectWithIndex.class); - assertEquals(indexes.size(), 2); - } - - @Test(expected = IndexingException.class) - public void testInvalidIndexNonComparable() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ObjectWithNonComparableIndex.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - Set indexes = operations.extractIndices(ObjectWithNonComparableIndex.class); - assertEquals(indexes.size(), 2); - } - - @Test(expected = IndexingException.class) - public void testInvalidIndexComparableAndIterable() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ObjectWithIterableIndex.class); - operations = new RepositoryOperations(ObjectWithIterableIndex.class, nitriteMapper, repository.getDocumentCollection()); - operations.extractIndices(ObjectWithIterableIndex.class); - } - - @Test(expected = ValidationException.class) - public void testGetFieldsUpToNullStartClass() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Employee.class); - operations = new RepositoryOperations(Employee.class, nitriteMapper, repository.getDocumentCollection()); - assertEquals(operations.getFieldsUpto(null, null).size(), 0); - } - - @Test(expected = ValidationException.class) - public void testGetFieldNoSuchField() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(getClass(), "test"); - } - - @Test - public void testGetFieldsUpTo() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Employee.class); - operations = new RepositoryOperations(TestObjectWithIndex.class, nitriteMapper, repository.getDocumentCollection()); - - assertEquals(operations.getFieldsUpto(A.class, B.class).size(), 3); - assertEquals(operations.getFieldsUpto(A.class, Object.class).size(), 5); - assertEquals(operations.getFieldsUpto(A.class, null).size(), 5); - - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - Object.class).size(), 5); - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - null).size(), 5); - assertEquals(operations.getFieldsUpto(ClassWithAnnotatedFields.class, - ClassWithNoAnnotatedFields.class).size(), 3); - } - - @Test(expected = NotIdentifiableException.class) - public void testCreateUniqueFilterInvalidId() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(B.class); - operations = new RepositoryOperations(B.class, nitriteMapper, repository.getDocumentCollection()); - - B b = new B(); - operations.createUniqueFilter(b); - } - - @Test(expected = NotIdentifiableException.class) - public void testGetIdFieldMultipleId() { - class Test implements Mappable { - @Id - private String id1; - - @Id - private Long id2; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("id1", id1) - .put("id2", id2); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id1 = document.get("id1", String.class); - id2 = document.get("id2", Long.class); - } - } - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Test.class); - operations = new RepositoryOperations(Test.class, nitriteMapper, repository.getDocumentCollection()); - } - - @Test(expected = ValidationException.class) - public void testInvalidEmbeddedKey() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(ClassWithAnnotatedFields.class, ".."); - } - - @Test(expected = ValidationException.class) - public void testInvalidGetField() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(ClassWithAnnotatedFields.class); - operations = new RepositoryOperations(ClassWithAnnotatedFields.class, nitriteMapper, repository.getDocumentCollection()); - operations.getField(ClassWithAnnotatedFields.class, "fake.fake"); - } - - @Test(expected = ValidationException.class) - public void testExtractInvalidIndex() { - @Index(value = "fake") - class Test implements Mappable { - private String test; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("test", test); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - test = document.get("test", String.class); - } - } - - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(Test.class); - operations = new RepositoryOperations(Test.class, nitriteMapper, repository.getDocumentCollection()); - - operations.extractIndices(Test.class); - } - - @Test - public void testFindAnnotationFromInterface() { - NitriteMapper nitriteMapper = db.getConfig().nitriteMapper(); - ObjectRepository repository = db.getRepository(TestInterface.class); - operations = new RepositoryOperations(TestInterface.class, nitriteMapper, repository.getDocumentCollection()); - - Set indices = operations.extractIndices(TestInterface.class); - assertFalse(indices.isEmpty()); - } - - @Index(value = "value") - private interface Interface { - String getValue(); - } - - private static class ClassWithAnnotatedFields extends ClassWithNoAnnotatedFields { - @Deprecated - Long longValue; - private String stringValue; - @Deprecated - private String anotherValue; - - @Deprecated - public ClassWithAnnotatedFields() { - } - - @Override - public Document write(NitriteMapper mapper) { - return super.write(mapper) - .put("stringValue", stringValue) - .put("anotherValue", anotherValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - super.read(mapper, document); - stringValue = document.get("stringValue", String.class); - anotherValue = document.get("anotherValue", String.class); - longValue = document.get("longValue", Long.class); - } - } - - private static class ClassWithNoAnnotatedFields implements Mappable { - private String stringValue; - private Integer integer; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("stringValue", stringValue) - .put("integer", integer); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - stringValue = document.get("stringValue", String.class); - integer = document.get("integer", Integer.class); - } - } - - private static class A extends B { - private String a; - private Long b; - private Integer c; - } - - private static class B implements Mappable { - String a; - private Short d; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("a", a) - .put("d", d); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - a = document.get("a", String.class); - d = document.get("d", Short.class); - } - } - - @Index(value = "testClass") - private static class ObjectWithNonComparableIndex implements Mappable { - private DbTestOperations testClass; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("testClass", testClass); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - testClass = document.get("testClass", DbTestOperations.class); - } - } - - @Index(value = "testClass") - private static class ObjectWithIterableIndex implements Mappable { - private TestClass testClass; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("testClass", testClass.write(mapper)); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - TestClass tc = new TestClass(); - tc.read(mapper, document.get("testClass", Document.class)); - testClass = tc; - } - } - - private static class TestClass implements Comparable, Iterable, Mappable { - @Override - public int compareTo(TestClass o) { - return 0; - } - - @Override - public Iterator iterator() { - return null; - } - - @Override - public Document write(NitriteMapper mapper) { - return createDocument(); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - - } - } - - @InheritIndices - private static class TestInterface implements Interface, Mappable { - @Getter - private String value; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument().put("value", value); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - value = document.get("value", String.class); - } - } - - @Index(value = "longValue") - @Index(value = "decimal") - private class TestObjectWithIndex implements Mappable { - private long longValue; - - private TestObject testObject; - - private BigDecimal decimal; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("longValue", longValue) - .put("testObject", testObject.write(mapper)) - .put("decimal", decimal.toPlainString()); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - longValue = document.get("longValue", Long.class); - testObject = new TestObject(); - testObject.read(mapper, document.get("testObject", Document.class)); - String decimalString = document.get("decimal", String.class); - decimal = new BigDecimal(decimalString); - } - } - - @Index(value = "longValue") - private class TestObject implements Mappable { - private String stringValue; - - private Long longValue; - - @Override - public Document write(NitriteMapper mapper) { - return createDocument() - .put("stringValue", stringValue) - .put("longValue", longValue); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - stringValue = document.get("stringValue", String.class); - longValue = document.get("longValue", Long.class); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java deleted file mode 100644 index 23d93d5b3..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassB.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -@EqualsAndHashCode -@ToString -class ClassB implements Comparable, Mappable { - @Getter - @Setter - private int number; - @Getter - @Setter - private String text; - - static ClassB create(int seed) { - ClassB classB = new ClassB(); - classB.setNumber(seed + 100); - classB.setText(Integer.toBinaryString(seed)); - return classB; - } - - @Override - public int compareTo(ClassB o) { - return Integer.compare(number, o.number); - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("number", number) - .put("text", text); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - number = document.get("number", Integer.class); - text = document.get("text", String.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java deleted file mode 100644 index 047f83bcd..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ClassC.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -@EqualsAndHashCode -@ToString -public class ClassC implements Mappable { - @Getter - @Setter - private long id; - @Getter - @Setter - private double digit; - @Getter - @Setter - private ClassA parent; - - public static ClassC create(int seed) { - ClassC classC = new ClassC(); - classC.id = seed * 5000; - classC.digit = seed * 69.65; - classC.parent = ClassA.create(seed); - return classC; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("id", id) - .put("digit", digit) - .put("parent", parent != null ? parent.write(mapper) : null); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Long.class); - digit = document.get("digit", Double.class); - if (document.get("parent") != null) { - parent = new ClassA(); - parent.read(mapper, document.get("parent", Document.class)); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java deleted file mode 100644 index 18310236a..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/Note.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -import java.io.Serializable; - -/** - * @author Anindya Chatterjee. - */ -@EqualsAndHashCode -public class Note implements Serializable, Mappable { - @Getter - @Setter - private Long noteId; - @Getter - @Setter - private String text; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument().put("noteId", noteId).put("text", text); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - noteId = document.get("noteId", Long.class); - text = document.get("text", String.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java deleted file mode 100644 index f201d620f..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/PersonEntity.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Entity; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; - -import java.util.Date; -import java.util.UUID; - -/** - * @author Anindya Chatterjee - */ -@Data -@Entity(value = "MyPerson", indices = { - @Index(value = "name", type = IndexType.Fulltext), - @Index(value = "status", type = IndexType.NonUnique) -}) -public class PersonEntity implements Mappable { - @Id - private String uuid; - private String name; - private String status; - private PersonEntity friend; - private Date dateCreated; - - public PersonEntity() { - this.uuid = UUID.randomUUID().toString(); - this.dateCreated = new Date(); - } - - public PersonEntity(String name) { - this.uuid = UUID.randomUUID().toString(); - this.name = name; - this.dateCreated = new Date(); - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("uuid", uuid) - .put("name", name) - .put("status", status) - .put("friend", friend != null ? friend.write(mapper) : null) - .put("dateCreated", dateCreated); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - uuid = document.get("uuid", String.class); - name = document.get("name", String.class); - status = document.get("status", String.class); - dateCreated = document.get("dateCreated", Date.class); - friend = new PersonEntity(); - friend.read(mapper, document.get("friend", Document.class)); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java deleted file mode 100644 index f2076ab48..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/RepeatableIndexTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee - */ -@Data -@Index(value = "firstName") -@Index(value = "age", type = IndexType.NonUnique) -@Index(value = "lastName", type = IndexType.Fulltext) -public class RepeatableIndexTest implements Mappable { - private String firstName; - private Integer age; - private String lastName; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("firstName", firstName) - .put("age", age) - .put("lastName", lastName); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - firstName = document.get("firstName", String.class); - age = document.get("age", Integer.class); - lastName = document.get("lastName", String.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java deleted file mode 100644 index fedfeb6ed..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SubEmployee.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -import java.util.Date; - -/** - * @author Anindya Chatterjee. - */ -@EqualsAndHashCode -public class SubEmployee implements Mappable { - @Getter - @Setter - private Long empId; - - @Getter - @Setter - private Date joinDate; - - @Getter - @Setter - private String address; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("empId", empId) - .put("joinDate", joinDate) - .put("address", address); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - empId = document.get("empId", Long.class); - joinDate = document.get("joinDate", Date.class); - address = document.get("address", String.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java deleted file mode 100644 index 816f1cb38..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithEmptyStringId.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithEmptyStringId implements Mappable { - @Id - private String name; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("name", name); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java deleted file mode 100644 index 3a252d9b5..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithOutId.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithOutId implements Comparable, Mappable { - private String name; - private long number; - - @Override - public int compareTo(WithOutId o) { - return Long.compare(number, o.number); - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("name", name) - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - number = document.get("number", Long.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java deleted file mode 100644 index 4332542ea..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithPrivateConstructor.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.repository.data; - -import lombok.EqualsAndHashCode; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee. - */ -@EqualsAndHashCode -public class WithPrivateConstructor implements Mappable { - private String name; - private long number; - - private WithPrivateConstructor() { - name = "test"; - number = 2; - } - - public static WithPrivateConstructor create(final String name, final long number) { - WithPrivateConstructor obj = new WithPrivateConstructor(); - obj.number = number; - obj.name = name; - return obj; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("name", name) - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - number = document.get("number", Long.class); - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java deleted file mode 100644 index a235b8dfd..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionCollectionTest.java +++ /dev/null @@ -1,770 +0,0 @@ -package org.dizitart.no2.transaction; - -import com.github.javafaker.Faker; -import org.dizitart.no2.collection.BaseCollectionTest; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.TransactionException; -import org.dizitart.no2.index.IndexType; -import org.junit.Test; - -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.collection.UpdateOptions.updateOptions; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -public class TransactionCollectionTest extends BaseCollectionTest { - - @Test - public void testCommitInsert() { - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - - Document document = createDocument("firstName", "John"); - txCol.insert(document); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 1); - assertNotEquals(collection.find(where("firstName").eq("John")).size(), 1); - - transaction.commit(); - - assertEquals(collection.find(where("firstName").eq("John")).size(), 1); - } - } - } - - @Test - public void testRollbackInsert() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - NitriteCollection txCol = transaction.getCollection("test"); - - Document document = createDocument("firstName", "John"); - Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); - txCol.insert(document); - txCol.insert(document2); - - // just to create UniqueConstraintViolation for rollback - collection.insert(createDocument("firstName", "Jane")); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertNotEquals(collection.find(where("firstName").eq("John")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - } - } - } - - @Test - public void testCommitUpdate() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - document.put("lastName", "Doe"); - - txCol.update(where("firstName").eq("John"), document, updateOptions(true)); - - assertEquals(txCol.find(where("lastName").eq("Doe")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - - transaction.commit(); - - assertEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - } - } - } - - @Test - public void testRollbackUpdate() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.insert(createDocument("firstName", "Jane")); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - NitriteCollection txCol = transaction.getCollection("test"); - - Document document = createDocument("firstName", "John"); - Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); - txCol.update(where("firstName").eq("Jane"), document2); - txCol.insert(document); - - // just to create UniqueConstraintViolation for rollback - collection.insert(createDocument("firstName", "John")); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 1); - assertEquals(txCol.find(where("lastName").eq("Doe")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(collection.find(where("firstName").eq("Jane")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - } - } - } - - @Test - public void testCommitRemove() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - - txCol.remove(where("firstName").eq("John")); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 0); - assertEquals(collection.find(where("firstName").eq("John")).size(), 1); - - transaction.commit(); - - assertEquals(collection.find(where("firstName").eq("John")).size(), 0); - } - } - } - - @Test - public void testRollbackRemove() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - - txCol.remove(where("firstName").eq("John")); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 0); - assertEquals(collection.find(where("firstName").eq("John")).size(), 1); - - txCol.insert(createDocument("firstName", "Jane")); - collection.insert(createDocument("firstName", "Jane")); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(collection.find(where("firstName").eq("John")).size(), 1); - assertEquals(collection.find(where("firstName").eq("Jane")).size(), 1); - } - } - } - - @Test - public void testCommitCreateIndex() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Fulltext)); - - assertTrue(txCol.hasIndex("firstName")); - assertFalse(collection.hasIndex("firstName")); - - transaction.commit(); - - assertTrue(collection.hasIndex("firstName")); - } - } - } - - @Test - public void testRollbackCreateIndex() { - Document document = createDocument("firstName", "John"); - Document document2 = createDocument("firstName", "Jane"); - collection.insert(document); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - - txCol.createIndex("firstName", indexOptions(IndexType.Unique)); - - assertTrue(txCol.hasIndex("firstName")); - assertFalse(collection.hasIndex("firstName")); - - txCol.insert(document2); - collection.insert(document2); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertFalse(collection.hasIndex("firstName")); - } - } - } - - @Test - public void testCommitClear() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - txCol.clear(); - - assertEquals(0, txCol.size()); - assertEquals(1, collection.size()); - - transaction.commit(); - - assertEquals(0, collection.size()); - } - } - } - - @Test - public void testRollbackClear() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - Document document = createDocument("firstName", "John"); - Document document2 = createDocument("firstName", "Jane"); - collection.insert(document); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - - txCol.clear(); - - assertEquals(0, txCol.size()); - assertEquals(1, collection.size()); - - txCol.insert(document2); - collection.insert(document2); - - throw new TransactionException("failed"); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(2, collection.size()); - } - } - } - - @Test - public void testCommitDropIndex() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - txCol.dropIndex("firstName"); - - assertFalse(txCol.hasIndex("firstName")); - assertTrue(collection.hasIndex("firstName")); - - transaction.commit(); - - assertFalse(collection.hasIndex("firstName")); - } - } - } - - @Test - public void testRollbackDropIndex() { - Document document = createDocument("firstName", "John").put("lastName", "Doe"); - Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); - collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - txCol.dropIndex("lastName"); - - assertFalse(txCol.hasIndex("lastName")); - assertTrue(collection.hasIndex("lastName")); - - txCol.insert(document2); - collection.insert(document2); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertTrue(collection.hasIndex("lastName")); - } - } - } - - @Test - public void testCommitDropAllIndices() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.Unique)); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - txCol.dropAllIndices(); - - assertFalse(txCol.hasIndex("firstName")); - assertFalse(txCol.hasIndex("lastName")); - assertTrue(collection.hasIndex("firstName")); - assertTrue(collection.hasIndex("lastName")); - - transaction.commit(); - - assertFalse(collection.hasIndex("firstName")); - assertFalse(collection.hasIndex("lastName")); - } - } - } - - @Test - public void testRollbackDropAllIndices() { - Document document = createDocument("firstName", "John").put("lastName", "Doe"); - collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - txCol.dropAllIndices(); - - assertFalse(txCol.hasIndex("firstName")); - assertFalse(txCol.hasIndex("lastName")); - assertTrue(collection.hasIndex("firstName")); - assertTrue(collection.hasIndex("lastName")); - - txCol.insert(createDocument("firstName", "Jane").put("lastName", "Doe")); - collection.insert(createDocument("firstName", "Jane").put("lastName", "Doe")); - - throw new TransactionException("failed"); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertTrue(collection.hasIndex("firstName")); - assertTrue(collection.hasIndex("lastName")); - } - } - } - - @Test - public void testCommitDropCollection() { - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - txCol.drop(); - - boolean expectedException = false; - try { - assertEquals(0, txCol.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - assertEquals(1, collection.size()); - - transaction.commit(); - - expectedException = false; - try { - assertEquals(0, collection.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - } - } - } - - @Test - public void testRollbackDropCollection() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - Document document = createDocument("firstName", "John"); - collection.insert(document); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - NitriteCollection txCol = transaction.getCollection("test"); - - txCol.drop(); - - boolean expectedException = false; - try { - assertEquals(0, txCol.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - assertEquals(1, collection.size()); - - throw new TransactionException("failed"); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(1, collection.size()); - } - } - } - - @Test - public void testCommitSetAttribute() { - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - NitriteCollection txCol = transaction.getCollection("test"); - - Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); - txCol.setAttributes(attributes); - - assertNull(collection.getAttributes()); - - transaction.commit(); - - assertEquals("value", collection.getAttributes().get("key")); - } - } - } - - @Test - public void testRollbackSetAttribute() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - NitriteCollection txCol = transaction.getCollection("test"); - - Attributes attributes = new Attributes(); - Map map = new HashMap<>(); - map.put("key", "value"); - attributes.setAttributes(map); - txCol.setAttributes(attributes); - - txCol.insert(createDocument("firstName", "John")); - txCol.insert(createDocument("firstName", "Jane").put("lastName", "Doe")); - - assertNull(collection.getAttributes()); - - // just to create UniqueConstraintViolation for rollback - collection.insert(createDocument("firstName", "Jane")); - - assertEquals(txCol.find(where("firstName").eq("John")).size(), 1); - assertNotEquals(collection.find(where("lastName").eq("Doe")).size(), 1); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertNull(collection.getAttributes().get("key")); - } - } - } - - @Test - public void testConcurrentInsertAndRemove() { - NitriteCollection collection = db.getCollection("test"); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); - collection.createIndex("id", indexOptions(IndexType.Unique)); - Faker faker = new Faker(); - List> futures = new ArrayList<>(); - - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - final long fi = i; - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - NitriteCollection txCol = transaction.getCollection("test"); - - for (int j = 0; j < 10; j++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("lastName", faker.name().lastName()) - .put("id", j + (fi * 10)); - txCol.insert(document); - } - - txCol.remove(where("id").eq(2 + (fi * 10))); - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(90, collection.size()); - } - } - - @Test - public void testConcurrentInsert() { - NitriteCollection collection = db.getCollection("test"); - Faker faker = new Faker(); - List> futures = new ArrayList<>(); - - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - NitriteCollection txCol = transaction.getCollection("test"); - - for (int j = 0; j < 10; j++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("lastName", faker.name().lastName()); - txCol.insert(document); - } - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(100, collection.size()); - } - } - - @Test - public void testConcurrentUpdate() { - NitriteCollection collection = db.getCollection("test"); - for (int i = 0; i < 10; i++) { - Document document = createDocument("id", i); - collection.insert(document); - } - - Faker faker = new Faker(); - List> futures = new ArrayList<>(); - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - NitriteCollection txCol = transaction.getCollection("test"); - - for (int j = 0; j < 10; j++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("lastName", faker.name().lastName()) - .put("id", j); - txCol.update(where("id").eq(j), document, updateOptions(true)); - } - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(10, collection.size()); - } - } - - @Test - public void testTransactionOnDifferentCollections() { - NitriteCollection col1 = db.getCollection("test1"); - NitriteCollection col2 = db.getCollection("test2"); - NitriteCollection col3 = db.getCollection("test3"); - col3.createIndex("id", indexOptions(IndexType.Unique)); - - Faker faker = new Faker(); - - try(Session session = db.createSession()) { - Transaction transaction = session.beginTransaction(); - - NitriteCollection test1 = transaction.getCollection("test1"); - NitriteCollection test2 = transaction.getCollection("test2"); - NitriteCollection test3 = transaction.getCollection("test3"); - - for (int i = 0; i < 10; i++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", i); - test1.insert(document); - - document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 10); - test2.insert(document); - - document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 20); - test3.insert(document); - } - - assertEquals(test1.size(), 10); - assertEquals(test2.size(), 10); - assertEquals(test3.size(), 10); - - assertEquals(col1.size(), 0); - assertEquals(col2.size(), 0); - assertEquals(col3.size(), 0); - - transaction.commit(); - - assertEquals(col1.size(), 10); - assertEquals(col2.size(), 10); - assertEquals(col3.size(), 10); - } - - - Transaction transaction = null; - try (Session session = db.createSession()) { - transaction = session.beginTransaction(); - - NitriteCollection test1 = transaction.getCollection("test1"); - NitriteCollection test2 = transaction.getCollection("test2"); - NitriteCollection test3 = transaction.getCollection("test3"); - - for (int i = 0; i < 10; i++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 30); - test1.insert(document); - - document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 40); - test2.insert(document); - - document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 50); - test3.insert(document); - } - - assertEquals(test1.size(), 20); - assertEquals(test2.size(), 20); - assertEquals(test3.size(), 20); - - assertEquals(col1.size(), 10); - assertEquals(col2.size(), 10); - assertEquals(col3.size(), 10); - - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", 52); - col3.insert(document); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - - assertEquals(col1.size(), 10); - assertEquals(col2.size(), 10); - assertEquals(col3.size(), 11); // last document added - } - } - - @Test(expected = TransactionException.class) - public void testFailureOnClosedTransaction() { - try(Session session = db.createSession()) { - Transaction transaction = session.beginTransaction(); - NitriteCollection col = transaction.getCollection("test"); - col.insert(createDocument("id", 1)); - transaction.commit(); - - col.insert(createDocument("id", 2)); - fail(); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java deleted file mode 100644 index b5b947381..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TransactionRepositoryTest.java +++ /dev/null @@ -1,808 +0,0 @@ -package org.dizitart.no2.transaction; - -import com.github.javafaker.Faker; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.TransactionException; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.BaseObjectRepositoryTest; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.data.SubEmployee; -import org.junit.Test; - -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -public class TransactionRepositoryTest extends BaseObjectRepositoryTest { - - @Test - public void testCommitInsert() { - ObjectRepository repository = db.getRepository(TxData.class); - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - TxData txData1 = new TxData(); - txData1.setId(1L); - txData1.setName("John"); - - txRepo.insert(txData1); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 1); - assertNotEquals(repository.find(where("name").eq("John")).size(), 1); - - transaction.commit(); - - assertEquals(repository.find(where("name").eq("John")).size(), 1); - } - } - } - - @Test - public void testRollbackInsert() { - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - TxData txData1 = new TxData(); - txData1.setId(1L); - txData1.setName("John"); - - TxData txData2 = new TxData(); - txData2.setId(2L); - txData2.setName("Jane"); - - txRepo.insert(txData1, txData2); - - txData2.setName("Molly"); - repository.insert(txData2); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 1); - assertEquals(repository.find(where("name").eq("John")).size(), 0); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(repository.find(where("name").eq("John")).size(), 0); - assertEquals(repository.find(where("name").eq("Molly")).size(), 1); - } - } - } - - @Test - public void testCommitUpdate() { - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(new TxData(1L, "John")); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - TxData txData1 = new TxData(1L, "Jane"); - txRepo.update(txData1, true); - - assertEquals(txRepo.find(where("name").eq("Jane")).size(), 1); - assertNotEquals(repository.find(where("name").eq("Jane")).size(), 1); - - transaction.commit(); - - assertEquals(repository.find(where("name").eq("Jane")).size(), 1); - } - } - } - - @Test - public void testRollbackUpdate() { - ObjectRepository repository = db.getRepository(TxData.class, "rollback"); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(new TxData(1L, "Jane")); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - ObjectRepository txRepo = transaction.getRepository(TxData.class, "rollback"); - - TxData txData1 = new TxData(); - txData1.setId(2L); - txData1.setName("John"); - - TxData txData2 = new TxData(); - txData2.setId(1L); - txData2.setName("Jane Doe"); - txRepo.update(txData2); - txRepo.insert(txData1); - - // just to create UniqueConstraintViolation for rollback - repository.insert(txData1); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 1); - assertEquals(txRepo.find(where("name").eq("Jane Doe")).size(), 1); - assertNotEquals(repository.find(where("name").eq("Jane Doe")).size(), 1); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(repository.find(where("name").eq("Jane")).size(), 1); - assertNotEquals(repository.find(where("name").eq("Jane Doe")).size(), 1); - } - } - } - - @Test - public void testCommitRemove() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - txRepo.remove(where("name").eq("John")); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 0); - assertEquals(repository.find(where("name").eq("John")).size(), 1); - - transaction.commit(); - - assertEquals(repository.find(where("name").eq("John")).size(), 0); - } - } - } - - @Test - public void testRollbackRemove() { - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - TxData txData1 = new TxData(1L, "John"); - repository.insert(txData1); - - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - txRepo.remove(where("name").eq("John")); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 0); - assertEquals(repository.find(where("name").eq("John")).size(), 1); - - TxData txData2 = new TxData(2L, "Jane"); - txRepo.insert(txData2); - repository.insert(txData2); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(repository.find(where("name").eq("John")).size(), 1); - assertEquals(repository.find(where("name").eq("Jane")).size(), 1); - } - } - } - - @Test - public void testCommitCreateIndex() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); - - assertTrue(txRepo.hasIndex("name")); - assertFalse(repository.hasIndex("name")); - - transaction.commit(); - - assertTrue(repository.hasIndex("name")); - } - } - } - - @Test - public void testRollbackCreateIndex() { - TxData txData1 = new TxData(1L, "John"); - TxData txData2 = new TxData(2L, "Jane"); - - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(txData1); - - try(Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); - - assertTrue(txRepo.hasIndex("name")); - assertFalse(repository.hasIndex("name")); - - txRepo.insert(txData2); - repository.insert(txData2); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertFalse(repository.hasIndex("name")); - } - } - } - - @Test - public void testCommitClear() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.clear(); - - assertEquals(0, txRepo.size()); - assertEquals(1, repository.size()); - - transaction.commit(); - - assertEquals(0, repository.size()); - } - } - } - - @Test - public void testRollbackClear() { - TxData txData1 = new TxData(1L, "John"); - TxData txData2 = new TxData(2L, "Jane"); - - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try(Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.clear(); - - assertEquals(0, txRepo.size()); - assertEquals(1, repository.size()); - - txRepo.insert(txData2); - repository.insert(txData2); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(2, repository.size()); - } - } - } - - @Test - public void testCommitDropIndex() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.dropIndex("name"); - - assertFalse(txRepo.hasIndex("name")); - assertTrue(repository.hasIndex("name")); - - transaction.commit(); - - assertFalse(repository.hasIndex("name")); - } - } - } - - @Test - public void testRollbackDropIndex() { - TxData txData1 = new TxData(1L, "John"); - TxData txData2 = new TxData(2L, "Jane"); - - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try(Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.dropIndex("name"); - - assertFalse(txRepo.hasIndex("name")); - assertTrue(repository.hasIndex("name")); - - txRepo.insert(txData2); - repository.insert(txData2); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertTrue(repository.hasIndex("name")); - } - } - } - - @Test - public void testCommitDropAllIndices() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.dropAllIndices(); - - assertFalse(txRepo.hasIndex("name")); - assertTrue(repository.hasIndex("name")); - - transaction.commit(); - - assertFalse(repository.hasIndex("name")); - } - } - } - - @Test - public void testRollbackDropAllIndices() { - TxData txData1 = new TxData(1L, "John"); - TxData txData2 = new TxData(2L, "Jane"); - - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try(Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.dropAllIndices(); - - assertFalse(txRepo.hasIndex("name")); - assertTrue(repository.hasIndex("name")); - - txRepo.insert(txData2); - repository.insert(txData2); - - throw new TransactionException("failed"); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertTrue(repository.hasIndex("name")); - } - } - } - - @Test - public void testCommitDropRepository() { - TxData txData1 = new TxData(1L, "John"); - ObjectRepository repository = db.getRepository(TxData.class); - repository.insert(txData1); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.drop(); - - boolean expectedException = false; - try { - assertEquals(0, txRepo.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - assertEquals(1, repository.size()); - - transaction.commit(); - - expectedException = false; - try { - assertEquals(0, repository.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - } - } - } - - @Test - public void testRollbackDropRepository() { - TxData txData1 = new TxData(1L, "John"); - - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - repository.insert(txData1); - - try(Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.drop(); - - boolean expectedException = false; - try { - assertEquals(0, txRepo.size()); - } catch (NitriteIOException e) { - expectedException = true; - } - assertTrue(expectedException); - assertEquals(1, repository.size()); - - throw new TransactionException("failed"); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertEquals(1, repository.size()); - } - } - } - - @Test - public void testCommitSetAttribute() { - ObjectRepository repository = db.getRepository(TxData.class); - - try (Session session = db.createSession()) { - try (Transaction transaction = session.beginTransaction()) { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); - txRepo.setAttributes(attributes); - - assertNull(repository.getAttributes()); - - transaction.commit(); - - assertEquals("value", repository.getAttributes().get("key")); - } - } - } - - @Test - public void testRollbackSetAttribute() { - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); - try (Session session = db.createSession()) { - Transaction transaction = null; - try { - transaction = session.beginTransaction(); - - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - Attributes attributes = new Attributes(); - Map map = new HashMap<>(); - map.put("key", "value"); - attributes.setAttributes(map); - txRepo.setAttributes(attributes); - - txRepo.insert(new TxData(1L, "John")); - txRepo.insert(new TxData(2L, "Jane")); - - assertNull(repository.getAttributes()); - - // just to create UniqueConstraintViolation for rollback - repository.insert(new TxData(2L, "Jane")); - - assertEquals(txRepo.find(where("name").eq("John")).size(), 1); - assertNotEquals(repository.find(where("name").eq("John")).size(), 1); - - transaction.commit(); - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - assertNull(repository.getAttributes().get("key")); - } - } - } - - @Test - public void testConcurrentInsertAndRemove() { - ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.NonUnique)); - Faker faker = new Faker(); - List> futures = new ArrayList<>(); - - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - final long fi = i; - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - for (long j = 0; j < 10; j++) { - TxData txData = new TxData(j + (fi * 10), faker.name().name()); - txRepo.insert(txData); - } - - txRepo.remove(where("id").eq(2L + (fi * 10))); - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(90, repository.size()); - } - } - - @Test - public void testConcurrentInsert() { - ObjectRepository repository = db.getRepository(TxData.class); - Faker faker = new Faker(); - List> futures = new ArrayList<>(); - - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - final long fi = i; - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - for (long j = 0; j < 10; j++) { - TxData txData = new TxData(j + (fi * 10), faker.name().name()); - txRepo.insert(txData); - } - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(100, repository.size()); - } - } - - @Test - public void testConcurrentUpdate() { - ObjectRepository repository = db.getRepository(TxData.class); - Faker faker = new Faker(); - for (long j = 0; j < 10; j++) { - TxData txData = new TxData(j, faker.name().name()); - repository.insert(txData); - } - - List> futures = new ArrayList<>(); - try (Session session = db.createSession()) { - ExecutorService executorService = Executors.newCachedThreadPool(); - for (int i = 0; i < 10; i++) { - Future future = executorService.submit(() -> { - Transaction transaction = session.beginTransaction(); - try { - ObjectRepository txRepo = transaction.getRepository(TxData.class); - - for (int j = 0; j < 10; j++) { - TxData txData = new TxData((long) j, faker.name().name()); - txRepo.update(where("id").eq(j), txData); - } - - transaction.commit(); - } catch (Exception e) { - e.printStackTrace(); - transaction.rollback(); - } finally { - transaction.close(); - } - }); - - futures.add(future); - } - - futures.forEach(future -> { - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - }); - - assertEquals(10, repository.size()); - } - } - - @Test - public void testTransactionOnDifferentRepositoriesAndCollections() { - ObjectRepository repo1 = db.getRepository(TxData.class); - ObjectRepository repo2 = db.getRepository(TxData.class, "2"); - ObjectRepository repo3 = db.getRepository(SubEmployee.class); - NitriteCollection col1 = db.getCollection("test1"); - col1.createIndex("id", indexOptions(IndexType.Unique)); - - Faker faker = new Faker(); - - try(Session session = db.createSession()) { - Transaction transaction = session.beginTransaction(); - - ObjectRepository txRepo1 = transaction.getRepository(TxData.class); - ObjectRepository txRepo2 = transaction.getRepository(TxData.class, "2"); - ObjectRepository txRepo3 = transaction.getRepository(SubEmployee.class); - NitriteCollection test1 = transaction.getCollection("test1"); - - for (long i = 0; i < 10; i++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", i); - test1.insert(document); - - TxData txData1 = new TxData(i, faker.name().name()); - txRepo1.insert(txData1); - - TxData txData2 = new TxData(i + 10, faker.name().name()); - txRepo2.insert(txData2); - - SubEmployee employee = new SubEmployee(); - employee.setAddress(faker.address().fullAddress()); - employee.setEmpId(i); - employee.setJoinDate(faker.date().birthday()); - txRepo3.insert(employee); - } - - assertEquals(test1.size(), 10); - assertEquals(txRepo1.size(), 10); - assertEquals(txRepo2.size(), 10); - assertEquals(txRepo3.size(), 10); - - assertEquals(col1.size(), 0); - assertEquals(repo1.size(), 0); - assertEquals(repo2.size(), 0); - assertEquals(repo3.size(), 0); - - transaction.commit(); - - assertEquals(col1.size(), 10); - assertEquals(repo1.size(), 10); - assertEquals(repo2.size(), 10); - assertEquals(repo3.size(), 10); - } - - Transaction transaction = null; - try (Session session = db.createSession()) { - transaction = session.beginTransaction(); - - ObjectRepository txRepo1 = transaction.getRepository(TxData.class); - ObjectRepository txRepo2 = transaction.getRepository(TxData.class, "2"); - ObjectRepository txRepo3 = transaction.getRepository(SubEmployee.class); - NitriteCollection test1 = transaction.getCollection("test1"); - - for (long i = 0; i < 10; i++) { - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", i + 10); - test1.insert(document); - - TxData txData1 = new TxData(i + 10, faker.name().name()); - txRepo1.insert(txData1); - - TxData txData2 = new TxData(i + 20, faker.name().name()); - txRepo2.insert(txData2); - - SubEmployee employee = new SubEmployee(); - employee.setAddress(faker.address().fullAddress()); - employee.setEmpId(i + 10); - employee.setJoinDate(faker.date().birthday()); - txRepo3.insert(employee); - } - - assertEquals(test1.size(), 20); - assertEquals(txRepo1.size(), 20); - assertEquals(txRepo2.size(), 20); - assertEquals(txRepo3.size(), 20); - - assertEquals(col1.size(), 10); - assertEquals(repo1.size(), 10); - assertEquals(repo2.size(), 10); - assertEquals(repo3.size(), 10); - - Document document = createDocument("firstName", faker.name().firstName()) - .put("id", 12L); - col1.insert(document); - - transaction.commit(); - - fail(); - } catch (TransactionException e) { - assert transaction != null; - transaction.rollback(); - - assertEquals(col1.size(), 11); // last doc added - assertEquals(repo1.size(), 10); - assertEquals(repo2.size(), 10); - assertEquals(repo3.size(), 10); - } - } - - @Test(expected = TransactionException.class) - public void testFailureOnClosedTransaction() { - try(Session session = db.createSession()) { - Transaction transaction = session.beginTransaction(); - ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.insert(new TxData(1L, "John")); - transaction.commit(); - - txRepo.insert(new TxData(2L, "Jane")); - fail(); - } - } -} diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java deleted file mode 100644 index 20ad7d6ac..000000000 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/transaction/TxData.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.transaction; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -class TxData implements Mappable { - @Id - private Long id; - private String name; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("id", id) - .put("name", name); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Long.class); - name = document.get("name", String.class); - } -} diff --git a/nitrite-rocksdb-adapter/build.gradle b/nitrite-rocksdb-adapter/build.gradle index c979cfb35..0604644b9 100644 --- a/nitrite-rocksdb-adapter/build.gradle +++ b/nitrite-rocksdb-adapter/build.gradle @@ -38,6 +38,7 @@ dependencies { testImplementation "uk.co.jemos.podam:podam:7.2.5.RELEASE" testImplementation "com.github.javafaker:javafaker:1.0.2" testImplementation "junit:junit:4.13.1" + testImplementation "org.mockito:mockito-core:3.9.0" testImplementation "org.apache.lucene:lucene-core:8.6.3" testImplementation "org.apache.lucene:lucene-analyzers-common:8.6.3" testImplementation "org.apache.lucene:lucene-queryparser:8.6.3" diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java index 43ce9f1e5..764952621 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/EntrySet.java @@ -26,7 +26,6 @@ public EntrySet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, } @Override - @SuppressWarnings("NullableProblems") public Iterator> iterator() { return new EntryIterator(); } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/KeySet.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/KeySet.java index f234936b2..73dd687ff 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/KeySet.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/KeySet.java @@ -21,7 +21,6 @@ public KeySet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, ObjectForm } @Override - @SuppressWarnings("NullableProblems") public Iterator iterator() { return new KeyIterator(); } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java index ec9a3f7d2..874c037da 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBMap.java @@ -3,14 +3,13 @@ import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.rocksdb.formatter.ObjectFormatter; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; import org.rocksdb.ColumnFamilyHandle; -import org.rocksdb.ComparatorOptions; import org.rocksdb.RocksDB; import org.rocksdb.RocksIterator; import org.rocksdb.util.BytewiseComparator; @@ -332,7 +331,7 @@ public boolean isEmpty() { @Override public void drop() { - store.removeMap(mapName); + store.removeMap(getName()); close(); } @@ -341,13 +340,11 @@ private void initialize() { this.objectFormatter = store.getStoreConfig().objectFormatter(); this.columnFamilyHandle = reference.getOrCreateColumnFamily(getName()); this.rocksDB = reference.getRocksDB(); - this.bytewiseComparator = new BytewiseComparator(new ComparatorOptions()); - this.reference.addComparator(bytewiseComparator); + this.bytewiseComparator = this.reference.getDbComparator(); } @Override public void close() { - bytewiseComparator.close(); - columnFamilyHandle.close(); + store.closeMap(getName()); } } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java index f209be1be..4bbd9437c 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBReference.java @@ -16,10 +16,12 @@ package org.dizitart.no2.rocksdb; -import lombok.Data; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.exceptions.NitriteIOException; import org.rocksdb.*; +import org.rocksdb.util.BytewiseComparator; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -30,22 +32,23 @@ /** * @author Anindya Chatterjee */ -@Data @Slf4j +@Getter +@Setter public class RocksDBReference implements AutoCloseable { private Options options; private DBOptions dbOptions; private ColumnFamilyOptions columnFamilyOptions; private RocksDB rocksDB; + private BytewiseComparator dbComparator; private List columnFamilyDescriptors; private Map columnFamilyHandleRegistry; - private List dbComparators; public RocksDBReference() { this.columnFamilyDescriptors = new ArrayList<>(); this.columnFamilyHandleRegistry = new ConcurrentHashMap<>(); - this.dbComparators = new ArrayList<>(); + this.dbComparator = null; } @Override @@ -56,7 +59,7 @@ public void close() throws RocksDBException { rocksDB.closeE(); dbOptions.close(); - dbComparators.forEach(AbstractImmutableNativeReference::close); + dbComparator.close(); columnFamilyOptions.close(); options.close(); } @@ -91,7 +94,20 @@ public void dropColumnFamily(String mapName) { } } - public void addComparator(AbstractComparator comparator) { - dbComparators.add(comparator); + public void closeColumnFamily(String mapName) { + if (columnFamilyHandleRegistry.containsKey(mapName)) { + ColumnFamilyHandle handle = columnFamilyHandleRegistry.get(mapName); + handle.close(); + columnFamilyHandleRegistry.remove(mapName); + } + } + + public BytewiseComparator getDbComparator() { + // delayed initialization, otherwise initializing + // it in ctor is throwing java.lang.UnsatisfiedLinkError + if (dbComparator == null) { + dbComparator = new BytewiseComparator(new ComparatorOptions()); + } + return dbComparator; } } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java index 0d05b7fae..11dd021ca 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/RocksDBStore.java @@ -114,6 +114,11 @@ public NitriteMap openMap(String mapName, } } + @Override + public void closeMap(String mapName) { + nitriteMapRegistry.remove(mapName); + } + @Override public void removeMap(String mapName) { reference.dropColumnFamily(mapName); @@ -127,6 +132,11 @@ public NitriteRTree openRTree(Strin throw new InvalidOperationException("rtree not supported on rocksdb store"); } + @Override + public void closeRTree(String rTreeName) { + throw new InvalidOperationException("rtree not supported on rocksdb store"); + } + @Override public void removeRTree(String mapName) { throw new InvalidOperationException("rtree not supported on rocksdb store"); diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/ValueSet.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/ValueSet.java index a74f6b71e..138b82660 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/ValueSet.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/ValueSet.java @@ -13,7 +13,8 @@ class ValueSet implements Iterable { private final ColumnFamilyHandle columnFamilyHandle; private final Class valueType; - public ValueSet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, ObjectFormatter objectFormatter, Class valueType) { + public ValueSet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, + ObjectFormatter objectFormatter, Class valueType) { this.rocksDB = rocksDB; this.columnFamilyHandle = columnFamilyHandle; this.objectFormatter = objectFormatter; @@ -21,7 +22,6 @@ public ValueSet(RocksDB rocksDB, ColumnFamilyHandle columnFamilyHandle, ObjectFo } @Override - @SuppressWarnings("NullableProblems") public Iterator iterator() { return new ValueIterator(); } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatter.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatter.java index 1bce3285e..d8399a37d 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatter.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatter.java @@ -126,6 +126,5 @@ private void registerInternalSerializers() { NitriteSerializers.registerAll(this); DefaultJavaSerializers.registerAll(this); DefaultTimeKeySerializers.registerAll(this); -// DefaultNumberKeySerializers.registerAll(this); } } diff --git a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java index 5602cda6a..334f08980 100644 --- a/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java +++ b/nitrite-rocksdb-adapter/src/main/java/org/dizitart/no2/rocksdb/formatter/NitriteSerializers.java @@ -8,11 +8,15 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.collection.meta.Attributes; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.index.DBValue; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexMeta; import org.dizitart.no2.store.UserCredential; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -105,21 +109,21 @@ public IndexMeta read(Kryo kryo, Input input, Class type) { } } - private static class IndexEntrySerializer extends Serializer { + private static class IndexDescriptorSerializer extends Serializer { @Override public void write(Kryo kryo, Output output, IndexDescriptor object) { + kryo.writeObject(output, object.getIndexFields()); output.writeString(object.getCollectionName()); - output.writeString(object.getIndexFields()); output.writeString(object.getIndexType()); } @Override public IndexDescriptor read(Kryo kryo, Input input, Class type) { + Fields fields = kryo.readObject(input, Fields.class); String collectionName = input.readString(); - String field = input.readString(); String indexType = input.readString(); - return new IndexDescriptor(indexType, field, collectionName); + return new IndexDescriptor(indexType, fields, collectionName); } } @@ -166,13 +170,43 @@ public Attributes read(Kryo kryo, Input input, Class type) { } } + private static class FieldsSerializer extends Serializer { + @Override + public void write(Kryo kryo, Output output, Fields object) { + kryo.writeObject(output, object.getFieldNames()); + } + + @Override + @SuppressWarnings("unchecked") + public Fields read(Kryo kryo, Input input, Class type) { + List fieldNames = (List) kryo.readObject(input, ArrayList.class); + return Fields.withNames(fieldNames.toArray(new String[0])); + } + } + + private static class DBValueSerializer extends Serializer { + + @Override + public void write(Kryo kryo, Output output, DBValue object) { + kryo.writeClassAndObject(output, object.getValue()); + } + + @Override + public DBValue read(Kryo kryo, Input input, Class type) { + Object value = kryo.readClassAndObject(input); + return new DBValue((Comparable) value); + } + } + public static void registerAll(KryoObjectFormatter kryoObjectFormatter) { kryoObjectFormatter.registerSerializer(NitriteId.class, new NitriteIdSerializer()); kryoObjectFormatter.registerSerializer(Pair.class, new PairSerializer()); kryoObjectFormatter.registerSerializer(Document.class, new DocumentSerializer()); kryoObjectFormatter.registerSerializer(IndexMeta.class, new IndexMetaSerializer()); - kryoObjectFormatter.registerSerializer(IndexDescriptor.class, new IndexEntrySerializer()); + kryoObjectFormatter.registerSerializer(IndexDescriptor.class, new IndexDescriptorSerializer()); kryoObjectFormatter.registerSerializer(UserCredential.class, new UserCredentialSerializer()); kryoObjectFormatter.registerSerializer(Attributes.class, new AttributesSerializer()); + kryoObjectFormatter.registerSerializer(Fields.class, new FieldsSerializer()); + kryoObjectFormatter.registerSerializer(DBValue.class, new DBValueSerializer()); } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/NitriteTest.java similarity index 84% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/NitriteTest.java index ce0c99fef..d22bd411d 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/NitriteTest.java @@ -1,36 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.UpdateOptions; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.ThreadPoolManager; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; @@ -42,23 +46,22 @@ import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; -import java.io.IOException; -import java.nio.file.Files; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Random; import java.util.Set; +import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; -import static java.nio.file.Paths.get; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; import static org.dizitart.no2.common.Constants.META_MAP_NAME; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -99,13 +102,13 @@ public void setUp() throws ParseException { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); collection.insert(doc1, doc2, doc3); } @After - public void tearDown() throws IOException { + public void tearDown() { if (collection.isOpen()) { collection.remove(ALL); collection.close(); @@ -116,7 +119,7 @@ public void tearDown() throws IOException { } catch (NitriteIOException ignore) { } } - Files.delete(get(fileName)); + deleteDb(fileName); } @Test @@ -195,27 +198,6 @@ public void testClose() { assertFalse(testCollection.isOpen()); } - @Test(expected = NitriteIOException.class) - public void testCloseReadonlyDatabase() { - db.close(); - db = null; - - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(fileName) - .readOnly(true) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate("test-user", "test-password"); - NitriteCollection testCollection = db.getCollection("test"); - testCollection.insert(createDocument("a", "b")); - db.close(); - - assertFalse(testCollection.isOpen()); - } - @Test public void testGetCollection() { NitriteCollection collection = db.getCollection("test-collection"); @@ -299,19 +281,6 @@ public void testGetCollectionInvalidName() { db.getCollection(META_MAP_NAME); } - @Test(expected = NitriteIOException.class) - public void testIssue112() { - MapDBModule storeModule = MapDBModule.withConfig() - .filePath(System.getProperty("java.io.tmpdir")) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - assertNull(db); - } - @Test public void testIssue185() throws InterruptedException { final ObjectRepository repository = db.getRepository(Receipt.class); @@ -341,8 +310,8 @@ public void testIssue185() throws InterruptedException { }).start(); for (int i = 0; i < 1000; ++i) { - repository.find(where("status").eq(Receipt.Status.COMPLETED).not()) - .sort("createdTimestamp", SortOrder.Descending).toList(); + repository.find(where("status").eq(Receipt.Status.COMPLETED).not(), + FindOptions.orderBy("createdTimestamp", SortOrder.Descending)).toList(); try { Thread.sleep(50); } catch (InterruptedException ignored) { @@ -383,10 +352,10 @@ public void testIssue212() { Document doc = createDocument("fifth_key", "fifth_key"); if (!collection.hasIndex("key")) { - collection.createIndex("key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "key"); } if (!collection.hasIndex("second_key")) { - collection.createIndex("second_key", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "second_key"); } collection.insert(doc1, doc2); @@ -398,6 +367,56 @@ public void testIssue212() { } } + @Test + public void testIssue245() throws Exception { + class ThreadRunner implements Runnable { + @Override + public void run() { + try { + long id = Thread.currentThread().getId(); + NitriteCollection collection = db.getCollection("testIssue245"); + + for (int i = 0; i < 5; i++) { + + System.out.println("Thread ID = " + id + " Inserting doc " + i); + Document doc = Document.createDocument(UUID.randomUUID().toString(), UUID.randomUUID().toString()); + + WriteResult result = collection.insert(doc);//db.commit(); + System.out.println("Result of insert = " + result.getAffectedCount()); + System.out.println("Thread id = " + id + " --> count = " + collection.size()); + + Thread.sleep(10); + + }//for closing + + collection.close(); + + } catch (Throwable e) { + e.printStackTrace(); + } + } + }; + + Thread t0 = new Thread(new ThreadRunner()); + Thread t1 = new Thread(new ThreadRunner()); + Thread t2 = new Thread(new ThreadRunner()); + + t0.start(); + t1.start(); + t2.start(); + + Thread.sleep(10 * 1000); + + t0.join(); + t1.join(); + t2.join(); + + NitriteCollection collection = db.getCollection("testIssue245"); + System.out.println("No of Documents = " + collection.size()); + collection.close(); + db.close(); + } + @Data @AllArgsConstructor @NoArgsConstructor @@ -422,13 +441,13 @@ public void read(NitriteMapper mapper, Document document) { @NoArgsConstructor @AllArgsConstructor @Indices({ - @Index(value = "synced", type = IndexType.NonUnique) + @Index(value = "synced", type = IndexType.NON_UNIQUE) }) public static class Receipt implements Mappable { - private Status status; @Id private String clientRef; private Boolean synced; + private Status status; private Long createdTimestamp = System.currentTimeMillis(); @Override @@ -453,6 +472,7 @@ public void read(NitriteMapper mapper, Document document) { this.createdTimestamp = document.get("createdTimestamp", Long.class); } } + public enum Status { COMPLETED, PREPARING, diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CustomFilterTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java similarity index 79% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CustomFilterTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java index 518a1b56b..75a15f156 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CustomFilterTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java @@ -1,22 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; -import org.dizitart.no2.collection.BaseCollectionTest; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.index.IndexType; import org.junit.Test; @@ -32,7 +33,7 @@ public class CustomFilterTest extends BaseCollectionTest { @Test public void testCustomFilter() { insert(); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); DocumentCursor cursor = collection.find(element -> element.getSecond().get("firstName", String.class) .equalsIgnoreCase("FN1")); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbTestOperations.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java similarity index 73% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbTestOperations.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java index 11cfeb258..ccf825dfe 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbTestOperations.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DbWriteCloseReadTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -23,34 +24,55 @@ import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.index.IndexType; +import org.junit.Rule; +import org.junit.Test; -import java.io.File; -import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author Anindya Chatterjee. */ -public class DbTestOperations { +public class DbWriteCloseReadTest { + private final String fileName = TestUtil.getRandomTempDbFile(); private Nitrite db; - private final String fileName = getRandomTempDbFile(); + private volatile boolean writeCompleted = false; + + @Rule + public Retry retry = new Retry(3); + + @Test + public void testWriteCloseRead() throws Exception { + try { + createDb(); + writeCollection(); + writeIndex(); + insertInCollection(); + } catch (ParseException pe) { + // ignore + } finally { + writeCompleted = true; + } - public static String getRandomTempDbFile() { - String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; - File file = new File(dataDir); - if (!file.exists()) { - assertTrue(file.mkdirs()); + try { + assertTrue(writeCompleted); + readCollection(); + } catch (Exception e) { + fail("collection read failed - " + e.getMessage()); + } finally { + deleteDb(); } - return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; } void createDb() { @@ -75,13 +97,13 @@ void writeIndex() { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); db.close(); } - void insertInCollection() throws ParseException { + void insertInCollection() throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); Document doc1 = createDocument("firstName", "fn1") @@ -114,7 +136,7 @@ void insertInCollection() throws ParseException { db.close(); } - void readCollection() throws ParseException { + void readCollection() throws Exception { NitriteCollection collection; db = TestUtil.createDb(fileName); @@ -155,15 +177,24 @@ void readCollection() throws ParseException { cursor = collection.find(where("birthDay").lte(new Date()).or(where("firstName").eq("fn12"))); assertEquals(cursor.size(), 3); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); - cursor = collection.find(where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")) - .not()); + cursor = collection.find( + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -178,8 +209,8 @@ void readCollection() throws ParseException { cursor = collection.find(where("firstName").notIn("fn1", "fn2")); assertEquals(cursor.size(), 1); - collection.createIndex("birthDay", indexOptions(IndexType.Unique)); - cursor = collection.find().sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + collection.createIndex("birthDay"); + cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -199,11 +230,10 @@ void readCollection() throws ParseException { db.close(); } - void deleteDb() throws IOException { + void deleteDb() { if (db != null && !db.isClosed()) { db.close(); } - - TestUtil.deleteFile(fileName); + TestUtil.deleteDb(fileName); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DocumentMetadataTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java similarity index 91% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DocumentMetadataTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java index 3d1268415..15d01451f 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DocumentMetadataTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/DocumentMetadataTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.events.EventType; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/MultiThreadedTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java similarity index 82% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/MultiThreadedTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java index c9b53257d..16dc19ca3 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/MultiThreadedTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -24,10 +26,10 @@ import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.util.Date; import java.util.Random; import java.util.UUID; @@ -44,24 +46,31 @@ /** * @author Anindya Chatterjee. */ -public class MultiThreadedTest extends AbstractTest { +public class MultiThreadedTest { + private static final String fileName = TestUtil.getRandomTempDbFile(); private NitriteCollection collection; private final int threadCount = 20; private final CountDownLatch latch = new CountDownLatch(threadCount); private final int iterationCount = 100; private final Random generator = new Random(); private final AtomicInteger docCounter = new AtomicInteger(0); - private ExecutorService executor = ThreadPoolManager.getThreadPool(threadCount, "MultiThreadedTest"); + private ExecutorService executor; + private Nitrite db; @Rule public Retry retry = new Retry(3); + @Before + public void setUp() { + executor = ThreadPoolManager.getThreadPool(threadCount, "MultiThreadedTest"); + } @Test public void testOperations() throws InterruptedException { + db = TestUtil.createDb(fileName); collection = db.getCollection("test"); collection.remove(Filter.ALL); - collection.createIndex("unixTime", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("unixTime"); db.commit(); for (int i = 0; i < threadCount; i++) { @@ -74,8 +83,8 @@ public void testOperations() throws InterruptedException { if (j == iterationCount / 2 && !collection.hasIndex("text") && !collection.hasIndex("date")) { - collection.createIndex("text", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("date", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "text"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "date"); } long unixTime = (long) document.get("unixTime"); @@ -116,8 +125,11 @@ public void testOperations() throws InterruptedException { } @After - public void cleanUp() throws IOException { - super.cleanUp(); + public void cleanUp() { + if (db != null && !db.isClosed()) { + db.close(); + } + TestUtil.deleteDb(fileName); if (executor != null && !executor.isShutdown()) { executor.shutdown(); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java similarity index 74% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java index 3af4e8a9c..9bd402c29 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.exceptions.NitriteIOException; @@ -22,9 +23,7 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; - -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.*; /** @@ -39,18 +38,18 @@ public class NitriteBuilderNegativeTest { @Test(expected = NitriteIOException.class) public void testOpenWithLock() { - db1 = TestUtil.createDb(filePath); - db2 = TestUtil.createDb(filePath); + db1 = createDb(filePath); + db2 = createDb(filePath); } @Test(expected = NitriteIOException.class) public void testInvalidDirectory() { String filePath = "/ytgr/hfurh/frij.db"; - db1 = TestUtil.createDb(filePath); + db1 = createDb(filePath); } @After - public void cleanUp() throws IOException { + public void cleanUp() { if (db1 != null && !db1.isClosed()) { db1.close(); } @@ -58,6 +57,6 @@ public void cleanUp() throws IOException { if (db2 != null && !db2.isClosed()) { db2.close(); } - TestUtil.deleteFile(filePath); + deleteDb(filePath); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java similarity index 94% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java index 8c0d361bb..f6436ee6d 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteBuilderTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; @@ -26,15 +27,17 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.NitriteSecurityException; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; +import org.dizitart.no2.rocksdb.RocksDBConfig; +import org.dizitart.no2.rocksdb.RocksDBModule; import org.dizitart.no2.store.StoreConfig; import org.junit.After; import org.junit.Before; @@ -48,9 +51,10 @@ import java.util.LinkedHashSet; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; import static org.dizitart.no2.common.module.NitriteModule.module; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.common.util.StringUtils.isNullOrEmpty; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -60,7 +64,6 @@ public class NitriteBuilderTest { private String fakeFile; private String filePath; private Nitrite db; - private Nitrite fakeDb; @Rule public Retry retry = new Retry(3); @@ -72,7 +75,7 @@ public void startup() { } @After - public void cleanup() throws IOException { + public void cleanup() { (new NitriteConfig()).fieldSeparator("."); if (db != null && !db.isClosed()) { @@ -80,20 +83,16 @@ public void cleanup() throws IOException { } if (Files.exists(Paths.get(filePath))) { - TestUtil.deleteFile(filePath); - } - - if (fakeDb != null && !fakeDb.isClosed()){ - fakeDb.close(); + TestUtil.deleteDb(filePath); } if (Files.exists(Paths.get(fakeFile))) { - TestUtil.deleteFile(fakeFile); + TestUtil.deleteDb(fakeFile); } } @Test - public void testConfig() throws IOException { + public void testConfig() { RocksDBModule storeModule = RocksDBModule.withConfig() .filePath(filePath) .build(); @@ -112,7 +111,7 @@ public void testConfig() throws IOException { assertFalse(isNullOrEmpty(storeConfig.filePath())); db.close(); - TestUtil.deleteFile(filePath); + TestUtil.deleteDb(filePath); } @Test @@ -232,7 +231,7 @@ public void testOpenOrCreateNullPassword() { @Test(expected = NitriteIOException.class) public void testDbInvalidDirectory() { fakeFile = System.getProperty("java.io.tmpdir") + File.separator + "fake" + File.separator + "fake.db"; - db = TestUtil.createDb(fakeFile, "test", "test"); + db = createDb(fakeFile, "test", "test"); assertNull(db); } @@ -292,7 +291,6 @@ public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig ni return null; } - @Override public void initialize(NitriteConfig nitriteConfig) { diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteCorruptedTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java similarity index 75% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteCorruptedTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java index c88436a61..72e18a326 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteCorruptedTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteCorruptedTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -25,15 +26,12 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.concurrent.ExecutorService; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -78,22 +76,31 @@ public void setUp() { } @After - public void tearDown() throws IOException { + public void tearDown() throws Exception { if (collection.isOpen()) { collection.remove(ALL); collection.close(); } - db.close(); - Files.delete(Paths.get(fileName)); + if (db != null && !db.isClosed()) { + db.close(); + } + TestUtil.deleteDb(fileName); } @Test(timeout = 10000) public void issue118() throws InterruptedException { - thread.start(); - Thread.sleep(10); - thread.interrupt(); - Thread.sleep(500); - assertTrue(collection.isOpen()); - assertFalse(db.isClosed()); + try { + thread.start(); + Thread.sleep(10); + thread.interrupt(); + Thread.sleep(500); + assertTrue(collection.isOpen()); + assertFalse(db.isClosed()); + } catch (InterruptedException e) { + if (db != null && !db.isClosed()) { + db.close(); + } + throw e; + } } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java index 01859692d..222038b62 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; @@ -27,14 +28,14 @@ import java.io.File; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; /** * @author Anindya Chatterjee. */ -public class NitriteStoreFactoryNegativeTest { +public class NitriteSecurityNegativeTest { private Nitrite db; private final String fileName = getRandomTempDbFile(); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java similarity index 68% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java index 32289bdda..ec9663db3 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/NitriteStoreFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteSecurityTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb; +package org.dizitart.no2.integration; import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; @@ -25,20 +26,16 @@ import org.junit.Test; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * @author Anindya Chatterjee. */ -public class NitriteStoreFactoryTest { +public class NitriteSecurityTest { private Nitrite db; private final String fileName = getRandomTempDbFile(); @@ -46,7 +43,7 @@ public class NitriteStoreFactoryTest { public Retry retry = new Retry(3); @Test - public void testSecured() throws IOException { + public void testSecured() { db = createDb(fileName, "test-user", "test-password"); NitriteCollection dbCollection = db.getCollection("test"); dbCollection.insert(createDocument("test", "test")); @@ -57,11 +54,11 @@ public void testSecured() throws IOException { dbCollection = db.getCollection("test"); assertEquals(dbCollection.find().size(), 1); db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } @Test - public void testUnsecured() throws IOException { + public void testUnsecured() { db = createDb(fileName); NitriteCollection dbCollection = db.getCollection("test"); dbCollection.insert(createDocument("test", "test")); @@ -72,26 +69,11 @@ public void testUnsecured() throws IOException { dbCollection = db.getCollection("test"); assertEquals(dbCollection.find().size(), 1); db.close(); - Files.delete(Paths.get(fileName)); - } - - @Test - public void testInMemory() { - db = createDb("test-user", "test-password"); - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - assertEquals(dbCollection.find().size(), 1); - db.close(); - - db = createDb(); - dbCollection = db.getCollection("test"); - assertEquals(dbCollection.find().size(), 0); - db.close(); + deleteDb(fileName); } @Test - public void testIssue116() throws IOException { + public void testIssue116() { db = createDb(fileName, "test-user", "test-password"); db.close(); try { @@ -101,7 +83,7 @@ public void testIssue116() throws IOException { assertNotNull(db); } finally { db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java similarity index 63% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index 42a0f246d..90b15b3a1 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/StressTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -1,32 +1,34 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.Data; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; import org.junit.After; @@ -36,22 +38,24 @@ import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; + /** * @author Anindya Chatterjee */ -public class StressTest { +public class NitriteStressTest { + private static final int TEST_SET_COUNT = 15000; + private final PodamFactory podamFactory = new PodamFactoryImpl(); private final String fileName = getRandomTempDbFile(); private Nitrite db; private NitriteCollection collection; @@ -61,25 +65,48 @@ public class StressTest { @Before public void before() { - MVStoreModule storeModule = MVStoreModule.withConfig() - .filePath(fileName) - .compress(true) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - + db = createDb(fileName); collection = db.getCollection("test"); System.out.println(fileName); } + @After + public void cleanUp() { + if (db != null && !db.isClosed()) { + long start = System.currentTimeMillis(); + db.close(); + System.out.println("Time to compact and close - " + (System.currentTimeMillis() - start) / 1000 + " seconds"); + } + + deleteDb(fileName); + } + + @Test + public void stressTest() { + ObjectRepository testRepository = db.getRepository(TestDto.class); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "lastName"); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDate"); + + int counter = 0; + try { + for (TestDto testDto : createTestSet()) { + testRepository.insert(testDto); + counter++; + } + } catch (Throwable t) { + System.err.println("Crashed after " + counter + " records"); + throw t; + } + + int size = testRepository.find().toList().size(); + assertEquals(counter, size); + } + @Test public void testIssue41() { - collection.createIndex("number", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("name", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("counter", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "number"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "name"); + collection.createIndex("counter"); Random random = new Random(); AtomicLong counter = new AtomicLong(System.currentTimeMillis()); @@ -119,16 +146,6 @@ public void testIssue41() { System.out.println("Iteration completed in " + ((System.currentTimeMillis() - start) / (1000)) + " seconds"); } - @After - public void clear() throws IOException { - if (db != null && !db.isClosed()) { - long start = System.currentTimeMillis(); - db.close(); - System.out.println("Time to compact and close - " + (System.currentTimeMillis() - start) / 1000 + " seconds"); - } - Files.delete(Paths.get(fileName)); - } - @Test public void testRepoPerformanceWithIndex() { // warm-up @@ -183,6 +200,15 @@ public void testRepoPerformanceWithoutIndex() { System.out.println("Time take to remove 10000 non-indexed items - " + diff + "ms"); } + private List createTestSet() { + List testData = new ArrayList<>(); + for (int i = 0; i < TEST_SET_COUNT; i++) { + TestDto testRecords = podamFactory.manufacturePojo(TestDto.class); + testData.add(testRecords); + } + return testData; + } + private List getItems(Class type) { PodamFactory generator = new PodamFactoryImpl(); List items = new ArrayList<>(); @@ -193,6 +219,79 @@ private List getItems(Class type) { return items; } + @Data + public static class TestDto implements Mappable { + + @XmlElement( + name = "StudentNumber", + required = true + ) + @Id + protected String studentNumber; + + @XmlElement( + name = "LastName", + required = true + ) + protected String lastName; + + @XmlElement( + name = "Prefixes" + ) + protected String prefixes; + + @XmlElement( + name = "Initials", + required = true + ) + protected String initials; + + @XmlElement( + name = "FirstNames" + ) + protected String firstNames; + @XmlElement( + name = "Nickname" + ) + protected String nickName; + + @XmlElement( + name = "BirthDate", + required = true + ) + @XmlSchemaType( + name = "date" + ) + protected String birthDate; + + + public TestDto() { + } + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("studentNumber", studentNumber) + .put("lastName", lastName) + .put("prefixes", prefixes) + .put("initials", initials) + .put("firstNames", firstNames) + .put("nickName", nickName) + .put("birthDate", birthDate); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + studentNumber = document.get("studentNumber", String.class); + lastName = document.get("lastName", String.class); + prefixes = document.get("prefixes", String.class); + initials = document.get("initials", String.class); + firstNames = document.get("firstNames", String.class); + nickName = document.get("nickName", String.class); + birthDate = document.get("birthDate", String.class); + } + } + @Data public static class PerfTest implements Mappable { private String firstName; @@ -220,9 +319,9 @@ public void read(NitriteMapper mapper, Document document) { } @Indices({ - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "age", type = IndexType.NonUnique), - @Index(value = "text", type = IndexType.Fulltext), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "age", type = IndexType.NON_UNIQUE), + @Index(value = "text", type = IndexType.FULL_TEXT), }) private static class PerfTestIndexed extends PerfTest { } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/Retry.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/Retry.java similarity index 66% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/Retry.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/Retry.java index 00e34e7ad..3d6a27d11 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/Retry.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/Retry.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.mapdb; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration; import org.junit.rules.TestRule; import org.junit.runner.Description; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/SerializabilityTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java similarity index 85% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/SerializabilityTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java index 31a165232..09ca50080 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/SerializabilityTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/SerializabilityTest.java @@ -1,22 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration; import lombok.Data; +import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.exceptions.ValidationException; @@ -28,10 +30,6 @@ import java.io.File; import java.io.Serializable; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.TestUtil.createDb; -import static org.junit.Assert.assertTrue; - /** * @author Anindya Chatterjee */ @@ -45,8 +43,8 @@ public class SerializabilityTest { @Before public void setUp() { - dbFile = new File(getRandomTempDbFile()); - db = createDb(dbFile.getPath()); + dbFile = new File(TestUtil.getRandomTempDbFile()); + db = TestUtil.createDb(dbFile.getPath()); collection = db.getCollection("test"); } @@ -57,8 +55,7 @@ public void tearDown() { } if (dbFile.exists()) { - boolean delete = dbFile.delete(); - assertTrue(delete); + TestUtil.deleteDb(dbFile.getPath()); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/TestUtil.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java similarity index 67% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/TestUtil.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java index f7b7833d4..91a4101ad 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/TestUtil.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -1,38 +1,58 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.exceptions.ObjectMappingException; +import org.dizitart.no2.rocksdb.RocksDBModule; import java.io.File; import java.io.IOException; import java.util.*; +import static org.junit.Assert.assertTrue; + /** * @author Anindya Chatterjee */ @Slf4j public class TestUtil { - public static void deleteFile(String fileName) throws IOException { + public static String getRandomTempDbFile() { + String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; + File file = new File(dataDir); + if (!file.exists()) { + assertTrue(file.mkdirs()); + } + return file.getPath() + File.separator + UUID.randomUUID() + ".db"; + } + + @SneakyThrows + public static void deleteDb(String fileName) { File file = new File(fileName); FileUtils.deleteDirectory(file); } @@ -97,6 +117,17 @@ public static Nitrite createDb(String filePath, String user, String password) { .openOrCreate(user, password); } + public static Document parse(String json) { + try { + ObjectMapper objectMapper = createObjectMapper(); + JsonNode node = objectMapper.readValue(json, JsonNode.class); + return loadDocument(node); + } catch (IOException e) { + log.error("Error while parsing json", e); + throw new ObjectMappingException("failed to parse json " + json); + } + } + private static Document loadDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); Iterator> fields = node.fields(); @@ -156,4 +187,20 @@ private static List loadArray(JsonNode array) { } return null; } + + private static ObjectMapper createObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility( + objectMapper.getSerializationConfig().getDefaultVisibilityChecker() + .withFieldVisibility(JsonAutoDetect.Visibility.ANY) + .withGetterVisibility(JsonAutoDetect.Visibility.NONE) + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + objectMapper.findAndRegisterModules(); + return objectMapper; + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/BaseCollectionTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java similarity index 91% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/BaseCollectionTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java index f91a7bf55..c1a34e3b0 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/BaseCollectionTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/BaseCollectionTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; @@ -22,11 +23,14 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.rocksdb.RocksDBModule; import org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter; import org.dizitart.no2.rocksdb.serializers.JodaTimeKryoKeySerializer; import org.joda.time.DateTime; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -38,7 +42,8 @@ import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; @Slf4j @RunWith(value = Parameterized.class) @@ -52,6 +57,9 @@ public abstract class BaseCollectionTest { protected SimpleDateFormat simpleDateFormat; private final String fileName = getRandomTempDbFile(); protected final KryoObjectFormatter fstMarshaller = new KryoObjectFormatter(); + + @Rule + public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Secured = {0}") public static Collection data() { @@ -61,9 +69,6 @@ public static Collection data() { }); } -// @Rule - public Retry retry = new Retry(3); - @Before public void setUp() { try { @@ -105,7 +110,7 @@ public void clear() { collection.close(); } if (db != null && !db.isClosed()) db.close(); - FileUtils.deleteDirectory(new File(fileName)); + deleteDb(fileName); } catch (Throwable t) { log.error("Error while clearing test database", t); } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java new file mode 100644 index 000000000..746fe397b --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Date; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexNegativeTest extends BaseCollectionTest { + + @Test(expected = UniqueConstraintException.class) + public void testCreateInvalidUniqueIndex() { + doc1 = createDocument("firstName", "fn3") + .put("lastName", "ln2") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", Arrays.asList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + + collection.createIndex("lastName", "firstName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateUniqueMultiKeyIndexOnArray() { + collection.createIndex("data", "lastName"); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateOnInvalidField() { + insert(); + // multiple null value will be created + collection.createIndex( "my-value", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testDropIndexOnNonIndexedField() { + collection.dropIndex("data", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testRebuildIndexInvalid() { + collection.rebuildIndex("unknown", "firstName"); + } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameFields() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + } + + @Test(expected = IndexingException.class) + public void testIndexAlreadyExists() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateCompoundTextIndex() { + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body", "lastName"); + } + + @Test(expected = IndexingException.class) + public void testCreateMultiKeyIndexSecondField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "data"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java new file mode 100644 index 000000000..8d37792ed --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import com.google.common.collect.Lists; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.Date; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.awaitility.Awaitility.await; +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionCompoundIndexTest extends BaseCollectionTest { + @Test + public void testCreateAndCheckIndex() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertFalse(collection.hasIndex("firstName", "lastName", "birthDay")); + assertFalse(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testCreateMultiKeyIndexFirstField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "data", "lastName"); + assertTrue(collection.hasIndex("data")); + assertTrue(collection.hasIndex("data", "lastName")); + assertFalse(collection.hasIndex("lastName")); + + insert(); + } + + @Test + public void testListIndexes() { + assertEquals(collection.listIndices().size(), 0); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); + assertEquals(collection.listIndices().size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + assertEquals(collection.listIndices().size(), 2); + } + + @Test + public void testDropIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + collection.dropIndex("firstName", "lastName"); + assertFalse(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertFalse(collection.hasIndex("firstName")); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testHasIndex() { + assertFalse(collection.hasIndex("lastName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + assertTrue(collection.hasIndex("lastName")); + } + + @Test + public void testDropAllIndexes() { + collection.dropAllIndices(); + + collection.createIndex("firstName", "lastName"); + collection.createIndex("firstName"); + assertEquals(collection.listIndices().size(), 2); + + collection.dropAllIndices(); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testRebuildIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + + insert(); + collection.rebuildIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName", "lastName")); + assertTrue(collection.hasIndex("firstName")); + } + + @Test + public void testDeleteWithIndex() { + collection.createIndex("firstName", "lastName"); + + insert(); + + WriteResult result = collection.remove(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + assertEquals(result.getAffectedCount(), 1); + + result = collection.remove(and(where("firstName").eq("fn2"), + where("birthDay").gte(new Date()))); + assertEquals(result.getAffectedCount(), 0); + } + + @Test + public void testRebuildIndexOnRunningIndex() { + insert(); + db.getStore().subscribe(System.out::println); + + collection.createIndex("firstName", "lastName"); + collection.rebuildIndex("firstName", "lastName"); + + assertTrue(collection.hasIndex("firstName", "lastName")); + } + + @Test + public void testNullValuesInIndexedFields() { + collection.createIndex("firstName", "lastName"); + collection.createIndex("birthDay", "lastName"); + Document document = createDocument("firstName", null) + .put("lastName", "ln1") + .put("birthDay", new Date()) + .put("data", new byte[]{1, 2, 3}) + .put("list", Lists.newArrayList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + + insert(); + collection.insert(document); + + DocumentCursor cursor = collection.find(where("fistName").eq(null)); + assertEquals("ln1", cursor.firstOrNull().get("lastName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + document = createDocument("firstName", "fn4") + .put("lastName", null) + .put("birthDay", null) + .put("data", new byte[]{1, 2, 3}) + .put("list", Lists.newArrayList("one", "two", "three")) + .put("body", "a quick brown fox jump over the lazy dog"); + collection.insert(document); + + cursor = collection.find(where("lastName").eq(null)); + assertEquals("fn4", cursor.firstOrNull().get("firstName", String.class)); + assertNull(cursor.firstOrNull().get("fistName", String.class)); + + cursor = collection.find(and(where("lastName").eq(null), where("birthDay").eq(null))); + assertNull(cursor.firstOrNull().get("lastName", String.class)); + } + + @Test + public void testDropAllAndCreateIndex() { + collection.createIndex("firstName", "lastName"); + assertTrue(collection.hasIndex("firstName")); + + DocumentCursor cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + FindPlan findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + + collection.dropAllIndices(); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + + collection.createIndex("firstName", "lastName"); + cursor = collection.find(and(where("firstName").eq("fn1"), + where("lastName").eq("ln1"))); + findPlan = cursor.getFindPlan(); + assertNotNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + } + + @Test + public void testIssue178() { + collection.dropAllIndices(); + collection.remove(Filter.ALL); + + Document doc1 = createDocument("field1", 5); + Document doc2 = createDocument("field1", 4.3).put("field2", 3.5); + Document doc3 = createDocument("field1", 0.03).put("field2", 5); + Document doc4 = createDocument("field1", 4).put("field2", 4.5); + Document doc5 = createDocument("field1", 5.0).put("field2", 5.0); + + collection.insert(doc1, doc2, doc3, doc4, doc5); + + DocumentCursor cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + + collection.createIndex("field1", "field2"); + cursor = collection.find(and(where("field1").eq(0.03), + where("field2").eq(5))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(and(where("field1").eq(5), + where("field2").eq(null))); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5)); + assertEquals(cursor.size(), 1); + + cursor = collection.find(where("field1").eq(5.0)); + assertEquals(cursor.size(), 1); + } + + @Test + public void testIndexEvent() { + NitriteCollection collection = db.getCollection("index-test"); + Random random = new Random(); + for (int i = 0; i < 10000; i++) { + Document document = createDocument("first", random.nextInt()) + .put("second", random.nextDouble()); + collection.insert(document); + } + + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); + collection.subscribe(eventInfo -> { + switch (eventInfo.getEventType()) { + case Insert: + case Remove: + case Update: + failed.set(true); + break; + case IndexStart: + case IndexEnd: + completed.set(true); + break; + } + }); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first", "second"); + assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); + } + + @Test + public void testIndexAndSearchOnNullValues() { + NitriteCollection collection = db.getCollection("index-on-null"); + collection.insert(createDocument("first", null).put("second", 123).put("third", new Integer[]{1, 2, null})); + collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); + collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); + + collection.createIndex("third", "first"); + assertEquals(collection.find(where("first").eq(null)).size(), 1); + + assertEquals(collection.find(where("third").eq(null)).size(), 2); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java index 546d6cc0d..9c9d9bd6a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteNegativeTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -22,7 +23,6 @@ import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java similarity index 92% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java index d157dc682..ca1660599 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionDeleteTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java @@ -1,27 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; @@ -74,7 +74,7 @@ public void testDeleteInEmptyCollection() { @Test public void testClear() { - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); insert(); DocumentCursor cursor = collection.find(); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java similarity index 84% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java index 44ff99c11..358e83a39 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/CollectionFieldIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java @@ -1,31 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.index.IndexType; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; @@ -35,17 +33,7 @@ /** * @author Anindya Chatterjee */ -public class CollectionFieldIndexTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() { - db = createDb(); - } - +public class CollectionFieldIndexTest extends BaseCollectionTest { @Test public void testCollection() { Document doc1 = Document.createDocument("name", "Anindya") @@ -79,9 +67,9 @@ public void testCollection() { }); NitriteCollection collection = db.getCollection("test"); - collection.createIndex("color", indexOptions(IndexType.Unique)); - collection.createIndex("books.tag", indexOptions(IndexType.NonUnique)); - collection.createIndex("books.name", indexOptions(IndexType.Fulltext)); + collection.createIndex("color"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "books.tag"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "books.name"); WriteResult writeResult = collection.insert(doc1, doc2, doc3); assertEquals(writeResult.getAffectedCount(), 3); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java new file mode 100644 index 000000000..8fd30693e --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.AndFilter; +import org.dizitart.no2.filters.IndexScanFilter; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.text.ParseException; +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class CollectionFindByCompoundIndexTest extends BaseCollectionTest { + + @Test + public void testFindByAndFilter() { + insert(); + collection.createIndex("list", "lastName", "firstName"); + DocumentCursor cursor = collection.find(and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1"), + where("list").eq("four") + )); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(findPlan.getIndexDescriptor(), collection.listIndices().toArray()[0]); + + IndexScanFilter indexScanFilter = findPlan.getIndexScanFilter(); + assertEquals(indexScanFilter.getFilters().get(0), where("list").eq("four")); + assertEquals(indexScanFilter.getFilters().get(1), where("lastName").eq("ln2")); + assertEquals(indexScanFilter.getFilters().get(2), where("firstName").notEq("fn1")); + + List documents = cursor.toList(); + assertEquals(documents.size(), 1); + assertEquals(documents.get(0).get("body", String.class), "quick hello world from nitrite"); + } + + @Test + public void testFindByOrFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + or( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getSubPlans()); + + assertEquals(2, findPlan.getSubPlans().size()); + assertNotNull(findPlan.getSubPlans().get(0).getIndexScanFilter()); + assertNotNull(findPlan.getSubPlans().get(1).getIndexScanFilter()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn2") + && d.get("lastName", String.class).equals("ln2")).count()); + + assertEquals(1, cursor.toList().stream().filter(d -> + d.get("firstName", String.class).equals("fn3") + && d.get("lastName", String.class).equals("ln2")).count()); + } + + @Test + public void testFindByAndFilterOrFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(2, cursor.size()); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNotNull(findPlan.getCollectionScanFilter()); + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(and( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + or( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ), findPlan.getCollectionScanFilter()); + } + + @Test + public void testFindByAndFilterAndFilter() { + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + and( + where("firstName").eq("fn3"), + where("lastName").eq("ln2") + ) + ) + ); + + assertEquals(1, cursor.size()); + FindPlan findPlan = cursor.getFindPlan(); + + assertNotNull(findPlan.getIndexDescriptor()); + assertEquals(collection.listIndices().toArray()[0], findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getIndexScanFilter()); + assertEquals(findPlan.getIndexScanFilter().getFilters(), + ((AndFilter) and( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + )).getFilters()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(where("firstName").eq("fn3"), findPlan.getCollectionScanFilter()); + + assertTrue(findPlan.getSubPlans().isEmpty()); + + assertEquals(cursor.toList().get(0).get("firstName", String.class), "fn3"); + } + + @Test + public void testFindByOrFilter() throws ParseException { + // all or clause has index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + collection.createIndex("birthDay"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(3, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindOrNoIndex() throws ParseException { + // on of the or clause has no index + insert(); + collection.createIndex("lastName", "firstName"); + collection.createIndex("firstName"); + DocumentCursor cursor = collection.find( + or( + or( + where("lastName").eq("ln2"), + where("firstName").notEq("fn1") + ), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")), + where("firstName").notEq("fn1") + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(0, findPlan.getSubPlans().size()); + assertEquals(3, cursor.size()); + } + + @Test + public void testFindAndNoIndex() throws ParseException { + // index at second field + insert(); + collection.createIndex("lastName", "firstName"); + DocumentCursor cursor = collection.find( + and( + where("firstName").notEq("fn1"), + where("birthDay").eq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertNull(findPlan.getIndexScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertEquals(0, cursor.size()); + } + + @Test + public void testSortByIndex() throws ParseException { + // multiple field sort in both direction + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } + + @Test + public void testBlockingSort() throws ParseException { + // multiple field sort in memory + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortNotCoveredByIndex() throws ParseException { + // some field sort by index, some by memory + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + List> blockingSortOrder = findPlan.getBlockingSortOrder(); + assertEquals(2, blockingSortOrder.size()); + + Pair pair = blockingSortOrder.get(0); + assertEquals("lastName", pair.getFirst()); + assertEquals(SortOrder.Ascending, pair.getSecond()); + + pair = blockingSortOrder.get(1); + assertEquals("birthDay", pair.getFirst()); + assertEquals(SortOrder.Descending, pair.getSecond()); + + assertNotNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertNull(findPlan.getIndexScanOrder()); + } + + @Test + public void testSortByIndexPrefix() throws ParseException { + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + ); + + List documents = cursor.toList(); + assertEquals(3, documents.size()); + + Document document = documents.get(0); + assertEquals("ln2", document.get("lastName")); + // duplicate birthday will have natural sort order - ascending + assertEquals(simpleDateFormat.parse("2010-06-12T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(1); + assertEquals("ln2", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2014-04-17T16:02:48.440Z"), document.get("birthDay")); + + document = documents.get(2); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + } + + @Test + public void testLimitAndSkip() throws ParseException { + // test skip and limit + + collection.createIndex("lastName", "birthDay"); + + Document doc = createDocument("firstName", "fn4") + .put("lastName", "ln3") + .put("birthDay", simpleDateFormat.parse("2016-04-17T16:02:48.440Z")) + .put("data", new byte[]{9, 4, 8}) + .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); + collection.insert(doc); + collection.insert(doc3); + collection.insert(doc1); + collection.insert(doc2); + + DocumentCursor cursor = collection.find( + and( + where("lastName").notEq("ln1"), + where("birthDay").notEq(simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) + ), + orderBy("lastName", SortOrder.Ascending) + .thenOrderBy("birthDay", SortOrder.Descending) + .skip(2) + .limit(1) + ); + + List documents = cursor.toList(); + assertEquals(1, documents.size()); + + Document document = documents.get(0); + assertEquals("ln3", document.get("lastName")); + assertEquals(simpleDateFormat.parse("2016-04-17T16:02:48.440Z"), document.get("birthDay")); + + FindPlan findPlan = cursor.getFindPlan(); + assertTrue(findPlan.getBlockingSortOrder().isEmpty()); + assertNull(findPlan.getCollectionScanFilter()); + assertNotNull(findPlan.getIndexDescriptor()); + assertFalse(findPlan.getIndexScanOrder().get("lastName")); + assertEquals(2L, (long)findPlan.getSkip()); + assertEquals(1L, (long)findPlan.getLimit()); + + // reverse scan + assertTrue(findPlan.getIndexScanOrder().get("birthDay")); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java similarity index 79% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java index 174c8a6a6..76b84a0e6 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindByIndexNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java @@ -1,26 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.filters.FluentFilter.where; @@ -33,7 +33,7 @@ public class CollectionFindByIndexNegativeTest extends BaseCollectionTest { @Test(expected = FilterException.class) public void testFindTextWithWildCardMultipleWord() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*ipsum dolor*")); assertEquals(cursor.size(), 1); @@ -42,7 +42,7 @@ public void testFindTextWithWildCardMultipleWord() { @Test(expected = FilterException.class) public void testFindTextWithOnlyWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*")); assertEquals(cursor.size(), 1); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java similarity index 79% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java index 42902951f..cbef67e26 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindByIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import com.github.javafaker.Faker; import org.dizitart.no2.collection.Document; @@ -24,7 +25,6 @@ import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import java.text.ParseException; @@ -33,27 +33,30 @@ import java.util.Date; import java.util.List; +import static org.dizitart.no2.integration.TestUtil.isSorted; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.filters.Filter.or; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.TestUtil.isSorted; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Anindya Chatterjee. */ -public class CollectionFindByIndexTest extends BaseCollectionTest { +public class CollectionFindBySingleFieldIndexTest extends BaseCollectionTest { @Test public void testFindByUniqueIndex() throws ParseException { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); cursor = collection.find(where("firstName").eq("fn10")); assertEquals(cursor.size(), 0); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); cursor = collection.find(where("birthDay").gt( simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); assertEquals(cursor.size(), 1); @@ -97,15 +100,23 @@ public void testFindByUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -124,8 +135,8 @@ public void testFindByUniqueIndex() throws ParseException { @Test public void testFindByNonUniqueIndex() throws ParseException { insert(); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDay"); DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); assertEquals(cursor.size(), 2); @@ -176,15 +187,23 @@ public void testFindByNonUniqueIndex() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); cursor = collection.find(where("data.1").eq((byte) 4)); @@ -203,7 +222,7 @@ public void testFindByNonUniqueIndex() throws ParseException { @Test public void testFindByFullTextIndexAfterInsert() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); DocumentCursor cursor = collection.find(where("body").text("Lorem")); @@ -225,7 +244,7 @@ public void testFindByFullTextIndexAfterInsert() { @Test public void testFindByFullTextIndexBeforeInsert() { - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); insert(); @@ -252,9 +271,9 @@ public void testFindByFullTextIndexBeforeInsert() { @Test public void testFindByIndexSortAscending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -266,9 +285,9 @@ public void testFindByIndexSortAscending() { @Test public void testFindByIndexSortDescending() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -280,10 +299,13 @@ public void testFindByIndexSortDescending() { @Test public void testFindByIndexLimitAndSort() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find( + orderBy("birthDay", SortOrder.Descending) + .skip(1) + .limit(2) + ); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -291,8 +313,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -300,8 +321,7 @@ public void testFindByIndexLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -313,7 +333,7 @@ public void testFindByIndexLimitAndSort() { @Test public void testFindAfterDroppedIndex() { insert(); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); @@ -325,7 +345,7 @@ public void testFindAfterDroppedIndex() { @Test public void testFindTextWithWildCard() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("Lo")); assertEquals(cursor.size(), 0); @@ -343,7 +363,7 @@ public void testFindTextWithWildCard() { @Test public void testFindTextWithEmptyString() { insert(); - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("")); assertEquals(cursor.size(), 0); @@ -357,8 +377,8 @@ public void testFindWithOrIndexed() { Document doc3 = Document.createDocument("firstName", "Jonas").put("lastName", "Doe"); Document doc4 = Document.createDocument("firstName", "Johan").put("lastName", "Day"); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); collection.insert(doc1, doc2, doc3, doc4); @@ -388,7 +408,7 @@ public void testIssue45() { Document doc3 = Document.createDocument("firstName", "Jonas").put("notes", list3); Document doc4 = Document.createDocument("firstName", "Johan").put("notes", list4); - collection.createIndex("notes", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "notes"); collection.insert(doc1, doc2, doc3, doc4); DocumentCursor cursor = collection.find(where("notes").text("fox")); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java similarity index 83% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java index 26b7eb507..8d446cf0f 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFindNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindNegativeTest.java @@ -1,33 +1,35 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import java.util.Date; import java.util.List; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; @@ -44,24 +46,25 @@ public void testFindFilterInvalidIndex() { @Test(expected = ValidationException.class) public void testFindOptionsNegativeOffset() { insert(); - collection.find().skipLimit(-1, 1); + collection.find(skipBy(-1).limit(1)); } @Test(expected = ValidationException.class) public void testFindOptionsNegativeSize() { insert(); - collection.find().skipLimit(0, -1); + collection.find(skipBy(0).limit(-1)); } + @Test public void testFindOptionsInvalidOffset() { insert(); - assertEquals(collection.find().skipLimit(10, 1).size(), 0); + assertEquals(collection.find(skipBy(10).limit(1)).size(), 0); } @Test(expected = ValidationException.class) public void testFindInvalidSort() { insert(); - collection.find().sort("data", SortOrder.Descending).toList(); + collection.find(orderBy("data", SortOrder.Descending)).toList(); } @Test(expected = FilterException.class) @@ -80,8 +83,8 @@ public void testFindWithRegexInvalidValue() { @Test(expected = ValidationException.class) public void testInvalidProjection() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", "ln2"); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java similarity index 79% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java index d5923b4dc..f5e5a2c04 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFindTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -25,7 +26,6 @@ import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.joda.time.DateTime; import org.junit.Test; @@ -34,16 +34,16 @@ import java.util.*; import java.util.stream.Collectors; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.*; import static org.dizitart.no2.common.Constants.*; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.TestUtil.isSorted; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.*; public class CollectionFindTest extends BaseCollectionTest { @@ -111,18 +111,25 @@ public void testFindWithFilter() throws ParseException { assertEquals(cursor.size(), 3); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1"))); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + )); assertEquals(cursor.size(), 1); cursor = collection.find( - where("birthDay").lte(new Date()) - .or(where("firstName").eq("fn12")) - .and(where("lastName").eq("ln1")).not()); + and( + or( + where("birthDay").lte(new Date()), + where("firstName").eq("fn12") + ), + where("lastName").eq("ln1") + ).not()); assertEquals(cursor.size(), 2); - cursor = collection.find(where("data.1").eq((byte) 4)); assertEquals(cursor.size(), 2); @@ -143,16 +150,16 @@ public void testFindWithFilter() throws ParseException { public void testFindWithSkipLimit() { insert(); - DocumentCursor cursor = collection.find().skipLimit(0, 1); + DocumentCursor cursor = collection.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); - cursor = collection.find().skipLimit(1, 3); + cursor = collection.find(skipBy(1).limit(3)); assertEquals(cursor.size(), 2); - cursor = collection.find().skipLimit(0, 30); + cursor = collection.find(skipBy(0).limit(30)); assertEquals(cursor.size(), 3); - cursor = collection.find().skipLimit(2, 3); + cursor = collection.find(skipBy(2).limit(3)); assertEquals(cursor.size(), 1); } @@ -160,21 +167,21 @@ public void testFindWithSkipLimit() { public void testFindWithSkip() { insert(); - DocumentCursor cursor = collection.find().skip(0); + DocumentCursor cursor = collection.find(skipBy(0)); assertEquals(cursor.size(), 3); - cursor = collection.find().skip(1); + cursor = collection.find(skipBy(1)); assertEquals(cursor.size(), 2); - cursor = collection.find().skip(30); + cursor = collection.find(skipBy(30)); assertEquals(cursor.size(), 0); - cursor = collection.find().skip(2); + cursor = collection.find(skipBy(2)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().skip(-1); + cursor = collection.find(skipBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; @@ -186,22 +193,22 @@ public void testFindWithSkip() { public void testFindWithLimit() { insert(); - DocumentCursor cursor = collection.find().limit(0); + DocumentCursor cursor = collection.find(limitBy(0)); assertEquals(cursor.size(), 0); - cursor = collection.find().limit(1); + cursor = collection.find(limitBy(1)); assertEquals(cursor.size(), 1); boolean invalid = false; try { - cursor = collection.find().limit(-1); + cursor = collection.find(limitBy(-1)); assertEquals(cursor.size(), 1); } catch (ValidationException e) { invalid = true; } assertTrue(invalid); - cursor = collection.find().limit(30); + cursor = collection.find(limitBy(30)); assertEquals(cursor.size(), 3); } @@ -209,7 +216,7 @@ public void testFindWithLimit() { public void testFindSortAscending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Ascending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -222,7 +229,7 @@ public void testFindSortAscending() { public void testFindSortDescending() { insert(); - DocumentCursor cursor = collection.find().sort("birthDay", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -235,8 +242,7 @@ public void testFindSortDescending() { public void testFindLimitAndSort() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); List dateList = new ArrayList<>(); for (Document document : cursor) { @@ -244,8 +250,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, false)); - cursor = collection.find(). - sort("birthDay", SortOrder.Ascending).skipLimit(1, 2); + cursor = collection.find(orderBy("birthDay", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); dateList = new ArrayList<>(); for (Document document : cursor) { @@ -253,8 +258,7 @@ public void testFindLimitAndSort() { } assertTrue(isSorted(dateList, true)); - cursor = collection.find(). - sort("firstName", SortOrder.Ascending).skipLimit(0, 30); + cursor = collection.find(orderBy("firstName", SortOrder.Ascending).skip(0).limit(30)); assertEquals(cursor.size(), 3); List nameList = new ArrayList<>(); for (Document document : cursor) { @@ -266,7 +270,7 @@ public void testFindLimitAndSort() { @Test public void testFindSortOnNonExistingField() { insert(); - DocumentCursor cursor = collection.find().sort("my-value", SortOrder.Descending); + DocumentCursor cursor = collection.find(orderBy("my-value", SortOrder.Descending)); assertEquals(cursor.size(), 3); } @@ -287,8 +291,7 @@ public void testFindInvalidFieldWithInvalidAccessor() { @Test public void testFindLimitAndSortInvalidField() { insert(); - DocumentCursor cursor = collection.find(). - sort("birthDay2", SortOrder.Descending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(orderBy("birthDay2", SortOrder.Descending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -311,8 +314,8 @@ public void testGetById() { @Test public void testFindWithFilterAndOption() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(1, 2); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(1).limit(2)); assertEquals(cursor.size(), 2); } @@ -335,8 +338,8 @@ public void testFindTextWithRegex() { @Test public void testProject() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); int iteration = 0; for (Document document : cursor) { switch (iteration) { @@ -358,8 +361,8 @@ public void testProject() { @Test public void testProjectWithCustomDocument() { insert(); - DocumentCursor cursor = collection.find(where("birthDay").lte(new Date())). - sort("firstName", SortOrder.Ascending).skipLimit(0, 3); + DocumentCursor cursor = collection.find(where("birthDay").lte(new Date()), + orderBy("firstName", SortOrder.Ascending).skip(0).limit(3)); Document projection = createDocument("firstName", null) .put("lastName", null); @@ -619,8 +622,8 @@ public void testFilterAll() { @Test public void testIssue72() { NitriteCollection coll = db.getCollection("test"); - coll.createIndex("id", IndexOptions.indexOptions(IndexType.Unique)); - coll.createIndex("group", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "id"); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "group"); coll.remove(ALL); @@ -630,13 +633,14 @@ public void testIssue72() { doc = createDocument().put("id", "test-2").put("group", "groupA").put("startTime", DateTime.now()); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(1).get("startTime")); assertNotNull(cursor.toList().get(0).get("startTime")); - cursor = coll.find(where("group").eq("groupA")).sort("startTime", SortOrder.Ascending); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending)); assertEquals(2, cursor.size()); assertNull(cursor.toList().get(0).get("startTime")); assertNotNull(cursor.toList().get(1).get("startTime")); @@ -654,8 +658,8 @@ public void testIssue93() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); } @@ -671,52 +675,16 @@ public void testNullOrderWithAllNull() { doc = createDocument().put("id", "test-1").put("group", "groupA"); assertEquals(1, coll.insert(doc).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(2, cursor.size()); - - DocumentCursor cursor2 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); - assertEquals(2, cursor2.size()); - - assertThat(cursor.toList(), is(cursor2.toList())); - - DocumentCursor cursor3 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(2, cursor3.size()); - - assertThat(cursor.toList(), is(cursor3.toList())); - - DocumentCursor cursor4 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(2, cursor4.size()); - - assertThat(cursor.toList(), is(cursor4.toList())); - - DocumentCursor cursor5 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(2, cursor5.size()); - - assertThat(cursor.toList(), is(cursor5.toList())); - - DocumentCursor cursor6 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(2, cursor6.size()); - - assertThat(cursor.toList(), is(cursor6.toList())); - - DocumentCursor cursor7 = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); - assertEquals(2, cursor7.size()); - - assertThat(cursor.toList(), is(cursor7.toList())); } @Test - public void testNullOrder() { + public void testDefaultNullOrder() { NitriteCollection coll = db.getCollection("test"); try { - coll.createIndex("startTime", IndexOptions.indexOptions(IndexType.NonUnique)); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "startTime"); } catch (IndexingException e) { // ignore } @@ -732,47 +700,18 @@ public void testNullOrder() { Document doc3 = createDocument().put("id", "test-3").put("group", "groupA").put("startTime", DateTime.now().plusMinutes(1)); assertEquals(1, coll.insert(doc3).getAffectedCount()); - DocumentCursor cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending); + DocumentCursor cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Descending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc3, doc2, doc1), - equalTo(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc3, doc2), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Default); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Descending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc3, doc2, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.First); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc1, doc2, doc3), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Default); + cursor = coll.find(where("group").eq("groupA"), + orderBy("startTime", SortOrder.Ascending)); assertEquals(3, cursor.size()); assertThat(Arrays.asList(doc1, doc2, doc3), is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); - - cursor = coll.find(where("group").eq("groupA")) - .sort("startTime", SortOrder.Ascending, NullOrder.Last); - assertEquals(3, cursor.size()); - assertThat(Arrays.asList(doc2, doc3, doc1), - is(cursor.toList().stream().map(CollectionFindTest::trimMeta).collect(Collectors.toList()))); } @Test @@ -791,8 +730,8 @@ public void testIssue144() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2, doc3); - DocumentCursor cursor = coll.find().sort("fruit", SortOrder.Ascending, - Collator.getInstance(Locale.FRANCE)); + DocumentCursor cursor = coll.find(orderBy("fruit", SortOrder.Ascending) + .collator(Collator.getInstance(Locale.FRANCE))); assertEquals(cursor.toList().get(1).get("fruit"), "Ôrange"); } @@ -844,7 +783,7 @@ public void testBetweenFilter() { NitriteCollection collection = db.getCollection("tag"); collection.insert(doc1, doc2, doc3, doc4, doc5); - collection.createIndex("age", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "age"); DocumentCursor cursor = collection.find(where("age").between(31, 35)); assertEquals(cursor.size(), 5); @@ -858,4 +797,29 @@ public void testBetweenFilter() { cursor = collection.find(where("age").between(31, 35, false).not()); assertEquals(cursor.size(), 2); } + + @Test + public void testByIdFilter() { + Document doc1 = createDocument("age", 31).put("tag", "one"); + Document doc2 = createDocument("age", 32).put("tag", "two"); + Document doc3 = createDocument("age", 33).put("tag", "three"); + Document doc4 = createDocument("age", 34).put("tag", "four"); + Document doc5 = createDocument("age", 35).put("tag", "five"); + + NitriteCollection collection = db.getCollection("tag"); + collection.insert(doc1, doc2, doc3, doc4, doc5); + + List documentList = collection.find().toList(); + Document document = documentList.get(0); + NitriteId nitriteId = document.getId(); + + Document result = collection.find(byId(nitriteId)).firstOrNull(); + assertEquals(document, result); + + result = collection.find(and(byId(nitriteId), where("age").notEq(null))).firstOrNull(); + assertEquals(document, result); + + result = collection.find(or(byId(nitriteId), where("tag").eq(document.get("tag")))).firstOrNull(); + assertEquals(document, result); + } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java similarity index 75% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java index cad0fdc3b..f6ce8612e 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java @@ -1,26 +1,26 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; import static org.junit.Assert.assertTrue; @@ -32,30 +32,30 @@ public class CollectionIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("lastName"); assertTrue(collection.hasIndex("lastName")); insert(); } @Test(expected = UniqueConstraintException.class) public void testCreateIndexOnArray() { - collection.createIndex("data", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("data"); assertTrue(collection.hasIndex("data")); // data array field has repetition, so unique constraint exception insert(); } - @Test + @Test(expected = UniqueConstraintException.class) public void testCreateOnInvalidField() { insert(); - collection.createIndex("my-value", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("my-value"); assertTrue(collection.hasIndex("my-value")); } @Test(expected = IndexingException.class) public void testCreateFullTextOnNonTextField() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "birthDay"); assertTrue(collection.hasIndex("birthDay")); } @@ -66,6 +66,6 @@ public void testDropIndexOnNonIndexedField() { @Test(expected = IndexingException.class) public void testRebuildIndexInvalid() { - collection.rebuildIndex("unknown", true); + collection.rebuildIndex("unknown"); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java new file mode 100644 index 000000000..247a1705a --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; +import java.util.concurrent.Callable; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee. + */ +public class CollectionIndexTest extends BaseCollectionTest { + + @Test + public void testCollection() { + Document doc1 = Document.createDocument("name", "Anindya") + .put("color", new String[]{"red", "green", "blue"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book ABCD") + .put("tag", new String[]{"tag1", "tag2"}), + Document.createDocument("name", "Book EFGH") + .put("tag", new String[]{"tag3", "tag1"}), + Document.createDocument("name", "No Tag") + }); + + Document doc2 = Document.createDocument("name", "Bill") + .put("color", new String[]{"purple", "yellow", "gray"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book abcd") + .put("tag", new String[]{"tag4", "tag5"}), + Document.createDocument("name", "Book wxyz") + .put("tag", new String[]{"tag3", "tag1"}), + Document.createDocument("name", "No Tag 2") + }); + + Document doc3 = Document.createDocument("name", "John") + .put("color", new String[]{"black", "sky", "violet"}) + .put("books", new Document[]{ + Document.createDocument("name", "Book Mnop") + .put("tag", new String[]{"tag6", "tag2"}), + Document.createDocument("name", "Book ghij") + .put("tag", new String[]{"tag3", "tag7"}), + Document.createDocument("name", "No Tag") + }); + + NitriteCollection collection = db.getCollection("test"); + collection.createIndex("color"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "books.tag"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "books.name"); + + WriteResult writeResult = collection.insert(doc1, doc2, doc3); + assertEquals(writeResult.getAffectedCount(), 3); + + DocumentCursor documents = collection.find(where("color").eq("red")); + assertTrue(isSimilar(documents.firstOrNull(), doc1, "name", "color", "books")); + + documents = collection.find(where("books.name").text("abcd")); + assertEquals(documents.size(), 2); + + documents = collection.find(where("books.tag").eq("tag2")); + assertEquals(documents.size(), 2); + + documents = collection.find(where("books.tag").eq("tag5")); + assertEquals(documents.size(), 1); + + documents = collection.find(where("books.tag").eq("tag10")); + assertEquals(documents.size(), 0); + } + + @Test + public void testCreateIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + + collection.createIndex("birthDay", null); + assertTrue(collection.hasIndex("birthDay")); + + insert(); + } + + @Test + public void testListIndexes() { + assertEquals(collection.listIndices().size(), 0); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + + assertEquals(collection.listIndices().size(), 3); + } + + @Test + public void testDropIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection.dropIndex("firstName"); + assertFalse(collection.hasIndex("firstName")); + } + + @Test + public void testDropAllIndexes() { + collection.dropAllIndices(); + + testCreateIndex(); + assertEquals(collection.listIndices().size(), 4); + + collection.dropAllIndices(); + assertEquals(collection.listIndices().size(), 0); + } + + @Test + public void testHasIndex() { + assertFalse(collection.hasIndex("lastName")); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + + assertFalse(collection.hasIndex("body")); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + assertTrue(collection.hasIndex("body")); + } + + @Test + public void testDeleteWithIndex() { + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + + insert(); + + WriteResult result = collection.remove(where("firstName").eq("fn1")); + assertEquals(result.getAffectedCount(), 1); + + DocumentCursor cursor = collection.find(); + assertEquals(cursor.size(), 2); + + result = collection.remove(where("body").text("Lorem")); + assertEquals(result.getAffectedCount(), 1); + + cursor = collection.find(); + assertEquals(cursor.size(), 1); + } + + @Test + public void testRebuildIndex() { + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); + insert(); + Collection indices = collection.listIndices(); + for (IndexDescriptor idx : indices) { + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); + } + } + + private Callable bodyIndexingCompleted() { + return () -> !collection.isIndexing("body"); + } + + @Test + public void testNullValueInIndexedField() { + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); + insert(); + + Document document = createDocument("firstName", null) + .put("lastName", "ln1") + .put("birthDay", null) + .put("data", new byte[]{1, 2, 3}) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) + .put("body", "a quick brown fox jump over the lazy dog"); + + collection.insert(document); + } + + @Test + public void testDropAllAndCreateIndex() { + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + collection.dropAllIndices(); + assertFalse(collection.hasIndex("firstName")); + + collection.createIndex("firstName"); + assertTrue(collection.hasIndex("firstName")); + + collection = db.getCollection("test"); + assertTrue(collection.hasIndex("firstName")); + } + + @Test + public void testIssue178() { + collection.dropAllIndices(); + collection.remove(Filter.ALL); + + Document doc1 = createDocument("field", 5); + Document doc2 = createDocument("field", 4.3); + Document doc3 = createDocument("field", 0.03); + Document doc4 = createDocument("field", 4); + Document doc5 = createDocument("field", 5.0); + + collection.insert(doc1, doc2, doc3, doc4, doc5); + + DocumentCursor cursor = collection.find(where("field").eq(5)); + assertEquals(cursor.size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); + + cursor = collection.find(where("field").eq(5)); + assertEquals(cursor.size(), 1); + } + + @Test + public void testIndexEvent() { + NitriteCollection collection = db.getCollection("index-test"); + Random random = new Random(); + for (int i = 0; i < 10000; i++) { + Document document = createDocument("first", random.nextInt()) + .put("second", random.nextDouble()); + collection.insert(document); + } + + collection.subscribe(eventInfo -> { + switch (eventInfo.getEventType()) { + case Insert: + fail("wrong event Insert"); + break; + case Update: + fail("wrong event Update"); + break; + case Remove: + fail("wrong event Remove"); + break; + case IndexStart: + case IndexEnd: + break; + } + assertTrue(eventInfo.getItem() instanceof String); + System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); + }); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); + assertEquals(collection.find().size(), 10000); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); + assertEquals(collection.find().size(), 10000); + } + + @Test + public void testIndexAndSearchOnNullValues() { + NitriteCollection collection = db.getCollection("index-on-null"); + collection.insert(createDocument("first", null).put("second", 123).put("third", new Integer[]{1, 2, null})); + collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); + collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); + + collection.createIndex("first"); + assertEquals(collection.find(where("first").eq(null)).size(), 1); + + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); + assertEquals(collection.find(where("third").eq(null)).size(), 2); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java similarity index 85% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java index e737708ab..02358caf6 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertNegativeTest.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.UniqueConstraintException; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java similarity index 90% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java index 93ef729ac..cd9558946 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionInsertTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionInsertTest.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.collection.Document.createDocument; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionJoinTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java similarity index 94% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionJoinTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java index c5f24ac93..caff44d61 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionJoinTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionJoinTest.java @@ -1,27 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Before; import org.junit.Test; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java new file mode 100644 index 000000000..b459e469b --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.index.IndexType; +import org.junit.Test; + +import static org.dizitart.no2.index.IndexOptions.indexOptions; +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee. + */ +public class CollectionSingleFieldIndexNegativeTest extends BaseCollectionTest { + + @Test(expected = UniqueConstraintException.class) + public void testCreateInvalidUniqueIndex() { + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "lastName"); + assertTrue(collection.hasIndex("lastName")); + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateIndexOnArray() { + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "data"); + assertTrue(collection.hasIndex("data")); + // data array field has repetition, so unique constraint exception + insert(); + } + + @Test(expected = UniqueConstraintException.class) + public void testCreateOnInvalidField() { + insert(); + // multiple null value will be created + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "my-value"); + assertTrue(collection.hasIndex("my-value")); + } + + @Test(expected = IndexingException.class) + public void testCreateFullTextOnNonTextField() { + insert(); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "birthDay"); + assertTrue(collection.hasIndex("birthDay")); + } + + @Test(expected = IndexingException.class) + public void testDropIndexOnNonIndexedField() { + collection.dropIndex("data"); + } + + @Test(expected = IndexingException.class) + public void testRebuildIndexInvalid() { + collection.rebuildIndex("unknown"); + } + + @Test(expected = IndexingException.class) + public void createMultipleIndexTypeOnSameField() { + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java similarity index 65% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java index 84994ee00..fe37845e1 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java @@ -1,22 +1,22 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; -import com.google.common.collect.Lists; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; @@ -25,12 +25,13 @@ import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.junit.Test; +import java.util.ArrayList; import java.util.Collection; import java.util.Random; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; import static org.awaitility.Awaitility.await; import static org.dizitart.no2.collection.Document.createDocument; @@ -41,20 +42,20 @@ /** * @author Anindya Chatterjee. */ -public class CollectionIndexTest extends BaseCollectionTest { +public class CollectionSingleFieldIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); - collection.createIndex("birthDay", null); + collection.createIndex("birthDay"); assertTrue(collection.hasIndex("birthDay")); insert(); @@ -64,13 +65,13 @@ public void testCreateIndex() { public void testListIndexes() { assertEquals(collection.listIndices().size(), 0); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); assertEquals(collection.listIndices().size(), 3); @@ -78,7 +79,7 @@ public void testListIndexes() { @Test public void testDropIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropIndex("firstName"); @@ -99,18 +100,18 @@ public void testDropAllIndexes() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); assertFalse(collection.hasIndex("body")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); } @Test public void testDeleteWithIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); @@ -127,53 +128,29 @@ public void testDeleteWithIndex() { assertEquals(cursor.size(), 1); } - @Test - public void testCreateIndexAsync() { - insert(); - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); - assertTrue(collection.isIndexing("body")); - - await().until(bodyIndexingCompleted()); - } - @Test public void testRebuildIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - insert(); - Collection indices = collection.listIndices(); - for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), false); - } - } - - @Test - public void testRebuildIndexAsync() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); - await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), true); - await().until(bodyIndexingCompleted()); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); } } @Test public void testRebuildIndexOnRunningIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexDescriptor idx = indices.iterator().next(); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex("body"); boolean error = false; try { - collection.rebuildIndex(idx.getIndexFields(), true); + collection.rebuildIndex("body"); } catch (IndexingException ie) { error = true; } finally { - assertTrue(error); + assertFalse(error); await().until(bodyIndexingCompleted()); } } @@ -184,15 +161,19 @@ private Callable bodyIndexingCompleted() { @Test public void testNullValueInIndexedField() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("birthDay", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); insert(); Document document = createDocument("firstName", null) .put("lastName", "ln1") .put("birthDay", null) .put("data", new byte[]{1, 2, 3}) - .put("list", Lists.newArrayList("one", "two", "three")) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) .put("body", "a quick brown fox jump over the lazy dog"); collection.insert(document); @@ -200,12 +181,12 @@ public void testNullValueInIndexedField() { @Test public void testDropAllAndCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropAllIndices(); assertFalse(collection.hasIndex("firstName")); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection = db.getCollection("test"); @@ -228,7 +209,7 @@ public void testIssue178() { DocumentCursor cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); - collection.createIndex("field", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); @@ -244,30 +225,30 @@ public void testIndexEvent() { collection.insert(document); } + AtomicBoolean failed = new AtomicBoolean(false); + AtomicBoolean completed = new AtomicBoolean(false); collection.subscribe(eventInfo -> { switch (eventInfo.getEventType()) { case Insert: - fail("wrong event Insert"); - break; - case Update: - fail("wrong event Update"); - break; case Remove: - fail("wrong event Remove"); + case Update: + failed.set(true); break; case IndexStart: case IndexEnd: + completed.set(true); break; } - assertTrue(eventInfo.getItem() instanceof String); - System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); }); - collection.createIndex("first", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); assertEquals(collection.find().size(), 10000); - collection.createIndex("second", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); assertEquals(collection.find().size(), 10000); + + await().until(completed::get); + assertFalse(failed.get()); } @Test @@ -277,10 +258,17 @@ public void testIndexAndSearchOnNullValues() { collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); - collection.createIndex("first", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.UNIQUE), "first"); assertEquals(collection.find(where("first").eq(null)).size(), 1); - collection.createIndex("third", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } + + @Test + public void testCreateCompoundAndSingleFieldIndexOnSameField() { + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionUpdateTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java similarity index 95% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionUpdateTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java index ed9e2f18c..86bff59b5 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionUpdateTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/CollectionUpdateTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -25,14 +26,11 @@ import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.exceptions.UniqueConstraintException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.common.util.DocumentUtils.isSimilar; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.index.IndexOptions.indexOptions; import static org.junit.Assert.*; public class CollectionUpdateTest extends BaseCollectionTest { @@ -246,7 +244,7 @@ public void testRegisterListenerAfterDrop() { } @Test(expected = NitriteIOException.class) - public void testRegisterListenerAfterClose() { + public void testRegisterListenerAfterClose() throws Exception { NitriteCollection collection = db.getCollection("test"); collection.close(); collection.subscribe(changeInfo -> fail("should not happen")); @@ -259,7 +257,7 @@ public void testIssue151() { NitriteCollection coll = db.getCollection("test"); coll.insert(doc1, doc2); - coll.createIndex("fruit", indexOptions(IndexType.Unique)); + coll.createIndex("fruit"); assertEquals(coll.find(where("fruit").eq("Apple")).size(), 1); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java new file mode 100644 index 000000000..0055f97ac --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/FieldProcessorTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.collection; + +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseCollectionTest { + + private Encryptor encryptor; + private NitriteCollection collection; + private Processor cvvProcessor; + + @Before + public void setUp() { + super.setUp(); + + encryptor = new AESEncryptor("s3k4e8"); + cvvProcessor = new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String cvv = document.get("cvv", String.class); + String encryptedCvv = encryptor.encrypt(cvv.getBytes(StandardCharsets.UTF_8)); + document.put("cvv", encryptedCvv); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCvv = document.get("cvv", String.class); + String cvv = encryptor.decrypt(encryptedCvv); + document.put("cvv", cvv); + return document; + } + }; + StringFieldEncryptionProcessor creditCardProcessor = new StringFieldEncryptionProcessor(encryptor); + creditCardProcessor.addFields("creditCardNumber"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(creditCardProcessor); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.addProcessor(cvvProcessor); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = collection.getStore().openMap("encryption-test", + NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + Document document = collection.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5500960345687452"); + assertEquals(document.get("cvv", String.class), "008"); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "5548960345687452"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + Encryptor wrongEncryptor = new AESEncryptor("secret"); + + collection = db.getCollection("encryption-test"); + collection.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "5548960345687452") + .put("cvv", "007") + .put("expiryDate", new Date()); + collection.insert(document); + + document = Document.createDocument("name", "Jane Doe") + .put("creditCardNumber", "5500960345687452") + .put("cvv", "008") + .put("expiryDate", new Date()); + collection.insert(document); + + collection.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testUpdateEncryptedField() { + Document document = Document.createDocument("name", "John Doe") + .put("creditCardNumber", "00000000000000") + .put("cvv", "007") + .put("expiryDate", new Date()); + + WriteResult writeResult = collection.update(where("name").eq("John Doe"), document); + assertEquals(writeResult.getAffectedCount(), 1); + + document = collection.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(document); + + assertEquals(document.get("creditCardNumber", String.class), "00000000000000"); + assertEquals(document.get("cvv", String.class), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + collection.createIndex("cvv"); + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + } + + @Test + public void testRemoveProcessor() { + Document document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNull(document); + + collection.removeProcessor(cvvProcessor); + + document = collection.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(document); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/NitriteCollectionTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java similarity index 63% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/NitriteCollectionTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java index 16ddfcf9b..ad3534435 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/NitriteCollectionTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/collection/NitriteCollectionTest.java @@ -1,44 +1,35 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.integration.collection; -import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.mapdb.Retry; -import org.junit.After; -import org.junit.Rule; import org.junit.Test; -import static org.dizitart.no2.mapdb.TestUtil.createDb; import static org.junit.Assert.assertEquals; /** * @author Anindya Chatterjee */ -public class NitriteCollectionTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); +public class NitriteCollectionTest extends BaseCollectionTest { @Test public void testAttributes() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); Attributes attributes = new Attributes("test"); @@ -46,11 +37,4 @@ public void testAttributes() { assertEquals(collection.getAttributes(), attributes); } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/EventTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/EventTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java index 83ad508d6..95baec828 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/common/event/EventTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/EventTest.java @@ -1,27 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.common.event; +package org.dizitart.no2.integration.event; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.Employee; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.events.EventType; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.rocksdb.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.rocksdb.RocksDBModule; -import org.dizitart.no2.rocksdb.repository.data.Employee; +import org.dizitart.no2.integration.repository.data.Employee; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -39,8 +42,8 @@ import static org.awaitility.Awaitility.await; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -57,6 +60,8 @@ public class EventTest { private ObjectRepository employeeRepository; private SampleListenerCollection listener; + @Rule + public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Protected = {0}") public static Collection data() { return Arrays.asList(new Object[][]{ @@ -65,9 +70,6 @@ public static Collection data() { }); } - @Rule - public Retry retry = new Retry(3); - @Before public void setUp() { RocksDBModule storeModule = RocksDBModule.withConfig() @@ -86,14 +88,9 @@ public void setUp() { .openOrCreate(); } - try { - employeeRepository = db.getRepository(Employee.class); - listener = new SampleListenerCollection(); - employeeRepository.subscribe(listener); - } catch (Exception e) { - System.out.println("NitriteConfig - " + db.getConfig()); - throw e; - } + employeeRepository = db.getRepository(Employee.class); + listener = new SampleListenerCollection(); + employeeRepository.subscribe(listener); } @Test @@ -208,7 +205,7 @@ public void testSingleEventListener() { e.setAddress("abcd"); employeeRepository.insert(e); - await().atMost(2, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); + await().atMost(1, TimeUnit.SECONDS).until(listenerPrepared(EventType.Insert)); assertEquals(count.get(), 1); } @@ -228,7 +225,7 @@ public void clear() throws IOException { db.close(); } - deleteFile(fileName); + deleteDb(fileName); } private Callable listenerPrepared(final EventType action) { diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/SampleListenerCollection.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java similarity index 87% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/SampleListenerCollection.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java index 1089753cf..6297ecbc1 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/common/event/SampleListenerCollection.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/event/SampleListenerCollection.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.common.event; +package org.dizitart.no2.integration.event; import lombok.Getter; import org.dizitart.no2.collection.events.CollectionEventInfo; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java similarity index 93% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java index 5bea38957..cb6128ba7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/MigrationTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/MigrationTest.java @@ -1,32 +1,46 @@ -package org.dizitart.no2.rocksdb.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import com.github.javafaker.Faker; -import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.Constants; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.MigrationException; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.migration.Instructions; import org.dizitart.no2.migration.Migration; import org.dizitart.no2.migration.TypeConverter; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.rocksdb.Retry; import org.dizitart.no2.rocksdb.RocksDBModule; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import java.io.File; -import java.io.IOException; import java.util.UUID; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.*; /** @@ -47,12 +61,12 @@ public void setUp() { } @After - public void cleanUp() throws IOException { + public void cleanUp() { if (!db.isClosed()) { db.close(); } - FileUtils.deleteDirectory(new File(dbPath)); + deleteDb(dbPath); } @Test @@ -84,7 +98,7 @@ public void migrate(Instructions instruction) { instruction.forRepository(OldClass.class, "demo1") .renameRepository("new", null) .changeDataType("empId", (TypeConverter) Long::parseLong) - .changeIdField("uuid", "empId") + .changeIdField(Fields.withNames("uuid"), Fields.withNames("empId")) .deleteField("uuid") .renameField("lastName", "familyName") .addField("fullName", document -> document.get("firstName", String.class) + " " @@ -127,8 +141,8 @@ public void testCollectionMigrate() { collection.insert(document); } - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("bloodGroup", IndexOptions.indexOptions(IndexType.NonUnique)); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "bloodGroup"); db.close(); Migration migration = new Migration(Constants.INITIAL_SCHEMA_VERSION, 2) { @@ -174,7 +188,7 @@ public void migrate(Instructions instructions) { .addField("address") .addField("vehicles", 1) .renameField("age", "ageGroup") - .createIndex("ageGroup", IndexType.NonUnique); + .createIndex(IndexType.NON_UNIQUE, "ageGroup"); } }; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java similarity index 69% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java index 87475198a..56ef25c22 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/NewClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/NewClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.rocksdb.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -14,9 +31,9 @@ */ @Data @Entity(value = "new", indices = { - @Index(value = "familyName", type = IndexType.NonUnique), - @Index(value = "fullName", type = IndexType.NonUnique), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "familyName", type = IndexType.NON_UNIQUE), + @Index(value = "fullName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class NewClass implements Mappable { @Id diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java similarity index 67% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java index 7827330dd..3bbb09b4e 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/migrate/OldClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/migrate/OldClass.java @@ -1,4 +1,21 @@ -package org.dizitart.no2.rocksdb.migrate; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.migrate; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -14,10 +31,10 @@ */ @Data @Entity(value = "old", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), - @Index(value = "literature.text", type = IndexType.Fulltext), - @Index(value = "literature.ratings", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), + @Index(value = "literature.text", type = IndexType.FULL_TEXT), + @Index(value = "literature.ratings", type = IndexType.NON_UNIQUE), }) public class OldClass implements Mappable { @Id diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/BaseObjectRepositoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java similarity index 76% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/BaseObjectRepositoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java index 80df40433..ae5716ff0 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/BaseObjectRepositoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/BaseObjectRepositoryTest.java @@ -1,40 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.rocksdb.Retry; import org.dizitart.no2.rocksdb.RocksDBModule; -import org.dizitart.no2.rocksdb.repository.data.*; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; import java.util.Arrays; import java.util.Collection; import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; @RunWith(value = Parameterized.class) public abstract class BaseObjectRepositoryTest { @@ -42,12 +42,16 @@ public abstract class BaseObjectRepositoryTest { public boolean isProtected = false; protected Nitrite db; - ObjectRepository companyRepository; - ObjectRepository employeeRepository; - ObjectRepository aObjectRepository; - ObjectRepository cObjectRepository; + protected ObjectRepository companyRepository; + protected ObjectRepository employeeRepository; + protected ObjectRepository aObjectRepository; + protected ObjectRepository cObjectRepository; + protected ObjectRepository bookRepository; + private final String fileName = getRandomTempDbFile(); + @Rule + public Retry retry = new Retry(3); @Parameterized.Parameters(name = "Protected = {0}") public static Collection data() { return Arrays.asList(new Object[][]{ @@ -56,9 +60,6 @@ public static Collection data() { }); } - @Rule - public Retry retry = new Retry(3); - @Before public void setUp() { openDb(); @@ -69,6 +70,8 @@ public void setUp() { aObjectRepository = db.getRepository(ClassA.class); cObjectRepository = db.getRepository(ClassC.class); + bookRepository = db.getRepository(Book.class); + for (int i = 0; i < 10; i++) { Company company = DataGenerator.generateCompanyRecord(); companyRepository.insert(company); @@ -78,6 +81,9 @@ public void setUp() { aObjectRepository.insert(ClassA.create(i + 50)); cObjectRepository.insert(ClassC.create(i + 30)); + + Book book = DataGenerator.randomBook(); + bookRepository.insert(book); } } @@ -98,7 +104,7 @@ protected void openDb() { } @After - public void clear() throws IOException { + public void clear() throws Exception { if (companyRepository != null && !companyRepository.isDropped()) { companyRepository.remove(ALL); } @@ -115,11 +121,15 @@ public void clear() throws IOException { cObjectRepository.remove(ALL); } + if (bookRepository != null && !bookRepository.isDropped()) { + bookRepository.remove(ALL); + } + if (db != null && !db.isClosed()) { db.commit(); db.close(); } - deleteFile(fileName); + deleteDb(fileName); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java index 3ef5b97f3..a89c10612 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/CustomFieldSeparatorTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -23,29 +24,28 @@ import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.Company; +import org.dizitart.no2.integration.repository.data.Note; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.dizitart.no2.rocksdb.Retry; import org.dizitart.no2.rocksdb.RocksDBModule; -import org.dizitart.no2.rocksdb.repository.data.Company; -import org.dizitart.no2.rocksdb.repository.data.Note; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.io.Serializable; import java.util.Date; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; /** @@ -74,10 +74,12 @@ public void setUp() { } @After - public void reset() throws IOException { + public void reset() { (new NitriteConfig()).fieldSeparator("."); - db.close(); - deleteFile(fileName); + if (db != null && !db.isClosed()) { + db.close(); + deleteDb(fileName); + } } @Test @@ -115,9 +117,9 @@ public void testFindByEmbeddedField() { @ToString @EqualsAndHashCode @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote:text", type = IndexType.Fulltext) + @Index(value = "joinDate", type = IndexType.NON_UNIQUE), + @Index(value = "address", type = IndexType.FULL_TEXT), + @Index(value = "employeeNote:text", type = IndexType.FULL_TEXT) }) public static class EmployeeForCustomSeparator implements Serializable, Mappable { @Id diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java new file mode 100644 index 000000000..73a093082 --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/FieldProcessorTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.integration.repository.data.EncryptedPerson; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.common.crypto.AESEncryptor; +import org.dizitart.no2.common.crypto.Encryptor; +import org.dizitart.no2.common.processors.Processor; +import org.dizitart.no2.common.processors.StringFieldEncryptionProcessor; +import org.dizitart.no2.exceptions.NitriteSecurityException; +import org.dizitart.no2.repository.ObjectRepository; +import org.dizitart.no2.store.NitriteMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +import static org.dizitart.no2.common.util.Iterables.toList; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class FieldProcessorTest extends BaseObjectRepositoryTest { + private ObjectRepository persons; + private StringFieldEncryptionProcessor fieldProcessor; + + @Before + public void setUp() { + super.setUp(); + persons = db.getRepository(EncryptedPerson.class); + fieldProcessor = new StringFieldEncryptionProcessor("s3k4e8"); + fieldProcessor.addFields("creditCardNumber", "cvv"); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + persons.insert(person); + + persons.addProcessor(fieldProcessor); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + persons.insert(person); + } + + @Test + public void testFieldEncryptionInNitriteMap() { + NitriteMap nitriteMap = persons.getDocumentCollection().getStore() + .openMap(findRepositoryName(EncryptedPerson.class, null), NitriteId.class, Document.class); + + List documents = toList(nitriteMap.values()); + for (Document document : documents) { + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5548960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("creditCardNumber", String.class).equalsIgnoreCase("5500960345687452")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("008")) { + Assert.fail("unencrypted secret text found"); + } + + if (document.get("cvv", String.class).equalsIgnoreCase("007")) { + Assert.fail("unencrypted secret text found"); + } + } + } + + @Test + public void testSuccessfulDecryption() { + EncryptedPerson person = persons.find(where("name").eq("Jane Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5500960345687452"); + assertEquals(person.getCvv(), "008"); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "5548960345687452"); + assertEquals(person.getCvv(), "007"); + } + + @Test(expected = NitriteSecurityException.class) + public void testFailedDecryption() { + ObjectRepository testPersons = db.getRepository(EncryptedPerson.class, "test"); + + Encryptor encryptor = new AESEncryptor("secret"); + Encryptor wrongEncryptor = new AESEncryptor("secret", "AES/GCM/NoPadding", + 5, 5, 5); + + testPersons.addProcessor(new Processor() { + @Override + public Document processBeforeWrite(Document document) { + String creditCardNumber = document.get("creditCardNumber", String.class); + String encryptedCreditCardNumber = encryptor.encrypt(creditCardNumber.getBytes(StandardCharsets.UTF_8)); + document.put("creditCardNumber", encryptedCreditCardNumber); + return document; + } + + @Override + public Document processAfterRead(Document document) { + String encryptedCreditCardNumber = document.get("creditCardNumber", String.class); + String creditCardNumber = wrongEncryptor.decrypt(encryptedCreditCardNumber); + document.put("creditCardNumber", creditCardNumber); + return document; + } + }); + + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("5548960345687452"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + testPersons.insert(person); + + person = new EncryptedPerson(); + person.setName("Jane Doe"); + person.setCreditCardNumber("5500960345687452"); + person.setCvv("008"); + person.setExpiryDate(new Date()); + testPersons.insert(person); + + testPersons.find(where("name").eq("Jane Doe")).firstOrNull(); + } + + @Test + public void testSearchOnEncryptedField() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testUpdateEncryptedField() { + EncryptedPerson person = new EncryptedPerson(); + person.setName("John Doe"); + person.setCreditCardNumber("00000000000000"); + person.setCvv("007"); + person.setExpiryDate(new Date()); + + WriteResult writeResult = persons.update(where("name").eq("John Doe"), person); + assertEquals(writeResult.getAffectedCount(), 1); + + person = persons.find(where("name").eq("John Doe")).firstOrNull(); + assertNotNull(person); + + assertEquals(person.getCreditCardNumber(), "00000000000000"); + assertEquals(person.getCvv(), "007"); + } + + @Test + public void testIndexOnEncryptedField() { + persons.createIndex("cvv"); + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + } + + @Test + public void testRemoveProcessor() { + EncryptedPerson person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNull(person); + + persons.removeProcessor(fieldProcessor); + + person = persons.find(where("cvv").eq("008")).firstOrNull(); + assertNotNull(person); + + person = persons.find(where("creditCardNumber").eq("5548960345687452")).firstOrNull(); + assertNotNull(person); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java index 1c22f544e..1a52708ce 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/InternalClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/InternalClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; import org.dizitart.no2.collection.Document; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java similarity index 83% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java index 777b3a7d3..dedd5e256 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/NitriteIdAsIdTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/NitriteIdAsIdTest.java @@ -1,39 +1,41 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.WithNitriteId; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.util.Iterables; import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.repository.data.WithNitriteId; +import org.dizitart.no2.integration.TestUtil; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -57,7 +59,7 @@ public void before() { @After public void after() throws IOException { db.close(); - Files.delete(Paths.get(fileName)); + deleteDb(fileName); } @Test diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectCursorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java similarity index 87% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectCursorTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java index 73a652dce..5be20ded7 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectCursorTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectCursorTest.java @@ -1,23 +1,24 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.Employee; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapdb.repository.data.Employee; import org.dizitart.no2.repository.Cursor; import org.junit.Test; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java similarity index 83% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java index ad97d8385..e070d485d 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ObjectRepositoryNegativeTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryNegativeTest.java @@ -1,39 +1,40 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; -import org.dizitart.no2.TestUtil; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.exceptions.*; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.integration.TestUtil; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import static org.dizitart.no2.DbTestOperations.getRandomTempDbFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -55,7 +56,7 @@ public void setUp() { public void close() throws IOException { db.close(); db = null; - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } @Test(expected = ObjectMappingException.class) @@ -131,7 +132,7 @@ public void testFindResultRemove() { result.iterator().remove(); } - @Test(expected = InvalidOperationException.class) + @Test(expected = IndexingException.class) public void testWithObjectId() { ObjectRepository repository = db.getRepository(WithObjectId.class); WithOutId id = new WithOutId(); @@ -208,4 +209,25 @@ public void testExternalNitriteId() { result = repository.update(obj, true); assertNotEquals(id.getIdValue(), result.iterator().next().getIdValue()); } + + @Test(expected = IndexingException.class) + public void testWithoutEmbeddedId() { + ObjectRepository repository = db.getRepository(WithoutEmbeddedId.class); + assertNull(repository); + } + + @Test(expected = InvalidIdException.class) + public void testGetByWrongIdType() { + ObjectRepository repository = db.getRepository(WithPublicField.class); + WithPublicField object = new WithPublicField(); + object.name = "test"; + object.number = 2; + + repository.insert(object); + + NitriteId id = NitriteId.createId("1"); + WithPublicField instance = repository.getById(id); + assertEquals(object.name, instance.name); + assertEquals(object.number, instance.number); + } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java similarity index 91% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index 86e230db7..4fd11a005 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/ObjectRepositoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; import com.github.javafaker.Faker; import lombok.Data; @@ -22,36 +23,35 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.repository.data.*; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.MappableMapper; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.ValidationException; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Entity; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; +import org.dizitart.no2.rocksdb.RocksDBModule; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Date; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; import static org.dizitart.no2.common.module.NitriteModule.module; +import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.*; /** @@ -67,7 +67,7 @@ public class ObjectRepositoryTest { @Before public void setUp() { NitriteMapper mapper = new MappableMapper(); - MapDBModule storeModule = MapDBModule.withConfig() + RocksDBModule storeModule = RocksDBModule.withConfig() .filePath(dbPath) .build(); @@ -82,7 +82,7 @@ public void setUp() { public void close() throws IOException { db.close(); db = null; - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } @Test @@ -166,7 +166,7 @@ public void testWithTransientField() { @Test public void testWriteThousandRecords() { - int count = 1000; + int count = 5000; ObjectRepository repository = db.getRepository(StressRecord.class); @@ -182,6 +182,7 @@ public void testWriteThousandRecords() { Cursor cursor = repository.find(where("failed").eq(false)); + for (StressRecord record : cursor) { record.setProcessed(true); repository.update(where("firstName").eq(record.getFirstName()), record); @@ -307,12 +308,12 @@ public void testKeyedRepository() { assertEquals(db.listRepositories().size(), 1); assertEquals(db.listKeyedRepository().size(), 2); - assertEquals(employeeRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(employeeRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(managerRepo.find(where("address").eq("xyz")).size(), 0); - assertEquals(managerRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("abcd")).size(), 0); + assertEquals(employeeRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(employeeRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(managerRepo.find(where("address").text("xyz")).size(), 0); + assertEquals(managerRepo.find(where("address").text("abcd")).size(), 1); + assertEquals(developerRepo.find(where("address").text("xyz")).size(), 1); + assertEquals(developerRepo.find(where("address").text("abcd")).size(), 0); } @Test @@ -359,8 +360,8 @@ public void testIssue217() { @Data @Entity(value = "entity.employee", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), }) private static class EmployeeEntity implements Mappable { private static final Faker faker = new Faker(); diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ProjectionTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java similarity index 82% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ProjectionTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java index 30c7d27e9..c6a85b0a3 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/ProjectionTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/ProjectionTest.java @@ -1,28 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.repository.data.SubEmployee; import org.junit.Test; import java.util.Iterator; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.junit.Assert.*; /** @@ -32,28 +34,28 @@ public class ProjectionTest extends BaseObjectRepositoryTest { @Test public void testHasMore() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertFalse(iterable.isEmpty()); } @Test public void testSize() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertEquals(iterable.size(), 5); } @Test public void testToString() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); assertNotNull(iterable.toString()); } @Test(expected = InvalidOperationException.class) public void testRemove() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) + RecordStream iterable = employeeRepository.find(skipBy(0).limit(5)) .project(SubEmployee.class); Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java new file mode 100644 index 000000000..9431d991e --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryCompoundIndexTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository; + +import org.dizitart.no2.integration.repository.data.Book; +import org.dizitart.no2.integration.repository.data.BookId; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +/** + * @author Anindya Chatterjee + */ +public class RepositoryCompoundIndexTest extends BaseObjectRepositoryTest { + + @Test + public void testFindById() { + BookId bookId = new BookId(); + bookId.setAuthor("John Doe"); + bookId.setIsbn("123456"); + bookId.setName("Nitrite Database"); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription("Some random book description"); + book.setPrice(22.56); + book.setPublisher("My Publisher House"); + book.setTags(Arrays.asList("database", "nosql")); + + bookRepository.insert(book); + + Book bookById = bookRepository.getById(bookId); + assertEquals(bookById, book); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java similarity index 79% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java index 7f099ec98..3c89260ac 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryFactoryTest.java @@ -1,42 +1,45 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.*; import org.dizitart.no2.collection.events.CollectionEventListener; import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.common.concurrent.LockService; +import org.dizitart.no2.common.processors.Processor; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.mapdb.Retry; -import org.dizitart.no2.mapdb.TestUtil; +import org.dizitart.no2.integration.Retry; +import org.dizitart.no2.integration.TestUtil; import org.dizitart.no2.repository.RepositoryFactory; import org.dizitart.no2.store.NitriteStore; import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.util.Collection; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertNotNull; /** @@ -44,10 +47,16 @@ */ public class RepositoryFactoryTest { private Nitrite db; + private final String fileName = getRandomTempDbFile(); @Rule public Retry retry = new Retry(3); + @Before + public void setUp() { + db = TestUtil.createDb(fileName); + } + @Test public void testRepositoryFactory() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); @@ -57,14 +66,12 @@ public void testRepositoryFactory() { @Test(expected = ValidationException.class) public void testNullType() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); factory.getRepository(db.getConfig(), null, "dummy"); } @Test public void testNullCollection() { RepositoryFactory factory = new RepositoryFactory(new CollectionFactory(new LockService())); - db = TestUtil.createDb(); factory.getRepository(db.getConfig(), DummyCollection.class, null); } @@ -75,14 +82,20 @@ public void testNullContext() { } @After - public void cleanUp() { + public void cleanUp() throws Exception { if (db != null && !db.isClosed()) { db.close(); } + TestUtil.deleteDb(fileName); } private static class DummyCollection implements NitriteCollection { + @Override + public WriteResult insert(Document document, Document... documents) { + return null; + } + @Override public WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) { return null; @@ -93,6 +106,16 @@ public WriteResult remove(Filter filter, boolean justOne) { return null; } + @Override + public DocumentCursor find() { + return null; + } + + @Override + public DocumentCursor find(Filter filter) { + return null; + } + @Override public DocumentCursor find(Filter filter, FindOptions findOptions) { return null; @@ -109,22 +132,22 @@ public String getName() { } @Override - public void createIndex(String field, IndexOptions indexOptions) { + public void addProcessor(Processor processor) { } @Override - public void createIndex(Fields fields, IndexOptions indexOptions) { + public void removeProcessor(Processor processor) { } @Override - public void rebuildIndex(String field) { + public void createIndex(IndexOptions indexOptions, String... fields) { } @Override - public void rebuildIndex(Fields fields) { + public void rebuildIndex(String... fields) { } @@ -134,32 +157,17 @@ public Collection listIndices() { } @Override - public boolean hasIndex(String field) { + public boolean hasIndex(String... fields) { return false; } @Override - public boolean hasIndex(Fields fields) { + public boolean isIndexing(String... fields) { return false; } @Override - public boolean isIndexing(String field) { - return false; - } - - @Override - public boolean isIndexing(Fields fields) { - return false; - } - - @Override - public void dropIndex(String field) { - - } - - @Override - public void dropIndex(Fields fields) { + public void dropIndex(String... fields) { } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java similarity index 75% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java index a231048d7..4dacdbff8 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryJoinTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryJoinTest.java @@ -1,81 +1,53 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; import lombok.Data; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.mapdb.MapDBModule; -import org.dizitart.no2.mapdb.MapDBModuleBuilder; -import org.dizitart.no2.mapdb.Retry; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Id; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.collection.FindOptions.skipBy; import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; import static org.junit.Assert.*; /** * @author Anindya Chatterjee */ -@RunWith(value = Parameterized.class) -public class RepositoryJoinTest { - @Parameterized.Parameter - public boolean inMemory = false; - @Parameterized.Parameter(value = 1) - public boolean isProtected = false; - - protected Nitrite db; - private final String fileName = getRandomTempDbFile(); +public class RepositoryJoinTest extends BaseObjectRepositoryTest { private ObjectRepository personRepository; private ObjectRepository
    addressRepository; - @Rule - public Retry retry = new Retry(3); - - @Parameterized.Parameters(name = "InMemory = {0}, Protected = {1}") - public static Collection data() { - return Arrays.asList(new Object[][]{ - {false, false}, - {false, true}, - {true, false}, - {true, true}, - }); - } - @Before public void setUp() { openDb(); @@ -103,27 +75,8 @@ public void setUp() { } } - private void openDb() { - MapDBModuleBuilder builder = MapDBModule.withConfig(); - - if (!inMemory) { - builder.filePath(fileName); - } - - MapDBModule storeModule = builder.build(); - NitriteBuilder nitriteBuilder = Nitrite.builder() - .fieldSeparator(".") - .loadModule(storeModule); - - if (isProtected) { - db = nitriteBuilder.openOrCreate("test-user1", "test-password1"); - } else { - db = nitriteBuilder.openOrCreate(); - } - } - @After - public void clear() throws IOException { + public void clear() throws Exception { if (personRepository != null && !personRepository.isDropped()) { personRepository.remove(ALL); } @@ -132,14 +85,7 @@ public void clear() throws IOException { addressRepository.remove(ALL); } - if (db != null) { - db.commit(); - db.close(); - } - - if (!inMemory) { - Files.delete(Paths.get(fileName)); - } + super.clear(); } @Test @@ -164,7 +110,7 @@ public void testJoin() { } } - result = personRepository.find().skipLimit(0, 5).join(addressRepository.find(), lookup, + result = personRepository.find(skipBy(0).limit(5)).join(addressRepository.find(), lookup, PersonDetails.class); assertEquals(result.size(), 5); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java similarity index 91% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index 023f1269b..d5bd0f5cb 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/RepositoryModificationTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.WriteResult; @@ -25,7 +27,6 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.repository.data.*; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; @@ -52,18 +53,19 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); - companyRepository.rebuildIndex("dateCreated", true); - assertTrue(companyRepository.isIndexing("dateCreated")); + companyRepository.rebuildIndex("dateCreated"); + // rebuild is sync + assertFalse(companyRepository.isIndexing("dateCreated")); await().until(() -> !companyRepository.isIndexing("dateCreated")); } @@ -73,7 +75,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex("dateCreated", IndexOptions.indexOptions(IndexType.NonUnique)); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } @@ -193,7 +195,7 @@ public void testUpdateWithJustOnceFalse() throws ParseException { @Test public void testUpsertTrue() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -218,7 +220,7 @@ public void testUpsertTrue() { @Test public void testUpsertFalse() { Date joiningDate = new Date(); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 0); Employee employee = new Employee(); @@ -245,7 +247,7 @@ public void testDeleteFilterAndWithOutOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate)); @@ -259,7 +261,7 @@ public void testDeleteFilterAndWithOption() { Date joiningDate = new Date(); prepareUpdateWithOptions(joiningDate); - Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); + Cursor result = employeeRepository.find(where("joinDate").eq(joiningDate)); assertEquals(result.size(), 2); WriteResult writeResult = employeeRepository.remove(where("joinDate").eq(joiningDate), true); @@ -278,7 +280,7 @@ public void testEmployeeRecord() { } } - Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); + Cursor cursor = employeeRepository.find(where("employeeNote.text").text("Class aptent")); assertEquals(cursor.size(), occurrence); } @@ -630,4 +632,26 @@ public void testUpdateObjectExistsUpsertFalse() { assertEquals(repo.find().firstOrNull().getId(), 1); assertEquals(repo.find().firstOrNull().getName(), "second"); } + + @Test + public void testNestedUpdate() { + Employee employee = employeeRepository.getById(1L); + assertNotNull(employee); + + Note note = employee.getEmployeeNote(); + String text = note.getText(); + assertNotNull(text); + + Document update = createDocument("employeeNote.text", "some updated text"); + WriteResult writeResult = employeeRepository.update(where("empId").eq(1L), update, true); + assertEquals(1, writeResult.getAffectedCount()); + + employee = employeeRepository.getById(1L); + assertNotNull(employee); + + note = employee.getEmployeeNote(); + assertNotNull(note); + assertNotEquals(text, note.getText()); + assertEquals("some updated text", note.getText()); + } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java index 89dae378f..68015c9f3 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/RepositorySearchTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java @@ -1,31 +1,34 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; import lombok.Getter; +import org.dizitart.no2.integration.repository.data.*; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.SortOrder; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.NotIdentifiableException; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.data.*; +import org.dizitart.no2.repository.Cursor; +import org.dizitart.no2.repository.ObjectRepository; import org.junit.Test; import java.util.Calendar; @@ -33,7 +36,9 @@ import java.util.GregorianCalendar; import java.util.List; -import static org.dizitart.no2.filters.Filter.ALL; +import static org.dizitart.no2.collection.FindOptions.orderBy; +import static org.dizitart.no2.collection.FindOptions.skipBy; +import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.*; @@ -44,7 +49,7 @@ public class RepositorySearchTest extends BaseObjectRepositoryTest { @Test public void testFindWithOptions() { - Cursor cursor = employeeRepository.find().skipLimit(0, 1); + Cursor cursor = employeeRepository.find(skipBy(0).limit(1)); assertEquals(cursor.size(), 1); assertNotNull(cursor.firstOrNull()); } @@ -115,11 +120,8 @@ public void testGetByIdNoId() { Note n2 = DataGenerator.randomNote(); Note n3 = DataGenerator.randomNote(); - assert n1 != null; n1.setNoteId(1000000L); - assert n2 != null; n2.setNoteId(2000000L); - assert n3 != null; n3.setNoteId(3000000L); repository.insert(n1, n2, n3); @@ -214,12 +216,14 @@ public void testAndFilter() { String address = emp.getAddress(); Date joinDate = emp.getJoinDate(); - Employee employee = employeeRepository.find( - where("empId").eq(id) - .and( - where("address").regex(address) - .and( - where("joinDate").eq(joinDate)))).firstOrNull(); + Cursor cursor = employeeRepository.find( + and( + where("empId").eq(id), + where("address").regex(address), + where("joinDate").eq(joinDate) + ) + ); + Employee employee = cursor.firstOrNull(); assertEquals(emp, employee); } @@ -230,11 +234,11 @@ public void testOrFilter() { long id = emp.getEmpId(); Employee employee = employeeRepository.find( - where("empId").eq(id) - .or( - where("address").regex("n/a") - .or( - where("joinDate").eq(null)))).firstOrNull(); + or( + where("empId").eq(id), + where("address").text("n/a"), + where("joinDate").eq(null) + )).firstOrNull(); assertEquals(emp, employee); } @@ -251,7 +255,7 @@ public void testNotFilter() { @Test public void testGreaterFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gt(id)) @@ -263,7 +267,7 @@ public void testGreaterFilter() { @Test public void testGreaterEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Ascending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Ascending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").gte(id)) @@ -275,7 +279,7 @@ public void testGreaterEqualFilter() { @Test public void testLesserThanFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lt(id)) @@ -287,7 +291,7 @@ public void testLesserThanFilter() { @Test public void testLesserEqualFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").lte(id)) @@ -310,10 +314,11 @@ public void testTextFilter() { @Test public void testRegexFilter() { - RecordStream employees = employeeRepository.find(); + Cursor employees = employeeRepository.find(); int count = employees.toList().size(); - List employeeList = employeeRepository.find(where("employeeNote.text").regex(".*")) + List employeeList = employeeRepository.find(where("emailAddress") + .regex("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$")) .toList(); assertEquals(employeeList.size(), count); @@ -321,7 +326,7 @@ public void testRegexFilter() { @Test public void testInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").in(id, id - 1, id - 2)) @@ -336,7 +341,7 @@ public void testInFilter() { @Test public void testNotInFilter() { - Employee emp = employeeRepository.find().sort("empId", SortOrder.Descending).firstOrNull(); + Employee emp = employeeRepository.find(orderBy("empId", SortOrder.Descending)).firstOrNull(); long id = emp.getEmpId(); List employeeList = employeeRepository.find(where("empId").notIn(id, id - 1, id - 2)) @@ -476,7 +481,7 @@ public void testFilterAll() { assertEquals(cursor.size(), 1); } - @Test + @Test(expected = FilterException.class) public void testEqualsOnTextIndex() { PersonEntity p1 = new PersonEntity("jhonny"); PersonEntity p2 = new PersonEntity("jhonny"); @@ -525,12 +530,12 @@ public void testIssue62() { Filter married = where("status").eq("Married"); assertEquals(repository.find(married).size(), 2); - assertEquals(repository.find(married).sort("status", SortOrder.Descending).size(), 2); + assertEquals(repository.find(married, orderBy("status", SortOrder.Descending)).size(), 2); - assertEquals(repository.find().sort("status", SortOrder.Descending).firstOrNull().getStatus(), "Un-Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Descending)).firstOrNull().getStatus(), "Un-Married"); - assertEquals(repository.find().sort("status", SortOrder.Ascending).size(), 3); - assertEquals(repository.find().sort("status", SortOrder.Ascending).firstOrNull().getStatus(), "Married"); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).size(), 3); + assertEquals(repository.find(orderBy("status", SortOrder.Ascending)).firstOrNull().getStatus(), "Married"); } @Test @@ -551,7 +556,7 @@ public void testRepeatableIndexAnnotation() { @Test public void testIdSet() { - Cursor employees = employeeRepository.find().sort("empId", SortOrder.Ascending); + Cursor employees = employeeRepository.find(orderBy("empId", SortOrder.Ascending)); assertEquals(employees.size(), 10); } @@ -559,11 +564,11 @@ public void testIdSet() { public void testBetweenFilter() { @Getter class TestData implements Mappable { - private Date age; + private Date age; - public TestData(Date age) { - this.age = age; - } + public TestData(Date age) { + this.age = age; + } @Override public Document write(NitriteMapper mapper) { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java similarity index 69% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java index 45a55d9b4..cf793fb10 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/UnAnnotatedObjectTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UnAnnotatedObjectTest.java @@ -1,29 +1,30 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository; +package org.dizitart.no2.integration.repository; +import org.dizitart.no2.integration.repository.data.ClassA; +import org.dizitart.no2.integration.repository.data.ClassC; import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.data.ClassA; -import org.dizitart.no2.repository.data.ClassC; +import org.dizitart.no2.repository.Cursor; import org.junit.Test; +import static org.dizitart.no2.collection.FindOptions.orderBy; import static org.dizitart.no2.filters.FluentFilter.where; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -34,18 +35,15 @@ public class UnAnnotatedObjectTest extends BaseObjectRepositoryTest { @Test - @SuppressWarnings("unchecked") public void testFind() { - Cursor cursor = aObjectRepository.find(); + Cursor cursor = aObjectRepository.find(); assertEquals(cursor.size(), 10); assertFalse(cursor.isEmpty()); - IndexOptions indexOptions = new IndexOptions(); - indexOptions.setIndexType(IndexType.Unique); - aObjectRepository.createIndex("b.number", indexOptions); + aObjectRepository.createIndex("b.number"); - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Ascending).skipLimit(0, 10); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Ascending).skip(0).limit(10)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -55,8 +53,8 @@ public void testFind() { System.out.println(classA); } - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Descending).skipLimit(2, 7); + cursor = aObjectRepository.find(where("b.number").eq(160).not(), + orderBy("b.number", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); @@ -66,8 +64,8 @@ public void testFind() { System.out.println(classA); } - cursor = cObjectRepository.find(where("id").gt(900)). - sort("id", SortOrder.Descending).skipLimit(2, 7); + cursor = cObjectRepository.find(where("id").gt(900), + orderBy("id", SortOrder.Descending).skip(2).limit(7)); System.out.println("Available - " + !cursor.isEmpty()); System.out.println("Total Size - " + cursor.size()); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java similarity index 94% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index 450e76ff7..8b2237f0b 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UniversalTextTokenizerTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -1,46 +1,45 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository; +package org.dizitart.no2.integration.repository; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.index.IndexType; import org.dizitart.no2.index.NitriteTextIndexer; import org.dizitart.no2.index.fulltext.Languages; import org.dizitart.no2.index.fulltext.UniversalTextTokenizer; -import org.dizitart.no2.rocksdb.RocksDBModule; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.Cursor; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; +import org.dizitart.no2.rocksdb.RocksDBModule; import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.io.IOException; - +import static org.dizitart.no2.common.module.NitriteModule.module; import static org.dizitart.no2.filters.Filter.ALL; import static org.dizitart.no2.filters.FluentFilter.where; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; -import static org.dizitart.no2.common.module.NitriteModule.module; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -82,7 +81,7 @@ public void setUp() { @After @Override - public void clear() throws IOException { + public void clear() throws Exception { if (textRepository != null && !textRepository.isDropped()) { textRepository.remove(ALL); } @@ -92,7 +91,7 @@ public void clear() throws IOException { db.close(); } - deleteFile(fileName); + deleteDb(fileName); } @Override @@ -167,7 +166,7 @@ public void testUniversalFullTextIndexing() { } @Indices( - @Index(value = "text", type = IndexType.Fulltext) + @Index(value = "text", type = IndexType.FULL_TEXT) ) public static class TextData implements Mappable { public int id; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java new file mode 100644 index 000000000..5a147769c --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.repository.annotations.Entity; +import org.dizitart.no2.repository.annotations.Id; +import org.dizitart.no2.repository.annotations.Index; + +import java.util.List; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity(value = "books", indices = { + @Index(value = "tags", type = IndexType.NON_UNIQUE), + @Index(value = "description", type = IndexType.FULL_TEXT), + @Index(value = { "price", "publisher" }) +}) +public class Book implements Mappable { + @Id(fieldName = "book_id") + private BookId bookId; + + private String publisher; + + private Double price; + + private List tags; + + private String description; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("book_id", mapper.convert(bookId, Document.class)) + .put("publisher", publisher) + .put("price", price) + .put("tags", tags) + .put("description", description); + } + + @Override + @SuppressWarnings("unchecked") + public void read(NitriteMapper mapper, Document document) { + bookId = mapper.convert(document.get("book_id"), BookId.class); + publisher = document.get("publisher", String.class); + price = document.get("price", Double.class); + tags = (List) document.get("tags", List.class); + description = document.get("description", String.class); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java new file mode 100644 index 000000000..239b493d3 --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/BookId.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Embedded; + +import static org.dizitart.no2.collection.Document.createDocument; + +/** + * @author Anindya Chatterjee + */ +@Data +public class BookId implements Mappable { + @Embedded(order = 0) + private String isbn; + + @Embedded(order = 1, fieldName = "book_name") + private String name; + + private String author; + + @Override + public Document write(NitriteMapper mapper) { + return createDocument("isbn", isbn) + .put("book_name", name) + .put("author", author); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + isbn = document.get("isbn", String.class); + name = document.get("book_name", String.class); + author = document.get("author", String.class); + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java index d86fc3576..d3c2ba644 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ChildClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ChildClass.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java similarity index 80% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java index 52d6eba2b..a8161c4e2 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassA.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassA.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -31,7 +32,7 @@ public class ClassA implements Mappable { @Getter @Setter - private ClassB classB; + private ClassB b; @Getter @Setter private UUID uid; @@ -45,7 +46,7 @@ public class ClassA implements Mappable { public static ClassA create(int seed) { ClassB classB = ClassB.create(seed); ClassA classA = new ClassA(); - classA.classB = classB; + classA.b = classB; classA.uid = new UUID(seed, seed + 50); classA.string = Integer.toHexString(seed); classA.blob = new byte[]{(byte) seed}; @@ -55,7 +56,7 @@ public static ClassA create(int seed) { @Override public Document write(NitriteMapper mapper) { return Document.createDocument() - .put("classB", classB != null ? classB.write(mapper) : null) + .put("b", b != null ? b.write(mapper) : null) .put("uid", uid) .put("string", string) .put("blob", blob); @@ -63,9 +64,9 @@ public Document write(NitriteMapper mapper) { @Override public void read(NitriteMapper mapper, Document document) { - if (document.get("classB") != null) { - classB = new ClassB(); - classB.read(mapper, document.get("classB", Document.class)); + if (document.get("b") != null) { + b = new ClassB(); + b.read(mapper, document.get("b", Document.class)); } uid = document.get("uid", UUID.class); string = document.get("string", String.class); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java index fb26ae4e3..a546b91e2 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ClassB.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassB.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java index d7bd57c6f..860fe1e93 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassC.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ClassC.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -39,7 +40,7 @@ public class ClassC implements Mappable { public static ClassC create(int seed) { ClassC classC = new ClassC(); - classC.id = seed * 5000; + classC.id = seed * 5000L; classC.digit = seed * 69.65; classC.parent = ClassA.create(seed); return classC; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java similarity index 77% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java index 32d153f78..944e17358 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Company.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Company.java @@ -1,25 +1,25 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; -import lombok.ToString; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; @@ -35,13 +35,12 @@ /** * @author Anindya Chatterjee. */ -@ToString @EqualsAndHashCode @Indices({ @Index(value = "companyName") }) public class Company implements Serializable, Mappable { - @Id + @Id(fieldName = "company_id") @Getter @Setter private Long companyId; @@ -64,7 +63,7 @@ public class Company implements Serializable, Mappable { @Override public Document write(NitriteMapper mapper) { - return Document.createDocument("companyId", companyId) + return Document.createDocument("company_id", companyId) .put("companyName", companyName) .put("dateCreated", dateCreated) .put("departments", departments) @@ -74,10 +73,20 @@ public Document write(NitriteMapper mapper) { @Override @SuppressWarnings("unchecked") public void read(NitriteMapper mapper, Document document) { - companyId = document.get("companyId", Long.class); + companyId = document.get("company_id", Long.class); companyName = document.get("companyName", String.class); dateCreated = document.get("dateCreated", Date.class); departments = document.get("departments", List.class); employeeRecord = document.get("employeeRecord", Map.class); } + + @Override + public String toString() { + return "Company{" + + "companyId=" + companyId + + ", companyName='" + companyName + '\'' + + ", dateCreated=" + dateCreated + + ", departments=" + departments + + '}'; + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/DataGenerator.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java similarity index 52% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/DataGenerator.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java index 5d5dbfd81..26e0dcf4a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/DataGenerator.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/DataGenerator.java @@ -1,42 +1,45 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; + +import com.github.javafaker.Faker; +import lombok.val; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * @author Anindya Chatterjee. */ public class DataGenerator { - private DataGenerator() {} - private static final Random random = new Random(System.currentTimeMillis()); private static final AtomicInteger counter = new AtomicInteger(random.nextInt()); + private static final Faker faker = new Faker(random); + + private DataGenerator() {} public static Company generateCompanyRecord() { Company company = new Company(); company.setCompanyId(System.nanoTime() + counter.incrementAndGet()); - company.setCompanyName(randomCompanyName()); - company.setDateCreated(randomDate()); + company.setCompanyName(faker.company().name()); + company.setDateCreated(faker.date().past(10, TimeUnit.DAYS)); List departments = departments(); company.setDepartments(departments); @@ -62,65 +65,41 @@ private static List generateEmployeeRecords(Company company, int count public static Employee generateEmployee() { Employee employee = new Employee(); employee.setEmpId(System.nanoTime() + counter.incrementAndGet()); - employee.setJoinDate(randomDate()); - employee.setAddress(UUID.randomUUID().toString().replace('-', ' ')); + employee.setJoinDate(faker.date().birthday()); + employee.setAddress(faker.address().fullAddress()); - byte[] blob = new byte[random.nextInt(8000)]; - random.nextBytes(blob); - employee.setBlob(blob); + employee.setBlob(faker.lorem().paragraph().getBytes(StandardCharsets.UTF_8)); employee.setEmployeeNote(randomNote()); + employee.setEmailAddress(faker.internet().emailAddress()); return employee; } - private static Date randomDate() { - return new Date(-946771200000L + - (Math.abs(random.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000))); - } - public static Note randomNote() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("test.text"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - long line = random.nextInt(49); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - Note note = new Note(); - note.setNoteId(line); - note.setText(strLine); - return note; - } - count++; - } - } catch (IOException e) { - // ignore - } - // ignore - return null; + Note note = new Note(); + note.setNoteId(System.nanoTime() + counter.incrementAndGet()); + note.setText(faker.lorem().paragraph()); + return note; } - private static String randomCompanyName() { - InputStream inputStream = ClassLoader.getSystemResourceAsStream("english.stop"); - - assert inputStream != null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { - String strLine; - int line = random.nextInt(570); - int count = 0; - while ((strLine = br.readLine()) != null) { - if (count == line) { - return strLine + System.nanoTime() + " inc."; - } - count++; - } - } catch (IOException e) { - // ignore + public static Book randomBook() { + BookId bookId = new BookId(); + val bookFaker = faker.book(); + bookId.setIsbn(faker.idNumber().ssnValid()); + bookId.setAuthor(bookFaker.author()); + bookId.setName(bookFaker.title()); + + Book book = new Book(); + book.setBookId(bookId); + book.setDescription(faker.backToTheFuture().quote()); + book.setPrice(faker.number().randomDouble(2, 100, 500)); + book.setPublisher(bookFaker.publisher()); + List tags = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + tags.add(bookFaker.genre()); } - // ignore - return null; + book.setTags(tags); + return book; } private static List departments() { diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java similarity index 92% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java index 1a30321eb..cb5304e29 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ElemMatch.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ElemMatch.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java similarity index 82% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 2f7f851c9..7204f5654 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Employee.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -35,9 +36,9 @@ */ @ToString @EqualsAndHashCode -@Index(value = "joinDate", type = IndexType.NonUnique) -@Index(value = "address", type = IndexType.Fulltext) -@Index(value = "employeeNote.text", type = IndexType.Fulltext) +@Index(value = "joinDate", type = IndexType.NON_UNIQUE) +@Index(value = "address", type = IndexType.FULL_TEXT) +@Index(value = "employeeNote.text", type = IndexType.FULL_TEXT) public class Employee implements Serializable, Mappable { @Id @Getter @@ -52,6 +53,10 @@ public class Employee implements Serializable, Mappable { @Setter private String address; + @Getter + @Setter + private String emailAddress; + @Getter @Setter private transient Company company; @@ -74,6 +79,7 @@ public Employee(Employee copy) { company = copy.company; blob = copy.blob; employeeNote = copy.employeeNote; + emailAddress = copy.emailAddress; } @Override @@ -83,6 +89,7 @@ public Document write(NitriteMapper mapper) { .put("joinDate", joinDate) .put("address", address) .put("blob", blob) + .put("emailAddress", emailAddress) .put("employeeNote", employeeNote != null ? employeeNote.write(mapper) : null); } @@ -92,6 +99,7 @@ public void read(NitriteMapper mapper, Document document) { joinDate = document.get("joinDate", Date.class); address = document.get("address", String.class); blob = document.get("blob", byte[].class); + emailAddress = document.get("emailAddress", String.class); if (document.get("employeeNote") != null) { employeeNote = new Note(); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java new file mode 100644 index 000000000..8b9d4b23b --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/EncryptedPerson.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Entity; + +import java.util.Date; + +/** + * @author Anindya Chatterjee + */ +@Data +@Entity +public class EncryptedPerson implements Mappable { + private String name; + private String creditCardNumber; + private String cvv; + private Date expiryDate; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument("name", name) + .put("creditCardNumber", creditCardNumber) + .put("cvv", cvv) + .put("expiryDate", expiryDate); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + name = document.get("name", String.class); + creditCardNumber = document.get("creditCardNumber", String.class); + cvv = document.get("cvv", String.class); + expiryDate = document.get("expiryDate", Date.class); + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java index 31906206d..67dc307d1 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/Note.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/Note.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java similarity index 89% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java index 7171c2ae6..bc2514543 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/ParentClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ParentClass.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.NitriteMapper; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.common.mapper.NitriteMapper; import java.util.Date; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index 911ac8ca4..2b90075fa 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/PersonEntity.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -33,8 +34,8 @@ */ @Data @Entity(value = "MyPerson", indices = { - @Index(value = "name", type = IndexType.Fulltext), - @Index(value = "status", type = IndexType.NonUnique) + @Index(value = "name", type = IndexType.FULL_TEXT), + @Index(value = "status", type = IndexType.NON_UNIQUE) }) public class PersonEntity implements Mappable { @Id diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java similarity index 89% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java index cc29f74df..65550d182 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/ProductScore.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/ProductScore.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java similarity index 84% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index e0030b59d..1ecadb243 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/RepeatableIndexTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; @@ -28,8 +29,8 @@ */ @Data @Index(value = "firstName") -@Index(value = "age", type = IndexType.NonUnique) -@Index(value = "lastName", type = IndexType.Fulltext) +@Index(value = "age", type = IndexType.NON_UNIQUE) +@Index(value = "lastName", type = IndexType.FULL_TEXT) public class RepeatableIndexTest implements Mappable { private String firstName; private Integer age; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java similarity index 90% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java index a526c516d..d1cb199c4 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/StressRecord.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/StressRecord.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java index fb4478192..8eaa3faf1 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/SubEmployee.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SubEmployee.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java similarity index 84% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index 1b935ba4e..198f16d0c 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/SuperDuperClass.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -1,35 +1,36 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Index; /** * @author Anindya Chatterjee */ @Getter @Setter -@Index(value = "text", type = IndexType.Fulltext) +@Index(value = "text", type = IndexType.FULL_TEXT) public class SuperDuperClass implements Mappable { private String text; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java similarity index 81% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java index ea80f05ca..efbb6766a 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCircularReference.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCircularReference.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java index 57c4b1940..79cafe0dc 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithClassField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithClassField.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java similarity index 83% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java index 3f611bacd..bea5dabe9 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithCustomConstructor.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithCustomConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java index 0b2c35dc0..229f1aaf7 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithDateId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithDateId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java similarity index 87% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java index 2cad5635f..a0048a6bb 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithEmptyStringId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithEmptyStringId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java similarity index 91% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java index 3787ebbbb..05afc21e8 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithFinalField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithFinalField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java similarity index 88% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java index 50cf53c57..2364be76d 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithNitriteId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNitriteId.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java index b77eb9c1a..0dc3fb68b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithNullId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithNullId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java similarity index 87% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java index dc0324132..5f00f97d4 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/repository/data/WithObjectId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithObjectId.java @@ -1,27 +1,28 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; import org.dizitart.no2.collection.Document; -import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.common.mapper.Mappable; import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; /** * @author Anindya Chatterjee. diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java index 63e8e993a..a7a2c56c9 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithOutGetterSetter.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutGetterSetter.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java index a96ff2224..09b63c2c2 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutId.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithOutId.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java similarity index 90% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java index b9bd97f64..a425209fb 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/repository/data/WithPrivateConstructor.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPrivateConstructor.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.EqualsAndHashCode; import org.dizitart.no2.collection.Document; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java index b02750c8a..793388231 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithPublicField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithPublicField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.Mappable; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java index 8f2957431..9c1ade657 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithTransientField.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithTransientField.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.repository.data; +package org.dizitart.no2.integration.repository.data; import lombok.Getter; import lombok.Setter; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java new file mode 100644 index 000000000..9ecb9a68b --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/repository/data/WithoutEmbeddedId.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.repository.data; + +import lombok.Data; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.common.mapper.Mappable; +import org.dizitart.no2.common.mapper.NitriteMapper; +import org.dizitart.no2.repository.annotations.Id; + +/** + * @author Anindya Chatterjee + */ +@Data +public class WithoutEmbeddedId implements Mappable { + @Id + private NestedId nestedId; + private String data; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("nestedId", nestedId.write(mapper)) + .put("data", data); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + Document nestedId = document.get("nestedId", Document.class); + this.nestedId = mapper.convert(nestedId, NestedId.class); + this.data = document.get("data", String.class); + } + + + @Data + public static class NestedId implements Mappable { + private Long id; + + @Override + public Document write(NitriteMapper mapper) { + return Document.createDocument() + .put("id", id); + } + + @Override + public void read(NitriteMapper mapper, Document document) { + id = document.get("id", Long.class); + } + } +} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteMapStressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteMapStressTest.java similarity index 87% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteMapStressTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteMapStressTest.java index 023bda1f1..65fe9c1de 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/mapdb/NitriteMapStressTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteMapStressTest.java @@ -1,39 +1,36 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.mapdb; +package org.dizitart.no2.integration.rocksdb; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapdb.Retry; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; import org.junit.After; import org.junit.Rule; import org.junit.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.UUID; -import static org.dizitart.no2.mapdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.mapdb.TestUtil.createDb; +import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -113,10 +110,10 @@ public void testNullPutIfAbsent() { } @After - public void tearDown() throws IOException { + public void tearDown() { if (db != null && !db.isClosed()) { db.close(); } - Files.delete(Paths.get(dbPath)); + deleteDb(dbPath); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteStoreEventTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteStoreEventTest.java similarity index 88% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteStoreEventTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteStoreEventTest.java index c50209f4f..d2f977486 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteStoreEventTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/rocksdb/NitriteStoreEventTest.java @@ -1,24 +1,25 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.rocksdb; +package org.dizitart.no2.integration.rocksdb; import lombok.Data; import org.dizitart.no2.Nitrite; -import org.dizitart.no2.rocksdb.Retry; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.rocksdb.RocksDBModule; import org.dizitart.no2.store.events.EventInfo; import org.dizitart.no2.store.events.StoreEventListener; @@ -28,13 +29,11 @@ import org.junit.Test; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.dizitart.no2.rocksdb.TestUtil.deleteFile; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -59,9 +58,7 @@ public void cleanup() throws IOException { db.close(); } - if (Files.exists(Paths.get(dbFile))) { - deleteFile(dbFile); - } + deleteDb(dbFile); } @Test diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java similarity index 77% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java index e6a7a0e23..de377b162 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/DocumentCursorTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/DocumentCursorTest.java @@ -1,36 +1,33 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.integration.stream; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.streams.DocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.junit.After; -import org.junit.Rule; import org.junit.Test; import java.util.Iterator; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -38,15 +35,10 @@ /** * @author Anindya Chatterjee. */ -public class DocumentCursorTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); +public class DocumentCursorTest extends BaseCollectionTest { @Test public void testFindResult() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); collection.insert(createDocument("first", "second")); @@ -56,7 +48,6 @@ public void testFindResult() { @Test(expected = InvalidOperationException.class) public void testIteratorRemove() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); collection.insert(createDocument("first", "second")); @@ -70,7 +61,6 @@ public void testIteratorRemove() { @Test public void testValidateProjection() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); collection.insert(createDocument("first", "second")); @@ -78,11 +68,4 @@ public void testValidateProjection() { RecordStream project = collection.find().project(projection); assertNotNull(project); } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } } diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java similarity index 76% rename from nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java index ad94cbe73..00923c738 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/collection/operation/JoinedDocumentStreamTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/stream/JoinedDocumentStreamTest.java @@ -1,36 +1,33 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.collection.operation; +package org.dizitart.no2.integration.stream; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.Retry; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.streams.JoinedDocumentStream; import org.dizitart.no2.common.Lookup; import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.streams.JoinedDocumentStream; import org.dizitart.no2.exceptions.InvalidOperationException; -import org.junit.After; -import org.junit.Rule; import org.junit.Test; import java.util.Iterator; -import static org.dizitart.no2.TestUtil.createDb; import static org.dizitart.no2.collection.Document.createDocument; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -38,15 +35,10 @@ /** * @author Anindya Chatterjee */ -public class JoinedDocumentStreamTest { - private Nitrite db; - - @Rule - public Retry retry = new Retry(3); +public class JoinedDocumentStreamTest extends BaseCollectionTest { @Test public void testFindResult() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); collection.insert(createDocument("first", "second")); @@ -56,7 +48,6 @@ public void testFindResult() { @Test(expected = InvalidOperationException.class) public void testIteratorRemove() { - db = createDb(); NitriteCollection collection = db.getCollection("test"); collection.insert(createDocument("first", "second")); @@ -68,11 +59,4 @@ public void testIteratorRemove() { iterator.remove(); } } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - } } diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionCollectionTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java similarity index 93% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionCollectionTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java index db5dc24be..05a2b095b 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionCollectionTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java @@ -1,13 +1,30 @@ -package org.dizitart.no2.mapdb.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; +import org.dizitart.no2.integration.collection.BaseCollectionTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.BaseCollectionTest; import org.dizitart.no2.transaction.Session; import org.dizitart.no2.transaction.Transaction; import org.junit.Test; @@ -50,7 +67,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -104,7 +121,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); collection.insert(createDocument("firstName", "Jane")); try (Session session = db.createSession()) { @@ -160,7 +177,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -198,7 +215,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Fulltext)); + txCol.createIndex(indexOptions(IndexType.FULL_TEXT), "firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -222,7 +239,7 @@ public void testRollbackCreateIndex() { transaction = session.beginTransaction(); NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex("firstName", indexOptions(IndexType.Unique)); + txCol.createIndex("firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -263,7 +280,7 @@ public void testCommitClear() { @Test public void testRollbackClear() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); Document document2 = createDocument("firstName", "Jane"); collection.insert(document); @@ -295,7 +312,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -317,8 +334,8 @@ public void testRollbackDropIndex() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -348,8 +365,8 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { Document document = createDocument("firstName", "John"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); + collection.createIndex("lastName"); try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { @@ -373,8 +390,8 @@ public void testCommitDropAllIndices() { public void testRollbackDropAllIndices() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); collection.insert(document); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -435,7 +452,7 @@ public void testCommitDropCollection() { @Test public void testRollbackDropCollection() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); Document document = createDocument("firstName", "John"); collection.insert(document); @@ -472,7 +489,9 @@ public void testCommitSetAttribute() { NitriteCollection txCol = transaction.getCollection("test"); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txCol.setAttributes(attributes); assertNull(collection.getAttributes()); @@ -486,7 +505,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -524,8 +543,8 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { NitriteCollection collection = db.getCollection("test"); - collection.createIndex("firstName", indexOptions(IndexType.NonUnique)); - collection.createIndex("id", indexOptions(IndexType.Unique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); + collection.createIndex("id"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -669,7 +688,7 @@ public void testTransactionOnDifferentCollections() { NitriteCollection col1 = db.getCollection("test1"); NitriteCollection col2 = db.getCollection("test2"); NitriteCollection col3 = db.getCollection("test3"); - col3.createIndex("id", indexOptions(IndexType.Unique)); + col3.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionRepositoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java similarity index 94% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionRepositoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index f0aa5cfaa..5e93303ed 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/transaction/TransactionRepositoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -1,14 +1,31 @@ -package org.dizitart.no2.mapdb.transaction; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.integration.transaction; import com.github.javafaker.Faker; +import org.dizitart.no2.integration.repository.BaseObjectRepositoryTest; +import org.dizitart.no2.integration.repository.data.SubEmployee; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.collection.meta.Attributes; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.TransactionException; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.mapdb.repository.BaseObjectRepositoryTest; -import org.dizitart.no2.mapdb.repository.data.SubEmployee; import org.dizitart.no2.repository.ObjectRepository; import org.dizitart.no2.transaction.Session; import org.dizitart.no2.transaction.Transaction; @@ -56,7 +73,7 @@ public void testCommitInsert() { @Test public void testRollbackInsert() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -116,7 +133,7 @@ public void testCommitUpdate() { @Test public void testRollbackUpdate() { ObjectRepository repository = db.getRepository(TxData.class, "rollback"); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(new TxData(1L, "Jane")); try (Session session = db.createSession()) { @@ -180,7 +197,7 @@ public void testCommitRemove() { @Test public void testRollbackRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); TxData txData1 = new TxData(1L, "John"); repository.insert(txData1); @@ -220,7 +237,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -245,7 +262,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex("name", indexOptions(IndexType.Fulltext)); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -290,7 +307,7 @@ public void testRollbackClear() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -320,7 +337,7 @@ public void testRollbackClear() { public void testCommitDropIndex() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -344,7 +361,7 @@ public void testRollbackDropIndex() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -374,7 +391,7 @@ public void testRollbackDropIndex() { public void testCommitDropAllIndices() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try (Session session = db.createSession()) { @@ -398,7 +415,7 @@ public void testRollbackDropAllIndices() { TxData txData2 = new TxData(2L, "Jane"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -461,7 +478,7 @@ public void testRollbackDropRepository() { TxData txData1 = new TxData(1L, "John"); ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); repository.insert(txData1); try(Session session = db.createSession()) { @@ -498,7 +515,9 @@ public void testCommitSetAttribute() { ObjectRepository txRepo = transaction.getRepository(TxData.class); Attributes attributes = new Attributes(); - attributes.setAttributes(Collections.singletonMap("key", "value")); + Map hashMap = new HashMap<>(); + hashMap.put("key", "value"); + attributes.setAttributes(hashMap); txRepo.setAttributes(attributes); assertNull(repository.getAttributes()); @@ -513,7 +532,7 @@ public void testCommitSetAttribute() { @Test public void testRollbackSetAttribute() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.Unique)); + repository.createIndex("name"); try (Session session = db.createSession()) { Transaction transaction = null; try { @@ -551,7 +570,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex("name", indexOptions(IndexType.NonUnique)); + repository.createIndex(indexOptions(IndexType.NON_UNIQUE), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); @@ -692,7 +711,7 @@ public void testTransactionOnDifferentRepositoriesAndCollections() { ObjectRepository repo2 = db.getRepository(TxData.class, "2"); ObjectRepository repo3 = db.getRepository(SubEmployee.class); NitriteCollection col1 = db.getCollection("test1"); - col1.createIndex("id", indexOptions(IndexType.Unique)); + col1.createIndex("id"); Faker faker = new Faker(); diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java similarity index 89% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java index fbc0d1f7f..1e5ed7ca6 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/transaction/TxData.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/transaction/TxData.java @@ -1,20 +1,21 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.transaction; +package org.dizitart.no2.integration.transaction; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/AbstractTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/AbstractTest.java deleted file mode 100644 index 4e9760a56..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/AbstractTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import org.dizitart.no2.Nitrite; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; - -import java.io.IOException; -import java.text.ParseException; - -/** - * @author Anindya Chatterjee - */ -public abstract class AbstractTest { - protected final String fileName = DbTestOperations.getRandomTempDbFile(); - protected Nitrite db; - - @Rule - public Retry retry = new Retry(3); - - @Before - public void setUp() throws ParseException { - RocksDBModule storeModule = RocksDBModule.withConfig() - .filePath(fileName) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .fieldSeparator(".") - .openOrCreate(); - } - - @After - public void cleanUp() throws IOException { - if (db != null && !db.isClosed()) { - db.close(); - } - TestUtil.deleteFile(fileName); - } -} diff --git a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFactoryTest.java similarity index 88% rename from nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFactoryTest.java rename to nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFactoryTest.java index 10002aa70..f8eb46ab3 100644 --- a/nitrite-mapdb-adapter/src/test/java/org/dizitart/no2/mapdb/collection/CollectionFactoryTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/CollectionFactoryTest.java @@ -1,26 +1,27 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.mapdb.collection; +package org.dizitart.no2.rocksdb; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.CollectionFactory; import org.dizitart.no2.common.concurrent.LockService; import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.mapdb.Retry; +import org.dizitart.no2.integration.Retry; import org.junit.Rule; import org.junit.Test; diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbWriteCloseReadTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbWriteCloseReadTest.java deleted file mode 100644 index fc9a25094..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/DbWriteCloseReadTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import org.junit.Rule; -import org.junit.Test; - -import java.text.ParseException; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Anindya Chatterjee. - */ -public class DbWriteCloseReadTest { - private final DbTestOperations operations = new DbTestOperations(); - private volatile boolean writeCompleted = false; - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testWriteCloseRead() throws Exception { - try { - operations.createDb(); - operations.writeCollection(); - operations.writeIndex(); - operations.insertInCollection(); - } catch (ParseException pe) { - // ignore - } finally { - writeCompleted = true; - } - - try { - assertTrue(writeCompleted); - operations.readCollection(); - } catch (Exception e) { - fail("collection read failed - " + e.getMessage()); - } finally { - operations.deleteDb(); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/EntrySetTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/EntrySetTest.java new file mode 100644 index 000000000..6aedeba98 --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/EntrySetTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.rocksdb; + +import org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter; +import org.junit.Test; +import org.rocksdb.ColumnFamilyHandle; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksIterator; + +import static org.mockito.Mockito.*; + +public class EntrySetTest { + @Test + public void testIterator() { + RocksDB rocksDB = mock(RocksDB.class); + when(rocksDB.newIterator((ColumnFamilyHandle) any())).thenReturn(mock(RocksIterator.class)); + KryoObjectFormatter objectFormatter = new KryoObjectFormatter(); + Class keyType = Object.class; + (new EntrySet<>(rocksDB, null, objectFormatter, keyType, Object.class, true)).iterator(); + verify(rocksDB).newIterator((ColumnFamilyHandle) any()); + } + + @Test + public void testIterator2() { + RocksDB rocksDB = mock(RocksDB.class); + when(rocksDB.newIterator((ColumnFamilyHandle) any())).thenReturn(mock(RocksIterator.class)); + KryoObjectFormatter objectFormatter = new KryoObjectFormatter(); + Class keyType = Object.class; + (new EntrySet<>(rocksDB, null, objectFormatter, keyType, Object.class, false)).iterator(); + verify(rocksDB).newIterator((ColumnFamilyHandle) any()); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/KeySetTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/KeySetTest.java new file mode 100644 index 000000000..af2613db3 --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/KeySetTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.rocksdb; + +import org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter; +import org.junit.Test; +import org.rocksdb.ColumnFamilyHandle; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksIterator; + +import static org.mockito.Mockito.*; + +public class KeySetTest { + @Test + public void testIterator() { + RocksDB rocksDB = mock(RocksDB.class); + when(rocksDB.newIterator((ColumnFamilyHandle) any())).thenReturn(mock(RocksIterator.class)); + KryoObjectFormatter objectFormatter = new KryoObjectFormatter(); + (new KeySet<>(rocksDB, null, objectFormatter, Object.class)).iterator(); + verify(rocksDB).newIterator((ColumnFamilyHandle) any()); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryNegativeTest.java deleted file mode 100644 index 784cc8700..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryNegativeTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.NitriteException; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.junit.Assert.assertEquals; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteStoreFactoryNegativeTest { - private final String fileName = getRandomTempDbFile(); - - @Rule - public Retry retry = new Retry(3); - - @Test(expected = NitriteException.class) - public void testOpenSecuredWithoutCredential() throws IOException { - try(Nitrite db = TestUtil.createDb(fileName, "test-user", "test-password")) { - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - db.close(); - - - try(Nitrite db2 = TestUtil.createDb(fileName)){ - dbCollection = db2.getCollection("test"); - assertEquals(dbCollection.find().size(), 1); - } - } finally { - TestUtil.deleteFile(fileName); - } - } - - @Test(expected = NitriteException.class) - public void testOpenUnsecuredWithCredential() throws IOException { - try(Nitrite db = TestUtil.createDb(fileName)) { - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - db.close(); - - try(Nitrite db2 = TestUtil.createDb(fileName, "test-user", "test-password")) { - dbCollection = db2.getCollection("test"); - assertEquals(dbCollection.find().size(), 1); - } - } finally { - TestUtil.deleteFile(fileName); - } - } - - @Test(expected = NitriteException.class) - public void testWrongCredential() throws IOException { - try(Nitrite db = TestUtil.createDb(fileName, "test-user", "test-password")) { - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - db.close(); - - try(Nitrite db2 = TestUtil.createDb(fileName, "test-user", "test-password2")) { - dbCollection = db2.getCollection("test"); - assertEquals(dbCollection.find().size(), 1); - } - } finally { - TestUtil.deleteFile(fileName); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java deleted file mode 100644 index 018da2613..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStoreFactoryTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import org.apache.commons.io.FileUtils; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.exceptions.NitriteSecurityException; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.rocksdb.DbTestOperations.getRandomTempDbFile; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteStoreFactoryTest { - private Nitrite db; - private final String fileName = getRandomTempDbFile(); - - @Rule - public Retry retry = new Retry(3); - - @Test - public void testSecured() throws IOException { - db = TestUtil.createDb(fileName, "test-user", "test-password"); - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - db.close(); - - db = TestUtil.createDb(fileName, "test-user", "test-password"); - dbCollection = db.getCollection("test"); - assertEquals(dbCollection.find().size(), 1); - db.close(); - TestUtil.deleteFile(fileName); - } - - @Test - public void testUnsecured() throws IOException { - db = TestUtil.createDb(fileName); - NitriteCollection dbCollection = db.getCollection("test"); - dbCollection.insert(createDocument("test", "test")); - db.commit(); - db.close(); - - db = TestUtil.createDb(fileName); - dbCollection = db.getCollection("test"); - assertEquals(dbCollection.find().size(), 1); - db.close(); - TestUtil.deleteFile(fileName); - } - - @Test - public void testIssue116() throws IOException { - db = TestUtil.createDb(fileName, "test-user", "test-password"); - db.close(); - try { - db = TestUtil.createDb(fileName,"test-user2", "test-password2"); - } catch (NitriteSecurityException se) { - db = TestUtil.createDb(fileName,"test-user", "test-password"); - assertNotNull(db); - } finally { - db.close(); - TestUtil.deleteFile(fileName); - } - } - - @After - public void cleanUp() { - if (db != null && !db.isClosed()) { - db.close(); - } - - FileUtils.deleteQuietly(new File(fileName)); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java deleted file mode 100644 index 1acfe7861..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteStressTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Id; -import org.junit.Rule; -import org.junit.Test; -import uk.co.jemos.podam.api.PodamFactory; -import uk.co.jemos.podam.api.PodamFactoryImpl; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlSchemaType; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; - - -/** - * @author Anindya Chatterjee - */ -public class NitriteStressTest extends AbstractTest { - private static final int TEST_SET_COUNT = 15000; - private final PodamFactory podamFactory = new PodamFactoryImpl(); - - @Rule - public Retry retry = new Retry(3); - - @Test - public void stressTest() { - ObjectRepository testRepository = db.getRepository(TestDto.class); - testRepository.createIndex("lastName", IndexOptions.indexOptions(IndexType.Fulltext)); - testRepository.createIndex("birthDate", IndexOptions.indexOptions(IndexType.NonUnique)); - - int counter = 0; - try { - for (TestDto testDto : createTestSet()) { - testRepository.insert(testDto); - counter++; - } - } catch (Throwable t) { - System.err.println("Crashed after " + counter + " records"); - throw t; - } - - int size = testRepository.find().toList().size(); - assertEquals(counter, size); - } - - private List createTestSet() { - List testData = new ArrayList<>(); - for (int i = 0; i < TEST_SET_COUNT; i++) { - TestDto testRecords = podamFactory.manufacturePojo(TestDto.class); - testData.add(testRecords); - } - return testData; - } - - @Data - public static class TestDto implements Mappable { - - @XmlElement( - name = "StudentNumber", - required = true - ) - @Id - protected String studentNumber; - - @XmlElement( - name = "LastName", - required = true - ) - protected String lastName; - - @XmlElement( - name = "Prefixes" - ) - protected String prefixes; - - @XmlElement( - name = "Initials", - required = true - ) - protected String initials; - - @XmlElement( - name = "FirstNames" - ) - protected String firstNames; - @XmlElement( - name = "Nickname" - ) - protected String nickName; - - @XmlElement( - name = "BirthDate", - required = true - ) - @XmlSchemaType( - name = "date" - ) - protected String birthDate; - - - public TestDto() { - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("studentNumber", studentNumber) - .put("lastName", lastName) - .put("prefixes", prefixes) - .put("initials", initials) - .put("firstNames", firstNames) - .put("nickName", nickName) - .put("birthDate", birthDate); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - studentNumber = document.get("studentNumber", String.class); - lastName = document.get("lastName", String.class); - prefixes = document.get("prefixes", String.class); - initials = document.get("initials", String.class); - firstNames = document.get("firstNames", String.class); - nickName = document.get("nickName", String.class); - birthDate = document.get("birthDate", String.class); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java deleted file mode 100644 index fb0b1cba0..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/NitriteTest.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.UpdateOptions; -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.common.concurrent.ThreadPoolManager; -import org.dizitart.no2.exceptions.NitriteIOException; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import uk.co.jemos.podam.api.PodamFactory; -import uk.co.jemos.podam.api.PodamFactoryImpl; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Locale; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.Constants.INTERNAL_NAME_SEPARATOR; -import static org.dizitart.no2.common.Constants.META_MAP_NAME; -import static org.dizitart.no2.filters.Filter.ALL; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteTest extends AbstractTest { - - private NitriteCollection collection; - private SimpleDateFormat simpleDateFormat; - - @Before - public void setUp() throws ParseException { - db = TestUtil.createDb(fileName, "test-user", "test-password"); - - simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); - - Document doc1 = createDocument("firstName", "fn1") - .put("lastName", "ln1") - .put("birthDay", simpleDateFormat.parse("2012-07-01T16:02:48.440Z")) - .put("data", new byte[]{1, 2, 3}) - .put("body", "a quick brown fox jump over the lazy dog"); - Document doc2 = createDocument("firstName", "fn2") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2010-06-12T16:02:48.440Z")) - .put("data", new byte[]{3, 4, 3}) - .put("body", "hello world from nitrite"); - Document doc3 = createDocument("firstName", "fn3") - .put("lastName", "ln2") - .put("birthDay", simpleDateFormat.parse("2014-04-17T16:02:48.440Z")) - .put("data", new byte[]{9, 4, 8}) - .put("body", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + - "Sed nunc mi, mattis ullamcorper dignissim vitae, condimentum non lorem."); - - collection = db.getCollection("test"); - collection.remove(ALL); - - collection.createIndex("body", IndexOptions.indexOptions(IndexType.Fulltext)); - collection.createIndex("firstName", IndexOptions.indexOptions(IndexType.Unique)); - collection.insert(doc1, doc2, doc3); - } - - @After - public void tearDown() { - if (collection.isOpen()) { - collection.remove(ALL); - collection.close(); - } - } - - @Test - public void testListCollectionNames() { - Set collectionNames = db.listCollectionNames(); - assertEquals(collectionNames.size(), 1); - } - - @Test - public void testListRepositories() { - db.getRepository(getClass()); - Set repositories = db.listRepositories(); - assertEquals(repositories.size(), 1); - } - - @Test - public void testHasCollection() { - assertTrue(db.hasCollection("test")); - assertFalse(db.hasCollection("lucene" + INTERNAL_NAME_SEPARATOR + "test")); - } - - @Test - public void testHasRepository() { - db.getRepository(getClass()); - assertTrue(db.hasRepository(getClass())); - assertFalse(db.hasRepository(String.class)); - } - - - @Test - public void testReopen() throws ParseException { - assertNotNull(db); - NitriteCollection testCollection = db.getCollection("test"); - assertNotNull(testCollection); - long prevSize = testCollection.find().size(); - - db.close(); - - db = null; - - db = TestUtil.createDb(fileName, "test-user", "test-password"); - - assertNotNull(db); - testCollection = db.getCollection("test"); - assertNotNull(testCollection); - long sizeNow = testCollection.find().size(); - assertEquals(prevSize, sizeNow); - - db.close(); - db = null; - db = TestUtil.createDb(fileName, "test-user", "test-password"); - - testCollection = db.getCollection("test"); - testCollection.insert(createDocument("firstName", "fn12") - .put("lastName", "ln12") - .put("birthDay", simpleDateFormat.parse("2010-07-01T16:02:48.440Z")) - .put("data", new byte[]{10, 20, 30}) - .put("body", "a quick brown fox jump over the lazy dog")); - - db.close(); - db = null; - db = TestUtil.createDb(fileName, "test-user", "test-password"); - - testCollection = db.getCollection("test"); - assertNotNull(testCollection); - sizeNow = testCollection.find().size(); - assertEquals(prevSize + 1, sizeNow); - } - - @Test - public void testClose() { - NitriteCollection testCollection = db.getCollection("test"); - testCollection.insert(createDocument("a", "b")); - db.close(); - - assertFalse(testCollection.isOpen()); - } - - @Test - public void testGetCollection() { - NitriteCollection collection = db.getCollection("test-collection"); - assertNotNull(collection); - assertEquals(collection.getName(), "test-collection"); - } - - @Test - public void testGetRepository() { - ObjectRepository repository = db.getRepository(NitriteTest.class); - assertNotNull(repository); - assertEquals(repository.getType(), NitriteTest.class); - } - - @Test - public void testGetRepositoryWithKey() { - ObjectRepository repository = db.getRepository(NitriteTest.class, "key"); - assertNotNull(repository); - assertEquals(repository.getType(), NitriteTest.class); - assertFalse(db.hasRepository(NitriteTest.class)); - assertTrue(db.hasRepository(NitriteTest.class, "key")); - } - - @Test - public void testMultipleGetCollection() { - NitriteCollection collection = db.getCollection("test-collection"); - assertNotNull(collection); - assertEquals(collection.getName(), "test-collection"); - - NitriteCollection collection2 = db.getCollection("test-collection"); - assertNotNull(collection2); - assertEquals(collection2.getName(), "test-collection"); - } - - @Test - public void testMultipleGetRepository() { - ObjectRepository repository = db.getRepository(NitriteTest.class); - assertNotNull(repository); - assertEquals(repository.getType(), NitriteTest.class); - - ObjectRepository repository2 = db.getRepository(NitriteTest.class); - assertNotNull(repository2); - assertEquals(repository2.getType(), NitriteTest.class); - } - - @Test(expected = ValidationException.class) - public void testGetRepositoryInvalid() { - db.getRepository(null); - } - - @Test(expected = NitriteIOException.class) - public void testGetCollectionNullStore() { - db = Nitrite.builder().openOrCreate(); - db.close(); - db.getCollection("test"); - } - - @Test(expected = NitriteIOException.class) - public void testGetRepositoryNullStore() { - db = Nitrite.builder().openOrCreate(); - db.close(); - db.getRepository(NitriteTest.class); - } - - @Test(expected = NitriteIOException.class) - public void testGetKeyedRepositoryNullStore() { - db = Nitrite.builder().openOrCreate(); - db.close(); - db.getRepository(NitriteTest.class, "key"); - } - - @Test(expected = NitriteIOException.class) - public void testCommitNullStore() { - db = Nitrite.builder().openOrCreate(); - db.close(); - db.commit(); - } - - @Test(expected = ValidationException.class) - public void testGetCollectionInvalidName() { - db.getCollection(META_MAP_NAME); - } - - @Test - public void testIssue185() throws InterruptedException { - final ObjectRepository repository = db.getRepository(Receipt.class); - final Receipt receipt = new Receipt(); - receipt.clientRef = "111-11111"; - receipt.status = Receipt.Status.PREPARING; - CountDownLatch latch = new CountDownLatch(1); - - new Thread(() -> { - for (int i = 0; i < 1000; ++i) { - try { - repository.update(receipt, true); - try { - Thread.sleep(50); - } catch (InterruptedException ignored) { - } - repository.remove(receipt); - try { - Thread.sleep(50); - } catch (InterruptedException ignored) { - } - } catch (Throwable t) { - t.printStackTrace(); - } - } - latch.countDown(); - }).start(); - - for (int i = 0; i < 1000; ++i) { - repository.find(where("status").eq(Receipt.Status.COMPLETED).not()) - .sort("createdTimestamp", SortOrder.Descending).toList(); - try { - Thread.sleep(50); - } catch (InterruptedException ignored) { - } - } - latch.await(); - } - - @Test - public void testIssue193() throws InterruptedException { - final ObjectRepository repository = db.getRepository(Receipt.class); - final PodamFactory factory = new PodamFactoryImpl(); - final String[] refs = new String[]{"1", "2", "3", "4", "5"}; - final Random random = new Random(); - ExecutorService pool = ThreadPoolManager.workerPool(); - - final CountDownLatch latch = new CountDownLatch(10000); - for (int i = 0; i < 10000; i++) { - pool.submit(() -> { - int refIndex = random.nextInt(5); - Receipt receipt = factory.manufacturePojoWithFullData(Receipt.class); - receipt.setClientRef(refs[refIndex]); - repository.update(receipt, true); - latch.countDown(); - }); - } - - latch.await(); - assertTrue(repository.find().size() <= 5); - pool.shutdown(); - } - - @Test - public void testIssue212() { - NitriteCollection collection = db.getCollection("testIssue212"); - Document doc1 = createDocument("key", "key").put("second_key", "second_key").put("third_key", "third_key"); - Document doc2 = createDocument("key", "key").put("second_key", "second_key").put("fourth_key", "fourth_key"); - Document doc = createDocument("fifth_key", "fifth_key"); - - if (!collection.hasIndex("key")) { - collection.createIndex("key", IndexOptions.indexOptions(IndexType.NonUnique)); - } - if (!collection.hasIndex("second_key")) { - collection.createIndex("second_key", IndexOptions.indexOptions(IndexType.NonUnique)); - } - - collection.insert(doc1, doc2); - collection.update(where("key").eq("key").and(where("second_key").eq("second_key")), - doc, UpdateOptions.updateOptions(true)); - - for (Document document : collection.find()) { - System.out.println(document); - } - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class CompatChild implements Mappable { - private Long childId; - private String lastName; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("childId", childId) - .put("lastName", lastName); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - childId = document.get("childId", Long.class); - lastName = document.get("lastName", String.class); - } - } - - @Data - @NoArgsConstructor - @AllArgsConstructor - @Indices({ - @Index(value = "synced", type = IndexType.NonUnique) - }) - public static class Receipt implements Mappable { - private Status status; - @Id - private String clientRef; - private Boolean synced; - private Long createdTimestamp = System.currentTimeMillis(); - - @Override - public Document write(NitriteMapper mapper) { - return createDocument("status", status) - .put("clientRef", clientRef) - .put("synced", synced) - .put("createdTimestamp", createdTimestamp); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document != null) { - Object status = document.get("status"); - if (status instanceof Status) { - this.status = (Status) status; - } else { - this.status = Status.valueOf(status.toString()); - } - this.clientRef = document.get("clientRef", String.class); - this.synced = document.get("synced", Boolean.class); - this.createdTimestamp = document.get("createdTimestamp", Long.class); - } - } - public enum Status { - COMPLETED, - PREPARING, - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBConfigTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBConfigTest.java index 3d596672c..48a8c1312 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBConfigTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBConfigTest.java @@ -1,9 +1,27 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + package org.dizitart.no2.rocksdb; +import org.junit.Test; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; - -import org.junit.Test; +import static org.junit.Assert.assertTrue; public class RocksDBConfigTest { @Test @@ -12,5 +30,17 @@ public void testConstructor() { assertFalse(actualRocksDBConfig.isInMemory()); assertNull(actualRocksDBConfig.options()); } + + @Test + public void testConstructor2() { + assertFalse((new RocksDBConfig()).isInMemory()); + } + + @Test + public void testConstructor3() { + RocksDBConfig actualRocksDBConfig = new RocksDBConfig(); + assertTrue(actualRocksDBConfig.objectFormatter() instanceof org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter); + assertTrue(actualRocksDBConfig.eventListeners().isEmpty()); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBMapTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBMapTest.java new file mode 100644 index 000000000..84f74a19a --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBMapTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.rocksdb; + +import org.junit.Test; + +import static org.mockito.Mockito.*; + +@SuppressWarnings("unchecked") +public class RocksDBMapTest { + @Test + public void testPutIfAbsent() { + RocksDBMap rocksDBMap = (RocksDBMap) mock(RocksDBMap.class); + when(rocksDBMap.putIfAbsent(any(), any())).thenReturn("42"); + rocksDBMap.putIfAbsent("42", "42"); + verify(rocksDBMap).putIfAbsent(any(), any()); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleBuilderTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleBuilderTest.java index ccd9edb25..bd6c87e4a 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleBuilderTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleBuilderTest.java @@ -1,13 +1,64 @@ -package org.dizitart.no2.rocksdb; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ -import static org.junit.Assert.assertNull; +package org.dizitart.no2.rocksdb; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + public class RocksDBModuleBuilderTest { @Test public void testConstructor() { assertNull((new RocksDBModuleBuilder()).options()); } + + @Test + public void testConstructor2() { + RocksDBModuleBuilder actualRocksDBModuleBuilder = new RocksDBModuleBuilder(); + RocksDBModuleBuilder actualFilePathResult = actualRocksDBModuleBuilder.filePath("Path"); + assertNull(actualRocksDBModuleBuilder.columnFamilyOptions()); + assertNull(actualRocksDBModuleBuilder.options()); + assertNull(actualRocksDBModuleBuilder.objectFormatter()); + assertEquals("Path", actualRocksDBModuleBuilder.filePath()); + assertTrue(actualRocksDBModuleBuilder.eventListeners().isEmpty()); + assertNull(actualRocksDBModuleBuilder.dbOptions()); + RocksDBConfig dbConfigResult = actualRocksDBModuleBuilder.dbConfig(); + assertNull(dbConfigResult.columnFamilyOptions()); + assertNull(dbConfigResult.options()); + assertTrue(dbConfigResult.objectFormatter() instanceof org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter); + assertFalse(dbConfigResult.isInMemory()); + assertNull(dbConfigResult.filePath()); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + assertNull(dbConfigResult.dbOptions()); + assertSame(actualRocksDBModuleBuilder, actualFilePathResult); + } + + @Test + public void testConstructor3() { + RocksDBModuleBuilder actualRocksDBModuleBuilder = new RocksDBModuleBuilder(); + assertTrue(actualRocksDBModuleBuilder.eventListeners().isEmpty()); + RocksDBConfig dbConfigResult = actualRocksDBModuleBuilder.dbConfig(); + assertTrue(dbConfigResult.objectFormatter() instanceof org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleTest.java index 814d28e94..d5930c9a1 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBModuleTest.java @@ -1,13 +1,39 @@ -package org.dizitart.no2.rocksdb; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ -import static org.junit.Assert.assertTrue; +package org.dizitart.no2.rocksdb; import org.junit.Test; +import static org.junit.Assert.assertTrue; + public class RocksDBModuleTest { @Test public void testConstructor() { assertTrue((new RocksDBModule("path")).getStore() instanceof RocksDBStore); } + + @Test + public void testWithConfig() { + RocksDBModuleBuilder actualWithConfigResult = RocksDBModule.withConfig(); + assertTrue(actualWithConfigResult.eventListeners().isEmpty()); + RocksDBConfig dbConfigResult = actualWithConfigResult.dbConfig(); + assertTrue(dbConfigResult.objectFormatter() instanceof org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter); + assertTrue(dbConfigResult.eventListeners().isEmpty()); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBReferenceTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBReferenceTest.java index 82a5531de..4f9fd24aa 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBReferenceTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBReferenceTest.java @@ -1,14 +1,38 @@ -package org.dizitart.no2.rocksdb; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ -import static org.junit.Assert.assertEquals; +package org.dizitart.no2.rocksdb; import org.junit.Test; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + public class RocksDBReferenceTest { + @Test public void testConstructor() { - assertEquals("RocksDBReference(options=null, dbOptions=null, columnFamilyOptions=null, rocksDB=null, columnFamilyD" - + "escriptors=[], columnFamilyHandleRegistry={}, dbComparators=[])", (new RocksDBReference()).toString()); + RocksDBReference actualRocksDBReference = new RocksDBReference(); + assertTrue(actualRocksDBReference.getColumnFamilyDescriptors().isEmpty()); + assertNull(actualRocksDBReference.getRocksDB()); + assertNull(actualRocksDBReference.getOptions()); + assertNull(actualRocksDBReference.getDbOptions()); + assertNull(actualRocksDBReference.getColumnFamilyOptions()); + assertTrue(actualRocksDBReference.getColumnFamilyHandleRegistry().isEmpty()); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreTest.java index 117cc1474..d34087441 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreTest.java @@ -1,13 +1,61 @@ -package org.dizitart.no2.rocksdb; +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ -import static org.junit.Assert.assertTrue; +package org.dizitart.no2.rocksdb; +import org.dizitart.no2.exceptions.InvalidOperationException; +import org.dizitart.no2.exceptions.NitriteException; import org.junit.Test; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + public class RocksDBStoreTest { @Test public void testConstructor() { assertTrue((new RocksDBStore()).isClosed()); + assertTrue((new RocksDBStore()).isClosed()); + } + + @Test + public void testConstructor2() { + RocksDBStore actualRocksDBStore = new RocksDBStore(); + assertFalse(actualRocksDBStore.hasUnsavedChanges()); + assertFalse(actualRocksDBStore.isReadOnly()); + } + + @Test(expected = NitriteException.class) + public void testOpenMap() { + RocksDBConfig rocksDBConfig = mock(RocksDBConfig.class); + when(rocksDBConfig.objectFormatter()).thenThrow(new NitriteException("An error occurred")); + + RocksDBStore rocksDBStore = new RocksDBStore(); + rocksDBStore.setStoreConfig(rocksDBConfig); + Class keyType = Object.class; + rocksDBStore.openMap("Map Name", keyType, Object.class); + verify(rocksDBConfig).objectFormatter(); + } + + @Test + public void testOpenRTree() { + RocksDBStore rocksDBStore = new RocksDBStore(); + Class keyType = Object.class; + assertThrows(InvalidOperationException.class, + () -> rocksDBStore.openRTree("R Tree Name", keyType, Object.class)); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreUtilsTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreUtilsTest.java new file mode 100644 index 000000000..43a478f04 --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBStoreUtilsTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.rocksdb; + +import org.dizitart.no2.exceptions.InvalidOperationException; +import org.dizitart.no2.store.events.StoreEventListener; +import org.junit.Test; + +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.mock; + +public class RocksDBStoreUtilsTest { + @Test + public void testOpenOrCreate() { + assertThrows(InvalidOperationException.class, () -> RocksDBStoreUtils.openOrCreate(new RocksDBConfig())); + } + + @Test + public void testOpenOrCreate2() { + RocksDBConfig rocksDBConfig = new RocksDBConfig(); + rocksDBConfig.addStoreEventListener(mock(StoreEventListener.class)); + assertThrows(InvalidOperationException.class, () -> RocksDBStoreUtils.openOrCreate(rocksDBConfig)); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBTest.java index 881f67602..175561fd7 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/RocksDBTest.java @@ -1,17 +1,18 @@ /* - * Copyright (c) 2019-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.dizitart.no2.rocksdb; @@ -21,7 +22,12 @@ import com.esotericsoftware.kryo.io.Input; import com.github.javafaker.Faker; import lombok.Data; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.integration.Retry; import org.dizitart.no2.store.NitriteMap; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.rocksdb.*; @@ -29,14 +35,42 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.text.ParseException; import java.util.*; +import static org.dizitart.no2.integration.TestUtil.deleteDb; +import static org.dizitart.no2.integration.TestUtil.getRandomTempDbFile; import static org.junit.Assert.assertEquals; /** * @author Anindya Chatterjee */ -public class RocksDBTest extends AbstractTest { +public class RocksDBTest { + private final String fileName = getRandomTempDbFile(); + private Nitrite db; + + @Rule + public Retry retry = new Retry(3); + + @Before + public void setUp() throws ParseException { + RocksDBModule storeModule = RocksDBModule.withConfig() + .filePath(fileName) + .build(); + + db = Nitrite.builder() + .loadModule(storeModule) + .fieldSeparator(".") + .openOrCreate(); + } + + @After + public void cleanUp() throws IOException { + if (db != null && !db.isClosed()) { + db.close(); + } + deleteDb(fileName); + } @Test public void testRocksDBMap() { diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java deleted file mode 100644 index b67d456db..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/StressTest.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; -import org.junit.Before; -import org.junit.Test; -import uk.co.jemos.podam.api.PodamFactory; -import uk.co.jemos.podam.api.PodamFactoryImpl; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class StressTest extends AbstractTest { - private NitriteCollection collection; - - @Before - public void before() { - collection = db.getCollection("test"); - } - - @Test - public void testIssue41() { - collection.createIndex("number", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("name", IndexOptions.indexOptions(IndexType.NonUnique)); - collection.createIndex("counter", IndexOptions.indexOptions(IndexType.Unique)); - - Random random = new Random(); - AtomicLong counter = new AtomicLong(System.currentTimeMillis()); - PodamFactory factory = new PodamFactoryImpl(); - - long start = System.currentTimeMillis(); - for (int i = 0; i < 100000; i++) { - Document doc = Document.createDocument(); - doc.put("number", random.nextDouble()); - doc.put("name", factory.manufacturePojo(String.class)); - doc.put("counter", counter.getAndIncrement()); - collection.insert(doc); - if (i % 10000 == 0) { - System.out.println(i + " entries written"); - } - } - System.out.println("Records inserted in " + ((System.currentTimeMillis() - start) / (1000 * 60)) + " minutes"); - - if (db.hasUnsavedChanges()) { - db.commit(); - } - - start = System.currentTimeMillis(); - DocumentCursor cursor = collection.find(); - System.out.println("Size ->" + cursor.size()); - System.out.println("Records size calculated in " + ((System.currentTimeMillis() - start) / (1000)) + " seconds"); - - int i = 0; - start = System.currentTimeMillis(); - for (Document element : cursor) { - assertNotNull(element); - i++; - if (i % 10000 == 0) { - System.out.println(i + " entries processed"); - } - } - System.out.println("Iteration completed in " + ((System.currentTimeMillis() - start) / (1000)) + " seconds"); - } - - @Test - public void testRepoPerformanceWithIndex() { - // warm-up - List items = getItems(PerfTestIndexed.class); - ObjectRepository repo = db.getRepository(PerfTestIndexed.class); - for (PerfTestIndexed item : items) { - assertNotNull(item); - repo.insert(item); - } - repo.remove(Filter.ALL); - repo.drop(); - - // actual calculation - repo = db.getRepository(PerfTestIndexed.class); - long start = System.currentTimeMillis(); - for (PerfTestIndexed item : items) { - repo.insert(item); - } - long diff = System.currentTimeMillis() - start; - System.out.println("Time take to insert 10000 indexed items - " + diff + "ms"); - - start = System.currentTimeMillis(); - repo.remove(Filter.ALL); - diff = System.currentTimeMillis() - start; - System.out.println("Time take to remove 10000 indexed items - " + diff + "ms"); - } - - @Test - public void testRepoPerformanceWithoutIndex() { - // warm-up - List items = getItems(PerfTest.class); - ObjectRepository repo = db.getRepository(PerfTest.class); - for (PerfTest item : items) { - assertNotNull(item); - repo.insert(item); - } - repo.remove(Filter.ALL); - repo.drop(); - - // actual calculation - repo = db.getRepository(PerfTest.class); - long start = System.currentTimeMillis(); - for (PerfTest item : items) { - repo.insert(item); - } - long diff = System.currentTimeMillis() - start; - System.out.println("Time take to insert 10000 non-indexed items - " + diff + "ms"); - - start = System.currentTimeMillis(); - repo.remove(Filter.ALL); - diff = System.currentTimeMillis() - start; - System.out.println("Time take to remove 10000 non-indexed items - " + diff + "ms"); - } - - private List getItems(Class type) { - PodamFactory generator = new PodamFactoryImpl(); - List items = new ArrayList<>(); - for (int i = 0; i < 10000; i++) { - items.add(generator.manufacturePojoWithFullData(type)); - } - assertEquals(items.size(), 10000); - return items; - } - - @Data - public static class PerfTest implements Mappable { - private String firstName; - private String lastName; - private Integer age; - private String text; - - @Override - public Document write(NitriteMapper mapper) { - Document document = Document.createDocument(); - document.put("firstName", firstName); - document.put("lastName", lastName); - document.put("age", age); - document.put("text", text); - return document; - } - - @Override - public void read(NitriteMapper mapper, Document document) { - this.firstName = (String) document.get("firstName"); - this.lastName = (String) document.get("lastName"); - this.age = (Integer) document.get("age"); - this.text = (String) document.get("text"); - } - } - - @Indices({ - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "age", type = IndexType.NonUnique), - @Index(value = "text", type = IndexType.Fulltext), - }) - private static class PerfTestIndexed extends PerfTest { - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/ValueSetTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/ValueSetTest.java new file mode 100644 index 000000000..da392e50c --- /dev/null +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/ValueSetTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.rocksdb; + +import org.dizitart.no2.rocksdb.formatter.KryoObjectFormatter; +import org.junit.Test; +import org.rocksdb.ColumnFamilyHandle; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksIterator; + +import static org.mockito.Mockito.*; + +public class ValueSetTest { + @Test + public void testIterator() { + RocksDB rocksDB = mock(RocksDB.class); + when(rocksDB.newIterator((ColumnFamilyHandle) any())).thenReturn(mock(RocksIterator.class)); + KryoObjectFormatter objectFormatter = new KryoObjectFormatter(); + (new ValueSet<>(rocksDB, null, objectFormatter, Object.class)).iterator(); + verify(rocksDB).newIterator((ColumnFamilyHandle) any()); + } +} + diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFactoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFactoryTest.java deleted file mode 100644 index e8806de40..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionFactoryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.collection; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.CollectionFactory; -import org.dizitart.no2.common.concurrent.LockService; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.rocksdb.Retry; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class CollectionFactoryTest { - - @Rule - public Retry retry = new Retry(3); - - @Test(expected = ValidationException.class) - public void testGetCollectionMapStoreNull() { - CollectionFactory factory = new CollectionFactory(new LockService()); - assertNotNull(factory); - - NitriteConfig config = new NitriteConfig(); - factory.getCollection(null, config, true); - } - - @Test(expected = ValidationException.class) - public void testGetCollectionContextNull() { - CollectionFactory factory = new CollectionFactory(new LockService()); - factory.getCollection("test", null, false); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatterTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatterTest.java index 4ccb88d69..eb44b2053 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatterTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/formatter/KryoObjectFormatterTest.java @@ -1,19 +1,20 @@ package org.dizitart.no2.rocksdb.formatter; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class KryoObjectFormatterTest { + @Test public void testEncode() { assertEquals(7, (new KryoObjectFormatter()).encode("object").length); - assertEquals(1, (new KryoObjectFormatter()).encode(null).length); + assertEquals(1, (new KryoObjectFormatter()).encode(null).length); } @Test public void testEncodeKey() { - assertEquals(1, (new KryoObjectFormatter()).encodeKey(null).length); + assertEquals(1, (new KryoObjectFormatter()).encodeKey(null).length); assertEquals(7, (new KryoObjectFormatter()).encodeKey("object").length); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java deleted file mode 100644 index 230fac3bc..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/InternalClass.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Data -class InternalClass implements Mappable { - @Id - private long id; - private String name; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("id", id) - .put("name", name); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Long.class); - name = document.get("name", String.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/NitriteIdAsIdTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/NitriteIdAsIdTest.java deleted file mode 100644 index 350632c9e..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/NitriteIdAsIdTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.common.util.Iterables; -import org.dizitart.no2.exceptions.InvalidIdException; -import org.dizitart.no2.rocksdb.AbstractTest; -import org.dizitart.no2.rocksdb.repository.data.WithNitriteId; -import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.Before; -import org.junit.Test; - -import java.text.ParseException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee - */ -public class NitriteIdAsIdTest extends AbstractTest { - private ObjectRepository repo; - - @Before - public void before() { - repo = db.getRepository(WithNitriteId.class); - } - - - @Test - public void testNitriteIdField() { - WithNitriteId item1 = new WithNitriteId(); - item1.name = "first"; - - WithNitriteId item2 = new WithNitriteId(); - item2.name = "second"; - - repo.insert(item1, item2); - - Cursor cursor = repo.find(); - for (WithNitriteId withNitriteId : cursor) { - System.out.println(withNitriteId.name); - assertNotNull(withNitriteId.idField); - } - - WithNitriteId withNitriteId = cursor.firstOrNull(); - withNitriteId.name = "third"; - - NitriteId id = withNitriteId.idField; - repo.update(withNitriteId); - - WithNitriteId byId = repo.getById(id); - assertEquals(withNitriteId, byId); - assertEquals(repo.size(), 2); - } - - @Test(expected = InvalidIdException.class) - public void setIdDuringInsert() { - WithNitriteId item1 = new WithNitriteId(); - item1.name = "first"; - item1.idField = NitriteId.newId(); - - repo.insert(item1); - } - - @Test - public void changeIdDuringUpdate() { - WithNitriteId item2 = new WithNitriteId(); - item2.name = "second"; - WriteResult result = repo.insert(item2); - NitriteId nitriteId = Iterables.firstOrNull(result); - WithNitriteId byId = repo.getById(nitriteId); - byId.idField = NitriteId.newId(); - - result = repo.update(byId); - assertEquals(result.getAffectedCount(), 0); - assertEquals(repo.size(), 1); - } - -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryNegativeTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryNegativeTest.java deleted file mode 100644 index db86865f7..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryNegativeTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - -import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.*; -import org.dizitart.no2.rocksdb.AbstractTest; -import org.dizitart.no2.rocksdb.repository.data.*; -import org.dizitart.no2.repository.ObjectRepository; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -public class ObjectRepositoryNegativeTest extends AbstractTest { - - @Test(expected = ObjectMappingException.class) - public void testWithCircularReference() { - ObjectRepository repository = db.getRepository(WithCircularReference.class); - - WithCircularReference parent = new WithCircularReference(); - parent.setName("parent"); - WithCircularReference object = new WithCircularReference(); - object.setName("test"); - object.setParent(parent); - // circular reference - parent.setParent(object); - - WriteResult result = repository.insert(object); - for (NitriteId id : result) { - WithCircularReference instance = repository.getById(id); - assertEquals(instance.getName(), object.getName()); - assertEquals(instance.getParent().getName(), object.getParent().getName()); - } - } - - @Test(expected = ObjectMappingException.class) - public void testWithCustomConstructor() { - ObjectRepository repository = db.getRepository(WithCustomConstructor.class); - - WithCustomConstructor object = new WithCustomConstructor("test", 2L); - - WriteResult result = repository.insert(object); - for (NitriteId id : result) { - WithCustomConstructor instance = repository.getById(id); - assertEquals(object.getName(), instance.getName()); - assertEquals(object.getNumber(), instance.getNumber()); - } - } - - @Test(expected = InvalidIdException.class) - public void testWithEmptyStringId() { - ObjectRepository repository = db.getRepository(WithEmptyStringId.class); - WithEmptyStringId object = new WithEmptyStringId(); - object.setName(""); // empty id value - - WriteResult result = repository.insert(object); - for (NitriteId id : result) { - WithEmptyStringId instance = repository.getById(id); - assertEquals(instance, object); - } - } - - @Test(expected = InvalidIdException.class) - public void testWithNullId() { - ObjectRepository repository = db.getRepository(WithNullId.class); - WithNullId object = new WithNullId(); - - WriteResult result = repository.insert(object); - for (NitriteId id : result) { - WithNullId instance = repository.getById(id); - assertEquals(instance, object); - } - } - - @Test(expected = ValidationException.class) - public void testWithValueTypeRepository() { - ObjectRepository repository = db.getRepository(String.class); - repository.insert("test"); - } - - @Test(expected = InvalidOperationException.class) - public void testFindResultRemove() { - ObjectRepository repository = db.getRepository(Employee.class); - repository.insert(DataGenerator.generateEmployee()); - RecordStream result = repository.find(); - result.iterator().remove(); - } - - @Test(expected = InvalidOperationException.class) - public void testWithObjectId() { - ObjectRepository repository = db.getRepository(WithObjectId.class); - WithOutId id = new WithOutId(); - id.setName("test"); - id.setNumber(1); - - WithObjectId object = new WithObjectId(); - object.setWithOutId(id); - repository.insert(object); - } - - @Test(expected = NotIdentifiableException.class) - public void testUpdateNoId() { - ObjectRepository repository = db.getRepository(WithOutId.class); - WithOutId object = new WithOutId(); - object.setName("name"); - object.setNumber(1L); - repository.update(object); - } - - @Test(expected = NotIdentifiableException.class) - public void testRemoveNoId() { - ObjectRepository repository = db.getRepository(WithOutId.class); - WithOutId object = new WithOutId(); - object.setName("name"); - object.setNumber(1L); - repository.remove(object); - } - - @Test(expected = ValidationException.class) - public void testProjectionFailedInstantiate() { - ObjectRepository repository = db.getRepository(WithOutId.class); - WithOutId object = new WithOutId(); - object.setName("name"); - object.setNumber(1L); - repository.insert(object); - - RecordStream project = repository.find().project(NitriteId.class); - assertNull(project.toList()); - } - - @Test(expected = ValidationException.class) - public void testNullInsert() { - ObjectRepository repository = db.getRepository(WithOutId.class); - repository.insert(null); - } - - @Test(expected = InvalidIdException.class) - public void testGetByNullId() { - ObjectRepository repository = db.getRepository(WithPublicField.class); - WithPublicField object = new WithPublicField(); - object.name = "test"; - object.number = 2; - - repository.insert(object); - WithPublicField instance = repository.getById(null); - assertEquals(object.name, instance.name); - assertEquals(object.number, instance.number); - } - - @Test - public void testExternalNitriteId() { - ObjectRepository repository = db.getRepository(WithNitriteId.class); - WithNitriteId obj = new WithNitriteId(); - NitriteId id = NitriteId.createId("1"); - obj.setIdField(id); - obj.setName("testExternalNitriteId"); - WriteResult result = repository.update(obj, true); - - obj = new WithNitriteId(); - id = result.iterator().next(); - obj.setIdField(id); - obj.setName("testExternalNitriteId"); - result = repository.update(obj, true); - assertNotEquals(id.getIdValue(), result.iterator().next().getIdValue()); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java deleted file mode 100644 index b84a9b265..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ObjectRepositoryTest.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - -import com.github.javafaker.Faker; -import lombok.Data; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.collection.meta.Attributes; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.repository.annotations.Entity; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.rocksdb.AbstractTest; -import org.dizitart.no2.rocksdb.repository.data.*; -import org.junit.Test; - -import java.util.Date; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.awaitility.Awaitility.await; -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee. - */ -public class ObjectRepositoryTest extends AbstractTest { - - @Test - public void testWithClassField() { - ObjectRepository repository = db.getRepository(WithClassField.class); - - WithClassField object = new WithClassField(); - object.setName("test"); - object.setClazz(String.class); - - repository.insert(object); - WithClassField instance = repository.getById("test"); - assertEquals(instance.getName(), object.getName()); - assertEquals(instance.getClazz(), object.getClazz()); - } - - @Test - public void testWithFinalField() { - ObjectRepository repository = db.getRepository(WithFinalField.class); - WithFinalField object = new WithFinalField(); - object.setName("test"); - - repository.insert(object); - for (WithFinalField instance : repository.find()) { - assertEquals(object.getName(), instance.getName()); - assertEquals(object.getNumber(), instance.getNumber()); - } - } - - @Test - public void testWithOutGetterSetter() { - ObjectRepository repository = db.getRepository(WithOutGetterSetter.class); - WithOutGetterSetter object = new WithOutGetterSetter(); - - repository.insert(object); - for (WithOutGetterSetter instance : repository.find()) { - assertEquals(object, instance); - } - } - - @Test - public void testWithOutId() { - ObjectRepository repository = db.getRepository(WithOutId.class); - WithOutId object = new WithOutId(); - object.setName("test"); - object.setNumber(2); - - repository.insert(object); - for (WithOutId instance : repository.find()) { - assertEquals(object.getName(), instance.getName()); - assertEquals(object.getNumber(), instance.getNumber()); - } - } - - @Test - public void testWithPublicField() { - ObjectRepository repository = db.getRepository(WithPublicField.class); - WithPublicField object = new WithPublicField(); - object.name = "test"; - object.number = 2; - - repository.insert(object); - WithPublicField instance = repository.getById("test"); - assertEquals(object.name, instance.name); - assertEquals(object.number, instance.number); - } - - @Test - public void testWithTransientField() { - ObjectRepository repository = db.getRepository(WithTransientField.class); - WithTransientField object = new WithTransientField(); - object.setNumber(2); - object.setName("test"); - - repository.insert(object); - WithTransientField instance = repository.getById(2L); - assertNotEquals(object.getName(), instance.getName()); - assertNull(instance.getName()); - assertEquals(object.getNumber(), instance.getNumber()); - } - - @Test - public void testWriteThousandRecords() { - int count = 5000; - - ObjectRepository repository = db.getRepository(StressRecord.class); - - for (int i = 0; i < count; i++) { - StressRecord record = new StressRecord(); - record.setFirstName(UUID.randomUUID().toString()); - record.setFailed(false); - record.setLastName(UUID.randomUUID().toString()); - record.setProcessed(false); - - repository.insert(record); - } - - Cursor cursor - = repository.find(where("failed").eq(false)); - - for (StressRecord record : cursor) { - record.setProcessed(true); - repository.update(where("firstName").eq(record.getFirstName()), record); - } - } - - @Test - public void testWithPackagePrivateClass() { - ObjectRepository repository = db.getRepository(InternalClass.class); - InternalClass internalClass = new InternalClass(); - internalClass.setId(1); - internalClass.setName("name"); - - repository.insert(internalClass); - InternalClass instance = repository.getById((long) 1); - assertEquals(internalClass.getName(), instance.getName()); - assertEquals(internalClass.getId(), instance.getId()); - } - - @Test - public void testWithPrivateConstructor() { - ObjectRepository repository = - db.getRepository(WithPrivateConstructor.class); - - WithPrivateConstructor object = WithPrivateConstructor.create("test", 2L); - repository.insert(object); - for (WithPrivateConstructor instance : repository.find()) { - assertEquals(object, instance); - } - } - - @Test - public void testWithDateAsId() { - ObjectRepository repository = db.getRepository(WithDateId.class); - - WithDateId object1 = new WithDateId(); - object1.setId(new Date(1482773634L)); - object1.setName("first date"); - repository.insert(object1); - - WithDateId object2 = new WithDateId(); - object2.setName("second date"); - object2.setId(new Date(1482773720L)); - repository.insert(object2); - - assertEquals(repository.find(where("id").eq(new Date(1482773634L))) - .firstOrNull(), object1); - assertEquals(repository.find(where("id").eq(new Date(1482773720L))) - .firstOrNull(), object2); - } - - @Test - public void testWithIdInheritance() { - ObjectRepository repository = db.getRepository(ChildClass.class); - assertTrue(repository.hasIndex("id")); - assertTrue(repository.hasIndex("date")); - assertTrue(repository.hasIndex("text")); - - ChildClass childClass = new ChildClass(); - childClass.setName("first"); - childClass.setDate(new Date(100000L)); - childClass.setId(1L); - childClass.setText("I am first class"); - repository.insert(childClass); - - childClass = new ChildClass(); - childClass.setName("seconds"); - childClass.setDate(new Date(100001L)); - childClass.setId(2L); - childClass.setText("I am second class"); - repository.insert(childClass); - - childClass = new ChildClass(); - childClass.setName("third"); - childClass.setDate(new Date(100002L)); - childClass.setId(3L); - childClass.setText("I am third class"); - repository.insert(childClass); - - assertEquals(repository.find(where("text").text("class")).size(), 3); - assertEquals(repository.find(where("text").text("second")).size(), 0); // filtered in stop words - assertEquals(repository.find(where("date").eq(new Date(100000L))).size(), 1); - assertEquals(repository.find(where("id").eq(1L)).size(), 1); - } - - @Test - public void testAttributes() { - ObjectRepository repository = db.getRepository(WithDateId.class); - Attributes attributes = new Attributes(repository.getDocumentCollection().getName()); - repository.setAttributes(attributes); - assertEquals(repository.getAttributes(), attributes); - } - - @Test - public void testKeyedRepository() { - // an object repository of employees who are managers - ObjectRepository managerRepo = db.getRepository(Employee.class, "managers"); - - // an object repository of all employee - ObjectRepository employeeRepo = db.getRepository(Employee.class); - - // and object repository of employees who are developers - ObjectRepository developerRepo = db.getRepository(Employee.class, "developers"); - - Employee manager = new Employee(); - manager.setEmpId(1L); - manager.setAddress("abcd"); - manager.setJoinDate(new Date()); - - Employee developer = new Employee(); - developer.setEmpId(2L); - developer.setAddress("xyz"); - developer.setJoinDate(new Date()); - - managerRepo.insert(manager); - employeeRepo.insert(manager, developer); - developerRepo.insert(developer); - - assertTrue(db.hasRepository(Employee.class)); - assertTrue(db.hasRepository(Employee.class, "managers")); - assertTrue(db.hasRepository(Employee.class, "developers")); - - assertEquals(db.listRepositories().size(), 1); - assertEquals(db.listKeyedRepository().size(), 2); - - assertEquals(employeeRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(employeeRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(managerRepo.find(where("address").eq("xyz")).size(), 0); - assertEquals(managerRepo.find(where("address").eq("abcd")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("xyz")).size(), 1); - assertEquals(developerRepo.find(where("address").eq("abcd")).size(), 0); - } - - @Test - public void testEntityRepository() { - ObjectRepository managerRepo = db.getRepository(EmployeeEntity.class, "managers"); - ObjectRepository employeeRepo = db.getRepository(EmployeeEntity.class); - ObjectRepository developerRepo = db.getRepository(EmployeeEntity.class, "developers"); - - managerRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); - employeeRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); - developerRepo.insert(new EmployeeEntity(), new EmployeeEntity(), new EmployeeEntity()); - - boolean errored = false; - try { - NitriteCollection collection = db.getCollection("entity.employee"); - } catch (ValidationException e) { - errored = true; - } - assertTrue(errored); - - assertTrue(db.listRepositories().contains("entity.employee")); - assertEquals(db.listKeyedRepository().size(), 2); - assertEquals(db.listCollectionNames().size(), 0); - - assertTrue(managerRepo.hasIndex("firstName")); - assertTrue(managerRepo.hasIndex("lastName")); - assertTrue(employeeRepo.hasIndex("lastName")); - assertTrue(employeeRepo.hasIndex("lastName")); - - managerRepo.drop(); - assertEquals(db.listKeyedRepository().size(), 1); - } - - @Test - public void testIssue217() { - ObjectRepository employeeRepo = db.getRepository(EmployeeEntity.class); - AtomicInteger counter = new AtomicInteger(0); - employeeRepo.subscribe(eventInfo -> counter.incrementAndGet()); - - ObjectRepository employeeRepo2 = db.getRepository(EmployeeEntity.class); - employeeRepo2.insert(new EmployeeEntity()); - await().atMost(5, TimeUnit.SECONDS).until(() -> counter.get() == 1); - } - - @Data - @Entity(value = "entity.employee", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), - }) - private static class EmployeeEntity implements Mappable { - private static final Faker faker = new Faker(); - - @Id - private Long id; - private String firstName; - private String lastName; - - public EmployeeEntity() { - id = faker.number().randomNumber(); - firstName = faker.name().firstName(); - lastName = faker.name().lastName(); - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("id", id) - .put("firstName", firstName) - .put("lastName", lastName); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - id = document.get("id", Long.class); - firstName = document.get("firstName", String.class); - lastName = document.get("lastName", String.class); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ProjectionTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ProjectionTest.java deleted file mode 100644 index 4e2b9dcd4..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/ProjectionTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - -import org.dizitart.no2.common.RecordStream; -import org.dizitart.no2.exceptions.InvalidOperationException; -import org.dizitart.no2.rocksdb.repository.data.SubEmployee; -import org.junit.Test; - -import java.util.Iterator; - -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -public class ProjectionTest extends BaseObjectRepositoryTest { - - @Test - public void testHasMore() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) - .project(SubEmployee.class); - assertFalse(iterable.isEmpty()); - } - - @Test - public void testSize() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) - .project(SubEmployee.class); - assertEquals(iterable.size(), 5); - } - - @Test - public void testToString() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) - .project(SubEmployee.class); - assertNotNull(iterable.toString()); - } - - @Test(expected = InvalidOperationException.class) - public void testRemove() { - RecordStream iterable = employeeRepository.find().skipLimit(0, 5) - .project(SubEmployee.class); - Iterator iterator = iterable.iterator(); - if (iterator.hasNext()) { - iterator.next(); - iterator.remove(); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UnAnnotatedObjectTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UnAnnotatedObjectTest.java deleted file mode 100644 index e3aab29aa..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/UnAnnotatedObjectTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository; - - -import org.dizitart.no2.common.SortOrder; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.repository.data.ClassA; -import org.dizitart.no2.rocksdb.repository.data.ClassC; -import org.dizitart.no2.repository.Cursor; -import org.junit.Test; - -import static org.dizitart.no2.filters.FluentFilter.where; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * @author Anindya Chatterjee. - */ -public class UnAnnotatedObjectTest extends BaseObjectRepositoryTest { - - @Test - @SuppressWarnings("unchecked") - public void testFind() { - Cursor cursor = aObjectRepository.find(); - assertEquals(cursor.size(), 10); - assertFalse(cursor.isEmpty()); - - IndexOptions indexOptions = new IndexOptions(); - indexOptions.setIndexType(IndexType.Unique); - aObjectRepository.createIndex("b.number", indexOptions); - - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Ascending).skipLimit(0, 10); - - System.out.println("Available - " + !cursor.isEmpty()); - System.out.println("Total Size - " + cursor.size()); - - Iterable findRecord = cursor.project(ClassA.class); - for (ClassA classA : findRecord) { - System.out.println(classA); - } - - cursor = aObjectRepository.find(where("b.number").eq(160).not()). - sort("b.number", SortOrder.Descending).skipLimit(2, 7); - - System.out.println("Available - " + !cursor.isEmpty()); - System.out.println("Total Size - " + cursor.size()); - - findRecord = cursor.project(ClassA.class); - for (ClassA classA : findRecord) { - System.out.println(classA); - } - - cursor = cObjectRepository.find(where("id").gt(900)). - sort("id", SortOrder.Descending).skipLimit(2, 7); - System.out.println("Available - " + !cursor.isEmpty()); - System.out.println("Total Size - " + cursor.size()); - - Iterable findRecordC = cursor.project(ClassC.class); - for (ClassC classC : findRecordC) { - System.out.println(classC); - } - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java deleted file mode 100644 index 8579166d8..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ClassA.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -import java.util.UUID; - -@EqualsAndHashCode -@ToString -public class ClassA implements Mappable { - @Getter - @Setter - private ClassB classB; - @Getter - @Setter - private UUID uid; - @Getter - @Setter - private String string; - @Getter - @Setter - private byte[] blob; - - public static ClassA create(int seed) { - ClassB classB = ClassB.create(seed); - ClassA classA = new ClassA(); - classA.classB = classB; - classA.uid = new UUID(seed, seed + 50); - classA.string = Integer.toHexString(seed); - classA.blob = new byte[]{(byte) seed}; - return classA; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("classB", classB != null ? classB.write(mapper) : null) - .put("uid", uid) - .put("string", string) - .put("blob", blob); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - if (document.get("classB") != null) { - classB = new ClassB(); - classB.read(mapper, document.get("classB", Document.class)); - } - uid = document.get("uid", UUID.class); - string = document.get("string", String.class); - blob = document.get("blob", byte[].class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java deleted file mode 100644 index b13c337ad..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/Company.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; -import org.dizitart.no2.repository.annotations.Index; -import org.dizitart.no2.repository.annotations.Indices; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * @author Anindya Chatterjee. - */ -@ToString -@EqualsAndHashCode -@Indices({ - @Index(value = "companyName") -}) -public class Company implements Serializable, Mappable { - @Id - @Getter - @Setter - private Long companyId; - - @Getter - @Setter - private String companyName; - - @Getter - @Setter - private Date dateCreated; - - @Getter - @Setter - private List departments; - - @Getter - @Setter - private Map> employeeRecord; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("companyId", companyId) - .put("companyName", companyName) - .put("dateCreated", dateCreated) - .put("departments", departments) - .put("employeeRecord", employeeRecord); - } - - @Override - @SuppressWarnings("unchecked") - public void read(NitriteMapper mapper, Document document) { - companyId = document.get("companyId", Long.class); - companyName = document.get("companyName", String.class); - dateCreated = document.get("dateCreated", Date.class); - departments = document.get("departments", List.class); - employeeRecord = document.get("employeeRecord", Map.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java deleted file mode 100644 index 6914fcadc..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/ProductScore.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee - */ -@Getter -@Setter -public class ProductScore implements Mappable { - private String product; - private int score; - - public ProductScore() { - } - - public ProductScore(String product, int score) { - this.product = product; - this.score = score; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("product", product) - .put("score", score); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - product = document.get("product", String.class); - score = document.get("score", Integer.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java deleted file mode 100644 index 6a36a7604..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/StressRecord.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class StressRecord implements Mappable { - @Id - private String firstName; - private boolean processed; - private String lastName; - private boolean failed; - private String notes; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument().put("firstName", firstName) - .put("processed", processed) - .put("lastName", lastName) - .put("failed", failed) - .put("notes", notes); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - firstName = document.get("firstName", String.class); - processed = document.get("processed", Boolean.class); - lastName = document.get("lastName", String.class); - failed = document.get("failed", Boolean.class); - notes = document.get("notes", String.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java deleted file mode 100644 index 0e5f8a054..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/SuperDuperClass.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Index; - -/** - * @author Anindya Chatterjee - */ -@Getter -@Setter -@Index(value = "text", type = IndexType.Fulltext) -public class SuperDuperClass implements Mappable { - private String text; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("text", text); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - text = document.get("text", String.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java deleted file mode 100644 index df3613b6a..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithClassField.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithClassField implements Mappable { - @Id - private String name; - private Class clazz; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("name", name) - .put("clazz", clazz); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - clazz = document.get("clazz", Class.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java deleted file mode 100644 index 94c36d7b8..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithNullId.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.Getter; -import lombok.Setter; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.repository.annotations.Id; - -/** - * @author Anindya Chatterjee. - */ -@Getter -@Setter -public class WithNullId implements Mappable { - @Id - private String name; - private long number; - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument() - .put("name", name) - .put("number", number); - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - number = document.get("number", Long.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java deleted file mode 100644 index bd42f1b2c..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/repository/data/WithOutGetterSetter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.repository.data; - -import lombok.EqualsAndHashCode; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.mapper.Mappable; -import org.dizitart.no2.common.mapper.NitriteMapper; - -/** - * @author Anindya Chatterjee. - */ -@EqualsAndHashCode -public class WithOutGetterSetter implements Mappable { - private String name; - private long number; - - public WithOutGetterSetter() { - name = "test"; - number = 2; - } - - @Override - public Document write(NitriteMapper mapper) { - return Document.createDocument("name", name) - .put("number", number); - - } - - @Override - public void read(NitriteMapper mapper, Document document) { - name = document.get("name", String.class); - number = document.get("number", Long.class); - } -} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteMapStressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteMapStressTest.java deleted file mode 100644 index 26134ba70..000000000 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/rocksdb/NitriteMapStressTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2019-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.rocksdb.rocksdb; - -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.ValidationException; -import org.dizitart.no2.rocksdb.AbstractTest; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteStore; -import org.junit.Test; - -import java.util.UUID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Anindya Chatterjee. - */ -public class NitriteMapStressTest extends AbstractTest { - - @Test - public void testWithInsertReadUpdate() { - NitriteStore nitriteStore = db.getStore(); - NitriteMap nitriteMap = nitriteStore.openMap("testWithInsertReadUpdate", String.class, Document.class); - - int count = 10000; - for (int i = 0; i < count; i++) { - Document record = Document.createDocument(); - record.put("firstName", UUID.randomUUID().toString()); - record.put("failed", false); - record.put("lastName", UUID.randomUUID().toString()); - record.put("processed", false); - - nitriteMap.put(UUID.randomUUID().toString(), record); - } - - for (Pair entry : nitriteMap.entries()) { - String key = entry.getFirst(); - Document record = entry.getSecond(); - - record.put("processed", true); - - nitriteMap.put(key, record); - } - - assertEquals(nitriteMap.size(), 10000); - } - - @Test - public void testNullKey() { - NitriteStore nitriteStore = db.getStore(); - NitriteMap nitriteMap = nitriteStore.openMap("testNullKey", String.class, Document.class); - nitriteMap.put(null, Document.createDocument()); - - assertNotNull(nitriteMap.get(null)); - assertEquals(nitriteMap.size(), 1); - - nitriteMap.put(null, Document.createDocument("first", 1)); - assertNotNull(nitriteMap.get(null)); - assertEquals(nitriteMap.size(), 1); - } - - @Test(expected = ValidationException.class) - public void testNullValue() { - NitriteStore nitriteStore = db.getStore(); - NitriteMap nitriteMap = nitriteStore.openMap("testNullValue", String.class, Document.class); - nitriteMap.put(null, null); - } - - @Test(expected = ValidationException.class) - public void testNullPutIfAbsent() { - NitriteStore nitriteStore = db.getStore(); - NitriteMap nitriteMap = nitriteStore.openMap("testNullPutIfAbsent", String.class, Document.class); - nitriteMap.putIfAbsent(null, null); - } -} diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/FluentFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/FluentFilter.java index bbafe16f1..1793e8564 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/FluentFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/FluentFilter.java @@ -22,7 +22,10 @@ import org.locationtech.jts.geom.Point; /** + * Fluent filter api for spatial data + * * @author Anindya Chatterjee + * @since 4.0 */ public class FluentFilter { private String field; @@ -30,24 +33,60 @@ public class FluentFilter { private FluentFilter() { } + /** + * Where clause for fluent filter. + * + * @param field the field + * @return the fluent filter + */ public static FluentFilter where(String field) { FluentFilter filter = new FluentFilter(); filter.field = field; return filter; } + /** + * Creates an spatial filter which matches documents where the spatial data + * of a field intersects the specified {@link Geometry} value. + * + * @param geometry the geometry + * @return the filter + */ public Filter intersects(Geometry geometry) { return new IntersectsFilter(field, geometry); } + /** + * Creates a spatial filter which matches documents where the spatial data + * of a field is within the specified {@link Geometry} value. + * + * @param geometry the geometry + * @return the filter + */ public Filter within(Geometry geometry) { return new WithinFilter(field, geometry); } + /** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified coordinate. + * + * @param point the point + * @param distance the distance + * @return the filter + */ public Filter near(Coordinate point, Double distance) { return new NearFilter(field, point, distance); } + /** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified point. + * + * @param point the point + * @param distance the distance + * @return the filter + */ public Filter near(Point point, Double distance) { return new NearFilter(field, point, distance); } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java index de84c3d25..89a1f7863 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/IntersectsFilter.java @@ -16,13 +16,13 @@ package org.dizitart.no2.spatial; -import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.index.IndexMap; import org.locationtech.jts.geom.Geometry; import java.util.List; /** + * @since 4.0 * @author Anindya Chatterjee */ class IntersectsFilter extends SpatialFilter { @@ -32,6 +32,12 @@ protected IntersectsFilter(String field, Geometry geometry) { @Override public List applyOnIndex(IndexMap indexMap) { - return false + // calculated from SpatialIndex + return null; + } + + @Override + public String toString() { + return "(" + getField() + " intersects " + getValue() + ")"; } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NearFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NearFilter.java index 4ae677884..fe4d4764e 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NearFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NearFilter.java @@ -22,6 +22,7 @@ import org.locationtech.jts.util.GeometricShapeFactory; /** + * @since 4.0 * @author Anindya Chatterjee */ class NearFilter extends WithinFilter { @@ -40,4 +41,9 @@ private static Geometry createCircle(Coordinate center, double radius) { shapeFactory.setSize(radius * 2); return shapeFactory.createCircle(); } + + @Override + public String toString() { + return "(" + getField() + " nears " + getValue() + ")"; + } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NitriteBoundingBox.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NitriteBoundingBox.java index 53ba2030a..f8249b568 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NitriteBoundingBox.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/NitriteBoundingBox.java @@ -26,6 +26,8 @@ import java.io.ObjectOutputStream; /** + * + * @since 4.0 * @author Anindya Chatterjee */ @Data diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java index eb563a437..5c8e8fe4d 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialFilter.java @@ -19,16 +19,24 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.filters.ComparableFilter; +import org.dizitart.no2.filters.IndexOnlyFilter; import org.locationtech.jts.geom.Geometry; /** + * Represents a spatial filter. + * + * @since 4.0 * @author Anindya Chatterjee */ -public abstract class SpatialFilter extends ComparableFilter { +public abstract class SpatialFilter extends IndexOnlyFilter { private final Geometry geometry; + /** + * Instantiates a new {@link SpatialFilter}. + * + * @param field the field + * @param geometry the geometry + */ protected SpatialFilter(String field, Geometry geometry) { super(field, geometry); this.geometry = geometry; @@ -41,6 +49,17 @@ public Geometry getValue() { @Override public boolean apply(Pair element) { - throw new FilterException(getField() + " is not indexed with spatial index"); + return false; + } + + @Override + public String supportedIndexType() { + return SpatialIndexer.SPATIAL_INDEX; + } + + @Override + public boolean canBeGrouped(IndexOnlyFilter other) { + return other instanceof SpatialFilter + && other.getField().equals(getField()); } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndex.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndex.java new file mode 100644 index 000000000..eb2edd966 --- /dev/null +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndex.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.spatial; + +import lombok.Getter; +import org.dizitart.no2.NitriteConfig; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; +import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.filters.ComparableFilter; +import org.dizitart.no2.filters.IndexScanFilter; +import org.dizitart.no2.index.BoundingBox; +import org.dizitart.no2.index.IndexDescriptor; +import org.dizitart.no2.index.NitriteIndex; +import org.dizitart.no2.store.NitriteRTree; +import org.dizitart.no2.store.NitriteStore; +import org.locationtech.jts.geom.Geometry; + +import java.util.LinkedHashSet; +import java.util.List; + +import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; + +/** + * Represents a spatial index in nitrite. + * + * @since 4.0 + * @author Anindya Chatterjee + */ +public class SpatialIndex implements NitriteIndex { + @Getter + private final IndexDescriptor indexDescriptor; + private final NitriteStore nitriteStore; + private final NitriteConfig nitriteConfig; + + /** + * Instantiates a new {@link SpatialIndex}. + * + * @param indexDescriptor the index descriptor + * @param nitriteConfig the nitrite config + */ + public SpatialIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + this.indexDescriptor = indexDescriptor; + this.nitriteConfig = nitriteConfig; + this.nitriteStore = nitriteConfig.getNitriteStore(); + } + + @Override + public void write(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + NitriteRTree indexMap = findIndexMap(); + if (element == null) { + indexMap.add(null, fieldValues.getNitriteId()); + } else { + Geometry geometry = parseGeometry(firstField, element); + BoundingBox boundingBox = new NitriteBoundingBox(geometry); + indexMap.add(boundingBox, fieldValues.getNitriteId()); + } + } + + @Override + public void remove(FieldValues fieldValues) { + Fields fields = fieldValues.getFields(); + List fieldNames = fields.getFieldNames(); + + String firstField = fieldNames.get(0); + Object element = fieldValues.get(firstField); + + NitriteRTree indexMap = findIndexMap(); + if (element == null) { + indexMap.remove(null, fieldValues.getNitriteId()); + } else { + Geometry geometry = parseGeometry(firstField, element); + BoundingBox boundingBox = new NitriteBoundingBox(geometry); + indexMap.remove(boundingBox, fieldValues.getNitriteId()); + } + } + + @Override + public void drop() { + NitriteRTree indexMap = findIndexMap(); + indexMap.clear(); + indexMap.drop(); + } + + @Override + public LinkedHashSet findNitriteIds(FindPlan findPlan) { + IndexScanFilter indexScanFilter = findPlan.getIndexScanFilter(); + if (indexScanFilter == null + || indexScanFilter.getFilters() == null + || indexScanFilter.getFilters().isEmpty()) { + throw new FilterException("no spatial filter found"); + } + + List filters = indexScanFilter.getFilters(); + ComparableFilter filter = filters.get(0); + + if (!(filter instanceof SpatialFilter)) { + throw new FilterException("spatial filter must be the first filter for index scan"); + } + + RecordStream keys = null; + NitriteRTree indexMap = findIndexMap(); + + SpatialFilter spatialFilter = (SpatialFilter) filter; + Geometry geometry = spatialFilter.getValue(); + BoundingBox boundingBox = new NitriteBoundingBox(geometry); + + if (filter instanceof WithinFilter) { + keys = indexMap.findContainedKeys(boundingBox); + } else if (filter instanceof IntersectsFilter) { + keys = indexMap.findIntersectingKeys(boundingBox); + } + + LinkedHashSet nitriteIds = new LinkedHashSet<>(); + if (keys != null) { + for (NitriteId nitriteId : keys) { + nitriteIds.add(nitriteId); + } + } + + return nitriteIds; + } + + private NitriteRTree findIndexMap() { + String mapName = deriveIndexMapName(indexDescriptor); + return nitriteStore.openRTree(mapName, BoundingBox.class, Geometry.class); + } + + private Geometry parseGeometry(String field, Object fieldValue) { + if (fieldValue == null) return null; + if (fieldValue instanceof String) { + return nitriteConfig.nitriteMapper().convert(fieldValue, Geometry.class); + } else if (fieldValue instanceof Geometry) { + return (Geometry) fieldValue; + } + throw new IndexingException("field " + field + " does not contain Geometry data"); + } +} diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java index d2bf851cd..091766b57 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialIndexer.java @@ -17,96 +17,85 @@ package org.dizitart.no2.spatial; import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.common.RecordStream; +import org.dizitart.no2.common.FieldValues; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.index.BoundingBox; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.store.NitriteMap; -import org.dizitart.no2.store.NitriteRTree; -import org.dizitart.no2.store.NitriteStore; -import org.locationtech.jts.geom.Geometry; + +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** + * Represents a spatial data indexer. + * * @author Anindya Chatterjee - * @since 4.0.0 + * @since 4.0 */ public class SpatialIndexer implements NitriteIndexer { - public static final String SpatialIndex = "Spatial"; - - private NitriteMapper nitriteMapper; - private NitriteStore nitriteStore; - - public SpatialIndexer clone() throws CloneNotSupportedException { - return (SpatialIndexer) super.clone(); - } - - public RecordStream findWithin(String collectionName, String field, Geometry geometry) { - NitriteRTree indexMap = getIndexMap(collectionName, field); - BoundingBox boundingBox = new NitriteBoundingBox(geometry); - return indexMap.findContainedKeys(boundingBox); - } + /** + * Spatial index type. + */ + public static final String SPATIAL_INDEX = "Spatial"; + private final Map indexRegistry; - public RecordStream findIntersects(String collectionName, String field, Geometry geometry) { - NitriteRTree indexMap = getIndexMap(collectionName, field); - BoundingBox boundingBox = new NitriteBoundingBox(geometry); - return indexMap.findIntersectingKeys(boundingBox); + /** + * Instantiates a new {@link SpatialIndexer}. + */ + public SpatialIndexer() { + this.indexRegistry = new ConcurrentHashMap<>(); } @Override public String getIndexType() { - return SpatialIndex; + return SPATIAL_INDEX; } @Override - public void writeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - if (fieldValue == null) return; - NitriteRTree indexMap = getIndexMap(collection.getName(), field); - Geometry geometry = parseGeometry(field, fieldValue); - BoundingBox boundingBox = new NitriteBoundingBox(geometry); - indexMap.add(boundingBox, nitriteId); + public void validateIndex(Fields fields) { + if (fields.getFieldNames().size() > 1) { + throw new IndexingException("spatial index can only be created on a single field"); + } } @Override - public void removeIndex(NitriteMap collection, NitriteId nitriteId, String field, Object fieldValue) { - if (fieldValue == null) return; - NitriteRTree indexMap = getIndexMap(collection.getName(), field); - Geometry geometry = parseGeometry(field, fieldValue); - BoundingBox boundingBox = new NitriteBoundingBox(geometry); - indexMap.remove(boundingBox, nitriteId); + public void dropIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + SpatialIndex spatialIndex = findSpatialIndex(indexDescriptor, nitriteConfig); + spatialIndex.drop(); } @Override - public void updateIndex(NitriteMap collection, NitriteId nitriteId, String field, Object newValue, Object oldValue) { - removeIndex(collection, nitriteId, field, oldValue); - writeIndex(collection, nitriteId, field, newValue); + public void writeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + SpatialIndex spatialIndex = findSpatialIndex(indexDescriptor, nitriteConfig); + spatialIndex.write(fieldValues); } @Override - public void dropIndex(NitriteMap collection, String field) { - // no action required + public void removeIndexEntry(FieldValues fieldValues, IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + SpatialIndex spatialIndex = findSpatialIndex(indexDescriptor, nitriteConfig); + spatialIndex.remove(fieldValues); } @Override - public void initialize(NitriteConfig nitriteConfig) { - this.nitriteStore = nitriteConfig.getNitriteStore(); - this.nitriteMapper = nitriteConfig.nitriteMapper(); + public LinkedHashSet findByFilter(FindPlan findPlan, NitriteConfig nitriteConfig) { + SpatialIndex spatialIndex = findSpatialIndex(findPlan.getIndexDescriptor(), nitriteConfig); + return spatialIndex.findNitriteIds(findPlan); } - private NitriteRTree getIndexMap(String collectionName, String field) { - String mapName = getIndexMapName(collectionName, field); - return nitriteStore.openRTree(mapName, BoundingBox.class, Geometry.class); + @Override + public void initialize(NitriteConfig nitriteConfig) { } - private Geometry parseGeometry(String field, Object fieldValue) { - if (fieldValue == null) return null; - if (fieldValue instanceof String) { - return nitriteMapper.convert(fieldValue, Geometry.class); - } else if (fieldValue instanceof Geometry) { - return (Geometry) fieldValue; + private SpatialIndex findSpatialIndex(IndexDescriptor indexDescriptor, NitriteConfig nitriteConfig) { + if (indexRegistry.containsKey(indexDescriptor)) { + return indexRegistry.get(indexDescriptor); } - throw new IndexingException("field " + field + " does not contain Geometry data"); + + SpatialIndex nitriteIndex = new SpatialIndex(indexDescriptor, nitriteConfig); + indexRegistry.put(indexDescriptor, nitriteIndex); + return nitriteIndex; } } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java index fc622fb9c..b15ae57f2 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/SpatialModule.java @@ -24,6 +24,9 @@ import static org.dizitart.no2.common.util.Iterables.setOf; /** + * A nitrite module to enable spatial data indexing. + * + * @since 4.0 * @author Anindya Chatterjee */ public class SpatialModule implements NitriteModule { diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java index a408e7617..fe25ea741 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/WithinFilter.java @@ -16,13 +16,13 @@ package org.dizitart.no2.spatial; -import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.index.IndexMap; import org.locationtech.jts.geom.Geometry; import java.util.List; /** + * @since 4.0 * @author Anindya Chatterjee */ class WithinFilter extends SpatialFilter { @@ -32,6 +32,12 @@ protected WithinFilter(String field, Geometry geometry) { @Override public List applyOnIndex(IndexMap indexMap) { - return false + // calculated from SpatialIndex + return null; + } + + @Override + public String toString() { + return "(" + getField() + " within " + getValue() + ")"; } } diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/BaseSpatialTest.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/BaseSpatialTest.java new file mode 100644 index 000000000..1ea4f9dd5 --- /dev/null +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/BaseSpatialTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.spatial; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.repository.ObjectRepository; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.common.Constants.*; +import static org.dizitart.no2.spatial.TestUtil.*; + +/** + * @author Anindya Chatterjee + */ +public abstract class BaseSpatialTest { + private String fileName; + protected Nitrite db; + protected NitriteCollection collection; + protected ObjectRepository repository; + protected SpatialData object1, object2, object3; + protected Document doc1, doc2, doc3; + + @Rule + public Retry retry = new Retry(3); + + @Before + public void before() throws ParseException { + fileName = getRandomTempDbFile(); + db = createDb(fileName); + + collection = db.getCollection("test"); + repository = db.getRepository(SpatialData.class); + insertObjects(); + insertDocuments(); + } + + protected void insertObjects() throws ParseException { + WKTReader reader = new WKTReader(); + + object1 = new SpatialData(); + object1.setGeometry(reader.read("POINT(500 505)")); + object1.setId(1L); + repository.insert(object1); + + object2 = new SpatialData(); + object2.setGeometry(reader.read("LINESTRING(550 551, 525 512, 565 566)")); + object2.setId(2L); + repository.insert(object2); + + object3 = new SpatialData(); + object3.setGeometry(reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")); + object3.setId(3L); + repository.insert(object3); + } + + protected void insertDocuments() throws ParseException { + WKTReader reader = new WKTReader(); + + doc1 = createDocument("key", 1L) + .put("location", reader.read("POINT(500 505)")); + collection.insert(doc1); + + doc2 = createDocument("key", 2L) + .put("location", reader.read("LINESTRING(550 551, 525 512, 565 566)")); + collection.insert(doc2); + + doc3 = createDocument("key", 3L) + .put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")); + collection.insert(doc3); + } + + @After + public void after() { + if (db != null && !db.isClosed()) { + db.close(); + } + + deleteDb(fileName); + } + + protected Document trimMeta(Document document) { + document.remove(DOC_ID); + document.remove(DOC_REVISION); + document.remove(DOC_MODIFIED); + document.remove(DOC_SOURCE); + return document; + } +} diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/Retry.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/Retry.java similarity index 97% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/Retry.java rename to nitrite-spatial/src/test/java/org/dizitart/no2/spatial/Retry.java index 678729f08..97691f917 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/Retry.java +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/Retry.java @@ -1,4 +1,4 @@ -package org.dizitart.no2.rocksdb; +package org.dizitart.no2.spatial; import org.junit.rules.TestRule; import org.junit.runner.Description; diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialData.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialData.java similarity index 85% rename from nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialData.java rename to nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialData.java index 9bf5f3c72..620fc2874 100644 --- a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialData.java +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialData.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.dizitart.no2.spatial.test; +package org.dizitart.no2.spatial; import lombok.Data; import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.locationtech.jts.geom.Geometry; -import static org.dizitart.no2.spatial.SpatialIndexer.SpatialIndex; +import static org.dizitart.no2.spatial.SpatialIndexer.SPATIAL_INDEX; /** * @author Anindya Chatterjee */ @Data -@Index(value = "geometry", type = SpatialIndex) +@Index(value = "geometry", type = SPATIAL_INDEX) public class SpatialData { @Id private Long id; diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexNegativeTest.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexNegativeTest.java new file mode 100644 index 000000000..6b7439b2f --- /dev/null +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexNegativeTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.spatial; + +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.exceptions.IndexingException; +import org.dizitart.no2.filters.FluentFilter; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.repository.Cursor; +import org.junit.Test; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; + +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Collectors; + +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.spatial.FluentFilter.where; +import static org.dizitart.no2.spatial.SpatialIndexer.SPATIAL_INDEX; +import static org.junit.Assert.assertEquals; + +/** + * @author Anindya Chatterjee + */ +public class SpatialIndexNegativeTest extends BaseSpatialTest { + + @Test(expected = FilterException.class) + public void testNoIndex() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + DocumentCursor cursor = collection.find(where("location").intersects(search)); + assertEquals(cursor.size(), 2); + assertEquals(cursor.toList(), Arrays.asList(doc1, doc2)); + } + + @Test(expected = IndexingException.class) + public void testIndexExists() { + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + } + + @Test(expected = FilterException.class) + public void testDropIndex() throws ParseException { + repository.dropIndex("geometry"); + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + Cursor cursor = repository.find(where("geometry").within(search)); + assertEquals(cursor.size(), 1); + } + + @Test(expected = FilterException.class) + public void testFindEqual() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POINT(500 505)"); + + Cursor cursor = repository.find(FluentFilter.where("geometry").eq(search)); + assertEquals(cursor.size(), 2); + assertEquals(cursor.toList(), Collections.singletonList(object1)); + } + + @Test(expected = IndexingException.class) + public void testCompoundIndex() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location", "key"); + DocumentCursor cursor1 = collection.find(where("location").intersects(search)); + assertEquals(cursor1.size(), 2); + assertEquals(cursor1.toList() + .stream() + .map(this::trimMeta) + .collect(Collectors.toList()), Arrays.asList(doc1, doc2)); + } + + @Test(expected = FilterException.class) + public void testMultipleSpatialIndexOnMultipleFields() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "area"); + + DocumentCursor cursor = collection.find( + and( + where("location").intersects(search), + where("area").within(search) + ) + ); + assertEquals(0, cursor.size()); + } +} diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexTest.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexTest.java new file mode 100644 index 000000000..3d8c14d64 --- /dev/null +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialIndexTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2017-2020. Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dizitart.no2.spatial; + +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.collection.Document; +import org.dizitart.no2.collection.DocumentCursor; +import org.dizitart.no2.collection.FindPlan; +import org.dizitart.no2.collection.NitriteCollection; +import org.dizitart.no2.common.WriteResult; +import org.dizitart.no2.filters.EqualsFilter; +import org.dizitart.no2.filters.FluentFilter; +import org.dizitart.no2.index.IndexOptions; +import org.dizitart.no2.mvstore.MVStoreModule; +import org.dizitart.no2.repository.Cursor; +import org.junit.Test; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; + +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Collectors; + +import static org.dizitart.no2.collection.Document.createDocument; +import static org.dizitart.no2.filters.Filter.and; +import static org.dizitart.no2.index.IndexType.UNIQUE; +import static org.dizitart.no2.spatial.FluentFilter.where; +import static org.dizitart.no2.spatial.SpatialIndexer.SPATIAL_INDEX; +import static org.junit.Assert.*; + +/** + * @author Anindya Chatterjee + */ +public class SpatialIndexTest extends BaseSpatialTest { + + @Test + public void testIntersect() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + Cursor cursor = repository.find(where("geometry").intersects(search)); + assertEquals(cursor.size(), 2); + assertEquals(cursor.toList(), Arrays.asList(object1, object2)); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor1 = collection.find(where("location").intersects(search)); + assertEquals(cursor1.size(), 2); + assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Arrays.asList(doc1, doc2)); + } + + @Test + public void testWithin() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + Cursor cursor = repository.find(where("geometry").within(search)); + assertEquals(cursor.size(), 1); + assertEquals(cursor.toList(), Collections.singletonList(object1)); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor1 = collection.find(where("location").within(search)); + assertEquals(cursor1.size(), 1); + assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); + } + + @Test + public void testNearPoint() throws ParseException { + WKTReader reader = new WKTReader(); + Point search = (Point) reader.read("POINT (490 490)"); + + Cursor cursor = repository.find(where("geometry").near(search, 20.0)); + assertEquals(cursor.size(), 1); + assertEquals(cursor.toList(), Collections.singletonList(object1)); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor1 = collection.find(where("location").near(search, 20.0)); + assertEquals(cursor1.size(), 1); + assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); + } + + @Test + public void testNearCoordinate() throws ParseException { + WKTReader reader = new WKTReader(); + Point search = (Point) reader.read("POINT (490 490)"); + Coordinate coordinate = search.getCoordinate(); + + Cursor cursor = repository.find(where("geometry").near(coordinate, 20.0)); + assertEquals(cursor.size(), 1); + assertEquals(cursor.toList(), Collections.singletonList(object1)); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor1 = collection.find(where("location").near(coordinate, 20.0)); + assertEquals(cursor1.size(), 1); + assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); + } + + @Test + public void testRemoveIndexEntry() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + WriteResult result = repository.remove(where("geometry").within(search)); + assertEquals(result.getAffectedCount(), 1); + } + + @Test + public void testUpdateIndex() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + SpatialData update = new SpatialData(); + update.setId(3L); + update.setGeometry(search); + + WriteResult result = repository.update(update); + assertEquals(result.getAffectedCount(), 1); + } + + @Test + public void testDropAllIndex() { + repository.dropAllIndices(); + + assertFalse(repository.hasIndex("geometry")); + } + + @Test + public void testParseGeometry() throws ParseException { + MVStoreModule storeModule = MVStoreModule.withConfig() + .filePath((String) null) + .build(); + + db = Nitrite.builder() + .loadModule(storeModule) + .loadModule(new SpatialModule()) + .fieldSeparator(".") + .openOrCreate(); + + WKTReader reader = new WKTReader(); + Geometry point = reader.read("POINT(500 505)"); + Document document = createDocument("geom", point); + + NitriteCollection collection = db.getCollection("test"); + collection.insert(document); + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "geom"); + Document doc = collection.find().firstOrNull(); + + Document update = doc.clone(); + update.put("geom", reader.read("POINT(0 0)")); + collection.update(update); + } + + @Test + public void testAndMixedQuery() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + collection.createIndex(IndexOptions.indexOptions(UNIQUE), "key"); + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor = collection.find( + and( + where("location").intersects(search), + FluentFilter.where("key").eq(2L) + ) + ); + + FindPlan findPlan = cursor.getFindPlan(); + assertEquals(1, findPlan.getIndexScanFilter().getFilters().size()); + assertTrue(findPlan.getIndexScanFilter().getFilters().get(0) instanceof IntersectsFilter); + assertTrue(findPlan.getCollectionScanFilter() instanceof EqualsFilter); + + assertEquals(cursor.size(), 1); + assertEquals(cursor.toList() + .stream() + .map(this::trimMeta) + .collect(Collectors.toList()), Collections.singletonList(doc2)); + } + @Test + public void testAndSpatialQuery() throws ParseException { + WKTReader reader = new WKTReader(); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + collection.createIndex(IndexOptions.indexOptions(SPATIAL_INDEX), "location"); + DocumentCursor cursor = collection.find( + and( + where("location").intersects(search), + where("location").within(search) + ) + ); + + assertEquals(cursor.size(), 2); + assertEquals(cursor.toList() + .stream() + .map(this::trimMeta) + .collect(Collectors.toList()), Arrays.asList(doc1, doc2)); + } +} diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialViewer.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialViewer.java new file mode 100644 index 000000000..0893b2180 --- /dev/null +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/SpatialViewer.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.spatial; + +import org.locationtech.jts.awt.ShapeWriter; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.WKTReader; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Anindya Chatterjee + */ +public class SpatialViewer { + public static void main(String[] args) { + JFrame f = new JFrame(); + f.getContentPane().add(new Paint()); + f.setSize(700, 700); + f.setVisible(true); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + } + + public static class Paint extends JPanel { + + public void paint(Graphics g) { + try { + Graphics2D g2d = (Graphics2D) g; + RenderingHints rh = new RenderingHints( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + rh.put(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + + g2d.setRenderingHints(rh); + + + WKTReader reader = new WKTReader(); + Geometry point = reader.read("POINT(500 505)"); + Geometry point2 = reader.read("POINT (490 490)"); + Geometry line = reader.read("LINESTRING(550 551, 525 512, 565 566)"); + Geometry polygon = reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))"); + Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); + + + ShapeWriter sw = new ShapeWriter(); + Shape pointShape = sw.toShape(point); + Shape pointShape2 = sw.toShape(point2); + Shape lineShape = sw.toShape(line); + Shape polygonShape = sw.toShape(polygon); + Shape searchShape = sw.toShape(search); + + g2d.setColor(Color.RED); + g2d.draw(pointShape); + g2d.draw(pointShape2); + g2d.draw(lineShape); + g2d.draw(polygonShape); + + g2d.setColor(Color.GREEN); + g2d.draw(searchShape); + + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/TestUtil.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/TestUtil.java new file mode 100644 index 000000000..99b0526f5 --- /dev/null +++ b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/TestUtil.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.spatial; + +import lombok.SneakyThrows; +import org.dizitart.no2.Nitrite; +import org.dizitart.no2.common.mapper.JacksonMapperModule; +import org.dizitart.no2.mvstore.MVStoreModule; +import org.dizitart.no2.spatial.mapper.GeometryExtension; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; + +import static org.junit.Assert.assertTrue; + +/** + * @author Anindya Chatterjee + */ +public class TestUtil { + public static String getRandomTempDbFile() { + String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; + File file = new File(dataDir); + if (!file.exists()) { + assertTrue(file.mkdirs()); + } + return file.getPath() + File.separator + UUID.randomUUID() + ".db"; + } + + public static Nitrite createDb(String fileName) { + MVStoreModule module = MVStoreModule.withConfig() + .filePath(fileName) + .build(); + + return Nitrite.builder() + .loadModule(module) + .loadModule(new JacksonMapperModule(new GeometryExtension())) + .loadModule(new SpatialModule()) + .fieldSeparator(".") + .openOrCreate(); + } + + @SneakyThrows + public static void deleteDb(String fileName) { + Files.delete(Paths.get(fileName)); + } +} diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/Retry.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/Retry.java deleted file mode 100644 index eb978cb53..000000000 --- a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/Retry.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.dizitart.no2.spatial.test; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -/** - * @author Anindya Chatterjee - */ -public class Retry implements TestRule { - private final int retryCount; - - public Retry(int retryCount) { - this.retryCount = retryCount; - } - - public Statement apply(Statement base, Description description) { - return statement(base, description); - } - - private Statement statement(final Statement base, final Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - Throwable caughtThrowable = null; - - // implement retry logic here - for (int i = 0; i < retryCount; i++) { - try { - base.evaluate(); - return; - } catch (Throwable t) { - caughtThrowable = t; - System.err.println(description.getDisplayName() + ": run " + (i + 1) + " failed"); - } - } - System.err.println(description.getDisplayName() + ": giving up after " + retryCount + " failures"); - throw caughtThrowable; - } - }; - } -} diff --git a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java b/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java deleted file mode 100644 index d371cb23a..000000000 --- a/nitrite-spatial/src/test/java/org/dizitart/no2/spatial/test/SpatialIndexTest.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.spatial.test; - -import org.dizitart.no2.Nitrite; -import org.dizitart.no2.collection.Document; -import org.dizitart.no2.collection.DocumentCursor; -import org.dizitart.no2.collection.NitriteCollection; -import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.filters.FluentFilter; -import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.common.mapper.JacksonMapperModule; -import org.dizitart.no2.mvstore.MVStoreModule; -import org.dizitart.no2.repository.Cursor; -import org.dizitart.no2.repository.ObjectRepository; -import org.dizitart.no2.spatial.SpatialModule; -import org.dizitart.no2.spatial.mapper.GeometryExtension; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.locationtech.jts.awt.ShapeWriter; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.Point; -import org.locationtech.jts.io.ParseException; -import org.locationtech.jts.io.WKTReader; - -import javax.swing.*; -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collections; -import java.util.UUID; -import java.util.stream.Collectors; - -import static org.dizitart.no2.collection.Document.createDocument; -import static org.dizitart.no2.common.Constants.*; -import static org.dizitart.no2.spatial.FluentFilter.where; -import static org.dizitart.no2.spatial.SpatialIndexer.SpatialIndex; -import static org.junit.Assert.*; - -/** - * @author Anindya Chatterjee - */ -public class SpatialIndexTest { - private final String fileName = getRandomTempDbFile(); - private Nitrite db; - private NitriteCollection collection; - private ObjectRepository repository; - private SpatialData object1, object2, object3; - private Document doc1, doc2, doc3; - - @Rule - public Retry retry = new Retry(3); - - public static void main(String[] args) { - JFrame f = new JFrame(); - f.getContentPane().add(new Paint()); - f.setSize(700, 700); - f.setVisible(true); - f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - } - - public static String getRandomTempDbFile() { - String dataDir = System.getProperty("java.io.tmpdir") + File.separator + "nitrite" + File.separator + "data"; - File file = new File(dataDir); - if (!file.exists()) { - assertTrue(file.mkdirs()); - } - return file.getPath() + File.separator + UUID.randomUUID().toString() + ".db"; - } - - @Before - public void before() throws ParseException { - MVStoreModule module = MVStoreModule.withConfig() - .filePath(fileName) - .build(); - - db = Nitrite.builder() - .loadModule(module) - .loadModule(new JacksonMapperModule(new GeometryExtension())) - .loadModule(new SpatialModule()) - .fieldSeparator(".") - .openOrCreate(); - - collection = db.getCollection("test"); - repository = db.getRepository(SpatialData.class); - insertObjects(); - insertDocuments(); - } - - protected void insertObjects() throws ParseException { - WKTReader reader = new WKTReader(); - - object1 = new SpatialData(); - object1.setGeometry(reader.read("POINT(500 505)")); - object1.setId(1L); - repository.insert(object1); - - object2 = new SpatialData(); - object2.setGeometry(reader.read("LINESTRING(550 551, 525 512, 565 566)")); - object2.setId(2L); - repository.insert(object2); - - object3 = new SpatialData(); - object3.setGeometry(reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")); - object3.setId(3L); - repository.insert(object3); - } - - protected void insertDocuments() throws ParseException { - WKTReader reader = new WKTReader(); - - doc1 = createDocument("key", 1L) - .put("location", reader.read("POINT(500 505)")); - collection.insert(doc1); - - doc2 = createDocument("key", 2L) - .put("location", reader.read("LINESTRING(550 551, 525 512, 565 566)")); - collection.insert(doc2); - - doc3 = createDocument("key", 3L) - .put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")); - collection.insert(doc3); - } - - @After - public void after() throws IOException { - if (db != null && !db.isClosed()) { - db.close(); - } - - Files.delete(Paths.get(fileName)); - } - - @Test - public void testIntersect() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - - Cursor cursor = repository.find(where("geometry").intersects(search)); - assertEquals(cursor.size(), 2); - assertEquals(cursor.toList(), Arrays.asList(object1, object2)); - - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - DocumentCursor cursor1 = collection.find(where("location").intersects(search)); - assertEquals(cursor1.size(), 2); - assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Arrays.asList(doc1, doc2)); - } - - @Test - public void testWithin() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - - Cursor cursor = repository.find(where("geometry").within(search)); - assertEquals(cursor.size(), 1); - assertEquals(cursor.toList(), Collections.singletonList(object1)); - - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - DocumentCursor cursor1 = collection.find(where("location").within(search)); - assertEquals(cursor1.size(), 1); - assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); - } - - @Test - public void testNearPoint() throws ParseException { - WKTReader reader = new WKTReader(); - Point search = (Point) reader.read("POINT (490 490)"); - - Cursor cursor = repository.find(where("geometry").near(search, 20.0)); - assertEquals(cursor.size(), 1); - assertEquals(cursor.toList(), Collections.singletonList(object1)); - - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - DocumentCursor cursor1 = collection.find(where("location").near(search, 20.0)); - assertEquals(cursor1.size(), 1); - assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); - } - - @Test - public void testNearCoordinate() throws ParseException { - WKTReader reader = new WKTReader(); - Point search = (Point) reader.read("POINT (490 490)"); - Coordinate coordinate = search.getCoordinate(); - - Cursor cursor = repository.find(where("geometry").near(coordinate, 20.0)); - assertEquals(cursor.size(), 1); - assertEquals(cursor.toList(), Collections.singletonList(object1)); - - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - DocumentCursor cursor1 = collection.find(where("location").near(coordinate, 20.0)); - assertEquals(cursor1.size(), 1); - assertEquals(cursor1.toList().stream().map(this::trimMeta).collect(Collectors.toList()), Collections.singletonList(doc1)); - } - - @Test(expected = FilterException.class) - public void testNoIndex() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - - DocumentCursor cursor1 = collection.find(where("location").intersects(search)); - assertEquals(cursor1.size(), 2); - assertEquals(cursor1.toList(), Arrays.asList(doc1, doc2)); - } - - @Test(expected = IndexingException.class) - public void testIndexExists() { - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - collection.createIndex("location", IndexOptions.indexOptions(SpatialIndex)); - } - - @Test - public void testRemoveIndexEntry() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - WriteResult result = repository.remove(where("geometry").within(search)); - assertEquals(result.getAffectedCount(), 1); - } - - @Test - public void testUpdateIndex() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - SpatialData update = new SpatialData(); - update.setId(3L); - update.setGeometry(search); - - WriteResult result = repository.update(update); - assertEquals(result.getAffectedCount(), 1); - } - - @Test(expected = FilterException.class) - public void testDropIndex() throws ParseException { - repository.dropIndex("geometry"); - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - Cursor cursor = repository.find(where("geometry").within(search)); - assertEquals(cursor.size(), 1); - } - - @Test - public void testDropAllIndex() { - repository.dropAllIndices(); - - assertFalse(repository.hasIndex("geometry")); - } - - @Test(expected = FilterException.class) - public void testFindEqual() throws ParseException { - WKTReader reader = new WKTReader(); - Geometry search = reader.read("POINT(500 505)"); - - Cursor cursor = repository.find(FluentFilter.where("geometry").eq(search)); - assertEquals(cursor.size(), 2); - assertEquals(cursor.toList(), Collections.singletonList(object1)); - } - - @Test - public void testParseGeometry() throws ParseException { - MVStoreModule storeModule = MVStoreModule.withConfig() - .filePath((String) null) - .build(); - - db = Nitrite.builder() - .loadModule(storeModule) - .loadModule(new SpatialModule()) - .fieldSeparator(".") - .openOrCreate(); - - WKTReader reader = new WKTReader(); - Geometry point = reader.read("POINT(500 505)"); - Document document = createDocument("geom", point); - - NitriteCollection collection = db.getCollection("test"); - collection.insert(document); - collection.createIndex("geom", IndexOptions.indexOptions(SpatialIndex)); - Document doc = collection.find().firstOrNull(); - - Document update = doc.clone(); - update.put("geom", reader.read("POINT(0 0)")); - collection.update(update); - } - - private Document trimMeta(Document document) { - document.remove(DOC_ID); - document.remove(DOC_REVISION); - document.remove(DOC_MODIFIED); - document.remove(DOC_SOURCE); - return document; - } - - public static class Paint extends JPanel { - - public void paint(Graphics g) { - try { - Graphics2D g2d = (Graphics2D) g; - RenderingHints rh = new RenderingHints( - RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - - rh.put(RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_QUALITY); - - g2d.setRenderingHints(rh); - - - WKTReader reader = new WKTReader(); - Geometry point = reader.read("POINT(500 505)"); - Geometry point2 = reader.read("POINT (490 490)"); - Geometry line = reader.read("LINESTRING(550 551, 525 512, 565 566)"); - Geometry polygon = reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))"); - Geometry search = reader.read("POLYGON ((490 490, 536 490, 536 515, 490 515, 490 490))"); - - - ShapeWriter sw = new ShapeWriter(); - Shape pointShape = sw.toShape(point); - Shape pointShape2 = sw.toShape(point2); - Shape lineShape = sw.toShape(line); - Shape polygonShape = sw.toShape(polygon); - Shape searchShape = sw.toShape(search); - - g2d.setColor(Color.RED); - g2d.draw(pointShape); - g2d.draw(pointShape2); - g2d.draw(lineShape); - g2d.draw(polygonShape); - - g2d.setColor(Color.GREEN); - g2d.draw(searchShape); - - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java index 4ec53e189..e62526647 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/NitriteJsonImporter.java @@ -25,7 +25,6 @@ import org.dizitart.no2.common.PersistentCollection; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.IndexOptions; import org.dizitart.no2.repository.ObjectRepository; import java.io.ByteArrayInputStream; @@ -33,6 +32,7 @@ import java.io.ObjectInputStream; import static org.dizitart.no2.common.Constants.*; +import static org.dizitart.no2.index.IndexOptions.indexOptions; /** * @author Anindya Chatterjee. @@ -180,11 +180,11 @@ private void readIndices(PersistentCollection collection) throws IOException parser.nextToken(); String data = parser.readValueAs(String.class); IndexDescriptor index = (IndexDescriptor) readEncodedObject(data); - if (collection != null && index != null - && index.getIndexFields() != null - && !collection.hasIndex(index.getIndexFields())) { - collection.createIndex(index.getIndexFields(), - IndexOptions.indexOptions(index.getIndexType())); + if (index != null) { + String[] fieldNames = index.getIndexFields().getFieldNames().toArray(new String[0]); + if (collection != null && index.getIndexFields() != null && !collection.hasIndex(fieldNames)) { + collection.createIndex(indexOptions(index.getIndexType()), fieldNames); + } } } } diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java b/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java index 5fcbe3790..6e97fa636 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/Employee.java @@ -37,9 +37,9 @@ @ToString @EqualsAndHashCode @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote.text", type = IndexType.Fulltext) + @Index(value = "joinDate", type = IndexType.NON_UNIQUE), + @Index(value = "address", type = IndexType.FULL_TEXT), + @Index(value = "employeeNote.text", type = IndexType.FULL_TEXT) }) public class Employee implements Serializable, Mappable { @Id diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java index 119da0e53..944ba4452 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/DefaultNitriteCollection.java @@ -190,7 +190,7 @@ public void createIndex(IndexOptions indexOptions, String... fields) { try { writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(indexFields, IndexType.Unique); + collectionOperations.createIndex(indexFields, IndexType.UNIQUE); } else { collectionOperations.createIndex(indexFields, indexOptions.getIndexType()); } @@ -304,16 +304,27 @@ public void drop() { try { writeLock.lock(); - collectionOperations.dropCollection(); + + if (collectionOperations != null) { + // close collection and indexes + collectionOperations.close(); + + // drop collection and indexes + collectionOperations.dropCollection(); + } + + // set all reference to null + this.nitriteMap = null; + this.nitriteConfig = null; + this.collectionOperations = null; + this.nitriteStore = null; + + // close event bus + closeEventBus(); } finally { writeLock.unlock(); } isDropped = true; - try { - close(); - } catch (Exception e) { - throw new NitriteIOException("failed to close the database", e); - } } public boolean isOpen() { @@ -327,10 +338,13 @@ public boolean isOpen() { } else return true; } - public void close() throws Exception { + public void close() { if (collectionOperations != null) { + // close collection and indexes collectionOperations.close(); } + + // set all reference to null this.nitriteMap = null; this.nitriteConfig = null; this.collectionOperations = null; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java index 6ca9cd7ba..225d5aa47 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/FindPlan.java @@ -20,6 +20,7 @@ import lombok.Data; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.EqualsFilter; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.filters.IndexScanFilter; import org.dizitart.no2.index.IndexDescriptor; @@ -37,11 +38,12 @@ */ @Data public class FindPlan { - private IndexDescriptor indexDescriptor; + private EqualsFilter byIdFilter; private IndexScanFilter indexScanFilter; - private Map indexScanOrder; - private Filter collectionScanFilter; + + private IndexDescriptor indexDescriptor; + private Map indexScanOrder; private List> blockingSortOrder; private Long skip; diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java index 11c071794..e2513f907 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/CollectionOperations.java @@ -263,16 +263,16 @@ public void setAttributes(Attributes attributes) { nitriteMap.setAttributes(attributes); } - public void close() throws Exception { + public void close() { if (indexOperations != null) { indexOperations.close(); } + nitriteMap.close(); } private void initialize() { this.processorChain = new ProcessorChain(); - IndexManager indexManager = new IndexManager(collectionName, nitriteConfig); - this.indexOperations = new IndexOperations(nitriteConfig, nitriteMap, eventBus, indexManager); + this.indexOperations = new IndexOperations(collectionName, nitriteConfig, nitriteMap, eventBus); this.readOperations = new ReadOperations(collectionName, indexOperations, nitriteConfig, nitriteMap, processorChain); diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java index 7336f65fb..58b129016 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/FindOptimizer.java @@ -21,11 +21,13 @@ import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.common.SortOrder; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.filters.*; import org.dizitart.no2.index.IndexDescriptor; import java.util.*; +import static org.dizitart.no2.common.Constants.DOC_ID; import static org.dizitart.no2.common.util.Iterables.firstOrNull; import static org.dizitart.no2.filters.Filter.and; import static org.dizitart.no2.filters.Filter.or; @@ -63,6 +65,21 @@ private FindPlan createFilterPlan(Collection indexDescriptors, } } + private List flattenAndFilter(AndFilter andFilter) { + List flattenedFilters = new ArrayList<>(); + if (andFilter != null) { + for (Filter filter : andFilter.getFilters()) { + if (filter instanceof AndFilter) { + List filters = flattenAndFilter((AndFilter) filter); + flattenedFilters.addAll(filters); + } else { + flattenedFilters.add(filter); + } + } + } + return flattenedFilters; + } + private FindPlan createOrPlan(Collection indexDescriptors, List filters) { FindPlan findPlan = new FindPlan(); @@ -99,20 +116,121 @@ private FindPlan createOrPlan(Collection indexDescriptors, List } private FindPlan createAndPlan(Collection indexDescriptors, List filters) { + FindPlan findPlan = new FindPlan(); + Set indexScanFilters = new LinkedHashSet<>(); + Set columnScanFilters = new LinkedHashSet<>(); + + // find out set id filter (if any) + planForIdFilter(findPlan, filters); + + // find out if there are any index only filter with index + planForIndexOnlyFilters(findPlan, indexScanFilters, indexDescriptors, filters); + + // if no id filter found or no index only filter found, scan for matching index + if (findPlan.getByIdFilter() == null && indexScanFilters.isEmpty()) { + planForIndexScanningFilters(findPlan, indexScanFilters, indexDescriptors, filters); + } + + // plan for column scan filters + planForCollectionScanningFilters(findPlan, indexScanFilters, columnScanFilters, filters); + + IndexScanFilter indexScanFilter; + if (indexScanFilters.size() == 1) { + indexScanFilter = new IndexScanFilter(Collections.singletonList(firstOrNull(indexScanFilters))); + findPlan.setIndexScanFilter(indexScanFilter); + } else if (indexScanFilters.size() > 1) { + indexScanFilter = new IndexScanFilter(indexScanFilters); + findPlan.setIndexScanFilter(indexScanFilter); + } + + if (columnScanFilters.size() == 1) { + findPlan.setCollectionScanFilter(firstOrNull(columnScanFilters)); + } else if (columnScanFilters.size() > 1) { + Filter andFilter = and(columnScanFilters.toArray(new Filter[0])); + findPlan.setCollectionScanFilter(andFilter); + } + + return findPlan; + } + + private void planForIdFilter(FindPlan findPlan, List filters) { + for (Filter filter : filters) { + if (filter instanceof EqualsFilter) { + EqualsFilter equalsFilter = (EqualsFilter) filter; + + // handle byId filter specially + if (equalsFilter.getField().equals(DOC_ID)) { + findPlan.setByIdFilter(equalsFilter); + } + break; + } + } + } + + private void planForIndexOnlyFilters(FindPlan findPlan, Set indexScanFilters, + Collection indexDescriptors, List filters) { + // find out if there are any filter which does not support covered queries + List indexOnlyFilters = new ArrayList<>(); + for (Filter filter : filters) { + if (filter instanceof IndexOnlyFilter) { + IndexOnlyFilter indexScanFilter = (IndexOnlyFilter) filter; + if (isCompatibleFilter(indexOnlyFilters, indexScanFilter)) { + // if filter is compatible with already identified index only filter then add + indexOnlyFilters.add(indexScanFilter); + } else { + throw new FilterException("a query can not have multiple index only filters"); + } + } + } + + // populate index descriptor for the index only filters + if (!indexOnlyFilters.isEmpty()) { + + // get any index only filter from the set + IndexOnlyFilter anyFilter = indexOnlyFilters.get(0); + for (IndexDescriptor indexDescriptor : indexDescriptors) { + + // check the index type match between filter and index descriptor + if (anyFilter.supportedIndexType().equals(indexDescriptor.getIndexType())) { + // choose the index descriptor and filters + findPlan.setIndexDescriptor(indexDescriptor); + indexScanFilters.addAll(indexOnlyFilters); + break; + } + } + + if (findPlan.getIndexDescriptor() == null) { + throw new FilterException(anyFilter.getField() + " is not indexed with " + + anyFilter.supportedIndexType() + " index"); + } + } + } + + private boolean isCompatibleFilter(List indexOnlyFilters, IndexOnlyFilter filter) { + if (indexOnlyFilters.isEmpty()) { + return true; + } else { + IndexOnlyFilter comparableFilter = indexOnlyFilters.get(0); + return comparableFilter.canBeGrouped(filter); + } + } + + private void planForIndexScanningFilters(FindPlan findPlan, Set indexScanFilters, + Collection indexDescriptors, List filters) { // descending sort based on cardinality of indices, consider the higher cardinality index first - NavigableMap> indexFilterMap = new TreeMap<>(Collections.reverseOrder()); + NavigableMap> indexFilterMap = new TreeMap<>(Collections.reverseOrder()); for (IndexDescriptor indexDescriptor : indexDescriptors) { List fieldNames = indexDescriptor.getIndexFields().getFieldNames(); - List indexedFilters = new ArrayList<>(); + List indexedFilters = new ArrayList<>(); for (String fieldName : fieldNames) { boolean matchFound = false; for (Filter filter : filters) { - if (filter instanceof FieldBasedFilter) { - String filterFieldName = ((FieldBasedFilter) filter).getField(); + if (filter instanceof ComparableFilter) { + String filterFieldName = ((ComparableFilter) filter).getField(); if (filterFieldName.equals(fieldName)) { - indexedFilters.add(filter); + indexedFilters.add((ComparableFilter) filter); matchFound = true; break; } @@ -130,58 +248,46 @@ private FindPlan createAndPlan(Collection indexDescriptors, Lis } } - FindPlan findPlan = new FindPlan(); - Set electedFilters = new HashSet<>(); - for (Map.Entry> entry : indexFilterMap.entrySet()) { + for (Map.Entry> entry : indexFilterMap.entrySet()) { // consider the filter combination if it encompasses more fields // than the previously selected filter - if (entry.getValue().size() > electedFilters.size()) { + if (entry.getValue().size() > indexScanFilters.size()) { // maintain the order in set - electedFilters = new LinkedHashSet<>(entry.getValue()); + indexScanFilters.addAll(entry.getValue()); findPlan.setIndexDescriptor(entry.getKey()); } } + } - // maintain the order in set - Set nonElectedFilters = new LinkedHashSet<>(); + private void planForCollectionScanningFilters(FindPlan findPlan, Set indexScanFilters, + Set columnScanFilters, List filters) { for (Filter filter : filters) { - if (!electedFilters.contains(filter)) { - nonElectedFilters.add(filter); + // ignore the elected filters for index scan and + // insert rest of the filters for column scan + // NOTE: for byId filter, index scan filters will always be empty + if (!(filter instanceof ComparableFilter) || !indexScanFilters.contains(filter)) { + // ignore the byId filter (if any) for column scan + if (filter != findPlan.getByIdFilter()) { + columnScanFilters.add(filter); + } } } - IndexScanFilter indexScanFilter; - if (electedFilters.size() == 1) { - indexScanFilter = new IndexScanFilter(Collections.singletonList(firstOrNull(electedFilters))); - findPlan.setIndexScanFilter(indexScanFilter); - } else if (electedFilters.size() > 1) { - indexScanFilter = new IndexScanFilter(electedFilters); - findPlan.setIndexScanFilter(indexScanFilter); - } - - if (nonElectedFilters.size() == 1) { - findPlan.setCollectionScanFilter(firstOrNull(nonElectedFilters)); - } else if (nonElectedFilters.size() > 1) { - Filter andFilter = and(nonElectedFilters.toArray(new Filter[0])); - findPlan.setCollectionScanFilter(andFilter); + // validate whether column scanning is supported for each filter, + // if there is no index scan available + if (indexScanFilters.isEmpty()) { + validateCollectionScanFilters(columnScanFilters); } - - return findPlan; } - private List flattenAndFilter(AndFilter andFilter) { - List flattenedFilters = new ArrayList<>(); - if (andFilter != null) { - for (Filter filter : andFilter.getFilters()) { - if (filter instanceof AndFilter) { - List filters = flattenAndFilter((AndFilter) filter); - flattenedFilters.addAll(filters); - } else { - flattenedFilters.add(filter); - } + private void validateCollectionScanFilters(Collection filters) { + for (Filter filter : filters) { + if (filter instanceof IndexOnlyFilter) { + throw new FilterException("collection scan is not supported for the filter " + filter); + } else if (filter instanceof TextFilter) { + throw new FilterException(((TextFilter) filter).getField() + " is not full-text indexed"); } } - return flattenedFilters; } private void readSortOption(FindOptions findOptions, FindPlan findPlan) { @@ -243,4 +349,5 @@ private void readLimitOption(FindOptions findOptions, FindPlan findPlan) { findPlan.setSkip(findOptions.skip()); } } + } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java index b43aa66d0..2464048e2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexManager.java @@ -74,7 +74,7 @@ public boolean hasIndexDescriptor(Fields fields) { * @return the index descriptors */ public Collection getIndexDescriptors() { - if (indexDescriptorCache == null || indexDescriptorCache.isEmpty()) { + if (indexDescriptorCache == null) { indexDescriptorCache = listIndexDescriptors(); } return indexDescriptorCache; @@ -101,10 +101,19 @@ public IndexDescriptor findExactIndexDescriptor(Fields fields) { } @Override - public void close() throws Exception { - if (indexMetaMap != null) { - indexMetaMap.close(); + public void close() { + // close all index maps + Iterable indexMetas = indexMetaMap.values(); + for (IndexMeta indexMeta : indexMetas) { + if (indexMeta != null && indexMeta.getIndexDescriptor() != null) { + String indexMapName = indexMeta.getIndexMap(); + NitriteMap indexMap = nitriteStore.openMap(indexMapName, Object.class, Object.class); + indexMap.close(); + } } + + // close index meta + indexMetaMap.close(); } /** @@ -125,7 +134,8 @@ boolean isDirtyIndex(Fields fields) { */ Collection listIndexDescriptors() { Set indexSet = new LinkedHashSet<>(); - for (IndexMeta indexMeta : indexMetaMap.values()) { + Iterable iterable = indexMetaMap.values(); + for (IndexMeta indexMeta : iterable) { indexSet.add(indexMeta.getIndexDescriptor()); } return Collections.unmodifiableSet(indexSet); @@ -170,6 +180,11 @@ void dropIndexDescriptor(Fields fields) { updateIndexDescriptorCache(); } + void dropIndexMeta() { + indexMetaMap.clear(); + indexMetaMap.drop(); + } + /** * Begin indexing. * diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java index ff74382fc..9d6dc9a45 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/IndexOperations.java @@ -31,24 +31,26 @@ * @author Anindya Chatterjee */ class IndexOperations implements AutoCloseable { + private final String collectionName; private final NitriteConfig nitriteConfig; - private final IndexManager indexManager; private final NitriteMap nitriteMap; private final EventBus, CollectionEventListener> eventBus; private final Map indexBuildTracker; + private IndexManager indexManager; - IndexOperations(NitriteConfig nitriteConfig, NitriteMap nitriteMap, - EventBus, CollectionEventListener> eventBus, - IndexManager indexManager) { + IndexOperations(String collectionName, NitriteConfig nitriteConfig, + NitriteMap nitriteMap, + EventBus, CollectionEventListener> eventBus) { + this.collectionName = collectionName; this.nitriteConfig = nitriteConfig; this.nitriteMap = nitriteMap; this.eventBus = eventBus; - this.indexManager = indexManager; this.indexBuildTracker = new ConcurrentHashMap<>(); + this.indexManager = new IndexManager(collectionName, nitriteConfig); } @Override - public void close() throws Exception { + public void close() { indexManager.close(); } @@ -115,7 +117,12 @@ void dropAllIndices() { } } + indexManager.dropIndexMeta(); indexBuildTracker.clear(); + + // recreate index manager to discard old native resources + // special measure for RocksDB adapter + this.indexManager = new IndexManager(collectionName, nitriteConfig); } boolean isIndexing(Fields field) { diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java index e8af3e5bb..4f7411feb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/ReadOperations.java @@ -21,6 +21,7 @@ import org.dizitart.no2.common.RecordStream; import org.dizitart.no2.common.streams.*; import org.dizitart.no2.common.tuples.Pair; +import org.dizitart.no2.filters.EqualsFilter; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.filters.LogicalFilter; import org.dizitart.no2.filters.NitriteFilter; @@ -34,6 +35,8 @@ import java.util.LinkedHashSet; import java.util.List; +import static org.dizitart.no2.common.tuples.Pair.pair; + /** * @author Anindya Chatterjee */ @@ -102,39 +105,43 @@ private void prepareLogicalFilter(LogicalFilter logicalFilter) { } private RecordStream> findSuitableStream(FindPlan findPlan) { - RecordStream> rawStream = null; - - // filtering stage - IndexDescriptor indexDescriptor = findPlan.getIndexDescriptor(); - if (indexDescriptor != null) { - // get optimized filter - NitriteIndexer indexer = nitriteConfig.findIndexer(indexDescriptor.getIndexType()); - LinkedHashSet nitriteIds = indexer.findByFilter(findPlan, nitriteConfig); - - // create indexed stream from optimized filter - RecordStream> indexedStream = new IndexedStream(nitriteIds, nitriteMap); + RecordStream> rawStream; + + if (!findPlan.getSubPlans().isEmpty()) { + // or filters get all sub stream by finding suitable stream of all sub plans + List>> subStreams = new ArrayList<>(); + for (FindPlan subPlan : findPlan.getSubPlans()) { + RecordStream> suitableStream = findSuitableStream(subPlan); + subStreams.add(suitableStream); + } + // union of all suitable stream of all sub plans + rawStream = new UnionStream(subStreams); - // create filtered stream from above result and un-optimized filters - rawStream = new FilteredStream(indexedStream, findPlan.getCollectionScanFilter()); + // return only distinct items + rawStream = new DistinctStream(rawStream); } else { - // it means we don't have any index and we won't have any optimized filter - if (findPlan.getCollectionScanFilter() != null) { - rawStream = new FilteredStream(nitriteMap.entries(), findPlan.getCollectionScanFilter()); + // and or single filter + if (findPlan.getByIdFilter() != null) { + EqualsFilter byIdFilter = findPlan.getByIdFilter(); + NitriteId nitriteId = NitriteId.createId((String) byIdFilter.getValue()); + rawStream = RecordStream.single(pair(nitriteId, nitriteMap.get(nitriteId))); } else { - if (!findPlan.getSubPlans().isEmpty()) { - // or filters get all sub stream by finding suitable stream of all sub plans - List>> subStreams = new ArrayList<>(); - for (FindPlan subPlan : findPlan.getSubPlans()) { - RecordStream> suitableStream = findSuitableStream(subPlan); - subStreams.add(suitableStream); - } - // union of all suitable stream of all sub plans - rawStream = new UnionStream(subStreams); - - // return only distinct items - rawStream = new DistinctStream(rawStream); + IndexDescriptor indexDescriptor = findPlan.getIndexDescriptor(); + if (indexDescriptor != null) { + // get optimized filter + NitriteIndexer indexer = nitriteConfig.findIndexer(indexDescriptor.getIndexType()); + LinkedHashSet nitriteIds = indexer.findByFilter(findPlan, nitriteConfig); + + // create indexed stream from optimized filter + rawStream = new IndexedStream(nitriteIds, nitriteMap); + } else { + rawStream = nitriteMap.entries(); } } + + if (findPlan.getCollectionScanFilter() != null) { + rawStream = new FilteredStream(rawStream, findPlan.getCollectionScanFilter()); + } } // sort and bound stage diff --git a/nitrite/src/main/java/org/dizitart/no2/common/Constants.java b/nitrite/src/main/java/org/dizitart/no2/common/Constants.java index 4bd245c38..1fe40ee42 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/Constants.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/Constants.java @@ -16,8 +16,8 @@ package org.dizitart.no2.common; -import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.exceptions.NitriteIOException; import java.io.BufferedReader; import java.io.IOException; @@ -31,7 +31,6 @@ * @author Anindya Chatterjee * @since 1.0 */ -@Slf4j public class Constants { private Constants() {} @@ -42,7 +41,7 @@ private Constants() {} v = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)).readLine(); } } catch (IOException e) { - log.error("Failed to load version information", e); + throw new NitriteIOException("failed to load version information", e); } NITRITE_VERSION = v; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java index 590563aeb..395dedc9a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/PersistentCollection.java @@ -256,6 +256,11 @@ default WriteResult update(T element) { */ long size(); + /** + * Closes this {@link PersistentCollection}. + * */ + void close(); + /** * Returns the {@link NitriteStore} instance for this collection. * diff --git a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java index a246086d7..2bfc34ea6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/RecordStream.java @@ -124,6 +124,17 @@ static RecordStream empty() { return RecordStream.fromIterable(Collections.emptySet()); } + /** + * Creates a {@link RecordStream} with a single element. + * + * @param the type parameter + * @param v the v + * @return the record stream + */ + static RecordStream single(V v) { + return RecordStream.fromIterable(Collections.singleton(v)); + } + /** * Gets the size of the {@link RecordStream}. * diff --git a/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java index 1b5cc7cfb..61a53e8c3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/module/PluginManager.java @@ -150,17 +150,17 @@ private synchronized void loadIfIndexer(NitritePlugin plugin) { } protected void loadInternalPlugins() { - if (!indexerMap.containsKey(IndexType.Unique)) { + if (!indexerMap.containsKey(IndexType.UNIQUE)) { log.debug("Loading default unique indexer"); loadPlugin(new UniqueIndexer()); } - if (!indexerMap.containsKey(IndexType.NonUnique)) { + if (!indexerMap.containsKey(IndexType.NON_UNIQUE)) { log.debug("Loading default non-unique indexer"); loadPlugin(new NonUniqueIndexer()); } - if (!indexerMap.containsKey(IndexType.Fulltext)) { + if (!indexerMap.containsKey(IndexType.FULL_TEXT)) { log.debug("Loading nitrite text indexer"); loadPlugin(new NitriteTextIndexer()); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java index 103343966..c290f4896 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java @@ -29,7 +29,7 @@ /** * @author Anindya Chatterjee. */ -class EqualsFilter extends ComparableFilter { +public class EqualsFilter extends ComparableFilter { EqualsFilter(String field, Object value) { super(field, value); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexOnlyFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexOnlyFilter.java new file mode 100644 index 000000000..5eac4a099 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexOnlyFilter.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.filters; + +/** + * Represents an index-only filter. This filter does not support + * collection scan. + * + * @since 4.0 + * @author Anindya Chatterjee + */ +public abstract class IndexOnlyFilter extends ComparableFilter { + /** + * Instantiates a new {@link IndexOnlyFilter}. + * + * @param field the field + * @param value the value + */ + public IndexOnlyFilter(String field, Object value) { + super(field, value); + } + + public abstract String supportedIndexType(); + + /** + * Checks if other filter can be grouped together with this filter. + * + * @param other the comparable filter + * @return the boolean + */ + public abstract boolean canBeGrouped(IndexOnlyFilter other); +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java index 2f045cc4e..03282e782 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/IndexScanFilter.java @@ -37,14 +37,14 @@ @ToString public class IndexScanFilter implements Filter { @Getter - private final List filters; + private final List filters; /** * Instantiates a new Index scan filter. * * @param filters the filters */ - public IndexScanFilter(Collection filters) { + public IndexScanFilter(Collection filters) { this.filters = new ArrayList<>(filters); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java index 380be384e..f82c078eb 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/StringFilter.java @@ -22,7 +22,7 @@ * @author Anindya Chatterjee * @since 1.0 */ -public abstract class StringFilter extends FieldBasedFilter { +public abstract class StringFilter extends ComparableFilter { /** * Instantiates a new String filter. * diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java index 5a1747c98..154e797f7 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/TextFilter.java @@ -21,6 +21,7 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.index.IndexMap; import org.dizitart.no2.index.fulltext.TextTokenizer; import org.dizitart.no2.store.NitriteMap; @@ -51,7 +52,22 @@ public class TextFilter extends StringFilter { @Override public boolean apply(Pair element) { - throw new FilterException(getField() + " is not full-text indexed"); + notNull(getField(), "field cannot be null"); + notNull(getStringValue(), "search term cannot be null"); + String searchString = getStringValue(); + Object docValue = element.getSecond().get(getField()); + + if (!(docValue instanceof String)) { + throw new FilterException("text filter can not be applied on non string field " + getField()); + } + + String docString = (String) docValue; + + if (searchString.startsWith("*") || searchString.endsWith("*")) { + searchString = searchString.replace("*", ""); + } + + return docString.toLowerCase().contains(searchString.toLowerCase()); } @Override @@ -179,4 +195,9 @@ private LinkedHashSet sortedIdsByScore(Map unsort return result; } + + @Override + public List applyOnIndex(IndexMap indexMap) { + return null; + } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java index 656871cf8..beec17621 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/CompoundIndex.java @@ -25,11 +25,13 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.tuples.Pair; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; -import java.util.*; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.NavigableMap; import java.util.concurrent.ConcurrentSkipListMap; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; @@ -67,19 +69,15 @@ public void write(FieldValues fieldValues) { // NOTE: only first field can have array or iterable value, subsequent fields can not validateIndexField(firstValue, firstField); + NitriteMap> indexMap = findIndexMap(); if (firstValue == null) { - NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (firstValue instanceof Comparable) { - NitriteMap> indexMap = findIndexMap(); - //wrap around a db value DBValue dbValue = new DBValue((Comparable) firstValue); addIndexElement(indexMap, fieldValues, dbValue); } else if (firstValue.getClass().isArray()) { Object[] array = convertToObjectArray(firstValue); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { // wrap around db value @@ -88,7 +86,6 @@ public void write(FieldValues fieldValues) { } } else if (firstValue instanceof Iterable) { Iterable iterable = (Iterable) firstValue; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { // wrap around db value @@ -108,20 +105,16 @@ public void remove(FieldValues fieldValues) { // NOTE: only first field can have array or iterable value, subsequent fields can not validateIndexField(firstValue, firstField); + NitriteMap> indexMap = findIndexMap(); if (firstValue == null) { - NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (firstValue instanceof Comparable) { - NitriteMap> indexMap = findIndexMap(); - // wrap around db value DBValue dbValue = new DBValue((Comparable) firstValue); removeIndexElement(indexMap, fieldValues, dbValue); } else if (firstValue.getClass().isArray()) { Object[] array = convertToObjectArray(firstValue); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { // wrap around db value @@ -130,7 +123,6 @@ public void remove(FieldValues fieldValues) { } } else if (firstValue instanceof Iterable) { Iterable iterable = (Iterable) firstValue; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { // wrap around db value @@ -163,8 +155,8 @@ private void addIndexElement(NitriteMap> index subMap = new ConcurrentSkipListMap<>(); } - indexMap.put(element, subMap); populateSubMap(subMap, fieldValues, 1); + indexMap.put(element, subMap); } private void removeIndexElement(NitriteMap> indexMap, @@ -256,7 +248,7 @@ private void deleteFromSubMap(NavigableMap subMap, FieldValues fieldValues, int private LinkedHashSet scanIndex(FindPlan findPlan, NitriteMap> indexMap) { - List filters = findPlan.getIndexScanFilter().getFilters(); + List filters = findPlan.getIndexScanFilter().getFilters(); IndexMap iMap = new IndexMap(indexMap); IndexScanner indexScanner = new IndexScanner(iMap); return indexScanner.doScan(filters, findPlan.getIndexScanOrder()); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java index 363ad8e22..12bf72253 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexDescriptor.java @@ -114,7 +114,7 @@ public boolean isCompoundIndex() { } private boolean isUniqueIndex() { - return indexType.equals(IndexType.Unique); + return indexType.equals(IndexType.UNIQUE); } private void writeObject(ObjectOutputStream stream) throws IOException { diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java index 0f609c3d2..458c4b337 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexMap.java @@ -25,6 +25,7 @@ import org.dizitart.no2.store.NitriteMap; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; /** * Represents an index map. @@ -247,7 +248,7 @@ public boolean hasNext() { * @return the terminal nitrite ids */ public List getTerminalNitriteIds() { - List terminalResult = new ArrayList<>(); + List terminalResult = new CopyOnWriteArrayList<>(); // scan each entry of the navigable map and collect all terminal nitrite-ids for (Pair, ?> entry : entries()) { diff --git a/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java index 5ff4ad391..0236b8395 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/IndexScanner.java @@ -20,7 +20,6 @@ import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.filters.ComparableFilter; -import org.dizitart.no2.filters.Filter; import java.util.LinkedHashSet; import java.util.List; @@ -53,17 +52,15 @@ public IndexScanner(IndexMap indexMap) { * @return the linked hash set */ @SuppressWarnings("unchecked") - public LinkedHashSet doScan(List filters, Map indexScanOrder) { + public LinkedHashSet doScan(List filters, Map indexScanOrder) { // linked-hash-set to return only unique ids preserving the order in index LinkedHashSet nitriteIds = new LinkedHashSet<>(); if (filters != null && !filters.isEmpty()) { // get the first filter to start scanning - Filter filter = filters.get(0); - - if (filter instanceof ComparableFilter) { - ComparableFilter comparableFilter = (ComparableFilter) filter; + ComparableFilter comparableFilter = filters.get(0); + if (comparableFilter != null) { // set the scan order of the index map boolean reverseScan = (indexScanOrder != null && indexScanOrder.containsKey(comparableFilter.getField())) @@ -87,7 +84,7 @@ public LinkedHashSet doScan(List filters, Map> subMaps = (List>) scanResult; - List remainingFilter = filters.subList(1, filters.size()); + List remainingFilter = filters.subList(1, filters.size()); for (NavigableMap subMap : subMaps) { // create an index map from the sub map and scan to get the @@ -100,7 +97,7 @@ public LinkedHashSet doScan(List filters, Map addNitriteIds(List nitriteIds, FieldValues fieldValues) { if (nitriteIds == null) { - nitriteIds = new ArrayList<>(); + nitriteIds = new CopyOnWriteArrayList<>(); } if (isUnique() && nitriteIds.size() == 1 diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java index de5a66a18..47cd4cf96 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NitriteTextIndexer.java @@ -63,7 +63,7 @@ public void initialize(NitriteConfig nitriteConfig) { @Override public String getIndexType() { - return IndexType.Fulltext; + return IndexType.FULL_TEXT; } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java index f5bd096ed..9d3c8b6d0 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/NonUniqueIndexer.java @@ -31,6 +31,6 @@ boolean isUnique() { @Override public String getIndexType() { - return IndexType.NonUnique; + return IndexType.NON_UNIQUE; } } diff --git a/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java index 88e17df8f..592caad86 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/SingleFieldIndex.java @@ -23,13 +23,14 @@ import org.dizitart.no2.common.DBNull; import org.dizitart.no2.common.FieldValues; import org.dizitart.no2.common.Fields; +import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; -import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; @@ -64,19 +65,16 @@ public void write(FieldValues fieldValues) { String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); - if (element == null) { - NitriteMap> indexMap = findIndexMap(); + NitriteMap> indexMap = findIndexMap(); + if (element == null) { addIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (element instanceof Comparable) { - NitriteMap> indexMap = findIndexMap(); - // wrap around db value DBValue dbValue = new DBValue((Comparable) element); addIndexElement(indexMap, fieldValues, dbValue); } else if (element.getClass().isArray()) { Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { // wrap around db value @@ -85,7 +83,6 @@ public void write(FieldValues fieldValues) { } } else if (element instanceof Iterable) { Iterable iterable = (Iterable) element; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { // wrap around db value @@ -103,19 +100,15 @@ public void remove(FieldValues fieldValues) { String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); + NitriteMap> indexMap = findIndexMap(); if (element == null) { - NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, DBNull.getInstance()); } else if (element instanceof Comparable) { - NitriteMap> indexMap = findIndexMap(); - // wrap around db value DBValue dbValue = new DBValue((Comparable) element); removeIndexElement(indexMap, fieldValues, dbValue); } else if (element.getClass().isArray()) { Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { // wrap around db value @@ -124,7 +117,6 @@ public void remove(FieldValues fieldValues) { } } else if (element instanceof Iterable) { Iterable iterable = (Iterable) element; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { // wrap around db value @@ -173,12 +165,12 @@ private void removeIndexElement(NitriteMap> indexMap, private NitriteMap> findIndexMap() { String mapName = deriveIndexMapName(indexDescriptor); - return nitriteStore.openMap(mapName, DBValue.class, ArrayList.class); + return nitriteStore.openMap(mapName, DBValue.class, CopyOnWriteArrayList.class); } private LinkedHashSet scanIndex(FindPlan findPlan, NitriteMap> indexMap) { - List filters = findPlan.getIndexScanFilter().getFilters(); + List filters = findPlan.getIndexScanFilter().getFilters(); IndexMap iMap = new IndexMap(indexMap); IndexScanner indexScanner = new IndexScanner(iMap); return indexScanner.doScan(filters, findPlan.getIndexScanOrder()); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java index 39d94ebfa..3c6a4aba4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/TextIndex.java @@ -24,13 +24,17 @@ import org.dizitart.no2.common.Fields; import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.filters.ComparableFilter; import org.dizitart.no2.filters.TextFilter; import org.dizitart.no2.index.fulltext.TextTokenizer; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; -import java.util.*; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; import static org.dizitart.no2.common.util.IndexUtils.deriveIndexMapName; import static org.dizitart.no2.common.util.ObjectUtils.convertToObjectArray; @@ -72,28 +76,22 @@ public void write(FieldValues fieldValues) { String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); - if (element == null) { - NitriteMap> indexMap = findIndexMap(); + NitriteMap> indexMap = findIndexMap(); + if (element == null) { addIndexElement(indexMap, fieldValues, null); } else if (element instanceof String) { - NitriteMap> indexMap = findIndexMap(); - addIndexElement(indexMap, fieldValues, (String) element); } else if (element.getClass().isArray()) { validateStringArrayIndexField(element, firstField); - Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { addIndexElement(indexMap, fieldValues, (String) item); } } else if (element instanceof Iterable) { validateStringIterableIndexField((Iterable) element, firstField); - Iterable iterable = (Iterable) element; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { addIndexElement(indexMap, fieldValues, (String) item); @@ -111,28 +109,21 @@ public void remove(FieldValues fieldValues) { String firstField = fieldNames.get(0); Object element = fieldValues.get(firstField); + NitriteMap> indexMap = findIndexMap(); if (element == null) { - NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, null); } else if (element instanceof String) { - NitriteMap> indexMap = findIndexMap(); - removeIndexElement(indexMap, fieldValues, (String) element); } else if (element.getClass().isArray()) { validateStringArrayIndexField(element, firstField); - Object[] array = convertToObjectArray(element); - NitriteMap> indexMap = findIndexMap(); for (Object item : array) { removeIndexElement(indexMap, fieldValues, (String) item); } } else if (element instanceof Iterable) { validateStringIterableIndexField((Iterable) element, firstField); - Iterable iterable = (Iterable) element; - NitriteMap> indexMap = findIndexMap(); for (Object item : iterable) { removeIndexElement(indexMap, fieldValues, (String) item); @@ -154,7 +145,7 @@ public LinkedHashSet findNitriteIds(FindPlan findPlan) { if (findPlan.getIndexScanFilter() == null) return new LinkedHashSet<>(); NitriteMap> indexMap = findIndexMap(); - List filters = findPlan.getIndexScanFilter().getFilters(); + List filters = findPlan.getIndexScanFilter().getFilters(); if (filters.size() == 1 && filters.get(0) instanceof TextFilter) { TextFilter textFilter = (TextFilter) filters.get(0); @@ -166,7 +157,7 @@ public LinkedHashSet findNitriteIds(FindPlan findPlan) { private NitriteMap> findIndexMap() { String mapName = deriveIndexMapName(indexDescriptor); - return nitriteStore.openMap(mapName, String.class, ArrayList.class); + return nitriteStore.openMap(mapName, String.class, CopyOnWriteArrayList.class); } @SuppressWarnings("unchecked") @@ -177,7 +168,7 @@ private void addIndexElement(NitriteMap> indexMap, FieldValues f List nitriteIds = (List) indexMap.get(word); if (nitriteIds == null) { - nitriteIds = new ArrayList<>(); + nitriteIds = new CopyOnWriteArrayList<>(); } nitriteIds = addNitriteIds(nitriteIds, fieldValues); diff --git a/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java b/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java index c576b943b..2eb859694 100644 --- a/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java +++ b/nitrite/src/main/java/org/dizitart/no2/index/UniqueIndexer.java @@ -25,7 +25,7 @@ public final class UniqueIndexer extends ComparableIndexer { @Override public String getIndexType() { - return IndexType.Unique; + return IndexType.UNIQUE; } @Override diff --git a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java index 318e6c6a2..3eb56806b 100644 --- a/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java +++ b/nitrite/src/main/java/org/dizitart/no2/migration/commands/ChangeIdField.java @@ -27,6 +27,6 @@ public void execute(Nitrite nitrite) { operations.dropIndex(oldFields); } - operations.createIndex(newFields, IndexType.Unique); + operations.createIndex(newFields, IndexType.UNIQUE); } } \ No newline at end of file diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java index 1f6a6a0ce..f6bebc643 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/DefaultObjectRepository.java @@ -176,7 +176,7 @@ public boolean isOpen() { } @Override - public void close() throws Exception { + public void close() { collection.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java index 143620032..635e5fd33 100644 --- a/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java +++ b/nitrite/src/main/java/org/dizitart/no2/repository/annotations/Index.java @@ -42,5 +42,5 @@ * * @return the index type */ - String type() default IndexType.Unique; + String type() default IndexType.UNIQUE; } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java index 615caa40d..6bca86a79 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteRTree.java @@ -71,4 +71,14 @@ public interface NitriteRTree extends AutoCloseable { * Closes this {@link NitriteRTree} instance. * */ void close(); + + /** + * Clears the data. + */ + void clear(); + + /** + * Drops this instance. + */ + void drop(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java index 5ab4989d2..960b93b8f 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/NitriteStore.java @@ -115,7 +115,14 @@ public interface NitriteStore extends NitritePlugin, NitriteMap openMap(String mapName, Class keyType, Class valueType); /** - * Removes a map from the store. + * Closes a {@link NitriteMap} in the store. + * + * @param mapName the map name + */ + void closeMap(String mapName); + + /** + * Removes a {@link NitriteMap} from the store. * * @param mapName the map name to remove. */ @@ -135,6 +142,14 @@ public interface NitriteStore extends NitritePlugin, */ NitriteRTree openRTree(String rTreeName, Class keyType, Class valueType); + + /** + * Closes a RTree in the store. + * + * @param rTreeName the RTree name + */ + void closeRTree(String rTreeName); + /** * Removes a RTree from the store. * diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java index 8c11f0b85..9fa4d0096 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryMap.java @@ -162,7 +162,7 @@ public void drop() { @Override public void close() { - + // nothing to close } private RecordStream> getStream(NavigableMap primaryMap) { diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java index 78139b6b2..293951224 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryRTree.java @@ -112,6 +112,16 @@ public void close() { } + @Override + public void clear() { + backingMap.clear(); + } + + @Override + public void drop() { + backingMap.clear(); + } + /** * The type Spatial key. */ diff --git a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java index 66afe540a..e801a0e14 100644 --- a/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/store/memory/InMemoryStore.java @@ -70,6 +70,8 @@ public void close() throws Exception { rTree.close(); } + nitriteMapRegistry.clear(); + nitriteRTreeMapRegistry.clear(); alert(StoreEvents.Closed); } @@ -91,6 +93,18 @@ public NitriteMap openMap(String mapName, Class keyT return nitriteMap; } + @Override + public void closeMap(String mapName) { + // nothing to close as it is volatile map, moreover, + // removing it form registry means loosing the map + } + + @Override + public void closeRTree(String rTreeName) { + // nothing to close as it is volatile map, moreover, + // removing it form registry means loosing the map + } + @Override public void removeMap(String mapName) { if (nitriteMapRegistry.containsKey(mapName)) { diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java index 4ef1e2b52..d64e7ec91 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalCollection.java @@ -297,7 +297,7 @@ public void createIndex(IndexOptions indexOptions, String... fieldNames) { Fields fields = Fields.withNames(fieldNames); writeLock.lock(); if (indexOptions == null) { - collectionOperations.createIndex(fields, IndexType.Unique); + collectionOperations.createIndex(fields, IndexType.UNIQUE); } else { collectionOperations.createIndex(fields, indexOptions.getIndexType()); } @@ -529,7 +529,7 @@ public boolean isOpen() { } @Override - public void close() throws Exception { + public void close() { if (collectionOperations != null) { collectionOperations.close(); } @@ -647,7 +647,7 @@ private void checkOpened() { } } - private void closeEventBus() throws Exception { + private void closeEventBus() { if (eventBus != null) { eventBus.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java index f58a31a71..54bb8c62a 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/DefaultTransactionalRepository.java @@ -173,7 +173,7 @@ public boolean isOpen() { } @Override - public void close() throws Exception { + public void close() { backingCollection.close(); } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java index c2bb93b52..fc6ba15d6 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalMap.java @@ -7,6 +7,7 @@ import org.dizitart.no2.store.memory.InMemoryMap; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; import static org.dizitart.no2.common.util.ObjectUtils.deepCopy; @@ -56,9 +57,9 @@ public V get(K k) { V result = backingMap.get(k); if (result == null) { result = primary.get(k); - if (result instanceof List) { + if (result instanceof CopyOnWriteArrayList) { // create a deep copy of the list so that it does not effect the original one - List list = deepCopy((ArrayList) result); + List list = deepCopy((CopyOnWriteArrayList) result); backingMap.put(k, (V) list); result = (V) list; } diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java index 5bb6354e5..1b96895e2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalRTree.java @@ -105,6 +105,16 @@ public void close() { map.clear(); } + @Override + public void clear() { + map.clear(); + } + + @Override + public void drop() { + map.clear(); + } + /* * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (https://h2database.com/html/license.html). diff --git a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java index 25253c776..d9478add4 100644 --- a/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java +++ b/nitrite/src/main/java/org/dizitart/no2/transaction/TransactionalStore.java @@ -57,6 +57,9 @@ public void close() throws Exception { for (NitriteRTree rTree : rTreeRegistry.values()) { rTree.close(); } + + mapRegistry.clear(); + rTreeRegistry.clear(); } @Override @@ -88,6 +91,18 @@ public NitriteMap openMap(String mapName, Class keyT return transactionalMap; } + @Override + public void closeMap(String mapName) { + // nothing to close as it is volatile map, moreover, + // removing it form registry means loosing the map + } + + @Override + public void closeRTree(String rTreeName) { + // nothing to close as it is volatile map, moreover, + // removing it form registry means loosing the map + } + @Override public void removeMap(String mapName) { mapRegistry.remove(mapName); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/FindPlanTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/FindPlanTest.java index cca0b1aca..b18f506d2 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/FindPlanTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/FindPlanTest.java @@ -17,19 +17,33 @@ package org.dizitart.no2.collection; -import org.dizitart.no2.common.Fields; import org.dizitart.no2.filters.Filter; -import org.dizitart.no2.filters.IndexScanFilter; -import org.dizitart.no2.index.IndexDescriptor; import org.junit.Test; -import java.util.ArrayList; -import java.util.HashMap; - import static org.junit.Assert.*; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; public class FindPlanTest { + @Test + public void testConstructor() { + FindPlan actualFindPlan = new FindPlan(); + assertTrue(actualFindPlan.getBlockingSortOrder().isEmpty()); + assertEquals( + "FindPlan(byIdFilter=null, indexScanFilter=null, collectionScanFilter=null, indexDescriptor=null," + + " indexScanOrder=null, blockingSortOrder=[], skip=null, limit=null, collator=null, subPlans=[])", + actualFindPlan.toString()); + assertTrue(actualFindPlan.getSubPlans().isEmpty()); + assertNull(actualFindPlan.getSkip()); + assertNull(actualFindPlan.getLimit()); + assertNull(actualFindPlan.getIndexScanOrder()); + assertNull(actualFindPlan.getIndexScanFilter()); + assertNull(actualFindPlan.getIndexDescriptor()); + assertNull(actualFindPlan.getCollectionScanFilter()); + assertNull(actualFindPlan.getCollator()); + assertNull(actualFindPlan.getByIdFilter()); + } + @Test public void testCanEqual() { assertFalse((new FindPlan()).canEqual("Other")); @@ -54,261 +68,5 @@ public void testEquals10() { findPlan1.setCollectionScanFilter(mock(Filter.class)); assertFalse(findPlan.equals(findPlan1)); } - - @Test - public void testEquals11() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setSkip(0L); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals12() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setBlockingSortOrder(null); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals13() { - FindPlan findPlan = new FindPlan(); - findPlan.setSubPlans(null); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setSubPlans(null); - assertTrue(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals14() { - FindPlan findPlan = new FindPlan(); - findPlan.setLimit(0L); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setLimit(0L); - assertTrue(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals15() { - FindPlan findPlan = new FindPlan(); - findPlan.setSkip(0L); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setSkip(0L); - assertTrue(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals16() { - FindPlan findPlan = new FindPlan(); - findPlan.setBlockingSortOrder(null); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setBlockingSortOrder(null); - assertTrue(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals17() { - FindPlan findPlan = new FindPlan(); - findPlan.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals18() { - FindPlan findPlan = new FindPlan(); - findPlan.setIndexScanFilter(new IndexScanFilter(new ArrayList())); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals19() { - FindPlan findPlan = new FindPlan(); - findPlan.setIndexScanOrder(new HashMap(1)); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals2() { - FindPlan findPlan = new FindPlan(); - assertTrue(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals20() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals21() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setIndexScanFilter(new IndexScanFilter(new ArrayList())); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals3() { - FindPlan findPlan = new FindPlan(); - findPlan.setSubPlans(null); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals4() { - FindPlan findPlan = new FindPlan(); - findPlan.setLimit(0L); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals5() { - FindPlan findPlan = new FindPlan(); - findPlan.setCollectionScanFilter(mock(Filter.class)); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals6() { - FindPlan findPlan = new FindPlan(); - findPlan.setSkip(0L); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals7() { - FindPlan findPlan = new FindPlan(); - findPlan.setBlockingSortOrder(null); - assertFalse(findPlan.equals(new FindPlan())); - } - - @Test - public void testEquals8() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setSubPlans(null); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testEquals9() { - FindPlan findPlan = new FindPlan(); - - FindPlan findPlan1 = new FindPlan(); - findPlan1.setLimit(0L); - assertFalse(findPlan.equals(findPlan1)); - } - - @Test - public void testHashCode() { - assertEquals(157971442, (new FindPlan()).hashCode()); - } - - @Test - public void testHashCode10() { - ArrayList findPlanList = new ArrayList(); - findPlanList.add(new FindPlan()); - - FindPlan findPlan = new FindPlan(); - findPlan.setSubPlans(findPlanList); - assertEquals(315942914, findPlan.hashCode()); - } - - @Test - public void testHashCode11() { - ArrayList findPlanList = new ArrayList(); - findPlanList.add(new FindPlan()); - findPlanList.add(new FindPlan()); - - FindPlan findPlan = new FindPlan(); - findPlan.setSubPlans(findPlanList); - assertEquals(918091250, findPlan.hashCode()); - } - - @Test - public void testHashCode2() { - FindPlan findPlan = new FindPlan(); - findPlan.setSubPlans(null); - assertEquals(157971484, findPlan.hashCode()); - } - - @Test - public void testHashCode3() { - FindPlan findPlan = new FindPlan(); - findPlan.setLimit(0L); - assertEquals(1549271361, findPlan.hashCode()); - } - - @Test - public void testHashCode4() { - // TODO: This test is incomplete. - // Reason: No meaningful assertions found. - // To help Diffblue Cover to find assertions, please add getters to the - // class under test that return fields written by the method under test. - // See https://diff.blue/R004 - - FindPlan findPlan = new FindPlan(); - findPlan.setCollectionScanFilter(mock(Filter.class)); - findPlan.hashCode(); - } - - @Test - public void testHashCode5() { - FindPlan findPlan = new FindPlan(); - findPlan.setSkip(0L); - assertEquals(640288039, findPlan.hashCode()); - } - - @Test - public void testHashCode6() { - FindPlan findPlan = new FindPlan(); - findPlan.setBlockingSortOrder(null); - assertEquals(158117644, findPlan.hashCode()); - } - - @Test - public void testHashCode7() { - // TODO: This test is incomplete. - // Reason: No meaningful assertions found. - // To help Diffblue Cover to find assertions, please add getters to the - // class under test that return fields written by the method under test. - // See https://diff.blue/R004 - - FindPlan findPlan = new FindPlan(); - findPlan.setIndexDescriptor(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - findPlan.hashCode(); - } - - @Test - public void testHashCode8() { - // TODO: This test is incomplete. - // Reason: No meaningful assertions found. - // To help Diffblue Cover to find assertions, please add getters to the - // class under test that return fields written by the method under test. - // See https://diff.blue/R004 - - FindPlan findPlan = new FindPlan(); - findPlan.setIndexScanFilter(new IndexScanFilter(new ArrayList())); - findPlan.hashCode(); - } - - @Test - public void testHashCode9() { - FindPlan findPlan = new FindPlan(); - findPlan.setIndexScanOrder(new HashMap(1)); - assertEquals(-363075081, findPlan.hashCode()); - } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java index 5efb43f35..827dec075 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java @@ -20,8 +20,9 @@ import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.common.Fields; import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.store.memory.InMemoryMap; +import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.index.UniqueIndexer; +import org.dizitart.no2.store.memory.InMemoryStore; import org.junit.Test; import java.util.ArrayList; @@ -30,59 +31,46 @@ import static org.mockito.Mockito.*; public class DocumentIndexWriterTest { + @Test public void testWriteIndexEntry() { ArrayList indexDescriptorList = new ArrayList<>(); - indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + indexDescriptorList.add(new IndexDescriptor(IndexType.UNIQUE, Fields.withNames("a"), "Collection Name")); + IndexOperations indexOperations = mock(IndexOperations.class); + when(indexOperations.listIndexes()).thenReturn(indexDescriptorList); NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - doNothing().when(nitriteIndexer).writeIndexEntry(any(), any(), any()); + doReturn(new UniqueIndexer()).when(nitriteConfig).findIndexer(IndexType.UNIQUE); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - (new DocumentIndexWriter(nitriteConfig, indexOperations)).writeIndexEntry(createDocument("a", "b")); - verify(indexManager).getIndexDescriptors(); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).writeIndexEntry(createDocument("a", 1)); + verify(indexOperations).listIndexes(); } @Test public void testRemoveIndexEntry() { ArrayList indexDescriptorList = new ArrayList<>(); - indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + indexDescriptorList.add(new IndexDescriptor(IndexType.UNIQUE, Fields.withNames("a"), "Collection Name")); + IndexOperations indexOperations = mock(IndexOperations.class); + when(indexOperations.listIndexes()).thenReturn(indexDescriptorList); NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - doNothing().when(nitriteIndexer).removeIndexEntry(any(), any(), any()); - - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - (new DocumentIndexWriter(nitriteConfig, indexOperations)).removeIndexEntry(createDocument("a", "b")); - verify(indexManager).getIndexDescriptors(); + doReturn(new UniqueIndexer()).when(nitriteConfig).findIndexer(IndexType.UNIQUE); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).removeIndexEntry(createDocument("a", 1)); + verify(indexOperations).listIndexes(); } @Test public void testUpdateIndexEntry() { ArrayList indexDescriptorList = new ArrayList<>(); - indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); + indexDescriptorList.add(new IndexDescriptor(IndexType.UNIQUE, Fields.withNames("a"), "Collection Name")); + IndexOperations indexOperations = mock(IndexOperations.class); + when(indexOperations.listIndexes()).thenReturn(indexDescriptorList); NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - doNothing().when(nitriteIndexer).removeIndexEntry(any(), any(), any()); + doReturn(new UniqueIndexer()).when(nitriteConfig).findIndexer(IndexType.UNIQUE); + doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - (new DocumentIndexWriter(nitriteConfig, indexOperations)).updateIndexEntry(createDocument("x", "y"), - createDocument("a", "b")); - verify(indexManager).getIndexDescriptors(); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).updateIndexEntry(createDocument("a", 1), createDocument("a", 2)); + verify(indexOperations).listIndexes(); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java index e2b5da575..a41bfea7f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/FindOptimizerTest.java @@ -27,8 +27,7 @@ import java.util.ArrayList; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.Mockito.mock; public class FindOptimizerTest { @@ -37,46 +36,62 @@ public void testOptimize() { FindOptimizer findOptimizer = new FindOptimizer(); Filter filter = mock(Filter.class); FindOptions findOptions = new FindOptions(); - FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList<>()); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList()); + assertTrue(actualOptimizeResult.getBlockingSortOrder().isEmpty()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); assertNull(actualOptimizeResult.getSkip()); assertNull(actualOptimizeResult.getLimit()); - assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); } @Test public void testOptimize2() { FindOptimizer findOptimizer = new FindOptimizer(); - Filter filter = mock(Filter.class); - findOptimizer.optimize(filter, null, new ArrayList<>()); + FindOptions findOptions = new FindOptions(); + FindPlan actualOptimizeResult = findOptimizer.optimize(null, findOptions, new ArrayList()); + assertTrue(actualOptimizeResult.getBlockingSortOrder().isEmpty()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); + assertNull(actualOptimizeResult.getSkip()); + assertNull(actualOptimizeResult.getLimit()); } @Test public void testOptimize3() { + FindOptimizer findOptimizer = new FindOptimizer(); + Filter filter = mock(Filter.class); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, null, new ArrayList()); + assertTrue(actualOptimizeResult.getBlockingSortOrder().isEmpty()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); + } + + @Test + public void testOptimize4() { FindOptimizer findOptimizer = new FindOptimizer(); Filter filter = mock(Filter.class); FindOptions findOptions = FindOptions.orderBy("Field Name", SortOrder.Ascending); - FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList<>()); - assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); + FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, new ArrayList()); + assertEquals(1, actualOptimizeResult.getBlockingSortOrder().size()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); assertNull(actualOptimizeResult.getSkip()); assertNull(actualOptimizeResult.getLimit()); } @Test - public void testOptimize4() { + public void testOptimize5() { FindOptimizer findOptimizer = new FindOptimizer(); Filter filter = mock(Filter.class); FindOptions findOptions = new FindOptions(); - ArrayList indexDescriptorList = new ArrayList<>(); + ArrayList indexDescriptorList = new ArrayList(); indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, indexDescriptorList); + assertTrue(actualOptimizeResult.getBlockingSortOrder().isEmpty()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); assertNull(actualOptimizeResult.getSkip()); assertNull(actualOptimizeResult.getLimit()); - assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); } @Test - public void testOptimize5() { + public void testOptimize6() { FindOptimizer findOptimizer = new FindOptimizer(); Filter filter = mock(Filter.class); FindOptions findOptions = new FindOptions(); @@ -85,12 +100,13 @@ public void testOptimize5() { fields.addField("Field"); IndexDescriptor e = new IndexDescriptor("Index Type", fields, "Collection Name"); - ArrayList indexDescriptorList = new ArrayList<>(); + ArrayList indexDescriptorList = new ArrayList(); indexDescriptorList.add(e); FindPlan actualOptimizeResult = findOptimizer.optimize(filter, findOptions, indexDescriptorList); + assertTrue(actualOptimizeResult.getBlockingSortOrder().isEmpty()); + assertTrue(actualOptimizeResult.getSubPlans().isEmpty()); assertNull(actualOptimizeResult.getSkip()); assertNull(actualOptimizeResult.getLimit()); - assertTrue(actualOptimizeResult.getCollator() instanceof java.text.RuleBasedCollator); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java deleted file mode 100644 index 19347cacd..000000000 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/IndexOperationsTest.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2017-2021 Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dizitart.no2.collection.operation; - -import org.dizitart.no2.NitriteConfig; -import org.dizitart.no2.common.Fields; -import org.dizitart.no2.exceptions.IndexingException; -import org.dizitart.no2.index.IndexDescriptor; -import org.dizitart.no2.index.NitriteIndexer; -import org.dizitart.no2.store.memory.InMemoryMap; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Collection; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -public class IndexOperationsTest { - @Test - public void testCreateIndex() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.findExactIndexDescriptor(any())) - .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertThrows(IndexingException.class, () -> indexOperations.createIndex(new Fields(), "Index Type")); - verify(indexManager).findExactIndexDescriptor(any()); - } - - @Test - public void testCreateIndex2() { - IndexManager indexManager = mock(IndexManager.class); - doNothing().when(indexManager).beginIndexing(any()); - doNothing().when(indexManager).endIndexing(any()); - when(indexManager.createIndexDescriptor(any(), anyString())) - .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - when(indexManager.findExactIndexDescriptor(any())).thenReturn(null); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); - NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - indexOperations.createIndex(new Fields(), "Index Type"); - verify(indexManager).endIndexing(any()); - verify(indexManager).createIndexDescriptor(any(), anyString()); - verify(indexManager).findExactIndexDescriptor(any()); - verify(indexManager).beginIndexing(any()); - } - - @Test - public void testBuildIndex() { - IndexManager indexManager = mock(IndexManager.class); - doNothing().when(indexManager).beginIndexing(any()); - doNothing().when(indexManager).endIndexing(any()); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); - NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - indexOperations.buildIndex(new IndexDescriptor("Index Type", new Fields(), "Collection Name"), true); - verify(indexManager).endIndexing(any()); - verify(indexManager).beginIndexing(any()); - } - - @Test - public void testDropIndex() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.findExactIndexDescriptor(any())) - .thenReturn(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); - NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - indexOperations.dropIndex(new Fields()); - verify(indexManager).findExactIndexDescriptor(any()); - } - - @Test - public void testDropIndex2() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.findExactIndexDescriptor(any())).thenReturn(null); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertThrows(IndexingException.class, () -> indexOperations.dropIndex(new Fields())); - verify(indexManager).findExactIndexDescriptor(any()); - } - - @Test - public void testDropIndex3() { - IndexDescriptor indexDescriptor = mock(IndexDescriptor.class); - when(indexDescriptor.getIndexType()).thenReturn("foo"); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.findExactIndexDescriptor(any())).thenReturn(indexDescriptor); - - NitriteIndexer nitriteIndexer = mock(NitriteIndexer.class); - NitriteConfig nitriteConfig = mock(NitriteConfig.class); - when(nitriteConfig.findIndexer(anyString())).thenReturn(nitriteIndexer); - - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - indexOperations.dropIndex(new Fields()); - verify(indexDescriptor).getIndexType(); - verify(indexManager).findExactIndexDescriptor(any()); - } - - @Test(expected = IndexingException.class) - public void testDropAllIndices() { - ArrayList indexDescriptorList = new ArrayList<>(); - indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name")); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - NitriteConfig nitriteConfig = new NitriteConfig(); - (new IndexOperations(nitriteConfig, new InMemoryMap<>("Map Name", null), null, indexManager)) - .dropAllIndices(); - verify(indexManager).getIndexDescriptors(); - } - - @Test(expected = IndexingException.class) - public void testDropAllIndices2() { - ArrayList indexDescriptorList = new ArrayList<>(); - indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("a"), "Collection Name")); - indexDescriptorList.add(new IndexDescriptor("Index Type", Fields.withNames("b"), "Collection Name")); - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - NitriteConfig nitriteConfig = new NitriteConfig(); - (new IndexOperations(nitriteConfig, new InMemoryMap<>("Map Name", null), null, indexManager)) - .dropAllIndices(); - verify(indexManager).getIndexDescriptors(); - } - - @Test - public void testIsIndexing() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.hasIndexDescriptor(any())).thenReturn(true); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertFalse(indexOperations.isIndexing(new Fields())); - verify(indexManager).hasIndexDescriptor(any()); - } - - @Test - public void testIsIndexing2() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.hasIndexDescriptor(any())).thenReturn(false); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertFalse(indexOperations.isIndexing(new Fields())); - verify(indexManager).hasIndexDescriptor(any()); - } - - @Test - public void testHasIndexEntry() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.hasIndexDescriptor(any())).thenReturn(true); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertTrue(indexOperations.hasIndexEntry(new Fields())); - verify(indexManager).hasIndexDescriptor(any()); - } - - @Test - public void testListIndexes() { - IndexManager indexManager = mock(IndexManager.class); - ArrayList indexDescriptorList = new ArrayList<>(); - when(indexManager.getIndexDescriptors()).thenReturn(indexDescriptorList); - NitriteConfig nitriteConfig = new NitriteConfig(); - Collection actualListIndexesResult = (new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager)).listIndexes(); - assertSame(indexDescriptorList, actualListIndexesResult); - assertTrue(actualListIndexesResult.isEmpty()); - verify(indexManager).getIndexDescriptors(); - } - - @Test - public void testFindIndexDescriptor() { - IndexManager indexManager = mock(IndexManager.class); - IndexDescriptor indexDescriptor = new IndexDescriptor("Index Type", new Fields(), "Collection Name"); - when(indexManager.findExactIndexDescriptor(any())).thenReturn(indexDescriptor); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertSame(indexDescriptor, indexOperations.findIndexDescriptor(new Fields())); - verify(indexManager).findExactIndexDescriptor(any()); - } - - @Test - public void testGetBuildFlag() { - // TODO: This test is incomplete. - // Reason: No meaningful assertions found. - // To help Diffblue Cover to find assertions, please add getters to the - // class under test that return fields written by the method under test. - // See https://diff.blue/R004 - - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, null); - indexOperations.getBuildFlag(new Fields()); - } - - @Test - public void testShouldRebuildIndex() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.isDirtyIndex(any())).thenReturn(true); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertTrue(indexOperations.shouldRebuildIndex(new Fields())); - verify(indexManager).isDirtyIndex(any()); - } - - @Test - public void testShouldRebuildIndex2() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.isDirtyIndex(any())).thenReturn(false); - NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - assertFalse(indexOperations.shouldRebuildIndex(new Fields())); - verify(indexManager).isDirtyIndex(any()); - } -} - diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java index af092f3c5..bbb99823d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/ReadOperationsTest.java @@ -21,8 +21,10 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.FindOptions; import org.dizitart.no2.collection.NitriteId; -import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.common.Fields; import org.dizitart.no2.common.processors.ProcessorChain; +import org.dizitart.no2.filters.Filter; +import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.memory.InMemoryMap; import org.junit.Test; @@ -33,31 +35,44 @@ import static org.mockito.Mockito.*; public class ReadOperationsTest { + @Test public void testFind() { - IndexManager indexManager = mock(IndexManager.class); - when(indexManager.getIndexDescriptors()).thenReturn(new ArrayList<>()); + IndexOperations indexOperations = mock(IndexOperations.class); + when(indexOperations.listIndexes()).thenReturn(new ArrayList<>()); NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, indexManager); - NitriteConfig nitriteConfig1 = new NitriteConfig(); InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); - ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig1, nitriteMap, - new ProcessorChain()); + + ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig, nitriteMap, + new ProcessorChain()); Filter filter = mock(Filter.class); assertTrue(readOperations.find(filter, new FindOptions()).toList().isEmpty()); - verify(indexManager).getIndexDescriptors(); + verify(indexOperations).listIndexes(); + } + + @Test + public void testFind2() { + ArrayList indexDescriptorList = new ArrayList<>(); + indexDescriptorList.add(new IndexDescriptor("Index Type", new Fields(), "Collection Name")); + IndexOperations indexOperations = mock(IndexOperations.class); + when(indexOperations.listIndexes()).thenReturn(indexDescriptorList); + NitriteConfig nitriteConfig = new NitriteConfig(); + InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); + + ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig, nitriteMap, + new ProcessorChain()); + Filter filter = mock(Filter.class); + assertTrue(readOperations.find(filter, new FindOptions()).toList().isEmpty()); + verify(indexOperations).listIndexes(); } @Test public void testGetById() { NitriteConfig nitriteConfig = new NitriteConfig(); - IndexOperations indexOperations = new IndexOperations(nitriteConfig, - new InMemoryMap<>("Map Name", null), null, null); - NitriteConfig nitriteConfig1 = new NitriteConfig(); InMemoryMap nitriteMap = new InMemoryMap<>("Map Name", null); - ReadOperations readOperations = new ReadOperations("Collection Name", indexOperations, nitriteConfig1, nitriteMap, - new ProcessorChain()); + + ReadOperations readOperations = new ReadOperations("Collection Name", null, nitriteConfig, nitriteMap, + new ProcessorChain()); assertNull(readOperations.getById(NitriteId.newId())); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java index 5440a196a..7156cd267 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java @@ -39,8 +39,8 @@ public void testConstructor() { new SortedDocumentStream(findPlan, (RecordStream>) mock(RecordStream.class)); List> blockingSortOrder = findPlan.getBlockingSortOrder(); assertTrue(blockingSortOrder instanceof java.util.ArrayList); - assertEquals("FindPlan(indexDescriptor=null, indexScanFilter=null, indexScanOrder=null, collectionScanFilter=null," - + " blockingSortOrder=[], skip=null, limit=null, collator=null, subPlans=[])", findPlan.toString()); + assertEquals("FindPlan(byIdFilter=null, indexScanFilter=null, collectionScanFilter=null, indexDescriptor=null," + + " indexScanOrder=null, blockingSortOrder=[], skip=null, limit=null, collator=null, subPlans=[])", findPlan.toString()); assertTrue(blockingSortOrder.isEmpty()); List subPlans = findPlan.getSubPlans(); assertTrue(subPlans instanceof java.util.ArrayList); diff --git a/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java index 6fe56c5e8..b7679c2c5 100644 --- a/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/filters/IndexScanFilterTest.java @@ -26,7 +26,7 @@ public class IndexScanFilterTest { @Test public void testConstructor() { - assertEquals("IndexScanFilter(filters=[])", (new IndexScanFilter(new ArrayList())).toString()); + assertEquals("IndexScanFilter(filters=[])", (new IndexScanFilter(new ArrayList<>())).toString()); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java b/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java index bf8c48c3e..647b16da4 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/IndexMapTest.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.TreeMap; +import java.util.concurrent.CopyOnWriteArrayList; import static org.junit.Assert.*; @@ -32,7 +33,7 @@ public void testConstructor() { TreeMap dbValueObjectMap = new TreeMap<>(); IndexMap actualIndexMap = new IndexMap(dbValueObjectMap); List terminalNitriteIds = actualIndexMap.getTerminalNitriteIds(); - assertTrue(terminalNitriteIds instanceof java.util.ArrayList); + assertTrue(terminalNitriteIds instanceof CopyOnWriteArrayList); assertFalse(actualIndexMap.isReverseScan()); assertTrue(terminalNitriteIds.isEmpty()); assertTrue(dbValueObjectMap.isEmpty()); @@ -43,7 +44,7 @@ public void testConstructor2() { InMemoryMap inMemoryMap = new InMemoryMap<>("Map Name", null); IndexMap actualIndexMap = new IndexMap(inMemoryMap); List terminalNitriteIds = actualIndexMap.getTerminalNitriteIds(); - assertTrue(terminalNitriteIds instanceof java.util.ArrayList); + assertTrue(terminalNitriteIds instanceof CopyOnWriteArrayList); assertFalse(actualIndexMap.isReverseScan()); assertTrue(terminalNitriteIds.isEmpty()); assertEquals("Map Name", inMemoryMap.getName()); diff --git a/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java index 8347f4fb5..4ccfe6ca9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/NitriteTextIndexerTest.java @@ -16,7 +16,7 @@ public class NitriteTextIndexerTest { @Test public void testConstructor() { - assertEquals(IndexType.Fulltext, (new NitriteTextIndexer(new EnglishTextTokenizer())).getIndexType()); + assertEquals(IndexType.FULL_TEXT, (new NitriteTextIndexer(new EnglishTextTokenizer())).getIndexType()); assertEquals("Fulltext", (new NitriteTextIndexer()).getIndexType()); } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java index 8fb86e862..7b411d385 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/NonUniqueIndexerTest.java @@ -10,7 +10,7 @@ public class NonUniqueIndexerTest { @Test public void testConstructor() { NonUniqueIndexer actualNonUniqueIndexer = new NonUniqueIndexer(); - assertEquals(IndexType.NonUnique, actualNonUniqueIndexer.getIndexType()); + assertEquals(IndexType.NON_UNIQUE, actualNonUniqueIndexer.getIndexType()); assertFalse(actualNonUniqueIndexer.isUnique()); } diff --git a/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java b/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java index f80bd996d..61ab9451d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/index/UniqueIndexerTest.java @@ -9,7 +9,7 @@ public class UniqueIndexerTest { @Test public void testConstructor() { UniqueIndexer actualUniqueIndexer = new UniqueIndexer(); - assertEquals(IndexType.Unique, actualUniqueIndexer.getIndexType()); + assertEquals(IndexType.UNIQUE, actualUniqueIndexer.getIndexType()); assertTrue(actualUniqueIndexer.isUnique()); } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java index e162cf21c..75a15f156 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/CustomFilterTest.java @@ -33,7 +33,7 @@ public class CustomFilterTest extends BaseCollectionTest { @Test public void testCustomFilter() { insert(); - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); DocumentCursor cursor = collection.find(element -> element.getSecond().get("firstName", String.class) .equalsIgnoreCase("FN1")); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java b/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java index dc3fbb421..588ba57b7 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/DbTestOperations.java @@ -79,9 +79,9 @@ void writeIndex() throws Exception { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); collection.createIndex("firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); db.close(); } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java index e77dc7cda..e2c3812e9 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/MultiThreadedTest.java @@ -80,8 +80,8 @@ public void testOperations() throws Exception { if (j == iterationCount / 2 && !collection.hasIndex("text") && !collection.hasIndex("date")) { - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "text"); - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "date"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "text"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "date"); } long unixTime = (long) document.get("unixTime"); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index 046c92e28..afc769d96 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -53,8 +53,8 @@ public class NitriteStressTest { public void stressTest() { Nitrite database = createDb(); ObjectRepository testRepository = database.getRepository(TestDto.class); - testRepository.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "lastName"); - testRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "birthDate"); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "lastName"); + testRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDate"); int counter = 0; try { diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java index 27bc65d8e..9e698a829 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/NitriteTest.java @@ -97,8 +97,8 @@ public void setUp() throws ParseException { collection = db.getCollection("test"); collection.remove(ALL); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); collection.insert(doc1, doc2, doc3); } @@ -284,11 +284,15 @@ public void testIssue193() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(10000); for (int i = 0; i < 10000; i++) { pool.submit(() -> { - int refIndex = random.nextInt(5); - Receipt receipt = factory.manufacturePojoWithFullData(Receipt.class); - receipt.setClientRef(refs[refIndex]); - repository.update(receipt, true); - latch.countDown(); + try { + int refIndex = random.nextInt(5); + Receipt receipt = factory.manufacturePojoWithFullData(Receipt.class); + receipt.setClientRef(refs[refIndex]); + repository.update(receipt, true); + latch.countDown(); + } catch (Throwable t) { + t.printStackTrace(); + } }); } @@ -305,10 +309,10 @@ public void testIssue212() { Document doc = createDocument("fifth_key", "fifth_key"); if (!collection.hasIndex("key")) { - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "key"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "key"); } if (!collection.hasIndex("second_key")) { - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "second_key"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "second_key"); } collection.insert(doc1, doc2); @@ -394,14 +398,14 @@ public void read(NitriteMapper mapper, Document document) { @NoArgsConstructor @AllArgsConstructor @Indices({ - @Index(value = "synced", type = IndexType.NonUnique) + @Index(value = "synced", type = IndexType.NON_UNIQUE) }) public static class Receipt implements Mappable { - private Status status; @Id private String clientRef; private Boolean synced; private Long createdTimestamp = System.currentTimeMillis(); + private Status status; @Override public Document write(NitriteMapper mapper) { diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java index 27a23e173..65142470c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/StressTest.java @@ -66,8 +66,8 @@ public void before() { @Test public void testIssue41() { - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "number"); - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "name"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "number"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "name"); collection.createIndex("counter"); Random random = new Random(); @@ -208,9 +208,9 @@ public void read(NitriteMapper mapper, Document document) { } @Indices({ - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "age", type = IndexType.NonUnique), - @Index(value = "text", type = IndexType.Fulltext), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "age", type = IndexType.NON_UNIQUE), + @Index(value = "text", type = IndexType.FULL_TEXT), }) private static class PerfTestIndexed extends PerfTest { } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java index d22be7ba8..746fe397b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexNegativeTest.java @@ -72,25 +72,25 @@ public void testRebuildIndexInvalid() { @Test(expected = IndexingException.class) public void createMultipleIndexTypeOnSameFields() { - collection.createIndex(indexOptions(IndexType.Unique), "lastName", "firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); } @Test(expected = IndexingException.class) public void testIndexAlreadyExists() { - collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName", "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName", "lastName"); } @Test(expected = IndexingException.class) public void testCreateCompoundTextIndex() { - collection.createIndex(indexOptions(IndexType.Fulltext), "body", "lastName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body", "lastName"); } @Test(expected = IndexingException.class) public void testCreateMultiKeyIndexSecondField() { - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "data"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "data"); assertTrue(collection.hasIndex("lastName")); insert(); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java index 51af747be..e0ce0646a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionCompoundIndexTest.java @@ -44,16 +44,16 @@ public class CollectionCompoundIndexTest extends BaseCollectionTest { @Test public void testCreateAndCheckIndex() { - collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); assertTrue(collection.hasIndex("firstName")); assertTrue(collection.hasIndex("firstName", "lastName")); assertFalse(collection.hasIndex("firstName", "lastName", "birthDay")); assertFalse(collection.hasIndex("lastName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); insert(); @@ -61,7 +61,7 @@ public void testCreateAndCheckIndex() { @Test public void testCreateMultiKeyIndexFirstField() { - collection.createIndex(indexOptions(IndexType.NonUnique), "data", "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "data", "lastName"); assertTrue(collection.hasIndex("data")); assertTrue(collection.hasIndex("data", "lastName")); assertFalse(collection.hasIndex("lastName")); @@ -72,10 +72,10 @@ public void testCreateMultiKeyIndexFirstField() { @Test public void testListIndexes() { assertEquals(collection.listIndices().size(), 0); - collection.createIndex(indexOptions(IndexType.Unique), "firstName", "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName", "lastName"); assertEquals(collection.listIndices().size(), 1); - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); assertEquals(collection.listIndices().size(), 2); } @@ -105,7 +105,7 @@ public void testDropIndex() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); assertTrue(collection.hasIndex("lastName")); } @@ -296,7 +296,7 @@ public void testIndexEvent() { } }); - collection.createIndex(indexOptions(IndexType.NonUnique), "first", "second"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first", "second"); assertEquals(collection.find().size(), 10000); await().until(completed::get); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java index f0c81e241..ca1660599 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionDeleteTest.java @@ -74,7 +74,7 @@ public void testDeleteInEmptyCollection() { @Test public void testClear() { - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); insert(); DocumentCursor cursor = collection.find(); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java similarity index 93% rename from nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java index 97f99f1bd..15fe879b5 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/CollectionFieldIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFieldIndexTest.java @@ -15,7 +15,7 @@ * */ -package org.dizitart.no2.integration; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; @@ -23,6 +23,7 @@ import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; import org.dizitart.no2.index.IndexType; +import org.dizitart.no2.integration.Retry; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -82,8 +83,8 @@ public void testCollection() { NitriteCollection collection = db.getCollection("test"); collection.createIndex("color"); - collection.createIndex(indexOptions(IndexType.NonUnique), "books.tag"); - collection.createIndex(indexOptions(IndexType.Fulltext), "books.name"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "books.tag"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "books.name"); WriteResult writeResult = collection.insert(doc1, doc2, doc3); assertEquals(writeResult.getAffectedCount(), 3); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java index d119f0844..8fd30693e 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByCompoundIndexTest.java @@ -354,7 +354,7 @@ public void testBlockingSort() throws ParseException { public void testSortNotCoveredByIndex() throws ParseException { // some field sort by index, some by memory - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); Document doc = createDocument("firstName", "fn4") .put("lastName", "ln3") diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java index 4be3bd9fd..76b84a0e6 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindByIndexNegativeTest.java @@ -33,7 +33,7 @@ public class CollectionFindByIndexNegativeTest extends BaseCollectionTest { @Test(expected = FilterException.class) public void testFindTextWithWildCardMultipleWord() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*ipsum dolor*")); assertEquals(cursor.size(), 1); @@ -42,7 +42,7 @@ public void testFindTextWithWildCardMultipleWord() { @Test(expected = FilterException.class) public void testFindTextWithOnlyWildCard() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("*")); assertEquals(cursor.size(), 1); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java index aaf2b8616..cbef67e26 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindBySingleFieldIndexTest.java @@ -49,14 +49,14 @@ public class CollectionFindBySingleFieldIndexTest extends BaseCollectionTest { @Test public void testFindByUniqueIndex() throws ParseException { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); cursor = collection.find(where("firstName").eq("fn10")); assertEquals(cursor.size(), 0); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); cursor = collection.find(where("birthDay").gt( simpleDateFormat.parse("2012-07-01T16:02:48.440Z"))); assertEquals(cursor.size(), 1); @@ -135,8 +135,8 @@ public void testFindByUniqueIndex() throws ParseException { @Test public void testFindByNonUniqueIndex() throws ParseException { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "lastName"); - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "birthDay"); DocumentCursor cursor = collection.find(where("lastName").eq("ln2")); assertEquals(cursor.size(), 2); @@ -222,7 +222,7 @@ public void testFindByNonUniqueIndex() throws ParseException { @Test public void testFindByFullTextIndexAfterInsert() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); DocumentCursor cursor = collection.find(where("body").text("Lorem")); @@ -244,7 +244,7 @@ public void testFindByFullTextIndexAfterInsert() { @Test public void testFindByFullTextIndexBeforeInsert() { - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); insert(); @@ -271,7 +271,7 @@ public void testFindByFullTextIndexBeforeInsert() { @Test public void testFindByIndexSortAscending() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Ascending)); assertEquals(cursor.size(), 3); @@ -285,7 +285,7 @@ public void testFindByIndexSortAscending() { @Test public void testFindByIndexSortDescending() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); DocumentCursor cursor = collection.find(orderBy("birthDay", SortOrder.Descending)); assertEquals(cursor.size(), 3); @@ -299,7 +299,7 @@ public void testFindByIndexSortDescending() { @Test public void testFindByIndexLimitAndSort() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "birthDay"); DocumentCursor cursor = collection.find( orderBy("birthDay", SortOrder.Descending) @@ -333,7 +333,7 @@ public void testFindByIndexLimitAndSort() { @Test public void testFindAfterDroppedIndex() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); DocumentCursor cursor = collection.find(where("firstName").eq("fn1")); assertEquals(cursor.size(), 1); @@ -345,7 +345,7 @@ public void testFindAfterDroppedIndex() { @Test public void testFindTextWithWildCard() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("Lo")); assertEquals(cursor.size(), 0); @@ -363,7 +363,7 @@ public void testFindTextWithWildCard() { @Test public void testFindTextWithEmptyString() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "body"); DocumentCursor cursor = collection.find(where("body").text("")); assertEquals(cursor.size(), 0); @@ -377,8 +377,8 @@ public void testFindWithOrIndexed() { Document doc3 = Document.createDocument("firstName", "Jonas").put("lastName", "Doe"); Document doc4 = Document.createDocument("firstName", "Johan").put("lastName", "Day"); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "firstName"); - collection.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "lastName"); collection.insert(doc1, doc2, doc3, doc4); @@ -408,7 +408,7 @@ public void testIssue45() { Document doc3 = Document.createDocument("firstName", "Jonas").put("notes", list3); Document doc4 = Document.createDocument("firstName", "Johan").put("notes", list4); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "notes"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "notes"); collection.insert(doc1, doc2, doc3, doc4); DocumentCursor cursor = collection.find(where("notes").text("fox")); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java index 967ba438c..25061010c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionFindTest.java @@ -34,7 +34,6 @@ import java.util.*; import java.util.stream.Collectors; -import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.collection.FindOptions.*; import static org.dizitart.no2.common.Constants.*; @@ -42,6 +41,7 @@ import static org.dizitart.no2.filters.Filter.*; import static org.dizitart.no2.filters.FluentFilter.$; import static org.dizitart.no2.filters.FluentFilter.where; +import static org.dizitart.no2.integration.TestUtil.isSorted; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.*; @@ -622,8 +622,8 @@ public void testFilterAll() { @Test public void testIssue72() { NitriteCollection coll = db.getCollection("test"); - coll.createIndex(IndexOptions.indexOptions(IndexType.Unique), "id"); - coll.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "group"); + coll.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "id"); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "group"); coll.remove(ALL); @@ -668,7 +668,7 @@ public void testIssue93() { public void testDefaultNullOrder() { NitriteCollection coll = db.getCollection("test"); try { - coll.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "startTime"); + coll.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "startTime"); } catch (IndexingException e) { // ignore } @@ -767,7 +767,7 @@ public void testBetweenFilter() { NitriteCollection collection = db.getCollection("tag"); collection.insert(doc1, doc2, doc3, doc4, doc5); - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "age"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "age"); DocumentCursor cursor = collection.find(where("age").between(31, 35)); assertEquals(cursor.size(), 5); @@ -781,4 +781,29 @@ public void testBetweenFilter() { cursor = collection.find(where("age").between(31, 35, false).not()); assertEquals(cursor.size(), 2); } + + @Test + public void testByIdFilter() { + Document doc1 = createDocument("age", 31).put("tag", "one"); + Document doc2 = createDocument("age", 32).put("tag", "two"); + Document doc3 = createDocument("age", 33).put("tag", "three"); + Document doc4 = createDocument("age", 34).put("tag", "four"); + Document doc5 = createDocument("age", 35).put("tag", "five"); + + NitriteCollection collection = db.getCollection("tag"); + collection.insert(doc1, doc2, doc3, doc4, doc5); + + List documentList = collection.find().toList(); + Document document = documentList.get(0); + NitriteId nitriteId = document.getId(); + + Document result = collection.find(byId(nitriteId)).firstOrNull(); + assertEquals(document, result); + + result = collection.find(and(byId(nitriteId), where("age").notEq(null))).firstOrNull(); + assertEquals(document, result); + + result = collection.find(or(byId(nitriteId), where("tag").eq(document.get("tag")))).firstOrNull(); + assertEquals(document, result); + } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java similarity index 66% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexNegativeTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java index f340795ec..5e9fff277 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexNegativeTest.java @@ -1,28 +1,29 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.exceptions.UniqueConstraintException; +import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.index.IndexOptions; -import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; +import static org.dizitart.no2.index.IndexType.FULL_TEXT; import static org.junit.Assert.assertTrue; /** @@ -32,30 +33,30 @@ public class CollectionIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { - collection.createIndex("lastName", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("lastName"); assertTrue(collection.hasIndex("lastName")); insert(); } @Test(expected = UniqueConstraintException.class) public void testCreateIndexOnArray() { - collection.createIndex("data", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("data"); assertTrue(collection.hasIndex("data")); // data array field has repetition, so unique constraint exception insert(); } - @Test + @Test(expected = UniqueConstraintException.class) public void testCreateOnInvalidField() { insert(); - collection.createIndex("my-value", IndexOptions.indexOptions(IndexType.Unique)); + collection.createIndex("my-value"); assertTrue(collection.hasIndex("my-value")); } @Test(expected = IndexingException.class) public void testCreateFullTextOnNonTextField() { insert(); - collection.createIndex("birthDay", IndexOptions.indexOptions(IndexType.Fulltext)); + collection.createIndex(IndexOptions.indexOptions(FULL_TEXT), "birthDay"); assertTrue(collection.hasIndex("birthDay")); } @@ -66,6 +67,16 @@ public void testDropIndexOnNonIndexedField() { @Test(expected = IndexingException.class) public void testRebuildIndexInvalid() { - collection.rebuildIndex("unknown", true); + collection.rebuildIndex("unknown"); + } + + @Test(expected = IndexingException.class) + public void testMultipleTextIndex() { + collection.createIndex(IndexOptions.indexOptions(FULL_TEXT), "body", "lastName"); + } + + @Test(expected = ValidationException.class) + public void testIndexOnNullField() { + collection.createIndex(IndexOptions.indexOptions(FULL_TEXT)); } } diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java similarity index 63% rename from nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java rename to nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java index b21c4445d..84fd453ac 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/rocksdb/collection/CollectionIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionIndexTest.java @@ -1,38 +1,35 @@ /* - * Copyright (c) 2017-2020. Nitrite author or authors. + * Copyright (c) 2017-2021 Nitrite author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ -package org.dizitart.no2.rocksdb.collection; +package org.dizitart.no2.integration.collection; -import com.google.common.collect.Lists; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; import org.dizitart.no2.collection.NitriteCollection; import org.dizitart.no2.common.WriteResult; -import org.dizitart.no2.exceptions.IndexingException; import org.dizitart.no2.filters.Filter; import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.index.IndexType; -import org.dizitart.no2.rocksdb.BaseCollectionTest; import org.junit.Test; +import java.util.ArrayList; import java.util.Collection; import java.util.Random; -import java.util.concurrent.Callable; -import static org.awaitility.Awaitility.await; import static org.dizitart.no2.collection.Document.createDocument; import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.index.IndexOptions.indexOptions; @@ -45,16 +42,16 @@ public class CollectionIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); - collection.createIndex("birthDay", null); + collection.createIndex("birthDay"); assertTrue(collection.hasIndex("birthDay")); insert(); @@ -64,13 +61,13 @@ public void testCreateIndex() { public void testListIndexes() { assertEquals(collection.listIndices().size(), 0); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); assertEquals(collection.listIndices().size(), 3); @@ -78,7 +75,7 @@ public void testListIndexes() { @Test public void testDropIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropIndex("firstName"); @@ -99,18 +96,18 @@ public void testDropAllIndexes() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex("lastName", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); assertFalse(collection.hasIndex("body")); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); } @Test public void testDeleteWithIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("body", indexOptions(IndexType.Fulltext)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); @@ -127,72 +124,31 @@ public void testDeleteWithIndex() { assertEquals(cursor.size(), 1); } - @Test - public void testCreateIndexAsync() { - insert(); - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); - assertTrue(collection.isIndexing("body")); - - await().until(bodyIndexingCompleted()); - } - @Test public void testRebuildIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - insert(); - Collection indices = collection.listIndices(); - for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), false); - } - } - - @Test - public void testRebuildIndexAsync() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, true)); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); - await().until(bodyIndexingCompleted()); - Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { - collection.rebuildIndex(idx.getIndexFields(), true); - await().until(bodyIndexingCompleted()); + collection.rebuildIndex(idx.getIndexFields().getFieldNames().toArray(new String[0])); } } - @Test - public void testRebuildIndexOnRunningIndex() { - collection.createIndex("body", indexOptions(IndexType.Fulltext, false)); - Collection indices = collection.listIndices(); - IndexDescriptor idx = indices.iterator().next(); - insert(); - collection.rebuildIndex(idx.getIndexFields(), true); - - boolean error = false; - try { - collection.rebuildIndex(idx.getIndexFields(), true); - } catch (IndexingException ie) { - error = true; - } finally { - assertTrue(error); - await().until(bodyIndexingCompleted()); - } - } - - private Callable bodyIndexingCompleted() { - return () -> !collection.isIndexing("body"); - } - @Test public void testNullValueInIndexedField() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); - collection.createIndex("birthDay", indexOptions(IndexType.NonUnique)); + collection.createIndex("firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); insert(); Document document = createDocument("firstName", null) .put("lastName", "ln1") .put("birthDay", null) .put("data", new byte[]{1, 2, 3}) - .put("list", Lists.newArrayList("one", "two", "three")) + .put("list", new ArrayList() {{ + add("one"); + add("two"); + add("three"); + }}) .put("body", "a quick brown fox jump over the lazy dog"); collection.insert(document); @@ -200,12 +156,12 @@ public void testNullValueInIndexedField() { @Test public void testDropAllAndCreateIndex() { - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection.dropAllIndices(); assertFalse(collection.hasIndex("firstName")); - collection.createIndex("firstName", indexOptions(IndexType.Unique)); + collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); collection = db.getCollection("test"); @@ -228,7 +184,7 @@ public void testIssue178() { DocumentCursor cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); - collection.createIndex("field", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); @@ -263,10 +219,10 @@ public void testIndexEvent() { System.out.println(eventInfo.getEventType() + " for field " + eventInfo.getItem()); }); - collection.createIndex("first", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); assertEquals(collection.find().size(), 10000); - collection.createIndex("second", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); assertEquals(collection.find().size(), 10000); } @@ -277,10 +233,10 @@ public void testIndexAndSearchOnNullValues() { collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); - collection.createIndex("first", indexOptions(IndexType.Unique)); + collection.createIndex("first"); assertEquals(collection.find(where("first").eq(null)).size(), 1); - collection.createIndex("third", indexOptions(IndexType.NonUnique)); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java index 3f7d1dfbc..b459e469b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexNegativeTest.java @@ -33,14 +33,14 @@ public class CollectionSingleFieldIndexNegativeTest extends BaseCollectionTest { @Test(expected = UniqueConstraintException.class) public void testCreateInvalidUniqueIndex() { - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "lastName"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); insert(); } @Test(expected = UniqueConstraintException.class) public void testCreateIndexOnArray() { - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "data"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "data"); assertTrue(collection.hasIndex("data")); // data array field has repetition, so unique constraint exception insert(); @@ -50,14 +50,14 @@ public void testCreateIndexOnArray() { public void testCreateOnInvalidField() { insert(); // multiple null value will be created - collection.createIndex(IndexOptions.indexOptions(IndexType.Unique), "my-value"); + collection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "my-value"); assertTrue(collection.hasIndex("my-value")); } @Test(expected = IndexingException.class) public void testCreateFullTextOnNonTextField() { insert(); - collection.createIndex(IndexOptions.indexOptions(IndexType.Fulltext), "birthDay"); + collection.createIndex(IndexOptions.indexOptions(IndexType.FULL_TEXT), "birthDay"); assertTrue(collection.hasIndex("birthDay")); } @@ -73,7 +73,7 @@ public void testRebuildIndexInvalid() { @Test(expected = IndexingException.class) public void createMultipleIndexTypeOnSameField() { - collection.createIndex(indexOptions(IndexType.Unique), "lastName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java index e840e2c27..fe37845e1 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/collection/CollectionSingleFieldIndexTest.java @@ -46,13 +46,13 @@ public class CollectionSingleFieldIndexTest extends BaseCollectionTest { @Test public void testCreateIndex() { - collection.createIndex(indexOptions(IndexType.Unique), "firstName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); collection.createIndex("birthDay"); @@ -68,10 +68,10 @@ public void testListIndexes() { collection.createIndex("firstName"); assertTrue(collection.hasIndex("firstName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); assertEquals(collection.listIndices().size(), 3); @@ -100,18 +100,18 @@ public void testDropAllIndexes() { @Test public void testHasIndex() { assertFalse(collection.hasIndex("lastName")); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); assertTrue(collection.hasIndex("lastName")); assertFalse(collection.hasIndex("body")); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); assertTrue(collection.hasIndex("body")); } @Test public void testDeleteWithIndex() { - collection.createIndex(indexOptions(IndexType.Unique), "firstName"); - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); @@ -130,7 +130,7 @@ public void testDeleteWithIndex() { @Test public void testRebuildIndex() { - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); Collection indices = collection.listIndices(); for (IndexDescriptor idx : indices) { @@ -140,7 +140,7 @@ public void testRebuildIndex() { @Test public void testRebuildIndexOnRunningIndex() { - collection.createIndex(indexOptions(IndexType.Fulltext), "body"); + collection.createIndex(indexOptions(IndexType.FULL_TEXT), "body"); insert(); collection.rebuildIndex("body"); @@ -161,8 +161,8 @@ private Callable bodyIndexingCompleted() { @Test public void testNullValueInIndexedField() { - collection.createIndex(indexOptions(IndexType.Unique), "firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "birthDay"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "birthDay"); insert(); Document document = createDocument("firstName", null) @@ -209,7 +209,7 @@ public void testIssue178() { DocumentCursor cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); - collection.createIndex(indexOptions(IndexType.NonUnique), "field"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "field"); cursor = collection.find(where("field").eq(5)); assertEquals(cursor.size(), 1); @@ -241,10 +241,10 @@ public void testIndexEvent() { } }); - collection.createIndex(indexOptions(IndexType.NonUnique), "first"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "first"); assertEquals(collection.find().size(), 10000); - collection.createIndex(indexOptions(IndexType.NonUnique), "second"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "second"); assertEquals(collection.find().size(), 10000); await().until(completed::get); @@ -258,17 +258,17 @@ public void testIndexAndSearchOnNullValues() { collection.insert(createDocument("first", "abcd").put("second", 456).put("third", new int[]{3, 1})); collection.insert(createDocument("first", "xyz").put("second", 789).put("third", null)); - collection.createIndex(indexOptions(IndexType.Unique), "first"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "first"); assertEquals(collection.find(where("first").eq(null)).size(), 1); - collection.createIndex(indexOptions(IndexType.NonUnique), "third"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "third"); assertEquals(collection.find(where("third").eq(null)).size(), 2); } @Test public void testCreateCompoundAndSingleFieldIndexOnSameField() { - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); - collection.createIndex(indexOptions(IndexType.Unique), "firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName", "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); + collection.createIndex(indexOptions(IndexType.UNIQUE), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName", "firstName"); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java index 42f6f2983..fe768e51a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/CustomFieldSeparatorTest.java @@ -107,9 +107,9 @@ public void testFindByEmbeddedField() { @ToString @EqualsAndHashCode @Indices({ - @Index(value = "joinDate", type = IndexType.NonUnique), - @Index(value = "address", type = IndexType.Fulltext), - @Index(value = "employeeNote:text", type = IndexType.Fulltext) + @Index(value = "joinDate", type = IndexType.NON_UNIQUE), + @Index(value = "address", type = IndexType.FULL_TEXT), + @Index(value = "employeeNote:text", type = IndexType.FULL_TEXT) }) public static class EmployeeForCustomSeparator implements Serializable, Mappable { @Id diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java index 94ec5cb3a..b49f11fbd 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/ObjectRepositoryTest.java @@ -349,8 +349,8 @@ public void testIssue217() { @Data @Entity(value = "entity.employee", indices = { - @Index(value = "firstName", type = IndexType.NonUnique), - @Index(value = "lastName", type = IndexType.NonUnique), + @Index(value = "firstName", type = IndexType.NON_UNIQUE), + @Index(value = "lastName", type = IndexType.NON_UNIQUE), }) private static class EmployeeEntity implements Mappable { private static final Faker faker = new Faker(); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java index 1ad119dfe..90559fea1 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositoryModificationTest.java @@ -53,14 +53,14 @@ public void testCreateIndex() { assertTrue(companyRepository.hasIndex("companyName")); assertFalse(companyRepository.hasIndex("dateCreated")); - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertTrue(companyRepository.hasIndex("dateCreated")); assertFalse(companyRepository.isIndexing("dateCreated")); } @Test public void testRebuildIndex() { - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); assertFalse(companyRepository.isIndexing("dateCreated")); companyRepository.rebuildIndex("dateCreated"); @@ -75,7 +75,7 @@ public void testListIndexes() { Collection indices = companyRepository.listIndices(); assertEquals(indices.size(), 2); - companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NonUnique), "dateCreated"); + companyRepository.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateCreated"); indices = companyRepository.listIndices(); assertEquals(indices.size(), 3); } diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java index 7de9d5691..29524a7cf 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/RepositorySearchTest.java @@ -494,6 +494,21 @@ public void testEqualsOnTextIndex() { List sameNamePeople = repository.find(where("name").eq("jhonny")).toList(); assertEquals(sameNamePeople.size(), 3); + + sameNamePeople = repository.find(where("name").eq("JHONNY")).toList(); + assertEquals(sameNamePeople.size(), 0); + + sameNamePeople = repository.find(where("name").text("jhonny")).toList(); + assertEquals(sameNamePeople.size(), 3); + + sameNamePeople = repository.find(where("name").text("JHONNY")).toList(); + assertEquals(sameNamePeople.size(), 3); + + sameNamePeople = repository.find(where("name").eq("jhon*")).toList(); + assertEquals(sameNamePeople.size(), 0); + + sameNamePeople = repository.find(where("name").text("jhon*")).toList(); + assertEquals(sameNamePeople.size(), 3); } @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java index 6fc86b22c..8d19eac2a 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/UniversalTextTokenizerTest.java @@ -157,7 +157,7 @@ public void testUniversalFullTextIndexing() { } @Indices( - @Index(value = "text", type = IndexType.Fulltext) + @Index(value = "text", type = IndexType.FULL_TEXT) ) public static class TextData implements Mappable { public int id; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java index 3100f9d64..5a147769c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Book.java @@ -35,8 +35,8 @@ */ @Data @Entity(value = "books", indices = { - @Index(value = "tags", type = IndexType.NonUnique), - @Index(value = "description", type = IndexType.Fulltext), + @Index(value = "tags", type = IndexType.NON_UNIQUE), + @Index(value = "description", type = IndexType.FULL_TEXT), @Index(value = { "price", "publisher" }) }) public class Book implements Mappable { diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java index 3f4e231f3..7204f5654 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/Employee.java @@ -36,9 +36,9 @@ */ @ToString @EqualsAndHashCode -@Index(value = "joinDate", type = IndexType.NonUnique) -@Index(value = "address", type = IndexType.Fulltext) -@Index(value = "employeeNote.text", type = IndexType.Fulltext) +@Index(value = "joinDate", type = IndexType.NON_UNIQUE) +@Index(value = "address", type = IndexType.FULL_TEXT) +@Index(value = "employeeNote.text", type = IndexType.FULL_TEXT) public class Employee implements Serializable, Mappable { @Id @Getter diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java index 63626c769..2b90075fa 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/PersonEntity.java @@ -34,8 +34,8 @@ */ @Data @Entity(value = "MyPerson", indices = { - @Index(value = "name", type = IndexType.Fulltext), - @Index(value = "status", type = IndexType.NonUnique) + @Index(value = "name", type = IndexType.FULL_TEXT), + @Index(value = "status", type = IndexType.NON_UNIQUE) }) public class PersonEntity implements Mappable { @Id diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java index 5c3eae9bd..1ecadb243 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/RepeatableIndexTest.java @@ -29,8 +29,8 @@ */ @Data @Index(value = "firstName") -@Index(value = "age", type = IndexType.NonUnique) -@Index(value = "lastName", type = IndexType.Fulltext) +@Index(value = "age", type = IndexType.NON_UNIQUE) +@Index(value = "lastName", type = IndexType.FULL_TEXT) public class RepeatableIndexTest implements Mappable { private String firstName; private Integer age; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java index c4e803b8d..198f16d0c 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/repository/data/SuperDuperClass.java @@ -30,7 +30,7 @@ */ @Getter @Setter -@Index(value = "text", type = IndexType.Fulltext) +@Index(value = "text", type = IndexType.FULL_TEXT) public class SuperDuperClass implements Mappable { private String text; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java index 7585a4542..05a2b095b 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionCollectionTest.java @@ -215,7 +215,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { NitriteCollection txCol = transaction.getCollection("test"); - txCol.createIndex(indexOptions(IndexType.Fulltext), "firstName"); + txCol.createIndex(indexOptions(IndexType.FULL_TEXT), "firstName"); assertTrue(txCol.hasIndex("firstName")); assertFalse(collection.hasIndex("firstName")); @@ -335,7 +335,7 @@ public void testRollbackDropIndex() { Document document2 = createDocument("firstName", "Jane").put("lastName", "Doe"); collection.insert(document); collection.createIndex("firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -391,7 +391,7 @@ public void testRollbackDropAllIndices() { Document document = createDocument("firstName", "John").put("lastName", "Doe"); collection.insert(document); collection.createIndex("firstName"); - collection.createIndex(indexOptions(IndexType.NonUnique), "lastName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "lastName"); try (Session session = db.createSession()) { Transaction transaction = null; @@ -543,7 +543,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { NitriteCollection collection = db.getCollection("test"); - collection.createIndex(indexOptions(IndexType.NonUnique), "firstName"); + collection.createIndex(indexOptions(IndexType.NON_UNIQUE), "firstName"); collection.createIndex("id"); Faker faker = new Faker(); List> futures = new ArrayList<>(); diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java index c23d64d99..4e506726d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/transaction/TransactionRepositoryTest.java @@ -237,7 +237,7 @@ public void testCommitCreateIndex() { try (Session session = db.createSession()) { try (Transaction transaction = session.beginTransaction()) { ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -262,7 +262,7 @@ public void testRollbackCreateIndex() { try { transaction = session.beginTransaction(); ObjectRepository txRepo = transaction.getRepository(TxData.class); - txRepo.createIndex(indexOptions(IndexType.Fulltext), "name"); + txRepo.createIndex(indexOptions(IndexType.FULL_TEXT), "name"); assertTrue(txRepo.hasIndex("name")); assertFalse(repository.hasIndex("name")); @@ -570,7 +570,7 @@ public void testRollbackSetAttribute() { @Test public void testConcurrentInsertAndRemove() { ObjectRepository repository = db.getRepository(TxData.class); - repository.createIndex(indexOptions(IndexType.NonUnique), "name"); + repository.createIndex(indexOptions(IndexType.NON_UNIQUE), "name"); Faker faker = new Faker(); List> futures = new ArrayList<>(); diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Documents.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Documents.kt index dfa626f0b..973446270 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Documents.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Documents.kt @@ -48,8 +48,18 @@ fun documentOf(pair: Pair): Document { return createDocument(pair.first, pair.second)!! } +/** + * Checks if a [Document] is empty. + * + * @return boolean value + */ fun Document.isEmpty() = this.size() == 0 +/** + * Checks if a [Document] is not empty. + * + * @return boolean value + */ fun Document.isNotEmpty() = !this.isEmpty() /** diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Nitrite.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Nitrite.kt index f15471c53..bc5759722 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Nitrite.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/Nitrite.kt @@ -52,7 +52,9 @@ fun Nitrite.getCollection(name: String, op: (NitriteCollection.() -> Unit)? = nu * @param [op] repository builder block * @return the object repository of type [T] */ -inline fun Nitrite.getRepository(noinline op: (ObjectRepository.() -> Unit)? = null): ObjectRepository { +inline fun Nitrite.getRepository( + noinline op: (ObjectRepository.() -> Unit)? = null +): ObjectRepository { val repository = this.getRepository(T::class.java) op?.invoke(repository) return repository @@ -68,17 +70,19 @@ inline fun Nitrite.getRepository(noinline op: (ObjectRepositor * @param [op] repository builder block * @return the object repository of type [T] */ -inline fun Nitrite.getRepository(key: String, noinline op: (ObjectRepository.() -> Unit)? = null): ObjectRepository { +inline fun Nitrite.getRepository( + key: String, + noinline op: (ObjectRepository.() -> Unit)? = null +): ObjectRepository { val repository = this.getRepository(T::class.java, key) op?.invoke(repository) return repository } /** - * Creates an [IndexOptions] with the specified [indexType] and [async] flag. + * Creates an [IndexOptions] with the specified [indexType]. * * @param [indexType] the type of index to be created. - * @param [async] if set to [true] then the index would be created asynchronously; otherwise synchronously. * @return a new [IndexOptions] */ -fun option(indexType: String = IndexType.Unique, async: Boolean = false): IndexOptions = IndexOptions.indexOptions(indexType, async) \ No newline at end of file +fun option(indexType: String = IndexType.UNIQUE): IndexOptions = IndexOptions.indexOptions(indexType) \ No newline at end of file diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/filters/Filters.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/filters/Filters.kt index c15d8d534..6583a008c 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/filters/Filters.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/filters/Filters.kt @@ -17,6 +17,8 @@ package org.dizitart.kno2.filters import org.dizitart.no2.filters.Filter +import org.dizitart.no2.filters.Filter.and +import org.dizitart.no2.filters.Filter.or import org.dizitart.no2.filters.FluentFilter import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry @@ -38,65 +40,73 @@ inline infix fun String.eq(value: T?): Filter = FluentFilter.where(t * Creates an not equality filter which does not matches documents where the value * of a field equals the specified [value]. */ -inline infix fun String.notEq(value: T?): Filter = FluentFilter.where(this).notEq(value) +inline infix fun String.notEq(value: T?): Filter = + FluentFilter.where(this).notEq(value) /** * Creates a greater than filter which matches those documents where the value * of the value is greater than (i.e. >) the specified [value]. */ -inline infix fun > String.gt(value: T?): Filter = FluentFilter.where(this).gt(value) +inline infix fun > String.gt(value: T?): Filter = + FluentFilter.where(this).gt(value) /** * Creates a greater equal filter which matches those documents where the value * of the value is greater than or equals to (i.e. >=) the specified [value]. */ -inline infix fun > String.gte(value: T?): Filter = FluentFilter.where(this).gte(value) +inline infix fun > String.gte(value: T?): Filter = + FluentFilter.where(this).gte(value) /** * Creates a lesser than filter which matches those documents where the value * of the value is less than (i.e. <) the specified [value]. */ -inline infix fun > String.lt(value: T?): Filter = FluentFilter.where(this).lt(value) +inline infix fun > String.lt(value: T?): Filter = + FluentFilter.where(this).lt(value) /** * Creates a lesser equal filter which matches those documents where the value * of the value is lesser than or equals to (i.e. <=) the specified [value]. */ -inline infix fun > String.lte(value: T?): Filter = FluentFilter.where(this).lte(value) +inline infix fun > String.lte(value: T?): Filter = + FluentFilter.where(this).lte(value) /** * Creates a between filter which matches those documents where the value * of the field is within the specified bound including the end values. */ -inline fun > String.between(lowerBound: T, upperBound: T): Filter - = FluentFilter.where(this).between(lowerBound, upperBound) +inline fun > String.between(lowerBound: T, upperBound: T): Filter = + FluentFilter.where(this).between(lowerBound, upperBound) /** * Creates a between filter which matches those documents where the value * of the field is within the specified bound. * */ -inline fun > String.between(lowerBound: T, upperBound: T, inclusive: Boolean): Filter - = FluentFilter.where(this).between(lowerBound, upperBound, inclusive) +inline fun > String.between(lowerBound: T, upperBound: T, inclusive: Boolean): Filter = + FluentFilter.where(this).between(lowerBound, upperBound, inclusive) /** * Creates a between filter which matches those documents where the value * of the field is within the specified bound. * */ -inline fun > String.between(lowerBound: T, upperBound: T, lowerInclusive: Boolean, - upperInclusive: Boolean): Filter - = FluentFilter.where(this).between(lowerBound, upperBound, lowerInclusive, upperInclusive) +inline fun > String.between( + lowerBound: T, upperBound: T, lowerInclusive: Boolean, + upperInclusive: Boolean +): Filter = FluentFilter.where(this).between(lowerBound, upperBound, lowerInclusive, upperInclusive) /** * Creates an in filter which matches the documents where * the value of a field equals any value in the specified array of [values]. */ -inline infix fun > String.within(values: Array): Filter = FluentFilter.where(this).`in`(*values) +inline infix fun > String.within(values: Array): Filter = + FluentFilter.where(this).`in`(*values) /** * Creates an in filter which matches the documents where * the value of a field equals any value in the specified array of [values]. */ -inline infix fun > String.within(values: Iterable): Filter = FluentFilter.where(this).`in`(*(values.toList().toTypedArray())) +inline infix fun > String.within(values: Iterable): Filter = + FluentFilter.where(this).`in`(*(values.toList().toTypedArray())) /** * Creates an element match filter that matches documents that contain an array @@ -116,79 +126,108 @@ infix fun String.text(value: String?): Filter = FluentFilter.where(this).text(va */ infix fun String.regex(value: String?): Filter = FluentFilter.where(this).regex(value) -inline infix fun String.within(value: T?): Filter = org.dizitart.no2.spatial.FluentFilter.where(this).within(value) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is within the specified Geometry value. + */ +inline infix fun String.within(value: T?): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this).within(value) -inline infix fun String.intersects(value: T?): Filter = org.dizitart.no2.spatial.FluentFilter.where(this).intersects(value) +/** + * Creates an spatial filter which matches documents where the spatial data + * of a field intersects the specified Geometry value. + */ +inline infix fun String.intersects(value: T?): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this).intersects(value) -inline fun String.near(value: T?, distance: Double): Filter = org.dizitart.no2.spatial.FluentFilter.where(this).near(value, distance) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified coordinate. + */ +inline fun String.near(value: T?, distance: Double): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this).near(value, distance) -inline fun String.near(value: T?, distance: Double): Filter = org.dizitart.no2.spatial.FluentFilter.where(this).near(value, distance) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified point. + */ +inline fun String.near(value: T?, distance: Double): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this).near(value, distance) /** * Creates an and filter which performs a logical AND operation on two filters and selects * the documents that satisfy both filters. */ -inline infix fun Filter.and(filter: T): Filter = this.and(filter) +inline infix fun Filter.and(filter: T): Filter = and(this, filter) /** * Creates an or filter which performs a logical OR operation on two filters and selects * the documents that satisfy at least one of the filter. */ -inline infix fun Filter.or(filter: T): Filter = this.or(filter) +inline infix fun Filter.or(filter: T): Filter = or(this, filter) /** * Creates an equality filter which matches objects where the value * of a property equals the specified [value]. */ -inline infix fun KProperty.eq(value: T?): Filter = FluentFilter.where(this.name).eq(value) +inline infix fun KProperty.eq(value: T?): Filter = + FluentFilter.where(this.name).eq(value) /** * Creates an not equality filter which does not matches objects where the value * of a property equals the specified [value]. */ -inline infix fun KProperty.notEq(value: T?): Filter = FluentFilter.where(this.name).notEq(value) +inline infix fun KProperty.notEq(value: T?): Filter = + FluentFilter.where(this.name).notEq(value) /** * Creates a greater than filter which matches those objects where the value * of the property is greater than (i.e. >) the specified [value]. */ -inline infix fun > KProperty.gt(value: T?): Filter = FluentFilter.where(this.name).gt(value) +inline infix fun > KProperty.gt(value: T?): Filter = + FluentFilter.where(this.name).gt(value) /** * Creates a greater equal filter which matches those objects where the value * of the property is greater than or equals to (i.e. >=) the specified [value]. */ -inline infix fun > KProperty.gte(value: T?): Filter = FluentFilter.where(this.name).gte(value) +inline infix fun > KProperty.gte(value: T?): Filter = + FluentFilter.where(this.name).gte(value) /** * Creates a lesser than filter which matches those objects where the value * of the property is less than (i.e. <) the specified [value]. */ -inline infix fun > KProperty.lt(value: T?): Filter = FluentFilter.where(this.name).lt(value) +inline infix fun > KProperty.lt(value: T?): Filter = + FluentFilter.where(this.name).lt(value) /** * Creates a lesser equal filter which matches those objects where the value * of the property is lesser than or equals to (i.e. <=) the specified [value]. */ -inline infix fun > KProperty.lte(value: T?): Filter = FluentFilter.where(this.name).lte(value) +inline infix fun > KProperty.lte(value: T?): Filter = + FluentFilter.where(this.name).lte(value) /** * Creates an in filter which matches the objects where * the value of a property equals any value in the specified array of [values]. */ -inline infix fun > KProperty.within(values: Array): Filter = FluentFilter.where(this.name).`in`(*values) +inline infix fun > KProperty.within(values: Array): Filter = + FluentFilter.where(this.name).`in`(*values) /** * Creates an in filter which matches the objects where * the value of a property equals any value in the specified list of [values]. */ -inline infix fun > KProperty.within(values: Iterable): Filter = FluentFilter.where(this.name).`in`(*(values.toList().toTypedArray())) +inline infix fun > KProperty.within(values: Iterable): Filter = + FluentFilter.where(this.name).`in`(*(values.toList().toTypedArray())) /** * Creates an element match filter that matches objects that contain an array * value with at least one element that matches the specified [filter]. */ -inline infix fun KProperty?>.elemMatch(filter: Filter): Filter = FluentFilter.where(this.name).elemMatch(filter) +inline infix fun KProperty?>.elemMatch(filter: Filter): Filter = + FluentFilter.where(this.name).elemMatch(filter) /** * Creates a text filter which performs a text search on the content of the property @@ -202,10 +241,30 @@ infix fun KProperty.text(value: String?): Filter = FluentFilter.where(t */ infix fun KProperty.regex(value: String?): Filter = FluentFilter.where(this.name).regex(value) -inline infix fun KProperty.within(value: T?): Filter = org.dizitart.no2.spatial.FluentFilter.where(this.name).within(value) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is within the specified Geometry value. + */ +inline infix fun KProperty.within(value: T?): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this.name).within(value) -inline infix fun KProperty.intersects(value: T?): Filter = org.dizitart.no2.spatial.FluentFilter.where(this.name).intersects(value) +/** + * Creates an spatial filter which matches documents where the spatial data + * of a field intersects the specified Geometry value. + */ +inline infix fun KProperty.intersects(value: T?): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this.name).intersects(value) -inline fun KProperty.near(value: Point, distance: Double): Filter = org.dizitart.no2.spatial.FluentFilter.where(this.name).near(value, distance) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified coordinate. + */ +inline fun KProperty.near(value: Point, distance: Double): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this.name).near(value, distance) -inline fun KProperty.near(value: Coordinate, distance: Double): Filter = org.dizitart.no2.spatial.FluentFilter.where(this.name).near(value, distance) +/** + * Creates a spatial filter which matches documents where the spatial data + * of a field is near the specified point. + */ +inline fun KProperty.near(value: Coordinate, distance: Double): Filter = + org.dizitart.no2.spatial.FluentFilter.where(this.name).near(value, distance) diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/package.md b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/package.md deleted file mode 100644 index 14e1d7991..000000000 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/package.md +++ /dev/null @@ -1,3 +0,0 @@ -# Package org.dizitart.kno2 - -Contains useful extensions for nitrite database. \ No newline at end of file diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt index 8a0e5736c..ef8aef206 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt @@ -39,7 +39,7 @@ import java.util.* class BackportJavaTimeTest { private val dbPath = getRandomTempDbFile() - @Index(value = "time", type = IndexType.NonUnique) + @Index(value = ["time"], type = IndexType.NON_UNIQUE) data class TestData( @Id val id: String = UUID.randomUUID().toString(), val time: LocalDateTime diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/FilterTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/FilterTest.kt index 34ccf7f77..3286e8f67 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/FilterTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/FilterTest.kt @@ -21,6 +21,7 @@ import org.dizitart.kno2.filters.* import org.dizitart.no2.collection.Document import org.dizitart.no2.common.Constants import org.dizitart.no2.index.IndexOptions +import org.dizitart.no2.index.IndexOptions.indexOptions import org.dizitart.no2.index.IndexType import org.dizitart.no2.mvstore.MVStoreModule import org.dizitart.no2.spatial.SpatialIndexer @@ -155,7 +156,7 @@ class FilterTest : BaseTest() { @Test fun testText() { db?.getCollection("test") { - createIndex("a", option(IndexType.Fulltext)) + createIndex(option(IndexType.FULL_TEXT), "a") insert(documentOf("a" to "Lorem ipsum dolor"), documentOf("a" to "quick brown fox jumps over lazy dog")) @@ -171,7 +172,7 @@ class FilterTest : BaseTest() { @Test fun testRegex() { db?.getCollection("test") { - createIndex("a", option(IndexType.Fulltext)) + createIndex(option(IndexType.FULL_TEXT), "a") insert(documentOf("a" to "lorem"), documentOf("a" to "dog")) @@ -252,7 +253,7 @@ class FilterTest : BaseTest() { val doc3 = documentOf("key" to 3L).put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")) insert(doc1, doc2, doc3) - createIndex("location", IndexOptions.indexOptions(SpatialIndexer.SpatialIndex)) + createIndex(indexOptions(SpatialIndexer.SPATIAL_INDEX), "location") val cursor1 = find("location" intersects search) assertEquals(cursor1.size(), 2) @@ -271,7 +272,7 @@ class FilterTest : BaseTest() { val doc3 = documentOf("key" to 3L).put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")) insert(doc1, doc2, doc3) - createIndex("location", IndexOptions.indexOptions(SpatialIndexer.SpatialIndex)) + createIndex(indexOptions(SpatialIndexer.SPATIAL_INDEX), "location") val cursor1 = find("location" within search) assertEquals(cursor1.size(), 1) @@ -290,7 +291,7 @@ class FilterTest : BaseTest() { val doc3 = documentOf("key" to 3L).put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")) insert(doc1, doc2, doc3) - createIndex("location", IndexOptions.indexOptions(SpatialIndexer.SpatialIndex)) + createIndex(indexOptions(SpatialIndexer.SPATIAL_INDEX), "location") val cursor1 = find("location".near(search, 20.0)) assertEquals(cursor1.size(), 1) @@ -310,7 +311,7 @@ class FilterTest : BaseTest() { val doc3 = documentOf("key" to 3L).put("location", reader.read("POLYGON ((550 521, 580 540, 570 564, 512 566, 550 521))")) insert(doc1, doc2, doc3) - createIndex("location", IndexOptions.indexOptions(SpatialIndexer.SpatialIndex)) + createIndex(indexOptions(SpatialIndexer.SPATIAL_INDEX), "location") val cursor1 = find("location".near(coordinate, 20.0)) assertEquals(cursor1.size(), 1) diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt index 19e41eb1b..de873a1b9 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/NitriteTest.kt @@ -17,9 +17,13 @@ package org.dizitart.kno2 import org.dizitart.kno2.filters.text +import org.dizitart.no2.collection.FindOptions +import org.dizitart.no2.collection.FindOptions.orderBy +import org.dizitart.no2.collection.FindOptions.skipBy import org.dizitart.no2.common.SortOrder import org.dizitart.no2.exceptions.UniqueConstraintException import org.dizitart.no2.index.IndexOptions +import org.dizitart.no2.index.IndexOptions.indexOptions import org.dizitart.no2.index.IndexType import org.dizitart.no2.mvstore.MVStoreModule import org.dizitart.no2.repository.annotations.Id @@ -76,7 +80,7 @@ class NitriteTest : BaseTest() { @Test fun testIndexOption() { db?.getCollection("test") { - createIndex("id", option(IndexType.Unique, true)) + createIndex(option(IndexType.UNIQUE), "id") assertTrue(hasIndex("id")) assertFalse(hasIndex("name")) } @@ -90,14 +94,14 @@ class NitriteTest : BaseTest() { documentOf("a" to 3), documentOf("a" to 4), documentOf("a" to 5)) - var cursor = find().skipLimit(0, 2) + var cursor = find(skipBy(0).limit(2)) assertEquals(cursor.size(), 2) - cursor = find().sort("a", SortOrder.Descending, NullOrder.First) + cursor = find(orderBy("a", SortOrder.Descending)) assertEquals(cursor.size(), 5) assertEquals(cursor.last()["a"], 1) - cursor = find().sort("a", SortOrder.Descending).skipLimit(0, 2) + cursor = find(orderBy("a", SortOrder.Descending).skip(0).limit(2)) assertEquals(cursor.size(), 2) assertEquals(cursor.last()["a"], 4) } @@ -168,7 +172,7 @@ class NitriteTest : BaseTest() { val repository = db?.getRepository()!! repository.insert(first) - repository.createIndex("ob1", IndexOptions.indexOptions(IndexType.Fulltext)); + repository.createIndex(indexOptions(IndexType.FULL_TEXT), "ob1"); var found = repository.find("ob1" text "value1") assertFalse(found.isEmpty) @@ -187,7 +191,7 @@ interface MyInterface { val id: UUID } -@Indices(value = [(Index(value = "name", type = IndexType.NonUnique))]) +@Indices(value = [(Index(value = ["name"], type = IndexType.NON_UNIQUE))]) abstract class SomeAbsClass( @Id override val id: UUID = UUID.randomUUID(), open val name: String = "abcd" @@ -214,7 +218,7 @@ data class CaObject( val name: String ) -@Indices(value = [(Index(value = "time", type = IndexType.Unique))]) +@Indices(value = [(Index(value = ["time"], type = IndexType.UNIQUE))]) data class ClassWithLocalDateTime( val name: String, val time: LocalDateTime diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/ObjectFilterTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/ObjectFilterTest.kt index 4409e4cac..0aa0b6990 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/ObjectFilterTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/ObjectFilterTest.kt @@ -321,7 +321,7 @@ class ObjectFilterTest : BaseTest() { } } -@Indices(Index(value = "text", type = IndexType.Fulltext)) +@Indices(Index(value = ["text"], type = IndexType.FULL_TEXT)) data class TestData(@Id val id: Int, val text: String, val list: List = listOf()) class ListData(val name: String, val score: Int) @@ -331,7 +331,7 @@ data class SimpleObject( val value: Boolean ) -@Index(value = "geometry", type = SpatialIndexer.SpatialIndex) +@Index(value = ["geometry"], type = SpatialIndexer.SPATIAL_INDEX) data class SpatialData( @Id val id: Long, val geometry: Geometry diff --git a/settings.gradle b/settings.gradle index ef83432f1..b988faedf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,6 +25,5 @@ include 'nitrite-replication' include 'nitrite-support' include 'potassium-nitrite' include 'nitrite-rocksdb-adapter' -include 'nitrite-mapdb-adapter' include 'nitrite-bom'

    The padding '=' characters at the end are considered optional, but + * if any are present, there must be the correct number of them. + * + * @param input the data to decode + * @param offset the position within the input array at which to start + * @param len the number of bytes of input to decode + * @param flags controls certain features of the decoded output. + * Pass {@code DEFAULT} to decode standard Base64. + * + * @throws IllegalArgumentException if the input contains + * incorrect padding + */ + public static byte[] decode(byte[] input, int offset, int len, int flags) { + // Allocate space for the most data the input could represent. + // (It could contain less if it contains whitespace, etc.) + Decoder decoder = new Decoder(flags, new byte[len*3/4]); + if (!decoder.process(input, offset, len)) { + throw new IllegalArgumentException("bad base-64"); + } + // Maybe we got lucky and allocated exactly enough output space. + if (decoder.op == decoder.output.length) { + return decoder.output; + } + // Need to shorten the array, so allocate a new one of the + // right size and copy. + byte[] temp = new byte[decoder.op]; + System.arraycopy(decoder.output, 0, temp, 0, decoder.op); + return temp; + } + /* package */ static class Decoder extends Coder { + /** + * Lookup table for turning bytes into their position in the + * Base64 alphabet. + */ + private static final int[] DECODE = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + /** + * Decode lookup table for the "web safe" variant (RFC 3548 + * sec. 4) where - and _ replace + and /. + */ + private static final int[] DECODE_WEBSAFE = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + /** Non-data values in the DECODE arrays. */ + private static final int SKIP = -1; + private static final int EQUALS = -2; + /** + * States 0-3 are reading through the next input tuple. + * State 4 is having read one '=' and expecting exactly + * one more. + * State 5 is expecting no more data or padding characters + * in the input. + * State 6 is the error state; an error has been detected + * in the input and no future input can "fix" it. + */ + private int state; // state number (0 to 6) + private final int value; + final private int[] alphabet; + public Decoder(int flags, byte[] output) { + this.output = output; + alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE; + state = 0; + value = 0; + } + + /** + * Decode another block of input data. + * + * @return true if the state machine is still healthy. false if + * bad base-64 data has been detected in the input stream. + */ + private boolean process(byte[] input, int offset, int len) { + if (this.state == 6) return false; + int p = offset; + len += offset; + // Using local variables makes the decoder about 12% + // faster than if we manipulate the member variables in + // the loop. (Even alphabet makes a measurable + // difference, which is somewhat surprising to me since + // the member variable is final.) + int state = this.state; + int value = this.value; + int op = 0; + final byte[] output = this.output; + final int[] alphabet = this.alphabet; + while (p < len) { + // Try the fast path: we're starting a new tuple and the + // next four bytes of the input stream are all data + // bytes. This corresponds to going through states + // 0-1-2-3-0. We expect to use this method for most of + // the data. + // + // If any of the next four bytes of input are non-data + // (whitespace, etc.), value will end up negative. (All + // the non-data values in decode are small negative + // numbers, so shifting any of them up and or'ing them + // together will result in a value with its top bit set.) + // + // You can remove this whole block and the output should + // be the same, just slower. + if (state == 0) { + while (p+4 <= len && + (value = ((alphabet[input[p] & 0xff] << 18) | + (alphabet[input[p+1] & 0xff] << 12) | + (alphabet[input[p+2] & 0xff] << 6) | + (alphabet[input[p+3] & 0xff]))) >= 0) { + output[op+2] = (byte) value; + output[op+1] = (byte) (value >> 8); + output[op] = (byte) (value >> 16); + op += 3; + p += 4; + } + if (p >= len) break; + } + // The fast path isn't available -- either we've read a + // partial tuple, or the next four input bytes aren't all + // data, or whatever. Fall back to the slower state + // machine implementation. + int d = alphabet[input[p++] & 0xff]; + switch (state) { + case 0: + if (d >= 0) { + value = d; + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + case 1: + if (d >= 0) { + value = (value << 6) | d; + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + case 2: + if (d >= 0) { + value = (value << 6) | d; + ++state; + } else if (d == EQUALS) { + // Emit the last (partial) output tuple; + // expect exactly one more padding character. + output[op++] = (byte) (value >> 4); + state = 4; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + case 3: + if (d >= 0) { + // Emit the output triple and return to state 0. + value = (value << 6) | d; + output[op+2] = (byte) value; + output[op+1] = (byte) (value >> 8); + output[op] = (byte) (value >> 16); + op += 3; + state = 0; + } else if (d == EQUALS) { + // Emit the last (partial) output tuple; + // expect no further data or padding characters. + output[op+1] = (byte) (value >> 2); + output[op] = (byte) (value >> 10); + op += 2; + state = 5; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + case 4: + if (d == EQUALS) { + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + case 5: + if (d != SKIP) { + this.state = 6; + return false; + } + break; + } + } + // Done reading input. Now figure out where we are left in + // the state machine and finish up. + switch (state) { + case 0: + // Output length is a multiple of three. Fine. + break; + case 1: + case 4: + // Read one padding '=' when we expected 2. Illegal. + // Read one extra input byte, which isn't enough to + // make another output byte. Illegal. + this.state = 6; + return false; + case 2: + // Read two extra input bytes, enough to emit 1 more + // output byte. Fine. + output[op++] = (byte) (value >> 4); + break; + case 3: + // Read three extra input bytes, enough to emit 2 more + // output bytes. Fine. + output[op++] = (byte) (value >> 10); + output[op++] = (byte) (value >> 2); + break; + case 5: + // Read all the padding '='s we expected and no more. + // Fine. + break; + } + this.state = state; + this.op = op; + return true; + } + } + // -------------------------------------------------------- + // encoding + // -------------------------------------------------------- + /** + * Base64-encode the given data and return a newly allocated + * String with the result. + * + * @param input the data to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static String encodeToString(byte[] input, int flags) { + return new String(encode(input, flags), StandardCharsets.US_ASCII); + } + + /** + * Base64-encode the given data and return a newly allocated + * byte[] with the result. + * + * @param input the data to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static byte[] encode(byte[] input, int flags) { + return encode(input, 0, input.length, flags); + } + /** + * Base64-encode the given data and return a newly allocated + * byte[] with the result. + * + * @param input the data to encode + * @param offset the position within the input array at which to + * start + * @param len the number of bytes of input to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static byte[] encode(byte[] input, int offset, int len, int flags) { + Encoder encoder = new Encoder(flags, null); + // Compute the exact length of the array we will produce. + int output_len = len / 3 * 4; + // Account for the tail of the data and the padding bytes, if any. + if (encoder.do_padding) { + if (len % 3 > 0) { + output_len += 4; + } + } else { + switch (len % 3) { + case 0: break; + case 1: output_len += 2; break; + case 2: output_len += 3; break; + } + } + // Account for the newlines, if any. + if (encoder.do_newline && len > 0) { + output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) * + (encoder.do_cr ? 2 : 1); + } + encoder.output = new byte[output_len]; + encoder.process(input, offset, len); + assert encoder.op == output_len; + return encoder.output; + } + + static class Encoder extends Coder { + /** + * Emit a new line every this many output tuples. Corresponds to + * a 76-character line length (the maximum allowable according to + * RFC 2045). + */ + public static final int LINE_GROUPS = 19; + /** + * Lookup table for turning Base64 alphabet positions (6 bits) + * into output bytes. + */ + private static final byte[] ENCODE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', + }; + /** + * Lookup table for turning Base64 alphabet positions (6 bits) + * into output bytes. + */ + private static final byte[] ENCODE_WEBSAFE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_', + }; + final private byte[] tail; + int tailLen; + private int count; + final public boolean do_padding; + final public boolean do_newline; + final public boolean do_cr; + final private byte[] alphabet; + public Encoder(int flags, byte[] output) { + this.output = output; + do_padding = (flags & NO_PADDING) == 0; + do_newline = (flags & NO_WRAP) == 0; + do_cr = (flags & CRLF) != 0; + alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE; + tail = new byte[2]; + tailLen = 0; + count = do_newline ? LINE_GROUPS : -1; + } + + private void process(byte[] input, int offset, int len) { + // Using local variables makes the encoder about 9% faster. + final byte[] alphabet = this.alphabet; + final byte[] output = this.output; + int op = 0; + int count = this.count; + int p = offset; + len += offset; + int v = -1; + // First we need to concatenate the tail of the previous call + // with any input bytes available now and see if we can empty + // the tail. + switch (tailLen) { + case 0: + // There was no tail. + break; + case 1: + if (p+2 <= len) { + // A 1-byte tail with at least 2 bytes of + // input available now. + v = ((tail[0] & 0xff) << 16) | + ((input[p++] & 0xff) << 8) | + (input[p++] & 0xff); + tailLen = 0; + }; + break; + case 2: + if (p+1 <= len) { + // A 2-byte tail with at least 1 byte of input. + v = ((tail[0] & 0xff) << 16) | + ((tail[1] & 0xff) << 8) | + (input[p++] & 0xff); + tailLen = 0; + } + break; + } + if (v != -1) { + output[op++] = alphabet[(v >> 18) & 0x3f]; + output[op++] = alphabet[(v >> 12) & 0x3f]; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (--count == 0) { + if (do_cr) output[op++] = '\r'; + output[op++] = '\n'; + count = LINE_GROUPS; + } + } + // At this point either there is no tail, or there are fewer + // than 3 bytes of input available. + // The main loop, turning 3 input bytes into 4 output bytes on + // each iteration. + while (p+3 <= len) { + v = ((input[p] & 0xff) << 16) | + ((input[p+1] & 0xff) << 8) | + (input[p+2] & 0xff); + output[op] = alphabet[(v >> 18) & 0x3f]; + output[op+1] = alphabet[(v >> 12) & 0x3f]; + output[op+2] = alphabet[(v >> 6) & 0x3f]; + output[op+3] = alphabet[v & 0x3f]; + p += 3; + op += 4; + if (--count == 0) { + if (do_cr) output[op++] = '\r'; + output[op++] = '\n'; + count = LINE_GROUPS; + } + } + // Finish up the tail of the input. Note that we need to + // consume any bytes in tail before any bytes + // remaining in input; there should be at most two bytes + // total. + if (p-tailLen == len-1) { + int t = 0; + v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4; + tailLen -= t; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (do_padding) { + output[op++] = '='; + output[op++] = '='; + } + if (do_newline) { + if (do_cr) output[op++] = '\r'; + output[op++] = '\n'; + } + } else if (p-tailLen == len-2) { + int t = 0; + v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) | + (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2); + tailLen -= t; + output[op++] = alphabet[(v >> 12) & 0x3f]; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (do_padding) { + output[op++] = '='; + } + if (do_newline) { + if (do_cr) output[op++] = '\r'; + output[op++] = '\n'; + } + } else if (do_newline && op > 0 && count != LINE_GROUPS) { + if (do_cr) output[op++] = '\r'; + output[op++] = '\n'; + } + assert tailLen == 0; + assert p == len; + this.op = op; + this.count = count; + } + } + + private Base64() { } // don't instantiate +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/Comparables.java b/nitrite/src/main/java/org/dizitart/no2/common/util/Comparables.java index 3dbfeac71..0c13bcd20 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/Comparables.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/Comparables.java @@ -1,11 +1,21 @@ package org.dizitart.no2.common.util; /** + * A utility class for comparables. + * + * @since 1.0 * @author Anindya Chatterjee */ public class Comparables { private Comparables() {} + /** + * Compares two comparable objects. + * + * @param first the first + * @param second the second + * @return the int + */ @SuppressWarnings({"rawtypes", "unchecked"}) public static int compare(Comparable first, Comparable second) { if (first instanceof Number && second instanceof Number) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/CryptoUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/CryptoUtils.java new file mode 100644 index 000000000..5081e78d0 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/CryptoUtils.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; + +/** + * A utility class for cryptographic operations + * + * @since 4.0 + * @author Anindya Chatterjee + */ +public class CryptoUtils { + + /** + * Gets random nonce. + * + * @param numBytes the number of bytes + * @return the byte [ ] + */ + public static byte[] getRandomNonce(int numBytes) { + byte[] nonce = new byte[numBytes]; + new SecureRandom().nextBytes(nonce); + return nonce; + } + + /** + * Gets password derived AES 256 bits secret key + * + * @param password the password + * @param salt the salt + * @return the aes key from password + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws InvalidKeySpecException the invalid key spec exception + */ + public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt) + throws NoSuchAlgorithmException, InvalidKeySpecException { + + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + // iterationCount = 65536 + // keyLength = 256 + KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); + return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/IndexUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/IndexUtils.java new file mode 100644 index 000000000..bfb9413b1 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/IndexUtils.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017-2021 Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dizitart.no2.common.util; + +import org.dizitart.no2.index.IndexDescriptor; + +import static org.dizitart.no2.common.Constants.*; + +/** + * A utility class for index. + * + * @author Anindya Chatterjee + * @since 1.0 + */ +public class IndexUtils { + private IndexUtils() {} + + /** + * Derives index map name. + * + * @param descriptor the descriptor + * @return the string + */ + public static String deriveIndexMapName(IndexDescriptor descriptor) { + return INDEX_PREFIX + + INTERNAL_NAME_SEPARATOR + + descriptor.getCollectionName() + + INTERNAL_NAME_SEPARATOR + + descriptor.getIndexFields().getEncodedName() + + INTERNAL_NAME_SEPARATOR + + descriptor.getIndexType(); + } + + /** + * Derives index meta map name. + * + * @param collectionName the collection name + * @return the string + */ + public static String deriveIndexMetaMapName(String collectionName) { + return INDEX_META_PREFIX + INTERNAL_NAME_SEPARATOR + collectionName; + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java index d8879b272..7ed5051e2 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/Iterables.java @@ -119,10 +119,11 @@ public static List listOf(T... items) { @SafeVarargs public static Set setOf(T... items) { + Set set = new HashSet<>(); if (items != null) { - return new HashSet<>(Arrays.asList(items)); + set.addAll(Arrays.asList(items)); } - return Collections.emptySet(); + return set; } public static long size(Iterable iterable) { diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/SecureString.java b/nitrite/src/main/java/org/dizitart/no2/common/util/SecureString.java index 84bc098a3..bad6e4899 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/SecureString.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/SecureString.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2017-2020. Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.dizitart.no2.common.util; import java.security.SecureRandom; @@ -7,7 +23,10 @@ * This is not a string but a CharSequence that can be cleared of its memory. * Important for handling passwords. Represents text that should be kept * confidential, such as by deleting it from computer memory when no longer - * needed or garbaged collected. + * needed or garbage collected. + * + * @since 4.0 + * @author Anindya Chatterjee */ public class SecureString implements CharSequence { diff --git a/nitrite/src/main/java/org/dizitart/no2/exceptions/MigrationException.java b/nitrite/src/main/java/org/dizitart/no2/exceptions/MigrationException.java index ec613b355..2980689dd 100644 --- a/nitrite/src/main/java/org/dizitart/no2/exceptions/MigrationException.java +++ b/nitrite/src/main/java/org/dizitart/no2/exceptions/MigrationException.java @@ -1,9 +1,17 @@ package org.dizitart.no2.exceptions; /** + * Exception thrown when a migration step fails. + * * @author Anindya Chatterjee + * @since 4.0 */ public class MigrationException extends NitriteException { + /** + * Instantiates a new Migration exception. + * + * @param errorMessage the error message + */ public MigrationException(String errorMessage) { super(errorMessage); } diff --git a/nitrite/src/main/java/org/dizitart/no2/exceptions/PluginException.java b/nitrite/src/main/java/org/dizitart/no2/exceptions/PluginException.java index 74ad3bcac..6363b7cac 100644 --- a/nitrite/src/main/java/org/dizitart/no2/exceptions/PluginException.java +++ b/nitrite/src/main/java/org/dizitart/no2/exceptions/PluginException.java @@ -17,13 +17,27 @@ package org.dizitart.no2.exceptions; /** + * Exception thrown when a nitrite plugin fails to load properly. + * * @author Anindya Chatterjee. + * @since 4.0 */ public class PluginException extends NitriteException { + /** + * Instantiates a new Plugin exception. + * + * @param errorMessage the error message + */ public PluginException(String errorMessage) { super(errorMessage); } + /** + * Instantiates a new Plugin exception. + * + * @param errorMessage the error message + * @param cause the cause + */ public PluginException(String errorMessage, Throwable cause) { super(errorMessage, cause); } diff --git a/nitrite/src/main/java/org/dizitart/no2/exceptions/TransactionException.java b/nitrite/src/main/java/org/dizitart/no2/exceptions/TransactionException.java index cf76276e6..ac4757488 100644 --- a/nitrite/src/main/java/org/dizitart/no2/exceptions/TransactionException.java +++ b/nitrite/src/main/java/org/dizitart/no2/exceptions/TransactionException.java @@ -1,13 +1,27 @@ package org.dizitart.no2.exceptions; /** + * Exception thrown when a transaction fails. + * * @author Anindya Chatterjee + * @since 4.0 */ public class TransactionException extends NitriteException { + /** + * Instantiates a new Transaction exception. + * + * @param errorMessage the error message + */ public TransactionException(String errorMessage) { super(errorMessage); } + /** + * Instantiates a new Transaction exception. + * + * @param errorMessage the error message + * @param error the error + */ public TransactionException(String errorMessage, Throwable error) { super(errorMessage, error); } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java index 845fb0d13..0c4e96a40 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/AndFilter.java @@ -23,11 +23,19 @@ import org.dizitart.no2.exceptions.FilterException; /** + * Represents an And filter. + * * @author Anindya Chatterjee + * @since 1.0 */ @Getter public class AndFilter extends LogicalFilter { + /** + * Instantiates a new And filter. + * + * @param filters the filters + */ AndFilter(Filter... filters) { super(filters); diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java new file mode 100644 index 000000000..e67d88ac3 --- /dev/null +++ b/nitrite/src/main/java/org/dizitart/no2/filters/ComparableFilter.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017-2020. Nitrite author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dizitart.no2.filters; + +import org.dizitart.no2.collection.NitriteId; +import org.dizitart.no2.exceptions.FilterException; +import org.dizitart.no2.index.IndexScanner; + +import java.util.List; +import java.util.Map; +import java.util.NavigableMap; + +/** + * Represents a filter based on document field holding {@link Comparable} values. + * + * @author Anindya Chatterjee + * @since 4.0 + */ +public abstract class ComparableFilter extends FieldBasedFilter { + /** + * Instantiates a new Comparable filter. + * + * @param field the field + * @param value the value + */ + public ComparableFilter(String field, Object value) { + super(field, value); + } + + /** + * Gets the {@link Comparable} value to filter. + * + * @return the comparable + */ + @SuppressWarnings("rawtypes") + public Comparable getComparable() { + if (getValue() == null) { + throw new FilterException("value parameter must not be null"); + } + return (Comparable) getValue(); + } + + /** + * Apply this filter on an nitrite index. + * + * @param indexScanner the index scanner + * @return the object + */ + public abstract Object applyOnIndex(IndexScanner indexScanner); + + /** + * Process values after index scanning. + * + * @param value the value + * @param subMap the sub map + * @param nitriteIds the nitrite ids + */ + @SuppressWarnings("unchecked") + protected void processIndexValue(Object value, + NavigableMap, Object> subMap, + List nitriteIds) { + if (value instanceof List) { + // if its is list then add it directly to nitrite ids + List result = (List) value; + nitriteIds.addAll(result); + } + + if (value instanceof NavigableMap) { + NavigableMap, ?> result = (NavigableMap, ?>) value; + for (Map.Entry, ?> comparableEntry : result.entrySet()) { + subMap.put(comparableEntry.getKey(), comparableEntry.getValue()); + } + } + } +} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/ComparisonFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/ComparisonFilter.java deleted file mode 100644 index 633330425..000000000 --- a/nitrite/src/main/java/org/dizitart/no2/filters/ComparisonFilter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017-2020. Nitrite author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.dizitart.no2.filters; - -import org.dizitart.no2.exceptions.FilterException; - -/** - * @author Anindya Chatterjee - */ -abstract class ComparisonFilter extends IndexAwareFilter { - protected ComparisonFilter(String field, Comparable value) { - super(field, value); - } - - @SuppressWarnings("rawtypes") - public Comparable getComparable() { - if (getValue() == null) { - throw new FilterException("value parameter must not be null"); - } - return (Comparable) getValue(); - } -} diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java index 12880f5e9..86de07bf3 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/EqualsFilter.java @@ -20,13 +20,7 @@ import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.tuples.Pair; -import org.dizitart.no2.exceptions.FilterException; -import org.dizitart.no2.index.ComparableIndexer; -import org.dizitart.no2.index.TextIndexer; -import org.dizitart.no2.store.NitriteMap; - -import java.util.LinkedHashSet; -import java.util.Set; +import org.dizitart.no2.index.IndexScanner; import static org.dizitart.no2.common.util.ObjectUtils.deepEquals; @@ -34,46 +28,11 @@ * @author Anindya Chatterjee. */ @ToString -class EqualsFilter extends IndexAwareFilter { +class EqualsFilter extends ComparableFilter { EqualsFilter(String field, Object value) { super(field, value); } - @Override - @SuppressWarnings("rawtypes") - protected Set findIndexedIdSet() { - Set idSet = new LinkedHashSet<>(); - if (getIsFieldIndexed()) { - if (getValue() == null || getValue() instanceof Comparable) { - if (getNitriteIndexer() instanceof ComparableIndexer) { - ComparableIndexer comparableIndexer = (ComparableIndexer) getNitriteIndexer(); - idSet = comparableIndexer.findEqual(getCollectionName(), getField(), (Comparable) getValue()); - } else if (getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String) { - // eq filter is not compatible with TextIndexer - setIsFieldIndexed(false); - } else { - throw new FilterException("eq filter is not supported on indexed field " - + getField()); - } - } else { - throw new FilterException(getValue() + " is not comparable"); - } - } - return idSet; - } - - @Override - protected Set findIdSet(NitriteMap collection) { - Set idSet = new LinkedHashSet<>(); - if (getOnIdField() && getValue() instanceof String) { - NitriteId nitriteId = NitriteId.createId((String) getValue()); - if (collection.containsKey(nitriteId)) { - idSet.add(nitriteId); - } - } - return idSet; - } - @Override public boolean apply(Pair element) { Document document = element.getSecond(); @@ -82,9 +41,7 @@ public boolean apply(Pair element) { } @Override - public void setIsFieldIndexed(Boolean isFieldIndexed) { - if (!(getNitriteIndexer() instanceof TextIndexer && getValue() instanceof String)) { - super.setIsFieldIndexed(isFieldIndexed); - } + public Object applyOnIndex(IndexScanner indexScanner) { + return indexScanner.get((Comparable) getValue()); } } diff --git a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java index 52d10c8d0..4e90f6967 100644 --- a/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java +++ b/nitrite/src/main/java/org/dizitart/no2/filters/FieldBasedFilter.java @@ -20,18 +20,17 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; -import org.dizitart.no2.exceptions.FilterException; import org.dizitart.no2.exceptions.ValidationException; import org.dizitart.no2.mapper.NitriteMapper; -import java.util.HashSet; -import java.util.Set; - import static org.dizitart.no2.common.util.ValidationUtils.notEmpty; import static org.dizitart.no2.common.util.ValidationUtils.notNull; /** + * Represents a filter based on value of a nitrite document field. + * * @author Anindya Chatterjee + * @since 4.0 */ @Data @EqualsAndHashCode(callSuper = true) @@ -44,58 +43,22 @@ public abstract class FieldBasedFilter extends NitriteFilter { @Getter(AccessLevel.NONE) private boolean processed = false; - protected FieldBasedFilter(String field, Object value) { - this.field = field; - this.value = value; - } - /** - * Creates an and filter which performs a logical AND operation on two filters and selects - * the documents that satisfy both filters. - *