Skip to content

Commit f8535b9

Browse files
committed
#80 create only missing indexes, skip existing
1 parent 3b8d654 commit f8535b9

File tree

2 files changed

+33
-61
lines changed

2 files changed

+33
-61
lines changed

src/main/java/com/arangodb/springframework/core/template/ArangoTemplate.java

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@
5252
import org.springframework.expression.ParserContext;
5353
import org.springframework.expression.spel.standard.SpelExpressionParser;
5454
import org.springframework.expression.spel.support.StandardEvaluationContext;
55-
import org.springframework.lang.Nullable;
56-
import org.springframework.util.ReflectionUtils;
5755

5856
import java.util.*;
5957
import java.util.Map.Entry;
@@ -63,6 +61,7 @@
6361
* @author Mark Vollmary
6462
* @author Christian Lechner
6563
* @author Reşat SABIQ
64+
* @author Arne Burmeister
6665
*/
6766
public class ArangoTemplate implements ArangoOperations, CollectionCallback, ApplicationContextAware {
6867

@@ -161,25 +160,22 @@ private ArangoCollection _collection(final String name, final ArangoPersistentEn
161160
}
162161
collection.create(options);
163162
}
164-
return new CollectionCacheValue(collection);
163+
return new CollectionCacheValue(collection, collection.getIndexes());
165164
});
166-
final Collection<Class<?>> entities = value.getEntities();
167165
final ArangoCollection collection = value.getCollection();
168-
if (persistentEntity != null && !entities.contains(entityClass)) {
169-
value.addEntityClass(entityClass);
166+
if (persistentEntity != null && value.addEntityClass(entityClass)) {
170167
if (transactional) {
171168
LOGGER.debug("Not ensuring any indexes of collection {} for {} during transaction", name, entityClass);
172169
} else {
173-
ensureCollectionIndexes(collection(collection), persistentEntity);
170+
ensureCollectionIndexes(collection(collection), persistentEntity, value.getIndexes());
174171
}
175172
}
176173
return collection;
177174
}
178175

