diff --git a/src/main/java/com/arangodb/ArangoDatabase.java b/src/main/java/com/arangodb/ArangoDatabase.java index f0cfede5f..8ba8447d7 100644 --- a/src/main/java/com/arangodb/ArangoDatabase.java +++ b/src/main/java/com/arangodb/ArangoDatabase.java @@ -26,6 +26,7 @@ import com.arangodb.model.*; import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; import java.util.Collection; import java.util.Map; @@ -703,7 +704,7 @@ TraversalEntity executeTraversal(Class vertexClass, Class edg ArangoView view(String name); /** - * Returns a {@code ArangoSearch} instance for the given ArangoSearch view name. + * Returns a {@link ArangoSearch} instance for the given view name. * * @param name Name of the view * @return ArangoSearch view handler @@ -711,6 +712,15 @@ TraversalEntity executeTraversal(Class vertexClass, Class edg */ ArangoSearch arangoSearch(String name); + /** + * Returns a {@link SearchAlias} instance for the given view name. + * + * @param name Name of the view + * @return SearchAlias view handler + * @since ArangoDB 3.10 + */ + SearchAlias searchAlias(String name); + /** * Creates a view of the given {@code type}, then returns view information from the server. * @@ -735,6 +745,19 @@ TraversalEntity executeTraversal(Class vertexClass, Class edg */ ViewEntity createArangoSearch(String name, ArangoSearchCreateOptions options) throws ArangoDBException; + /** + * Creates a SearchAlias view with the given {@code options}, then returns view information from the server. + * + * @param name The name of the view + * @param options Additional options, can be null + * @return information about the view + * @throws ArangoDBException + * @see API + * Documentation + * @since ArangoDB 3.10 + */ + ViewEntity createSearchAlias(String name, SearchAliasCreateOptions options) throws ArangoDBException; + /** * Creates an Analyzer * diff --git a/src/main/java/com/arangodb/ArangoSearch.java b/src/main/java/com/arangodb/ArangoSearch.java index 7a6600d79..0d4a0d84d 100644 --- a/src/main/java/com/arangodb/ArangoSearch.java +++ b/src/main/java/com/arangodb/ArangoSearch.java @@ -29,7 +29,7 @@ * Interface for operations on ArangoDB view level for ArangoSearch views. * * @author Mark Vollmary - * @see View API Documentation + * @see View API Documentation * @since ArangoDB 3.4.0 */ public interface ArangoSearch extends ArangoView { diff --git a/src/main/java/com/arangodb/SearchAlias.java b/src/main/java/com/arangodb/SearchAlias.java new file mode 100644 index 000000000..7f732fe87 --- /dev/null +++ b/src/main/java/com/arangodb/SearchAlias.java @@ -0,0 +1,92 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb; + +import com.arangodb.entity.ViewEntity; +import com.arangodb.entity.arangosearch.SearchAliasPropertiesEntity; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasPropertiesOptions; + +/** + * Interface for operations on ArangoDB view level for SearchAlias views. + * + * @author Michele Rastelli + * @see View API Documentation + * @since ArangoDB 3.10 + */ +public interface SearchAlias extends ArangoView { + + /** + * Creates a view, then returns view information from the server. + * + * @return information about the view + * @throws ArangoDBException + * @see API + * Documentation + */ + ViewEntity create() throws ArangoDBException; + + /** + * Creates a view with the given {@code options}, then returns view information from the server. + * + * @param options Additional options, can be null + * @return information about the view + * @throws ArangoDBException + * @see API + * Documentation + */ + ViewEntity create(SearchAliasCreateOptions options) throws ArangoDBException; + + /** + * Reads the properties of the specified view. + * + * @return properties of the view + * @throws ArangoDBException + * @see API + * Documentation + */ + SearchAliasPropertiesEntity getProperties() throws ArangoDBException; + + /** + * Partially changes properties of the view. + * + * @param options properties to change + * @return properties of the view + * @throws ArangoDBException + * @see API + * Documentation + */ + SearchAliasPropertiesEntity updateProperties(SearchAliasPropertiesOptions options) throws ArangoDBException; + + /** + * Changes properties of the view. + * + * @param options properties to change + * @return properties of the view + * @throws ArangoDBException + * @see API + * Documentation + */ + SearchAliasPropertiesEntity replaceProperties(SearchAliasPropertiesOptions options) throws ArangoDBException; + +} diff --git a/src/main/java/com/arangodb/async/ArangoDatabaseAsync.java b/src/main/java/com/arangodb/async/ArangoDatabaseAsync.java index 420034655..147f2a89e 100644 --- a/src/main/java/com/arangodb/async/ArangoDatabaseAsync.java +++ b/src/main/java/com/arangodb/async/ArangoDatabaseAsync.java @@ -29,6 +29,7 @@ import com.arangodb.model.*; import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; import java.util.Collection; import java.util.Map; @@ -682,7 +683,7 @@ CompletableFuture getDocument(final String id, final Class type, final ArangoViewAsync view(String name); /** - * Returns a {@code ArangoSearchAsync} instance for the given ArangoSearch view name. + * Returns a {@link ArangoSearchAsync} instance for the given ArangoSearch view name. * * @param name Name of the view * @return ArangoSearch view handler @@ -690,6 +691,15 @@ CompletableFuture getDocument(final String id, final Class type, final */ ArangoSearchAsync arangoSearch(String name); + /** + * Returns a {@link SearchAliasAsync} instance for the given view name. + * + * @param name Name of the view + * @return SearchAlias view handler + * @since ArangoDB 3.10 + */ + SearchAliasAsync searchAlias(String name); + /** * Creates a view of the given {@code type}, then returns view information from the server. * @@ -712,6 +722,18 @@ CompletableFuture getDocument(final String id, final Class type, final */ CompletableFuture createArangoSearch(String name, ArangoSearchCreateOptions options); + /** + * Creates a SearchAlias view with the given {@code options}, then returns view information from the server. + * + * @param name The name of the view + * @param options Additional options, can be null + * @return information about the view + * @see API + * Documentation + * @since ArangoDB 3.10 + */ + CompletableFuture createSearchAlias(String name, SearchAliasCreateOptions options); + /** * Creates an Analyzer * diff --git a/src/main/java/com/arangodb/async/ArangoSearchAsync.java b/src/main/java/com/arangodb/async/ArangoSearchAsync.java index d738012c1..33e659d26 100644 --- a/src/main/java/com/arangodb/async/ArangoSearchAsync.java +++ b/src/main/java/com/arangodb/async/ArangoSearchAsync.java @@ -31,7 +31,7 @@ * Interface for operations on ArangoDB view level for ArangoSearch views. * * @author Mark Vollmary - * @see View API Documentation + * @see View API Documentation * @since ArangoDB 3.4.0 */ public interface ArangoSearchAsync extends ArangoViewAsync { diff --git a/src/main/java/com/arangodb/async/SearchAliasAsync.java b/src/main/java/com/arangodb/async/SearchAliasAsync.java new file mode 100644 index 000000000..cfb6d8a84 --- /dev/null +++ b/src/main/java/com/arangodb/async/SearchAliasAsync.java @@ -0,0 +1,89 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.async; + +import com.arangodb.entity.ViewEntity; +import com.arangodb.entity.arangosearch.SearchAliasPropertiesEntity; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasPropertiesOptions; + +import java.util.concurrent.CompletableFuture; + +/** + * Interface for operations on ArangoDB view level for SearchAlias views. + * + * @author Michele Rastelli + * @see View API Documentation + * @since ArangoDB 3.10 + */ +public interface SearchAliasAsync extends ArangoViewAsync { + + /** + * Creates a view, then returns view information from the server. + * + * @return information about the view + * @see API + * Documentation + */ + CompletableFuture create(); + + /** + * Creates a view with the given {@code options}, then returns view information from the server. + * + * @param options Additional options, can be null + * @return information about the view + * @see API + * Documentation + */ + CompletableFuture create(SearchAliasCreateOptions options); + + /** + * Reads the properties of the specified view. + * + * @return properties of the view + * @see API + * Documentation + */ + CompletableFuture getProperties(); + + /** + * Partially changes properties of the view. + * + * @param options properties to change + * @return properties of the view + * @see API + * Documentation + */ + CompletableFuture updateProperties(SearchAliasPropertiesOptions options); + + /** + * Changes properties of the view. + * + * @param options properties to change + * @return properties of the view + * @see API + * Documentation + */ + CompletableFuture replaceProperties(SearchAliasPropertiesOptions options); + +} diff --git a/src/main/java/com/arangodb/async/internal/ArangoDatabaseAsyncImpl.java b/src/main/java/com/arangodb/async/internal/ArangoDatabaseAsyncImpl.java index 61fed58d9..9913a38c9 100644 --- a/src/main/java/com/arangodb/async/internal/ArangoDatabaseAsyncImpl.java +++ b/src/main/java/com/arangodb/async/internal/ArangoDatabaseAsyncImpl.java @@ -22,13 +22,7 @@ import com.arangodb.ArangoDBException; import com.arangodb.DbName; -import com.arangodb.async.ArangoCollectionAsync; -import com.arangodb.async.ArangoCursorAsync; -import com.arangodb.async.ArangoDatabaseAsync; -import com.arangodb.async.ArangoGraphAsync; -import com.arangodb.async.ArangoRouteAsync; -import com.arangodb.async.ArangoSearchAsync; -import com.arangodb.async.ArangoViewAsync; +import com.arangodb.async.*; import com.arangodb.entity.*; import com.arangodb.entity.arangosearch.AnalyzerEntity; import com.arangodb.entity.arangosearch.analyzer.SearchAnalyzer; @@ -51,6 +45,7 @@ import com.arangodb.model.TraversalOptions; import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; import com.arangodb.velocypack.Type; import com.arangodb.velocystream.Request; @@ -450,6 +445,11 @@ public ArangoSearchAsync arangoSearch(final String name) { return new ArangoSearchAsyncImpl(this, name); } + @Override + public SearchAliasAsync searchAlias(String name) { + return new SearchAliasAsyncImpl(this, name); + } + @Override public CompletableFuture createView(final String name, final ViewType type) { return executor.execute(createViewRequest(name, type), ViewEntity.class); @@ -460,6 +460,11 @@ public CompletableFuture createArangoSearch(final String name, final return executor.execute(createArangoSearchRequest(name, options), ViewEntity.class); } + @Override + public CompletableFuture createSearchAlias(String name, SearchAliasCreateOptions options) { + return executor.execute(createSearchAliasRequest(name, options), ViewEntity.class); + } + @Override public CompletableFuture createAnalyzer(AnalyzerEntity options) { return executor.execute(createAnalyzerRequest(options), AnalyzerEntity.class); diff --git a/src/main/java/com/arangodb/async/internal/SearchAliasAsyncImpl.java b/src/main/java/com/arangodb/async/internal/SearchAliasAsyncImpl.java new file mode 100644 index 000000000..d5e4cbd4f --- /dev/null +++ b/src/main/java/com/arangodb/async/internal/SearchAliasAsyncImpl.java @@ -0,0 +1,87 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.async.internal; + +import com.arangodb.async.SearchAliasAsync; +import com.arangodb.entity.ViewEntity; +import com.arangodb.entity.arangosearch.SearchAliasPropertiesEntity; +import com.arangodb.internal.InternalSearchAlias; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasPropertiesOptions; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; + +public class SearchAliasAsyncImpl + extends InternalSearchAlias + implements SearchAliasAsync { + + SearchAliasAsyncImpl(final ArangoDatabaseAsyncImpl db, final String name) { + super(db, name); + } + + @Override + public CompletableFuture exists() { + return getInfo().thenApply(Objects::nonNull).exceptionally(Objects::isNull); + } + + @Override + public CompletableFuture drop() { + return executor.execute(dropRequest(), Void.class); + } + + @Override + public synchronized CompletableFuture rename(final String newName) { + return executor.execute(renameRequest(newName), ViewEntity.class); + } + + @Override + public CompletableFuture getInfo() { + return executor.execute(getInfoRequest(), ViewEntity.class); + } + + @Override + public CompletableFuture create() { + return create(new SearchAliasCreateOptions()); + } + + @Override + public CompletableFuture create(final SearchAliasCreateOptions options) { + return db().createSearchAlias(name(), options); + } + + @Override + public CompletableFuture getProperties() { + return executor.execute(getPropertiesRequest(), SearchAliasPropertiesEntity.class); + } + + @Override + public CompletableFuture updateProperties(final SearchAliasPropertiesOptions options) { + return executor.execute(updatePropertiesRequest(options), SearchAliasPropertiesEntity.class); + } + + @Override + public CompletableFuture replaceProperties( + final SearchAliasPropertiesOptions options) { + return executor.execute(replacePropertiesRequest(options), SearchAliasPropertiesEntity.class); + } + +} diff --git a/src/main/java/com/arangodb/entity/ViewType.java b/src/main/java/com/arangodb/entity/ViewType.java index 21c039906..1c7399547 100644 --- a/src/main/java/com/arangodb/entity/ViewType.java +++ b/src/main/java/com/arangodb/entity/ViewType.java @@ -25,6 +25,7 @@ */ public enum ViewType { - ARANGO_SEARCH + ARANGO_SEARCH, + SEARCH_ALIAS } diff --git a/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java b/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java index 246662ec9..ad94f3f40 100644 --- a/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java +++ b/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java @@ -36,6 +36,7 @@ public class CollectionLink { private StoreValuesType storeValues; private final Collection fields; private final Collection nested; + private Boolean inBackground; private CollectionLink(final String name) { super(); @@ -112,6 +113,18 @@ public CollectionLink nested(final FieldLink... nested) { return this; } + /** + * @param inBackground If set to true, then no exclusive lock is used on the source collection during View index + * creation, so that it remains basically available. inBackground is an option that can be set + * when adding links. It does not get persisted as it is not a View property, but only a + * one-off option. (default: false) + * @return link + */ + public CollectionLink inBackground(final Boolean inBackground) { + this.inBackground = inBackground; + return this; + } + public String getName() { return name; } @@ -140,4 +153,7 @@ public Collection getNested() { return nested; } + public Boolean getInBackground() { + return inBackground; + } } \ No newline at end of file diff --git a/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java b/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java index 69d37b634..9da26f02f 100644 --- a/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java +++ b/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java @@ -13,6 +13,7 @@ public class FieldLink { private StoreValuesType storeValues; private final Collection fields; private final Collection nested; + private Boolean inBackground; private FieldLink(final String name) { super(); @@ -89,6 +90,18 @@ public FieldLink nested(final FieldLink... nested) { return this; } + /** + * @param inBackground If set to true, then no exclusive lock is used on the source collection during View index + * creation, so that it remains basically available. inBackground is an option that can be set + * when adding links. It does not get persisted as it is not a View property, but only a + * one-off option. (default: false) + * @return link + */ + public FieldLink inBackground(final Boolean inBackground) { + this.inBackground = inBackground; + return this; + } + public String getName() { return name; } @@ -116,4 +129,8 @@ public Collection getFields() { public Collection getNested() { return nested; } + + public Boolean getInBackground() { + return inBackground; + } } \ No newline at end of file diff --git a/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java new file mode 100644 index 000000000..2c741abfa --- /dev/null +++ b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java @@ -0,0 +1,23 @@ +package com.arangodb.entity.arangosearch; + +/** + * @author Michele Rastelli + * @since ArabgoDB 3.10 + */ +public class SearchAliasIndex { + private final String collection; + private final String index; + + public SearchAliasIndex(String collection, String index) { + this.collection = collection; + this.index = index; + } + + public String getCollection() { + return collection; + } + + public String getIndex() { + return index; + } +} diff --git a/src/main/java/com/arangodb/entity/arangosearch/SearchAliasProperties.java b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasProperties.java new file mode 100644 index 000000000..23378b525 --- /dev/null +++ b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasProperties.java @@ -0,0 +1,45 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.entity.arangosearch; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +/** + * @author Michele Rastelli + * @see API Documentation + * @since ArangoDB 3.10 + */ +public class SearchAliasProperties { + + private final Collection indexes = new ArrayList<>(); + + public Collection getIndexes() { + return indexes; + } + + public void addIndexes(SearchAliasIndex... indexes) { + Collections.addAll(this.indexes, indexes); + } + +} diff --git a/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java new file mode 100644 index 000000000..94a2f94d8 --- /dev/null +++ b/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java @@ -0,0 +1,49 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.entity.arangosearch; + +import com.arangodb.entity.ViewEntity; +import com.arangodb.entity.ViewType; + +import java.util.Collection; + +/** + * @author Michele Rastelli + * @see API Documentation + */ +public class SearchAliasPropertiesEntity extends ViewEntity { + + private final SearchAliasProperties properties; + + public SearchAliasPropertiesEntity(final String id, final String name, final ViewType type, + final SearchAliasProperties properties) { + super(id, name, type); + this.properties = properties; + } + + /** + * @return A list of inverted indexes to add to the View. + */ + public Collection getIndexes() { + return properties.getIndexes(); + } + +} diff --git a/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java b/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java index 6b38136ac..49501f903 100644 --- a/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java +++ b/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java @@ -30,6 +30,7 @@ import com.arangodb.model.*; import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; import com.arangodb.util.ArangoCursorInitializer; import com.arangodb.velocypack.Type; import com.arangodb.velocystream.Request; @@ -413,6 +414,11 @@ public ArangoSearch arangoSearch(final String name) { return new ArangoSearchImpl(this, name); } + @Override + public SearchAlias searchAlias(String name) { + return new SearchAliasImpl(this, name); + } + @Override public ViewEntity createView(final String name, final ViewType type) throws ArangoDBException { return executor.execute(createViewRequest(name, type), ViewEntity.class); @@ -424,6 +430,11 @@ public ViewEntity createArangoSearch(final String name, final ArangoSearchCreate return executor.execute(createArangoSearchRequest(name, options), ViewEntity.class); } + @Override + public ViewEntity createSearchAlias(String name, SearchAliasCreateOptions options) throws ArangoDBException { + return executor.execute(createSearchAliasRequest(name, options), ViewEntity.class); + } + @Override public AnalyzerEntity createAnalyzer(AnalyzerEntity options) throws ArangoDBException { return executor.execute(createAnalyzerRequest(options), AnalyzerEntity.class); diff --git a/src/main/java/com/arangodb/internal/InternalArangoDatabase.java b/src/main/java/com/arangodb/internal/InternalArangoDatabase.java index 5549dbf74..34610d61d 100644 --- a/src/main/java/com/arangodb/internal/InternalArangoDatabase.java +++ b/src/main/java/com/arangodb/internal/InternalArangoDatabase.java @@ -29,9 +29,7 @@ import com.arangodb.internal.util.ArangoSerializationFactory.Serializer; import com.arangodb.internal.util.RequestUtils; import com.arangodb.model.*; -import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; -import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; -import com.arangodb.model.arangosearch.ArangoSearchOptionsBuilder; +import com.arangodb.model.arangosearch.*; import com.arangodb.util.ArangoSerializer; import com.arangodb.velocypack.Type; import com.arangodb.velocypack.VPackSlice; @@ -476,6 +474,11 @@ protected Request createArangoSearchRequest(final String name, final ArangoSearc ArangoSearchOptionsBuilder.build(options != null ? options : new ArangoSearchCreateOptions(), name))); } + protected Request createSearchAliasRequest(final String name, final SearchAliasCreateOptions options) { + return request(dbName, RequestType.POST, InternalArangoView.PATH_API_VIEW).setBody(util().serialize( + SearchAliasOptionsBuilder.build(options != null ? options : new SearchAliasCreateOptions(), name))); + } + protected Request getAnalyzerRequest(final String name) { return request(dbName, RequestType.GET, InternalArangoView.PATH_API_ANALYZER, name); } diff --git a/src/main/java/com/arangodb/internal/InternalSearchAlias.java b/src/main/java/com/arangodb/internal/InternalSearchAlias.java new file mode 100644 index 000000000..72f6b5954 --- /dev/null +++ b/src/main/java/com/arangodb/internal/InternalSearchAlias.java @@ -0,0 +1,50 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.internal; + +import com.arangodb.model.arangosearch.SearchAliasPropertiesOptions; +import com.arangodb.velocystream.Request; +import com.arangodb.velocystream.RequestType; + +public class InternalSearchAlias, D extends InternalArangoDatabase, E extends ArangoExecutor> + extends InternalArangoView { + + protected InternalSearchAlias(final D db, final String name) { + super(db, name); + } + + protected Request getPropertiesRequest() { + return request(db.dbName(), RequestType.GET, PATH_API_VIEW, name, "properties"); + } + + protected Request replacePropertiesRequest(final SearchAliasPropertiesOptions options) { + final Request request = request(db.dbName(), RequestType.PUT, PATH_API_VIEW, name, "properties"); + request.setBody(util().serialize(options != null ? options : new SearchAliasPropertiesOptions())); + return request; + } + + protected Request updatePropertiesRequest(final SearchAliasPropertiesOptions options) { + final Request request = request(db.dbName(), RequestType.PATCH, PATH_API_VIEW, name, "properties"); + request.setBody(util().serialize(options != null ? options : new SearchAliasPropertiesOptions())); + return request; + } + +} diff --git a/src/main/java/com/arangodb/internal/SearchAliasImpl.java b/src/main/java/com/arangodb/internal/SearchAliasImpl.java new file mode 100644 index 000000000..589e4e208 --- /dev/null +++ b/src/main/java/com/arangodb/internal/SearchAliasImpl.java @@ -0,0 +1,97 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.internal; + +import com.arangodb.ArangoDBException; +import com.arangodb.SearchAlias; +import com.arangodb.entity.ViewEntity; +import com.arangodb.entity.arangosearch.SearchAliasPropertiesEntity; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; +import com.arangodb.model.arangosearch.SearchAliasPropertiesOptions; + +/** + * @author Michele Rastelli + */ +public class SearchAliasImpl extends InternalSearchAlias + implements SearchAlias { + + protected SearchAliasImpl(final ArangoDatabaseImpl db, final String name) { + super(db, name); + } + + @Override + public boolean exists() throws ArangoDBException { + try { + getInfo(); + return true; + } catch (final ArangoDBException e) { + if (ArangoErrors.ERROR_ARANGO_DATA_SOURCE_NOT_FOUND.equals(e.getErrorNum())) { + return false; + } + throw e; + } + } + + @Override + public void drop() throws ArangoDBException { + executor.execute(dropRequest(), Void.class); + } + + @Override + public synchronized ViewEntity rename(final String newName) throws ArangoDBException { + final ViewEntity result = executor.execute(renameRequest(newName), ViewEntity.class); + name = result.getName(); + return result; + } + + @Override + public ViewEntity getInfo() throws ArangoDBException { + return executor.execute(getInfoRequest(), ViewEntity.class); + } + + @Override + public ViewEntity create() throws ArangoDBException { + return create(new SearchAliasCreateOptions()); + } + + @Override + public ViewEntity create(final SearchAliasCreateOptions options) throws ArangoDBException { + return db().createSearchAlias(name(), options); + } + + @Override + public SearchAliasPropertiesEntity getProperties() throws ArangoDBException { + return executor.execute(getPropertiesRequest(), SearchAliasPropertiesEntity.class); + } + + @Override + public SearchAliasPropertiesEntity updateProperties(final SearchAliasPropertiesOptions options) + throws ArangoDBException { + return executor.execute(updatePropertiesRequest(options), SearchAliasPropertiesEntity.class); + } + + @Override + public SearchAliasPropertiesEntity replaceProperties(final SearchAliasPropertiesOptions options) + throws ArangoDBException { + return executor.execute(replacePropertiesRequest(options), SearchAliasPropertiesEntity.class); + } + +} diff --git a/src/main/java/com/arangodb/internal/velocypack/VPackDeserializers.java b/src/main/java/com/arangodb/internal/velocypack/VPackDeserializers.java index 3971cac66..7e7c0a3f5 100644 --- a/src/main/java/com/arangodb/internal/velocypack/VPackDeserializers.java +++ b/src/main/java/com/arangodb/internal/velocypack/VPackDeserializers.java @@ -21,17 +21,7 @@ package com.arangodb.internal.velocypack; import com.arangodb.entity.*; -import com.arangodb.entity.arangosearch.AnalyzerType; -import com.arangodb.entity.arangosearch.ArangoSearchCompression; -import com.arangodb.entity.arangosearch.ArangoSearchProperties; -import com.arangodb.entity.arangosearch.ArangoSearchPropertiesEntity; -import com.arangodb.entity.arangosearch.CollectionLink; -import com.arangodb.entity.arangosearch.ConsolidationPolicy; -import com.arangodb.entity.arangosearch.ConsolidationType; -import com.arangodb.entity.arangosearch.FieldLink; -import com.arangodb.entity.arangosearch.PrimarySort; -import com.arangodb.entity.arangosearch.StoreValuesType; -import com.arangodb.entity.arangosearch.StoredValue; +import com.arangodb.entity.arangosearch.*; import com.arangodb.entity.arangosearch.analyzer.*; import com.arangodb.model.CollectionSchema; import com.arangodb.model.ZKDIndexOptions; @@ -151,8 +141,17 @@ public class VPackDeserializers { return minReplicationFactor; }; - public static final VPackDeserializer VIEW_TYPE = (parent, vpack, context) -> "arangosearch".equals(vpack.getAsString()) ? ViewType.ARANGO_SEARCH - : ViewType.valueOf(vpack.getAsString().toUpperCase(Locale.ENGLISH)); + public static final VPackDeserializer VIEW_TYPE = (parent, vpack, context) -> { + String value = vpack.getAsString(); + switch (value) { + case "arangosearch": + return ViewType.ARANGO_SEARCH; + case "search-alias": + return ViewType.SEARCH_ALIAS; + default: + throw new IllegalArgumentException("Unknown view type: " + value); + } + }; public static final VPackDeserializer STORED_VALUE = (parent, vpack, context) -> { VPackSlice fields = vpack.get("fields"); @@ -340,4 +339,18 @@ protected static FieldLink deserializeField(final Entry fiel InvertedIndexPrimarySort.Field.Direction.asc : InvertedIndexPrimarySort.Field.Direction.desc; return new InvertedIndexPrimarySort.Field(vpack.get("field").getAsString(), dir); }; + + public static final VPackDeserializer SEARCH_ALIAS_PROPERTIES_ENTITY = (parent, vpack, context) -> { + String id = vpack.get("id").getAsString(); + String name = vpack.get("name").getAsString(); + ViewType type = context.deserialize(vpack.get("type"), ViewType.class); + SearchAliasProperties properties = context.deserialize(vpack, SearchAliasProperties.class); + return new SearchAliasPropertiesEntity(id, name, type, properties); + }; + + public static final VPackDeserializer SEARCH_ALIAS_INDEX = (parent, vpack, context) -> { + String collection = vpack.get("collection").getAsString(); + String index = vpack.get("index").getAsString(); + return new SearchAliasIndex(collection, index); + }; } diff --git a/src/main/java/com/arangodb/internal/velocypack/VPackDriverModule.java b/src/main/java/com/arangodb/internal/velocypack/VPackDriverModule.java index 0cccb9893..79311d745 100644 --- a/src/main/java/com/arangodb/internal/velocypack/VPackDriverModule.java +++ b/src/main/java/com/arangodb/internal/velocypack/VPackDriverModule.java @@ -20,6 +20,7 @@ package com.arangodb.internal.velocypack; +import com.arangodb.SearchAlias; import com.arangodb.entity.*; import com.arangodb.entity.arangosearch.*; import com.arangodb.entity.arangosearch.analyzer.SearchAnalyzer; @@ -79,6 +80,7 @@ public > void setup(final C context) { context.registerSerializer(ViewType.class, VPackSerializers.VIEW_TYPE); context.registerSerializer(ArangoSearchPropertiesOptions.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES_OPTIONS); context.registerSerializer(ArangoSearchProperties.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES); + context.registerSerializer(SearchAliasProperties.class, VPackSerializers.SEARCH_ALIAS_PROPERTIES); context.registerSerializer(ConsolidationType.class, VPackSerializers.CONSOLIDATE_TYPE); context.registerSerializer(CollectionSchema.class, VPackSerializers.COLLECTION_VALIDATION); context.registerSerializer(ZKDIndexOptions.FieldValueTypes.class, VPackSerializers.ZKD_FIELD_VALUE_TYPES); @@ -104,6 +106,8 @@ public > void setup(final C context) { context.registerDeserializer(CollectionSchema.class, VPackDeserializers.COLLECTION_VALIDATION); context.registerDeserializer(ZKDIndexOptions.FieldValueTypes.class, VPackDeserializers.ZKD_FIELD_VALUE_TYPES); context.registerDeserializer(InvertedIndexPrimarySort.Field.class, VPackDeserializers.INVERTED_INDEX_PRIMARY_SORT_FIELD); + context.registerDeserializer(SearchAliasPropertiesEntity.class, VPackDeserializers.SEARCH_ALIAS_PROPERTIES_ENTITY); + context.registerDeserializer(SearchAliasIndex.class, VPackDeserializers.SEARCH_ALIAS_INDEX); } @Override diff --git a/src/main/java/com/arangodb/internal/velocypack/VPackSerializers.java b/src/main/java/com/arangodb/internal/velocypack/VPackSerializers.java index 467b1add6..1a4d48f55 100644 --- a/src/main/java/com/arangodb/internal/velocypack/VPackSerializers.java +++ b/src/main/java/com/arangodb/internal/velocypack/VPackSerializers.java @@ -30,6 +30,7 @@ import com.arangodb.model.TraversalOptions.Order; import com.arangodb.model.ZKDIndexOptions; import com.arangodb.model.arangosearch.ArangoSearchPropertiesOptions; +import com.arangodb.model.arangosearch.SearchAliasCreateOptions; import com.arangodb.velocypack.*; import com.arangodb.velocystream.Request; @@ -131,8 +132,13 @@ public class VPackSerializers { }; public static final VPackSerializer VIEW_TYPE = (builder, attribute, value, context) -> { - final String type = value == ViewType.ARANGO_SEARCH ? "arangosearch" : value.name().toLowerCase(Locale.ENGLISH); - builder.add(attribute, type); + if (value == ViewType.ARANGO_SEARCH) { + builder.add(attribute, "arangosearch"); + } else if (value == ViewType.SEARCH_ALIAS) { + builder.add(attribute, "search-alias"); + } else { + throw new IllegalArgumentException(); + } }; public static final VPackSerializer ARANGO_SEARCH_PROPERTIES_OPTIONS = (builder, attribute, value, context) -> { @@ -183,6 +189,10 @@ public class VPackSerializers { if (storeValues != null) { builder.add("storeValues", storeValues.name().toLowerCase(Locale.ENGLISH)); } + Boolean inBackground = collectionLink.getInBackground(); + if (inBackground != null) { + builder.add("inBackground", inBackground); + } serializeFieldLinks(builder, collectionLink.getFields()); serializeNested(builder, collectionLink.getNested()); builder.close(); @@ -227,6 +237,15 @@ public class VPackSerializers { }; + public static final VPackSerializer SEARCH_ALIAS_PROPERTIES = (builder, attribute, value, context) -> { + Collection indexes = value.getIndexes(); + builder.add("indexes", ValueType.ARRAY); + for (SearchAliasIndex index : indexes) { + context.serialize(builder, null, index); + } + builder.close(); + }; + private static void serializeFieldLinks(final VPackBuilder builder, final Collection links) { if (!links.isEmpty()) { builder.add("fields", ValueType.OBJECT); @@ -266,6 +285,10 @@ private static void serializeFields(final VPackBuilder builder, final Collection if (storeValues != null) { builder.add("storeValues", storeValues.name().toLowerCase(Locale.ENGLISH)); } + Boolean inBackground = fieldLink.getInBackground(); + if (inBackground != null) { + builder.add("inBackground", inBackground); + } serializeFieldLinks(builder, fieldLink.getFields()); serializeNested(builder, fieldLink.getNested()); builder.close(); diff --git a/src/main/java/com/arangodb/model/arangosearch/SearchAliasCreateOptions.java b/src/main/java/com/arangodb/model/arangosearch/SearchAliasCreateOptions.java new file mode 100644 index 000000000..280e7e3d1 --- /dev/null +++ b/src/main/java/com/arangodb/model/arangosearch/SearchAliasCreateOptions.java @@ -0,0 +1,56 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model.arangosearch; + +import com.arangodb.entity.ViewType; +import com.arangodb.entity.arangosearch.*; + +/** + * @author Michele Rastelli + * @since ArangoDB 3.10 + */ +public class SearchAliasCreateOptions { + + private String name; + private final ViewType type; + private final SearchAliasProperties properties; + + public SearchAliasCreateOptions() { + super(); + type = ViewType.SEARCH_ALIAS; + properties = new SearchAliasProperties(); + } + + protected SearchAliasCreateOptions name(final String name) { + this.name = name; + return this; + } + + /** + * @param indexes A list of inverted indexes to add to the View. + * @return options + */ + public SearchAliasCreateOptions indexes(final SearchAliasIndex... indexes) { + properties.addIndexes(indexes); + return this; + } + +} diff --git a/src/main/java/com/arangodb/model/arangosearch/SearchAliasOptionsBuilder.java b/src/main/java/com/arangodb/model/arangosearch/SearchAliasOptionsBuilder.java new file mode 100644 index 000000000..155e916be --- /dev/null +++ b/src/main/java/com/arangodb/model/arangosearch/SearchAliasOptionsBuilder.java @@ -0,0 +1,35 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model.arangosearch; + +/** + * @author Michele Rastelli + */ +public abstract class SearchAliasOptionsBuilder { + + private SearchAliasOptionsBuilder() { + super(); + } + + public static SearchAliasCreateOptions build(final SearchAliasCreateOptions options, final String name) { + return options.name(name); + } +} diff --git a/src/main/java/com/arangodb/model/arangosearch/SearchAliasPropertiesOptions.java b/src/main/java/com/arangodb/model/arangosearch/SearchAliasPropertiesOptions.java new file mode 100644 index 000000000..93a3eff6b --- /dev/null +++ b/src/main/java/com/arangodb/model/arangosearch/SearchAliasPropertiesOptions.java @@ -0,0 +1,51 @@ +/* + * DISCLAIMER + * + * Copyright 2018 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model.arangosearch; + +import com.arangodb.entity.arangosearch.*; + +/** + * @author Michele Rastelli + * @since ArangoDB 3.10 + */ +public class SearchAliasPropertiesOptions { + + private final SearchAliasProperties properties; + + public SearchAliasPropertiesOptions() { + super(); + properties = new SearchAliasProperties(); + } + + public SearchAliasProperties getProperties() { + return properties; + } + + /** + * @param indexes A list of inverted indexes to add to the View. + * @return options + */ + public SearchAliasPropertiesOptions indexes(SearchAliasIndex... indexes) { + properties.addIndexes(indexes); + return this; + } + +} diff --git a/src/test/java/com/arangodb/ArangoSearchTest.java b/src/test/java/com/arangodb/ArangoSearchTest.java index cb4489ca8..705b81ff6 100644 --- a/src/test/java/com/arangodb/ArangoSearchTest.java +++ b/src/test/java/com/arangodb/ArangoSearchTest.java @@ -20,14 +20,15 @@ package com.arangodb; +import com.arangodb.entity.InvertedIndexField; import com.arangodb.entity.ViewEntity; import com.arangodb.entity.ViewType; import com.arangodb.entity.arangosearch.*; import com.arangodb.entity.arangosearch.analyzer.*; -import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; -import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; -import com.arangodb.model.arangosearch.ArangoSearchPropertiesOptions; +import com.arangodb.model.InvertedIndexOptions; +import com.arangodb.model.arangosearch.*; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -51,6 +52,11 @@ static void init() { initCollections(COLL_1, COLL_2); } + @BeforeEach + void setUp() { + assumeTrue(isLessThanVersion(3, 10) || isSingleServer()); + } + @ParameterizedTest(name = "{index}") @MethodSource("dbs") void exists(ArangoDatabase db) { @@ -60,6 +66,15 @@ void exists(ArangoDatabase db) { assertThat(db.arangoSearch(viewName).exists()).isTrue(); } + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void createAndExistsSearchAlias(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + db.createSearchAlias(viewName, new SearchAliasCreateOptions()); + assertThat(db.arangoSearch(viewName).exists()).isTrue(); + } + @ParameterizedTest(name = "{index}") @MethodSource("dbs") void getInfo(ArangoDatabase db) { @@ -99,7 +114,7 @@ void rename(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void create(ArangoDatabase db) { + void createArangoSearchView(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); final ViewEntity info = db.arangoSearch(viewName).create(); @@ -112,7 +127,20 @@ void create(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void createWithOptions(ArangoDatabase db) { + void createSearchAliasView(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + final ViewEntity info = db.searchAlias(viewName).create(); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(db.searchAlias(viewName).exists()).isTrue(); + } + + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void createArangoSearchViewWithOptions(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); final ArangoSearchCreateOptions options = new ArangoSearchCreateOptions(); @@ -126,7 +154,7 @@ void createWithOptions(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void createWithPrimarySort(ArangoDatabase db) { + void createArangoSearchViewWithPrimarySort(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 5)); String viewName = "view-" + rnd(); final ArangoSearchCreateOptions options = new ArangoSearchCreateOptions(); @@ -162,7 +190,7 @@ void createWithPrimarySort(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void createWithCommitIntervalMsec(ArangoDatabase db) { + void createArangoSearchViewWithCommitIntervalMsec(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 5)); String viewName = "view-" + rnd(); final ArangoSearchCreateOptions options = new ArangoSearchCreateOptions(); @@ -183,7 +211,50 @@ void createWithCommitIntervalMsec(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void getProperties(ArangoDatabase db) { + void createSearchAliasViewWithOptions(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions(); + final ViewEntity info = db.searchAlias(viewName).create(options); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(db.searchAlias(viewName).exists()).isTrue(); + } + + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void createSearchAliasViewWithIndexesAndGetProperties(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollection col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))); + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .anyMatch(i -> i.getCollection().equals(COLL_1) && i.getIndex().equals(idxName)); + } + + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void getArangoSearchViewProperties(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); final ArangoSearch view = db.arangoSearch(viewName); @@ -203,7 +274,7 @@ void getProperties(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void updateProperties(ArangoDatabase db) { + void updateArangoSearchViewProperties(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); final ArangoSearch view = db.arangoSearch(viewName); @@ -236,7 +307,47 @@ void updateProperties(ArangoDatabase db) { @ParameterizedTest(name = "{index}") @MethodSource("dbs") - void replaceProperties(ArangoDatabase db) { + void updateSearchAliasViewWithIndexesAndGetProperties(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollection col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))); + ArangoCollection col2 = db.collection(COLL_2); + String idxName2 = "idx-" + rnd(); + col2.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName2) + .fields(new InvertedIndexField().name("a" + rnd()))); + + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options); + db.searchAlias(viewName).updateProperties(new SearchAliasPropertiesOptions() + .indexes(new SearchAliasIndex(COLL_2, idxName2))); + + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .hasSize(2) + .anyMatch(i -> i.getCollection().equals(COLL_1) && i.getIndex().equals(idxName)) + .anyMatch(i -> i.getCollection().equals(COLL_2) && i.getIndex().equals(idxName2)); + } + + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void replaceArangoSearchViewProperties(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); final ArangoSearch view = db.arangoSearch(viewName); @@ -253,6 +364,45 @@ void replaceProperties(ArangoDatabase db) { assertThat(link.getFields().iterator().next().getName()).isEqualTo("value"); } + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void replaceSearchAliasViewWithIndexesAndGetProperties(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollection col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))); + ArangoCollection col2 = db.collection(COLL_2); + String idxName2 = "idx-" + rnd(); + col2.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName2) + .fields(new InvertedIndexField().name("a" + rnd()))); + + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options); + db.searchAlias(viewName).replaceProperties(new SearchAliasPropertiesOptions() + .indexes(new SearchAliasIndex(COLL_2, idxName2))); + + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .hasSize(1) + .anyMatch(i -> i.getCollection().equals(COLL_2) && i.getIndex().equals(idxName2)); + } + private void createGetAndDeleteAnalyzer(ArangoDatabase db, AnalyzerEntity options) { String fullyQualifiedName = db.dbName().get() + "::" + options.getName(); @@ -754,7 +904,7 @@ void enhancedTextAnalyzerTyped(ArangoDatabase db) { void arangoSearchOptions(ArangoDatabase db) { assumeTrue(isAtLeastVersion(3, 4)); String viewName = "view-" + rnd(); - FieldLink field = FieldLink.on("f1"); + FieldLink field = FieldLink.on("f1").inBackground(true); if (isEnterprise()) { field.nested(FieldLink.on("f2")); } @@ -763,7 +913,8 @@ void arangoSearchOptions(ArangoDatabase db) { .fields(field) .includeAllFields(true) .storeValues(StoreValuesType.ID) - .trackListPositions(false); + .trackListPositions(false) + .inBackground(true); if (isEnterprise()) { link.nested(FieldLink.on("f3")); } diff --git a/src/test/java/com/arangodb/ArangoViewTest.java b/src/test/java/com/arangodb/ArangoViewTest.java index 5d63b02ac..09121b7ff 100644 --- a/src/test/java/com/arangodb/ArangoViewTest.java +++ b/src/test/java/com/arangodb/ArangoViewTest.java @@ -26,6 +26,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import java.util.Collection; + import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -61,6 +63,31 @@ void getInfo(ArangoDatabase db) { assertThat(info.getType()).isEqualTo(ViewType.ARANGO_SEARCH); } + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void getInfoSearchAlias(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + String name = "view-" + rnd(); + db.createView(name, ViewType.SEARCH_ALIAS); + final ViewEntity info = db.view(name).getInfo(); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(name); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + } + + @ParameterizedTest(name = "{index}") + @MethodSource("dbs") + void getViews(ArangoDatabase db) { + assumeTrue(isAtLeastVersion(3, 10)); + String name1 = "view-" + rnd(); + String name2 = "view-" + rnd(); + db.createView(name1, ViewType.ARANGO_SEARCH); + db.createView(name2, ViewType.SEARCH_ALIAS); + Collection views = db.getViews(); + assertThat(views).extracting(ViewEntity::getName).contains(name1, name2); + } + @ParameterizedTest(name = "{index}") @MethodSource("dbs") void drop(ArangoDatabase db) { diff --git a/src/test/java/com/arangodb/async/ArangoSearchTest.java b/src/test/java/com/arangodb/async/ArangoSearchTest.java index 47c183b54..ba382509e 100644 --- a/src/test/java/com/arangodb/async/ArangoSearchTest.java +++ b/src/test/java/com/arangodb/async/ArangoSearchTest.java @@ -20,16 +20,21 @@ package com.arangodb.async; +import com.arangodb.ArangoCollection; import com.arangodb.ArangoDBException; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.InvertedIndexField; import com.arangodb.entity.ViewEntity; import com.arangodb.entity.ViewType; import com.arangodb.entity.arangosearch.*; import com.arangodb.entity.arangosearch.analyzer.*; -import com.arangodb.model.arangosearch.AnalyzerDeleteOptions; -import com.arangodb.model.arangosearch.ArangoSearchCreateOptions; -import com.arangodb.model.arangosearch.ArangoSearchPropertiesOptions; +import com.arangodb.model.InvertedIndexOptions; +import com.arangodb.model.arangosearch.*; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.util.*; import java.util.concurrent.ExecutionException; @@ -45,12 +50,21 @@ class ArangoSearchTest extends BaseTest { private static final String VIEW_NAME = "view_test"; + private static final String COLL_1 = "view_update_prop_test_collection"; + private static final String COLL_2 = "view_replace_prop_test_collection"; @BeforeAll static void setup() throws InterruptedException, ExecutionException { if (!isAtLeastVersion(arangoDB, 3, 4)) return; db.createArangoSearch(VIEW_NAME, new ArangoSearchCreateOptions()).get(); + db.createCollection(COLL_1).get(); + db.createCollection(COLL_2).get(); + } + + @BeforeEach + void setUp() throws ExecutionException, InterruptedException { + assumeTrue(isLessThanVersion(3, 10) || isSingleServer()); } @Test @@ -59,6 +73,14 @@ void exists() throws InterruptedException, ExecutionException { assertThat(db.arangoSearch(VIEW_NAME).exists().get()).isTrue(); } + @Test + void createAndExistsSearchAlias() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + db.createSearchAlias(viewName, new SearchAliasCreateOptions()).get(); + assertThat(db.arangoSearch(viewName).exists().get()).isTrue(); + } + @Test void getInfo() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); @@ -92,7 +114,7 @@ void rename() throws InterruptedException, ExecutionException { } @Test - void create() throws InterruptedException, ExecutionException { + void createArangoSearchView() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); final String name = VIEW_NAME + "_createtest"; final ViewEntity info = db.arangoSearch(name).create().get(); @@ -104,7 +126,19 @@ void create() throws InterruptedException, ExecutionException { } @Test - void createWithOptions() throws InterruptedException, ExecutionException { + void createSearchAliasView() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + final ViewEntity info = db.searchAlias(viewName).create().get(); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(db.searchAlias(viewName).exists().get()).isTrue(); + } + + @Test + void createArangoSearchViewWithOptions() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); final String name = VIEW_NAME + "_createtest_withotpions"; final ViewEntity info = db.arangoSearch(name).create(new ArangoSearchCreateOptions()).get(); @@ -116,7 +150,7 @@ void createWithOptions() throws InterruptedException, ExecutionException { } @Test - void createWithPrimarySort() throws ExecutionException, InterruptedException { + void createArangoSearchViewWithPrimarySort() throws ExecutionException, InterruptedException { assumeTrue(isAtLeastVersion(3, 5)); final String name = "createWithPrimarySort"; final ArangoSearchCreateOptions options = new ArangoSearchCreateOptions(); @@ -135,7 +169,7 @@ void createWithPrimarySort() throws ExecutionException, InterruptedException { } @Test - void createWithCommitIntervalMsec() throws ExecutionException, InterruptedException { + void createArangoSearchViewWithCommitIntervalMsec() throws ExecutionException, InterruptedException { assumeTrue(isAtLeastVersion(3, 5)); final String name = "createWithCommitIntervalMsec"; final ArangoSearchCreateOptions options = new ArangoSearchCreateOptions(); @@ -155,7 +189,49 @@ void createWithCommitIntervalMsec() throws ExecutionException, InterruptedExcept } @Test - void getProperties() throws InterruptedException, ExecutionException { + void createSearchAliasViewWithOptions() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions(); + final ViewEntity info = db.searchAlias(viewName).create(options).get(); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(db.searchAlias(viewName).exists().get()).isTrue(); + } + + @Test + void createSearchAliasViewWithIndexesAndGetProperties() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollectionAsync col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))) + .get(); + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options).get(); + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties().get(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .anyMatch(i -> i.getCollection().equals(COLL_1) && i.getIndex().equals(idxName)); + } + + @Test + void getArangoSearchViewProperties() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); final String name = VIEW_NAME + "_getpropertiestest"; final ArangoSearchAsync view = db.arangoSearch(name); @@ -174,9 +250,8 @@ void getProperties() throws InterruptedException, ExecutionException { } @Test - void updateProperties() throws InterruptedException, ExecutionException { + void updateArangoSearchViewProperties() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); - db.createCollection("view_update_prop_test_collection").get(); final String name = VIEW_NAME + "_updatepropertiestest"; final ArangoSearchAsync view = db.arangoSearch(name); view.create(new ArangoSearchCreateOptions()).get(); @@ -207,9 +282,49 @@ void updateProperties() throws InterruptedException, ExecutionException { } @Test - void replaceProperties() throws InterruptedException, ExecutionException { + void updateSearchAliasViewWithIndexesAndGetProperties() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollectionAsync col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))) + .get(); + ArangoCollectionAsync col2 = db.collection(COLL_2); + String idxName2 = "idx-" + rnd(); + col2.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName2) + .fields(new InvertedIndexField().name("a" + rnd()))) + .get(); + + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options).get(); + db.searchAlias(viewName).updateProperties(new SearchAliasPropertiesOptions() + .indexes(new SearchAliasIndex(COLL_2, idxName2))); + + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties().get(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .hasSize(2) + .anyMatch(i -> i.getCollection().equals(COLL_1) && i.getIndex().equals(idxName)) + .anyMatch(i -> i.getCollection().equals(COLL_2) && i.getIndex().equals(idxName2)); + } + + @Test + void replaceArangoSearchViewProperties() throws InterruptedException, ExecutionException { assumeTrue(isAtLeastVersion(3, 4)); - db.createCollection("view_replace_prop_test_collection").get(); final String name = VIEW_NAME + "_replacepropertiestest"; final ArangoSearchAsync view = db.arangoSearch(name); view.create(new ArangoSearchCreateOptions()).get(); @@ -225,6 +340,46 @@ void replaceProperties() throws InterruptedException, ExecutionException { assertThat(link.getFields().iterator().next().getName()).isEqualTo("value"); } + @Test + void replaceSearchAliasViewWithIndexesAndGetProperties() throws ExecutionException, InterruptedException { + assumeTrue(isAtLeastVersion(3, 10)); + ArangoCollectionAsync col = db.collection(COLL_1); + String idxName = "idx-" + rnd(); + col.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName) + .fields(new InvertedIndexField().name("a" + rnd()))) + .get(); + ArangoCollectionAsync col2 = db.collection(COLL_2); + String idxName2 = "idx-" + rnd(); + col2.ensureInvertedIndex(new InvertedIndexOptions() + .name(idxName2) + .fields(new InvertedIndexField().name("a" + rnd()))) + .get(); + + String viewName = "view-" + rnd(); + final SearchAliasCreateOptions options = new SearchAliasCreateOptions() + .indexes(new SearchAliasIndex(COLL_1, idxName)); + final ViewEntity info = db.searchAlias(viewName).create(options).get(); + db.searchAlias(viewName).replaceProperties(new SearchAliasPropertiesOptions() + .indexes(new SearchAliasIndex(COLL_2, idxName2))); + + assertThat(info).isNotNull(); + assertThat(info.getId()).isNotNull(); + assertThat(info.getName()).isEqualTo(viewName); + assertThat(info.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + + final SearchAliasPropertiesEntity properties = db.searchAlias(viewName).getProperties().get(); + assertThat(properties).isNotNull(); + assertThat(properties.getId()).isNotNull(); + assertThat(properties.getName()).isEqualTo(viewName); + assertThat(properties.getType()).isEqualTo(ViewType.SEARCH_ALIAS); + assertThat(properties.getIndexes()) + .isNotNull() + .isNotEmpty() + .hasSize(1) + .anyMatch(i -> i.getCollection().equals(COLL_2) && i.getIndex().equals(idxName2)); + } + private void createGetAndDeleteTypedAnalyzer(SearchAnalyzer analyzer) throws ExecutionException, InterruptedException { String fullyQualifiedName = db.dbName().get() + "::" + analyzer.getName(); diff --git a/src/test/java/com/arangodb/async/BaseTest.java b/src/test/java/com/arangodb/async/BaseTest.java index db4f312aa..e5bb2d11c 100644 --- a/src/test/java/com/arangodb/async/BaseTest.java +++ b/src/test/java/com/arangodb/async/BaseTest.java @@ -25,6 +25,7 @@ import com.arangodb.entity.License; import com.arangodb.entity.ServerRole; import com.arangodb.mapping.ArangoJack; +import com.arangodb.util.TestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -84,6 +85,14 @@ protected boolean isAtLeastVersion(final int major, final int minor) throws Inte return isAtLeastVersion(major, minor, 0); } + boolean isLessThanVersion(final int major, final int minor) throws ExecutionException, InterruptedException { + return isLessThanVersion(major, minor, 0); + } + + boolean isLessThanVersion(final int major, final int minor, final int patch) throws ExecutionException, InterruptedException { + return TestUtils.isLessThanVersion(db.getVersion().get().getVersion(), major, minor, patch); + } + boolean isStorageEngine(ArangoDBEngine.StorageEngineName name) throws ExecutionException, InterruptedException { return name.equals(db.getEngine().get().getName()); }