179176
@SuppressWarnings("deprecation")
180177
private static void ensureCollectionIndexes(final CollectionOperations collection,
181-
final ArangoPersistentEntity<?> persistentEntity) {
182-
Collection<IndexEntity> existing = collection.getIndexes();
178+
final ArangoPersistentEntity<?> persistentEntity, Collection<IndexEntity> existing) {
183179
persistentEntity.getPersistentIndexes().forEach(index -> ensurePersistentIndex(collection, index, existing));
184180
persistentEntity.getPersistentIndexedProperties().forEach(p -> ensurePersistentIndex(collection, p, existing));
185181
persistentEntity.getGeoIndexes().forEach(index -> ensureGeoIndex(collection, index, existing));
@@ -198,8 +194,8 @@ private static void ensurePersistentIndex(final CollectionOperations collection,
198194
.sparse(annotation.sparse())
199195
.deduplicate(annotation.deduplicate());
200196
Collection<String> fields = Arrays.asList(annotation.fields());
201-
if (existing.stream().noneMatch(index -> equalPersistentIndex(index, options, fields))) {
202-
collection.ensurePersistentIndex(fields, options);
197+
if (createNewIndex(IndexType.persistent, fields, existing)) {
198+
existing.add(collection.ensurePersistentIndex(fields, options));
203199
}
204200
}
205201

@@ -211,46 +207,34 @@ private static void ensurePersistentIndex(final CollectionOperations collection,
211207
.sparse(i.sparse())
212208
.deduplicate(i.deduplicate()));
213209
Collection<String> fields = Collections.singleton(value.getFieldName());
214-
if (existing.stream().noneMatch(index -> equalPersistentIndex(index, options, fields))) {
215-
collection.ensurePersistentIndex(fields, options);
210+
if (createNewIndex(IndexType.persistent, fields, existing)) {
211+
existing.add(collection.ensurePersistentIndex(fields, options));
216212
}
217213
}
218214

219-
private static boolean equalPersistentIndex(IndexEntity index, PersistentIndexOptions options, Collection<String> fields) {
220-
return isIndexWithTypeAndFields(index, IndexType.persistent, fields)
221-
&& isEqualOption(index.getUnique(), options.getUnique(), false)
222-
&& isEqualOption(index.getSparse(), options.getSparse(), false)
223-
&& isEqualOption(index.getDeduplicate(), options.getDeduplicate(), false);
224-
}
225-
226215
private static void ensureGeoIndex(final CollectionOperations collection, final GeoIndex annotation, Collection<IndexEntity> existing) {
227216
GeoIndexOptions options = new GeoIndexOptions().geoJson(annotation.geoJson());
228217
Collection<String> fields = Arrays.asList(annotation.fields());
229-
if (existing.stream().noneMatch(index -> equalGeoIndex(index, options, fields))) {
230-
collection.ensureGeoIndex(fields, options);
218+
if (createNewIndex(IndexType.geo, fields, existing)) {
219+
existing.add(collection.ensureGeoIndex(fields, options));
231220
}
232221
}
233222

234223
private static void ensureGeoIndex(final CollectionOperations collection, final ArangoPersistentProperty value, Collection<IndexEntity> existing) {
235224
final GeoIndexOptions options = new GeoIndexOptions();
236225
value.getGeoIndexed().ifPresent(i -> options.geoJson(i.geoJson()));
237226
Collection<String> fields = Collections.singleton(value.getFieldName());
238-
if (existing.stream().noneMatch(index -> equalGeoIndex(index, options, fields))) {
239-
collection.ensureGeoIndex(fields, options);
227+
if (createNewIndex(IndexType.geo, fields, existing)) {
228+
existing.add(collection.ensureGeoIndex(fields, options));
240229
}
241230
}
242231

243-
private static boolean equalGeoIndex(IndexEntity index, GeoIndexOptions options, Collection<String> fields) {
244-
return isIndexWithTypeAndFields(index, IndexType.geo, fields)
245-
&& isEqualOption(index.getGeoJson(), options.getGeoJson(), false);
246-
}
247-
248232
@SuppressWarnings("deprecation")
249233
private static void ensureFulltextIndex(final CollectionOperations collection, final FulltextIndex annotation, Collection<IndexEntity> existing) {
250234
Collection<String> fields = Collections.singleton(annotation.field());
251235
FulltextIndexOptions options = new FulltextIndexOptions().minLength(annotation.minLength() > -1 ? annotation.minLength() : null);
252-
if (existing.stream().noneMatch(index -> equalFulltextIndex(index, options, fields))) {
253-
collection.ensureFulltextIndex(fields, options);
236+
if (createNewIndex(IndexType.fulltext, fields, existing)) {
237+
existing.add(collection.ensureFulltextIndex(fields, options));
254238
}
255239
}
256240

@@ -260,30 +244,25 @@ private static void ensureFulltextIndex(final CollectionOperations collection,
260244
final FulltextIndexOptions options = new FulltextIndexOptions();
261245
value.getFulltextIndexed().ifPresent(i -> options.minLength(i.minLength() > -1 ? i.minLength() : null));
262246
Collection<String> fields = Collections.singleton(value.getFieldName());
263-
if (existing.stream().noneMatch(index -> equalFulltextIndex(index, options, fields))) {
264-
collection.ensureFulltextIndex(fields, options);
247+
if (createNewIndex(IndexType.fulltext, fields, existing)) {
248+
existing.add(collection.ensureFulltextIndex(fields, options));
265249
}
266250
}
267251

268-
private static boolean equalFulltextIndex(IndexEntity index, FulltextIndexOptions options, Collection<String> fields) {
269-
return isIndexWithTypeAndFields(index, IndexType.fulltext, fields)
270-
&& isEqualOption(index.getMinLength(), options.getMinLength(), 0);
271-
}
272-
273252
private static void ensureTtlIndex(final CollectionOperations collection, final TtlIndex annotation, Collection<IndexEntity> existing) {
274253
TtlIndexOptions options = new TtlIndexOptions().expireAfter(annotation.expireAfter());
275254
Collection<String> fields = Collections.singleton(annotation.field());
276-
if (existing.stream().noneMatch(index -> equalTtlIndex(index, options, fields))) {
277-
collection.ensureTtlIndex(fields, options);
255+
if (createNewIndex(IndexType.ttl, fields, existing)) {
256+
existing.add(collection.ensureTtlIndex(fields, options));
278257
}
279258
}
280259

281260
private static void ensureTtlIndex(final CollectionOperations collection, final ArangoPersistentProperty value, Collection<IndexEntity> existing) {
282261
final TtlIndexOptions options = new TtlIndexOptions();
283262
value.getTtlIndexed().ifPresent(i -> options.expireAfter(i.expireAfter()));
284263
Collection<String> fields = Collections.singleton(value.getFieldName());
285-
if (existing.stream().noneMatch(index -> equalTtlIndex(index, options, fields))) {
286-
collection.ensureTtlIndex(fields, options);
264+
if (createNewIndex(IndexType.ttl, fields, existing)) {
265+
existing.add(collection.ensureTtlIndex(fields, options));
287266
}
288267
}
289268

@@ -306,28 +285,15 @@ private static void ensureMDPrefixedIndex(final CollectionOperations collection,
306285
);
307286
}
308287

309-
private static boolean equalTtlIndex(IndexEntity index, TtlIndexOptions options, Collection<String> fields) {
310-
return isIndexWithTypeAndFields(index, IndexType.ttl, fields)
311-
&& isEqualOption(index.getExpireAfter(), getProtected(options, "getExpireAfter"), 0);
288+
private static boolean createNewIndex(IndexType type, Collection<String> fields, Collection<IndexEntity> existing) {
289+
return existing.stream()
290+
.noneMatch(index -> isIndexWithTypeAndFields(index, type, fields));
312291
}
313292

314293
private static boolean isIndexWithTypeAndFields(IndexEntity index, IndexType type, Collection<String> fields) {
315294
return index.getType() == type && index.getFields().size() == fields.size() && index.getFields().containsAll(fields);
316295
}
317296

318-
private static <T> boolean isEqualOption(T value, @Nullable T optionalValue, T defaultValue) {
319-
return value.equals(optionalValue == null ? defaultValue : optionalValue);
320-
}
321-
322-
@SuppressWarnings("unchecked")
323-
@Deprecated
324-
// can be removed for driver 7 as all option getters are visible
325-
private static <T> T getProtected(Object options, String getterName) {
326-
Method getter = ReflectionUtils.findMethod(options.getClass(), getterName);
327-
ReflectionUtils.makeAccessible(getter);
328-
return (T) ReflectionUtils.invokeMethod(getter, options);
329-
}
330-
331297
private Optional<String> determineCollectionFromId(final Object id) {
332298
return id != null ? Optional.ofNullable(MetadataUtils.determineCollectionFromId(converter.convertId(id)))
333299
: Optional.empty();

src/main/java/com/arangodb/springframework/core/template/CollectionCacheValue.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@
44
import java.util.concurrent.CopyOnWriteArrayList;
55

66
import com.arangodb.ArangoCollection;
7+
import com.arangodb.entity.IndexEntity;
78

89
class CollectionCacheValue {
910

1011
private final ArangoCollection collection;
1112
private final Collection<Class<?>> entities;
13+
private final Collection<IndexEntity> indexes;
1214

13-
public CollectionCacheValue(final ArangoCollection collection) {
15+
public CollectionCacheValue(final ArangoCollection collection, Collection<IndexEntity> indexes) {
1416
super();
1517
this.collection = collection;
1618
this.entities = new CopyOnWriteArrayList<>();
19+
this.indexes = indexes;
1720
}
1821

1922
public ArangoCollection getCollection() {
@@ -24,8 +27,11 @@ public Collection<Class<?>> getEntities() {
2427
return entities;
2528
}
2629

27-
public void addEntityClass(final Class<?> entityClass) {
28-
entities.add(entityClass);
30+
public Collection<IndexEntity> getIndexes() {
31+
return indexes;
32+
}
33+
public boolean addEntityClass(final Class<?> entityClass) {
34+
return entities.add(entityClass);
2935
}
3036

3137
}

0 commit comments

Comments
 (0)