[15x] Remove ElasticSearch support

This commit is contained in:
Rob Bygrave
2023-10-10 23:45:08 +13:00
parent c0ebfbc4e0
commit cd0c066431
159 changed files with 34 additions and 7768 deletions
@@ -1321,11 +1321,6 @@ public interface Database {
*/
ScriptRunner script();
/**
* Return the Document store.
*/
DocumentStore docStore();
/**
* Returns the set of properties/paths that are unknown (do not map to known properties or paths).
* <p>
@@ -1,94 +0,0 @@
package io.ebean;
/**
* Bean holding the details to update the document store.
*/
public final class DocStoreQueueEntry {
/**
* Action to either update or delete a document from the index.
*/
public enum Action {
/**
* Action is to update a document in the doc store.
*/
INDEX(1),
/**
* Action is to delete a document from the doc store..
*/
DELETE(2),
/**
* An update is required based on a change to a nested/embedded object at a given path.
*/
NESTED(3);
int value;
Action(int value) {
this.value = value;
}
/**
* Return the value associated with this action type.
*/
public int getValue() {
return value;
}
}
private final Action type;
private final String queueId;
private final String path;
private final Object beanId;
/**
* Construct for an INDEX or DELETE action.
*/
public DocStoreQueueEntry(Action type, String queueId, Object beanId) {
this(type, queueId, null, beanId);
}
/**
* Construct for an NESTED/embedded path invalidation action.
*/
public DocStoreQueueEntry(Action type, String queueId, String path, Object beanId) {
this.type = type;
this.queueId = queueId;
this.path = path;
this.beanId = beanId;
}
/**
* Return the event type.
*/
public Action getType() {
return type;
}
/**
* Return the associate queueId.
*/
public String getQueueId() {
return queueId;
}
/**
* Return the path if this is a nested update.
*/
public String getPath() {
return path;
}
/**
* Return the bean id (which matches the document id).
*/
public Object getBeanId() {
return beanId;
}
}
@@ -1,312 +0,0 @@
package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.docstore.DocQueryContext;
import io.ebean.docstore.RawDoc;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* Document storage operations.
*/
@NonNullApi
public interface DocumentStore {
/**
* Update the associated document store using the result of the query.
* <p>
* This will execute the query against the database creating a document for each
* bean graph and sending this to the document store.
* </p>
* <p>
* Note that the select and fetch paths of the query is set for you to match the
* document structure needed based on <code>@DocStore</code> and <code>@DocStoreEmbedded</code>
* so what this query requires is the predicates only.
* </p>
* <p>
* This query will be executed using findEach so it is safe to use a query
* that will fetch a lot of beans. The default bulkBatchSize is used.
* </p>
*
* @param query The query that selects object to send to the document store.
*/
<T> void indexByQuery(Query<T> query);
/**
* Update the associated document store index using the result of the query additionally specifying a
* bulkBatchSize to use for sending the messages to ElasticSearch.
*
* @param query The query that selects object to send to the document store.
* @param bulkBatchSize The batch size to use when bulk sending to the document store.
*/
<T> void indexByQuery(Query<T> query, int bulkBatchSize);
/**
* Update the document store for all beans of this type.
* <p>
* This is the same as indexByQuery where the query has no predicates and so fetches all rows.
* </p>
*/
void indexAll(Class<?> beanType);
/**
* Return the bean by fetching it's content from the document store.
* If the document is not found null is returned.
* <p>
* Typically this is called indirectly by findOne() on the query.
* </p>
* <pre>{@code
*
* Customer customer =
* database.find(Customer.class)
* .setUseDocStore(true)
* .setId(42)
* .findOne();
*
* }</pre>
*/
@Nullable
<T> T find(DocQueryContext<T> request);
/**
* Execute the find list query. This request is prepared to execute secondary queries.
* <p>
* Typically this is called indirectly by findList() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* List<Customer> newCustomers =
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .findList();
*
* }</pre>
*/
<T> List<T> findList(DocQueryContext<T> request);
/**
* Execute the query against the document store returning the paged list.
* <p>
* The query should have <code>firstRow</code> or <code>maxRows</code> set prior to calling this method.
* </p>
* <p>
* Typically this is called indirectly by findPagedList() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* PagedList<Customer> newCustomers =
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .setMaxRows(50)
* .findPagedList();
*
* }</pre>
*/
<T> PagedList<T> findPagedList(DocQueryContext<T> request);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEach() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEach((Order order) -> {
* // process the bean ...
* });
*
* }</pre>
*/
<T> void findEach(DocQueryContext<T> query, Consumer<T> consumer);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* Unlike findEach() this provides the opportunity to stop iterating through the large query.
* </p>
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEachWhile() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new Predicate<Order>() {
* @Override
* public void accept(Order bean) {
* // process the bean
*
* // return true to continue, false to stop
* // boolean shouldContinue = ...
* return shouldContinue;
* }
* });
*
* }</pre>
*/
<T> void findEachWhile(DocQueryContext<T> query, Predicate<T> consumer);
/**
* Find each processing raw documents.
*
* @param indexNameType The full index name and type
* @param rawQuery The query to execute
* @param consumer Consumer to process each document
*/
void findEach(String indexNameType, String rawQuery, Consumer<RawDoc> consumer);
/**
* Find each processing raw documents stopping when the predicate returns false.
*
* @param indexNameType The full index name and type
* @param rawQuery The query to execute
* @param consumer Consumer to process each document until false is returned
*/
void findEachWhile(String indexNameType, String rawQuery, Predicate<RawDoc> consumer);
/**
* Process the queue entries sending updates to the document store or queuing them for later processing.
*/
long process(List<DocStoreQueueEntry> queueEntries) throws IOException;
/**
* Drop the index from the document store (similar to DDL drop table).
* <pre>{@code
*
* DocumentStore documentStore = database.docStore();
*
* documentStore.dropIndex("product_copy");
*
* }</pre>
*/
void dropIndex(String indexName);
/**
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
* <pre>{@code
*
* DocumentStore documentStore = database.docStore();
*
* // uses product_copy.mapping.json resource
* // ... to define mappings for the index
*
* documentStore.createIndex("product_copy", null);
*
* }</pre>
*
* @param indexName the name of the new index
* @param alias the alias of the index
*/
void createIndex(String indexName, String alias);
/**
* Modify the settings on an index.
* <p>
* For example, this can be used be used to set elasticSearch refresh_interval
* on an index before a bulk update.
* </p>
* <pre>{@code
*
* // refresh_interval -1 ... disable refresh while bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "-1");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
* <pre>{@code
*
* // refresh_interval 1s ... restore after bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "1s");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* @param indexName the name of the index to update settings on
* @param settings the settings to set on the index
*/
void indexSettings(String indexName, Map<String, Object> settings);
/**
* Copy the index to a new index.
* <p>
* This copy process does not use the database but instead will copy from the source index to a destination index.
* </p>
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy");
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex);
/**
* Copy entries from an index to a new index but limiting to documents that have been
* modified since the sinceEpochMillis time.
* <p>
* To support this the document needs to have a <code>@WhenModified</code> property.
* </p>
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy", sinceMillis);
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex, long sinceEpochMillis);
/**
* Copy from a source index to a new index taking only the documents
* matching the given query.
* <pre>{@code
*
* // predicates to select the source documents to copy
* Query<Product> query = database.find(Product.class)
* .where()
* .ge("whenModified", new Timestamp(since))
* .ge("name", "A")
* .lt("name", "D")
* .query();
*
* // copy from the source index to "product_copy" index
* long copyCount = documentStore.copyIndex(query, "product_copy", 1000);
*
* }</pre>
*
* @param query The query to select the source documents to copy
* @param newIndex The target index to copy the documents to
* @param bulkBatchSize The ElasticSearch bulk batch size, if 0 uses the default.
* @return The number of documents copied to the new index.
*/
long copyIndex(Query<?> query, String newIndex, int bulkBatchSize);
}
@@ -1,7 +1,5 @@
package io.ebean;
import io.ebean.search.*;
import java.util.Collection;
import java.util.Map;
@@ -625,31 +623,6 @@ public interface ExpressionFactory {
*/
Expression raw(String raw);
/**
* Create a Text Match expression (currently doc store/Elastic only).
*/
Expression textMatch(String propertyName, String search, Match options);
/**
* Create a Text Multi match expression (currently doc store/Elastic only).
*/
Expression textMultiMatch(String query, MultiMatch options);
/**
* Create a text simple query expression (currently doc store/Elastic only).
*/
Expression textSimple(String search, TextSimple options);
/**
* Create a text query string expression (currently doc store/Elastic only).
*/
Expression textQueryString(String search, TextQueryString options);
/**
* Create a text common terms expression (currently doc store/Elastic only).
*/
Expression textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -2,7 +2,6 @@ package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.search.*;
import jakarta.persistence.NonUniqueResultException;
import java.sql.Connection;
@@ -553,19 +552,6 @@ public interface ExpressionList<T> {
*/
Query<T> setDistinct(boolean distinct);
/**
* Set the index(es) to search for a document store which uses partitions.
* <p>
* For example, when executing a query against ElasticSearch with daily indexes we can
* explicitly specify the indexes to search against.
* </p>
*
* @param indexName The index or indexes to search against
* @return This query
* @see Query#setDocIndexName(String)
*/
Query<T> setDocIndexName(String indexName);
/**
* Set the first row to fetch.
*
@@ -649,14 +635,6 @@ public interface ExpressionList<T> {
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
}
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocsStore);
/**
* Set true if you want to disable lazy loading.
* <p>
@@ -1578,47 +1556,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
/**
* Add a match expression.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search);
/**
* Add a match expression with options.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search, Match options);
/**
* Add a multi-match expression.
*/
ExpressionList<T> multiMatch(String search, String... properties);
/**
* Add a multi-match expression using options.
*/
ExpressionList<T> multiMatch(String search, MultiMatch options);
/**
* Add a simple query string expression.
*/
ExpressionList<T> textSimple(String search, TextSimple options);
/**
* Add a query string expression.
*/
ExpressionList<T> textQueryString(String search, TextQueryString options);
/**
* Add common terms expression.
*/
ExpressionList<T> textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -1761,42 +1698,6 @@ public interface ExpressionList<T> {
*/
Junction<T> disjunction();
/**
* Start a list of expressions that will be joined by MUST.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to and().
* </p>
*/
Junction<T> must();
/**
* Start a list of expressions that will be joined by SHOULD.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to or().
* </p>
*/
Junction<T> should();
/**
* Start a list of expressions that will be joined by MUST NOT.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to not().
* </p>
*/
Junction<T> mustNot();
/**
* End a junction returning the parent expression list.
* <p>
@@ -316,43 +316,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> setPersistenceContextScope(PersistenceContextScope scope);
/**
* Set the index(es) to search for a document store which uses partitions.
* <p>
* For example, when executing a query against ElasticSearch with daily indexes we can
* explicitly specify the indexes to search against.
* </p>
* <pre>{@code
*
* // explicitly specify the indexes to search
* query.setDocIndexName("logstash-2016.11.5,logstash-2016.11.6")
*
* // search today's index
* query.setDocIndexName("$today")
*
* // search the last 3 days
* query.setDocIndexName("$last-3")
*
* }</pre>
* <p>
* If the indexName is specified with ${daily} e.g. "logstash-${daily}" ... then we can use
* $today and $last-x as the search docIndexName like the examples below.
* </p>
* <pre>{@code
*
* // search today's index
* query.setDocIndexName("$today")
*
* // search the last 3 days
* query.setDocIndexName("$last-3")
*
* }</pre>
*
* @param indexName The index or indexes to search against
* @return This query
*/
Query<T> setDocIndexName(String indexName);
/**
* Return the ExpressionFactory used by this query.
*/
@@ -1288,27 +1251,6 @@ public interface Query<T> extends CancelableQuery {
*/
ExpressionList<T> where();
/**
* Add Full text search expressions for Document store queries.
* <p>
* This is currently ElasticSearch only and provides the full text
* expressions such as Match and Multi-Match.
* </p>
* <p>
* This automatically makes this query a "Doc Store" query and will execute
* against the document store (ElasticSearch).
* </p>
* <p>
* Expressions added here are added to the "query" section of an ElasticSearch
* query rather than the "filter" section.
* </p>
* <p>
* Expressions added to the where() are added to the "filter" section of an
* ElasticSearch query.
* </p>
*/
ExpressionList<T> text();
/**
* This applies a filter on the 'many' property list rather than the root
* level objects.
@@ -1567,14 +1509,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> setLabel(String label);
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocStore);
/**
* When set to true when you want the returned beans to be read only.
*/
@@ -1,9 +1,7 @@
package io.ebean;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DocStoreConfig;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -211,29 +209,6 @@ public interface Transaction extends AutoCloseable {
*/
boolean isActive();
/**
* Set the behavior for document store updates on this transaction.
* <p>
* For example, set the mode to DocStoreEvent.IGNORE for this transaction and
* then any changes via this transaction are not sent to the doc store. This
* would be used when doing large bulk inserts into the database and we want
* to control how that is sent to the document store.
* </p>
*/
void setDocStoreMode(DocStoreMode mode);
/**
* Set the batch size to use for sending messages to the document store.
* <p>
* You might set this if you know the changes in this transaction result in especially large or
* especially small payloads and want to adjust the batch size to match.
* </p>
* <p>
* Setting this overrides the default of {@link DocStoreConfig#getBulkBatchSize()}
* </p>
*/
void setDocStoreBatchSize(int batchSize);
/**
* Explicitly turn off or on the cascading nature of save() and delete(). This
* gives the developer exact control over what beans are saved and deleted
@@ -132,16 +132,6 @@ public class DatabaseConfig {
*/
private List<String> packages = new ArrayList<>();
/**
* Configuration for the ElasticSearch integration.
*/
private DocStoreConfig docStoreConfig = new DocStoreConfig();
/**
* Set to true when the Database only uses Document store.
*/
private boolean docStoreOnly;
/**
* This is used to populate @WhoCreated, @WhoModified and
* support other audit features (who executed a query etc).
@@ -1561,34 +1551,6 @@ public class DatabaseConfig {
}
}
/**
* Return true if this Database is a Document store only instance (has no JDBC DB).
*/
public boolean isDocStoreOnly() {
return docStoreOnly;
}
/**
* Set to true if this Database is Document store only instance (has no JDBC DB).
*/
public void setDocStoreOnly(boolean docStoreOnly) {
this.docStoreOnly = docStoreOnly;
}
/**
* Return the configuration for the ElasticSearch integration.
*/
public DocStoreConfig getDocStoreConfig() {
return docStoreConfig;
}
/**
* Set the configuration for the ElasticSearch integration.
*/
public void setDocStoreConfig(DocStoreConfig docStoreConfig) {
this.docStoreConfig = docStoreConfig;
}
/**
* Return the constraint naming convention used in DDL generation.
*/
@@ -2771,13 +2733,6 @@ public class DatabaseConfig {
readOnlyDataSourceConfig.loadSettings(p.properties, name + "-ro");
}
/**
* This is broken out to allow overridden behaviour.
*/
protected void loadDocStoreSettings(PropertiesWrapper p) {
docStoreConfig.loadSettings(p);
}
/**
* This is broken out to allow overridden behaviour.
*/
@@ -2809,11 +2764,6 @@ public class DatabaseConfig {
}
loadDataSourceSettings(p);
if (docStoreConfig == null) {
docStoreConfig = new DocStoreConfig();
}
loadDocStoreSettings(p);
defaultServer = p.getBoolean("defaultServer", defaultServer);
autoPersistUpdates = p.getBoolean("autoPersistUpdates", autoPersistUpdates);
loadModuleInfo = p.getBoolean("loadModuleInfo", loadModuleInfo);
@@ -2828,7 +2778,6 @@ public class DatabaseConfig {
queryPlanCapturePeriodSecs = p.getLong("queryPlan.capturePeriodSecs", queryPlanCapturePeriodSecs);
queryPlanCaptureMaxTimeMillis = p.getLong("queryPlan.captureMaxTimeMillis", queryPlanCaptureMaxTimeMillis);
queryPlanCaptureMaxCount = p.getInt("queryPlan.captureMaxCount", queryPlanCaptureMaxCount);
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
localOnlyL2Cache = p.getBoolean("localOnlyL2Cache", localOnlyL2Cache);
enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
@@ -1,320 +0,0 @@
package io.ebean.config;
import io.ebean.Transaction;
import io.ebean.annotation.DocStoreMode;
/**
* Configuration for the Document store integration (e.g. ElasticSearch).
*/
public class DocStoreConfig {
/**
* True when the Document store integration is active/on.
*/
protected boolean active;
/**
* Set to true means Ebean will generate mapping files on startup.
*/
protected boolean generateMapping;
/**
* When true the Document store should drop and re-create document indexes.
*/
protected boolean dropCreate;
/**
* When true the Document store should create any document indexes that don't already exist.
*/
protected boolean create;
/**
* The URL of the Document store. For example: http://localhost:9200.
*/
protected String url;
/**
* Credential that be used for authentication to document store.
*/
protected String username;
/**
* Password credential that be used for authentication to document store.
*/
protected String password;
/**
* Set to true such that the client allows connections to invalid/self signed SSL certificates.
*/
protected boolean allowAllCertificates;
/**
* The default mode used by indexes.
*/
protected DocStoreMode persist = DocStoreMode.UPDATE;
/**
* The default batch size to use for the Bulk API calls.
*/
protected int bulkBatchSize = 1000;
/**
* Resource path for the Document store mapping files.
*/
protected String mappingPath;
/**
* Suffix used for mapping files.
*/
protected String mappingSuffix;
/**
* Location of resources that mapping files are generated into.
*/
protected String pathToResources = "src/main/resources";
/**
* Return true if the Document store (ElasticSearch) integration is active.
*/
public boolean isActive() {
String systemValue = System.getProperty("ebean.docstore.active");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return active;
}
/**
* Set to true to make the Document store (ElasticSearch) integration active.
*/
public void setActive(boolean active) {
this.active = active;
}
/**
* Return the URL to the Document store.
*/
public String getUrl() {
String systemValue = System.getProperty("ebean.docstore.url");
if (systemValue != null) {
return systemValue;
}
return url;
}
/**
* Return the user credential for connecting to the document store.
*/
public String getUsername() {
return username;
}
/**
* Set the user credential for connecting to the document store.
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Return the password credential for connecting to the document store.
*/
public String getPassword() {
return password;
}
/**
* Set the password credential for connecting to the document store.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the URL to the Document store.
* <p>
* For a local ElasticSearch server this would be: http://localhost:9200
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Return true if Ebean should generate mapping files on server startup.
*/
public boolean isGenerateMapping() {
String systemValue = System.getProperty("ebean.docstore.generateMapping");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return generateMapping;
}
/**
* Set to true if Ebean should generate mapping files on server startup.
*/
public void setGenerateMapping(boolean generateMapping) {
this.generateMapping = generateMapping;
}
/**
* Return true if the document store should recreate mapped indexes.
*/
public boolean isDropCreate() {
String systemValue = System.getProperty("ebean.docstore.dropCreate");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return dropCreate;
}
/**
* Set to true if the document store should recreate mapped indexes.
*/
public void setDropCreate(boolean dropCreate) {
this.dropCreate = dropCreate;
}
/**
* Create true if the document store should create mapped indexes that don't yet exist.
* This is only used if dropCreate is false.
*/
public boolean isCreate() {
String systemValue = System.getProperty("ebean.docstore.create");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return create;
}
/**
* Set to true if the document store should create mapped indexes that don't yet exist.
* This is only used if dropCreate is false.
*/
public void setCreate(boolean create) {
this.create = create;
}
/**
* Return true if the client allows connections to invalid/self signed SSL certificates.
*/
public boolean isAllowAllCertificates() {
return allowAllCertificates;
}
/**
* Set to true such that the client allows connections to invalid/self signed SSL certificates.
*/
public void setAllowAllCertificates(boolean allowAllCertificates) {
this.allowAllCertificates = allowAllCertificates;
}
/**
* Return the default batch size to use for calls to the Bulk API.
*/
public int getBulkBatchSize() {
return bulkBatchSize;
}
/**
* Set the default batch size to use for calls to the Bulk API.
* <p>
* The batch size can be set on a transaction via {@link Transaction#setDocStoreBatchSize(int)}.
* </p>
*/
public void setBulkBatchSize(int bulkBatchSize) {
this.bulkBatchSize = bulkBatchSize;
}
/**
* Return the mapping path.
*/
public String getMappingPath() {
return mappingPath;
}
/**
* Set the mapping path.
*/
public void setMappingPath(String mappingPath) {
this.mappingPath = mappingPath;
}
/**
* Return the mapping suffix.
*/
public String getMappingSuffix() {
return mappingSuffix;
}
/**
* Set the mapping suffix.
*/
public void setMappingSuffix(String mappingSuffix) {
this.mappingSuffix = mappingSuffix;
}
/**
* Return the relative file system path to resources when generating mapping files.
*/
public String getPathToResources() {
return pathToResources;
}
/**
* Set the relative file system path to resources when generating mapping files.
*/
public void setPathToResources(String pathToResources) {
this.pathToResources = pathToResources;
}
/**
* Return the default behavior for when Insert, Update and Delete events occur on beans that have an associated
* Document store.
*/
public DocStoreMode getPersist() {
return persist;
}
/**
* Set the default behavior for when Insert, Update and Delete events occur on beans that have an associated
* Document store.
* <ul>
* <li>DocStoreEvent.UPDATE - build and send message to Bulk API</li>
* <li>DocStoreEvent.QUEUE - add an entry with the index type and id only into a queue for later processing</li>
* <li>DocStoreEvent.IGNORE - ignore. Most likely used when some scheduled batch job handles updating the index</li>
* </ul>
* <p>
* You might choose to use QUEUE if that particular index data is updating very frequently or the cost of indexing
* is expensive. Setting it to QUEUE can mean many changes can be batched together potentially coalescing multiple
* updates for an index entry into a single update.
* </p>
* <p>
* You might choose to use IGNORE when you have your own external process for updating the indexes. In this case
* you don't want Ebean to do anything when the data changes.
* </p>
*/
public void setPersist(DocStoreMode persist) {
this.persist = persist;
}
/**
* Load settings specified in properties files.
*/
public void loadSettings(PropertiesWrapper properties) {
active = properties.getBoolean("docstore.active", active);
url = properties.get("docstore.url", url);
username = properties.get("docstore.username", url);
password = properties.get("docstore.password", url);
persist = properties.getEnum(DocStoreMode.class, "docstore.persist", persist);
bulkBatchSize = properties.getInt("docstore.bulkBatchSize", bulkBatchSize);
generateMapping = properties.getBoolean("docstore.generateMapping", generateMapping);
dropCreate = properties.getBoolean("docstore.dropCreate", dropCreate);
create = properties.getBoolean("docstore.create", create);
allowAllCertificates = properties.getBoolean("docstore.allowAllCertificates", allowAllCertificates);
mappingPath = properties.get("docstore.mappingPath", mappingPath);
mappingSuffix = properties.get("docstore.mappingSuffix", mappingSuffix);
pathToResources = properties.get("docstore.pathToResources", pathToResources);
}
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document Mapping for a bean marker interface.
*/
public interface DocMapping {
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document query request context marker interface.
*/
public interface DocQueryContext<T> {
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document update context marker interface.
*/
public interface DocUpdateContext {
}
@@ -1,102 +0,0 @@
package io.ebean.docstore;
import java.util.Map;
/**
* Raw document.
*/
public class RawDoc {
private Map<String, Object> source;
private String id;
private double score;
private String index;
private String type;
/**
* Construct the document with all the meta data.
*/
public RawDoc(Map<String, Object> source, String id, double score, String index, String type) {
this.source = source;
this.id = id;
this.score = score;
this.index = index;
this.type = type;
}
/**
* Construct empty (typically for JSON marshalling).
*/
public RawDoc() {
}
/**
* Return the source document as a Map.
*/
public Map<String, Object> getSource() {
return source;
}
/**
* Return the Id value.
*/
public String getId() {
return id;
}
/**
* Return the score.
*/
public double getScore() {
return score;
}
/**
* Return the index name.
*/
public String getIndex() {
return index;
}
/**
* Return the index type.
*/
public String getType() {
return type;
}
/**
* Set the source document.
*/
public void setSource(Map<String, Object> source) {
this.source = source;
}
/**
* Set the id value.
*/
public void setId(String id) {
this.id = id;
}
/**
* Set the score.
*/
public void setScore(double score) {
this.score = score;
}
/**
* Set the index name.
*/
public void setIndex(String index) {
this.index = index;
}
/**
* Set the index type.
*/
public void setType(String type) {
this.type = type;
}
}
@@ -1,72 +0,0 @@
package io.ebean.plugin;
import io.ebean.FetchPath;
import io.ebean.Query;
import io.ebean.docstore.DocUpdateContext;
import java.io.IOException;
/**
* Doc store functions for a specific entity bean type.
*
* @param <T> The type of entity bean
*/
public interface BeanDocType<T> {
/**
* Return the doc store index type for this bean type.
*/
String indexType();
/**
* Return the doc store index name for this bean type.
*/
String indexName();
/**
* Apply the appropriate fetch path to the query such that the query returns beans matching
* the document store structure with the expected embedded properties.
*/
void applyPath(Query<T> spiQuery);
/**
* Return the FetchPath for the embedded document.
*/
FetchPath embedded(String path);
/**
* For embedded 'many' properties we need a FetchPath relative to the root which is used to
* build and replace the embedded list.
*/
FetchPath embeddedManyRoot(String path);
/**
* Return a 'raw' property mapped for the given property.
* If none exists the given property is returned.
*/
String rawProperty(String property);
/**
* Store the bean in the doc store index.
* <p>
* This somewhat assumes the bean is fetched with appropriate path properties
* to match the expected document structure.
*/
void index(Object idValue, T bean, DocUpdateContext txn) throws IOException;
/**
* Add a delete by Id to the doc store.
*/
void deleteById(Object idValue, DocUpdateContext txn) throws IOException;
/**
* Add a embedded document update to the doc store.
*
* @param idValue the Id value of the bean holding the embedded document
* @param embeddedProperty the embedded property
* @param embeddedRawContent the content of the embedded document in JSON form
* @param txn the doc store transaction to add the update to
*/
void updateEmbedded(Object idValue, String embeddedProperty, String embeddedRawContent, DocUpdateContext txn) throws IOException;
}
@@ -2,7 +2,6 @@ package io.ebean.plugin;
import io.ebean.Query;
import io.ebean.config.dbplatform.IdType;
import io.ebean.docstore.DocMapping;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistListener;
@@ -145,30 +144,6 @@ public interface BeanType<T> {
*/
IdType idType();
/**
* Return true if this bean type has doc store backing.
*/
boolean isDocStoreMapped();
/**
* Return the DocumentMapping for this bean type.
* <p>
* This is the document structure and mapping options for how this bean type is mapped
* for the document store.
* </p>
*/
DocMapping docMapping();
/**
* Return the doc store queueId for this bean type.
*/
String docStoreQueueId();
/**
* Return the doc store support for this bean type.\
*/
BeanDocType<T> docStore();
/**
* Add the discriminator value to the query if needed.
*/
@@ -38,11 +38,6 @@ public interface SpiServer extends Database {
*/
List<? extends BeanType<?>> beanTypes(String baseTableName);
/**
* Return the bean type for a given doc store queueId.
*/
BeanType<?> beanTypeForQueueId(String queueId);
/**
* Return a BeanLoader.
*/
@@ -1,98 +0,0 @@
package io.ebean.search;
/**
* Options for the text match and multi match expressions.
*/
public abstract class AbstractMatch {
protected boolean operatorAnd;
protected String analyzer;
protected double boost;
protected String minShouldMatch;
protected int maxExpansions;
protected String zeroTerms;
protected double cutoffFrequency;
protected String fuzziness;
protected int prefixLength;
protected String rewrite;
/**
* Return true if using the AND operator otherwise using the OR operator.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the boost.
*/
public double getBoost() {
return boost;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the zero terms option.
*/
public String getZeroTerms() {
return zeroTerms;
}
/**
* Return the cutoff frequency.
*/
public double getCutoffFrequency() {
return cutoffFrequency;
}
/**
* Return the max expansions.
*/
public int getMaxExpansions() {
return maxExpansions;
}
/**
* Return the analyzer.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the fuzziness.
*/
public String getFuzziness() {
return fuzziness;
}
/**
* Return the prefix length.
*/
public int getPrefixLength() {
return prefixLength;
}
/**
* Return the rewrite option.
*/
public String getRewrite() {
return rewrite;
}
}
@@ -1,117 +0,0 @@
package io.ebean.search;
/**
* Options for the text match expression.
*/
public class Match extends AbstractMatch {
protected boolean phrase;
protected boolean phrasePrefix;
public Match() {
}
/**
* Set this to be a "Phrase" type expression.
*/
public Match phrase() {
phrase = true;
return this;
}
/**
* Set this to be a "Phrase Prefix" type expression.
*/
public Match phrasePrefix() {
phrasePrefix = true;
return this;
}
/**
* Use the AND operator (rather than OR).
*/
public Match opAnd() {
operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public Match opOr() {
operatorAnd = false;
return this;
}
/**
* Set the zero terms.
*/
public Match zeroTerms(String zeroTerms) {
this.zeroTerms = zeroTerms;
return this;
}
/**
* Set the cutoff frequency.
*/
public Match cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set the max expansions (for phrase prefix only).
*/
public Match maxExpansions(int maxExpansions) {
this.maxExpansions = maxExpansions;
return this;
}
/**
* Set the Analyzer to use for this expression.
*/
public Match analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the boost.
*/
public Match boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the rewrite to use.
*/
public Match minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the rewrite to use.
*/
public Match rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return true if this is a phrase query.
*/
public boolean isPhrase() {
return phrase;
}
/**
* Return true if this is a phrase prefix query.
*/
public boolean isPhrasePrefix() {
return phrasePrefix;
}
}
@@ -1,148 +0,0 @@
package io.ebean.search;
/**
* Options for the text match expression.
*/
public class MultiMatch extends AbstractMatch {
/**
* The MultiMatch type.
*/
public enum Type {
BEST_FIELDS,
MOST_FIELDS,
CROSS_FIELDS,
PHRASE,
PHRASE_PREFIX
}
protected final String[] fields;
protected Type type = Type.BEST_FIELDS;
protected double tieBreaker;
/**
* Create with the given fields.
*/
public static MultiMatch fields(String... fields) {
return new MultiMatch(fields);
}
/**
* Construct with a set of fields.
*/
public MultiMatch(String... fields) {
this.fields = fields;
}
/**
* Set the type of query.
*/
public MultiMatch type(Type type) {
this.type = type;
return this;
}
/**
* Set the tieBreaker to use.
*/
public MultiMatch tieBreaker(double tieBreaker) {
this.tieBreaker = tieBreaker;
return this;
}
/**
* Use the AND operator (rather than OR).
*/
public MultiMatch opAnd() {
operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public MultiMatch opOr() {
operatorAnd = false;
return this;
}
/**
* Set the minimum should match value.
*/
public MultiMatch minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the boost.
*/
public MultiMatch boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the zero terms.
*/
public MultiMatch zeroTerms(String zeroTerms) {
this.zeroTerms = zeroTerms;
return this;
}
/**
* Set the cutoff frequency.
*/
public MultiMatch cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set the max expansions (for phrase prefix only).
*/
public MultiMatch maxExpansions(int maxExpansions) {
this.maxExpansions = maxExpansions;
return this;
}
/**
* Set the Analyzer to use for this expression.
*/
public MultiMatch analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the rewrite to use.
*/
public MultiMatch rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return the type.
*/
public Type getType() {
return type;
}
/**
* Return the fields to search.
*/
public String[] getFields() {
return fields;
}
/**
* Return the tie breaker.
*/
public double getTieBreaker() {
return tieBreaker;
}
}
@@ -1,139 +0,0 @@
package io.ebean.search;
/**
* Text common terms query.
* <p>
* This maps to an ElasticSearch "common terms query".
* </p>
* <pre>{@code
*
* TextCommonTerms options = new TextCommonTerms()
* .cutoffFrequency(0.001)
* .minShouldMatch("50%")
* .lowFreqOperatorAnd(true)
* .highFreqOperatorAnd(true);
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textCommonTerms("the brown", options)
* .findList();
*
* }</pre>
* <pre>{@code
*
* // ElasticSearch expression
*
* "common": {
* "body": {
* "query": "the brown",
* "cutoff_frequency": 0.001,
* "low_freq_operator": "and",
* "high_freq_operator": "and",
* "minimum_should_match": "50%"
* }
* }
*
* }</pre>
*/
public class TextCommonTerms {
protected double cutoffFrequency;
protected boolean lowFreqOperatorAnd;
protected boolean highFreqOperatorAnd;
protected String minShouldMatch;
protected String minShouldMatchLowFreq;
protected String minShouldMatchHighFreq;
/**
* Set the cutoff frequency.
*/
public TextCommonTerms cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set to true if low frequency terms should use AND operator.
*/
public TextCommonTerms lowFreqOperatorAnd(boolean opAnd) {
this.lowFreqOperatorAnd = opAnd;
return this;
}
/**
* Set to true if high frequency terms should use AND operator.
*/
public TextCommonTerms highFreqOperatorAnd(boolean opAnd) {
this.highFreqOperatorAnd = opAnd;
return this;
}
/**
* Set the minimum should match.
*/
public TextCommonTerms minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the minimum should match for low frequency terms.
*/
public TextCommonTerms minShouldMatchLowFreq(String minShouldMatchLowFreq) {
this.minShouldMatchLowFreq = minShouldMatchLowFreq;
return this;
}
/**
* Set the minimum should match for high frequency terms.
*/
public TextCommonTerms minShouldMatchHighFreq(String minShouldMatchHighFreq) {
this.minShouldMatchHighFreq = minShouldMatchHighFreq;
return this;
}
/**
* Return true if low freq should use the AND operator.
*/
public boolean isLowFreqOperatorAnd() {
return lowFreqOperatorAnd;
}
/**
* Return true if high freq should use the AND operator.
*/
public boolean isHighFreqOperatorAnd() {
return highFreqOperatorAnd;
}
/**
* Return the cutoff frequency.
*/
public double getCutoffFrequency() {
return cutoffFrequency;
}
/**
* Return the minimum to match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the minimum to match for high frequency.
*/
public String getMinShouldMatchHighFreq() {
return minShouldMatchHighFreq;
}
/**
* Return the minimum to match for low frequency.
*/
public String getMinShouldMatchLowFreq() {
return minShouldMatchLowFreq;
}
}
@@ -1,398 +0,0 @@
package io.ebean.search;
/**
* Text query string options.
* <p>
* This maps to an ElasticSearch "query string query".
* </p>
* <pre>{@code
*
* TextQueryString options = new TextQueryString()
* .analyzeWildcard(true)
* .fields("name")
* .lenient(true)
* .opAnd();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
* <pre>{@code
*
* // just use default options
* TextQueryString options = new TextQueryString();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
*/
public class TextQueryString {
public static final int DEFAULT_FUZZY_MAX_EXPANSIONS = 50;
protected final String[] fields;
/**
* Only used when multiple fields set.
*/
protected boolean useDisMax = true;
/**
* Only used when multiple fields set.
*/
protected double tieBreaker;
protected String defaultField;
protected boolean operatorAnd;
protected String analyzer;
protected boolean allowLeadingWildcard = true;
protected boolean lowercaseExpandedTerms = true;
protected int fuzzyMaxExpansions = DEFAULT_FUZZY_MAX_EXPANSIONS;
protected String fuzziness;
protected int fuzzyPrefixLength;
protected double phraseSlop;
protected double boost;
protected boolean analyzeWildcard;
protected boolean autoGeneratePhraseQueries;
protected String minShouldMatch;
protected boolean lenient;
protected String locale;
protected String timeZone;
protected String rewrite;
/**
* Create with given fields.
*/
public static TextQueryString fields(String... fields) {
return new TextQueryString(fields);
}
/**
* Construct with the fields to use.
*/
public TextQueryString(String... fields) {
this.fields = fields;
}
/**
* Use the AND operator (rather than OR).
*/
public TextQueryString opAnd() {
this.operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public TextQueryString opOr() {
this.operatorAnd = false;
return this;
}
/**
* Set the locale.
*/
public TextQueryString locale(String locale) {
this.locale = locale;
return this;
}
/**
* Set lenient mode.
*/
public TextQueryString lenient(boolean lenient) {
this.lenient = lenient;
return this;
}
/**
* Set the minimum should match.
*/
public TextQueryString minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the analyzer.
*/
public TextQueryString analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set useDisMax option (when multiple fields only).
*/
public TextQueryString useDisMax(boolean useDisMax) {
this.useDisMax = useDisMax;
return this;
}
/**
* Set tieBreaker option (when multiple fields only).
*/
public TextQueryString tieBreaker(double tieBreaker) {
this.tieBreaker = tieBreaker;
return this;
}
/**
* Set the default field.
*/
public TextQueryString defaultField(String defaultField) {
this.defaultField = defaultField;
return this;
}
/**
* Set allow leading wildcard mode.
*/
public TextQueryString allowLeadingWildcard(boolean allowLeadingWildcard) {
this.allowLeadingWildcard = allowLeadingWildcard;
return this;
}
/**
* Set lowercase expanded terms mode.
*/
public TextQueryString lowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
this.lowercaseExpandedTerms = lowercaseExpandedTerms;
return this;
}
/**
* Set fuzzy max expansions.
*/
public TextQueryString fuzzyMaxExpansions(int fuzzyMaxExpansions) {
this.fuzzyMaxExpansions = fuzzyMaxExpansions;
return this;
}
/**
* Set fuzziness.
*/
public TextQueryString fuzziness(String fuzziness) {
this.fuzziness = fuzziness;
return this;
}
/**
* Set the fuzzy prefix length.
*/
public TextQueryString fuzzyPrefixLength(int fuzzyPrefixLength) {
this.fuzzyPrefixLength = fuzzyPrefixLength;
return this;
}
/**
* Set the phrase slop.
*/
public TextQueryString phraseSlop(double phraseSlop) {
this.phraseSlop = phraseSlop;
return this;
}
/**
* Set the boost.
*/
public TextQueryString boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the analyze wildcard mode.
*/
public TextQueryString analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
return this;
}
/**
* Set the auto generate phrase queries mode.
*/
public TextQueryString autoGeneratePhraseQueries(boolean autoGeneratePhraseQueries) {
this.autoGeneratePhraseQueries = autoGeneratePhraseQueries;
return this;
}
/**
* Set the time zone.
*/
public TextQueryString timeZone(String timeZone) {
this.timeZone = timeZone;
return this;
}
/**
* Set the rewrite option.
*/
public TextQueryString rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return the rewrite option.
*/
public String getRewrite() {
return rewrite;
}
/**
* Return the fields.
*/
public String[] getFields() {
return fields;
}
/**
* Return true if AND is the default operator.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the analyzer.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the locale.
*/
public String getLocale() {
return locale;
}
/**
* Return lenient mode.
*/
public boolean isLenient() {
return lenient;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the useDixMax mode.
*/
public boolean isUseDisMax() {
return useDisMax;
}
/**
* Return the tie breaker.
*/
public double getTieBreaker() {
return tieBreaker;
}
/**
* Return the default field.
*/
public String getDefaultField() {
return defaultField;
}
/**
* Return the allow leading wildcard mode.
*/
public boolean isAllowLeadingWildcard() {
return allowLeadingWildcard;
}
/**
* Return the lowercase expanded terms mode.
*/
public boolean isLowercaseExpandedTerms() {
return lowercaseExpandedTerms;
}
/**
* Return the fuzzy max expansions.
*/
public int getFuzzyMaxExpansions() {
return fuzzyMaxExpansions;
}
/**
* Return the fuzziness.
*/
public String getFuzziness() {
return fuzziness;
}
/**
* Return the fuzzy prefix length.
*/
public int getFuzzyPrefixLength() {
return fuzzyPrefixLength;
}
/**
* Return the phrase slop.
*/
public double getPhraseSlop() {
return phraseSlop;
}
/**
* Return the analyze wildcard mode.
*/
public boolean isAnalyzeWildcard() {
return analyzeWildcard;
}
/**
* Return the boost.
*/
public double getBoost() {
return boost;
}
/**
* Return the auto generate phase queries mode.
*/
public boolean isAutoGeneratePhraseQueries() {
return autoGeneratePhraseQueries;
}
/**
* Return the time zone.
*/
public String getTimeZone() {
return timeZone;
}
}
@@ -1,193 +0,0 @@
package io.ebean.search;
/**
* Simple text query options.
* <p>
* This maps to an ElasticSearch "simple text query".
* </p>
* <pre>{@code
*
* TextSimple options = new TextSimple()
* .analyzeWildcard(true)
* .fields("name")
* .lenient(true)
* .opAnd();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
*/
public class TextSimple {
protected String[] fields;
protected boolean operatorAnd;
protected String analyzer;
protected String flags;
protected boolean lowercaseExpandedTerms = true;
protected boolean analyzeWildcard;
protected String locale;
protected boolean lenient;
protected String minShouldMatch;
/**
* Construct
*/
public TextSimple() {
}
/**
* Set the fields.
*/
public TextSimple fields(String... fields) {
this.fields = fields;
return this;
}
/**
* Use AND as the default operator.
*/
public TextSimple opAnd() {
this.operatorAnd = true;
return this;
}
/**
* Use OR as the default operator.
*/
public TextSimple opOr() {
this.operatorAnd = false;
return this;
}
/**
* Set the analyzer
*/
public TextSimple analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the flags.
*/
public TextSimple flags(String flags) {
this.flags = flags;
return this;
}
/**
* Set the false to not use lowercase expanded terms.
*/
public TextSimple lowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
this.lowercaseExpandedTerms = lowercaseExpandedTerms;
return this;
}
/**
* Set to true to use analyze wildcard.
*/
public TextSimple analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
return this;
}
/**
* Set the locale.
*/
public TextSimple locale(String locale) {
this.locale = locale;
return this;
}
/**
* Set the lenient mode.
*/
public TextSimple lenient(boolean lenient) {
this.lenient = lenient;
return this;
}
/**
* Set the minimum should match.
*/
public TextSimple minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Return lenient mode.
*/
public boolean isLenient() {
return lenient;
}
/**
* Return true to analyse wildcard.
*/
public boolean isAnalyzeWildcard() {
return analyzeWildcard;
}
/**
* Return lowercase expanded terms mode.
*/
public boolean isLowercaseExpandedTerms() {
return lowercaseExpandedTerms;
}
/**
* Return true if the default operator should be AND.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the analyzer to use.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the fields.
*/
public String[] getFields() {
return fields;
}
/**
* Return the locale.
*/
public String getLocale() {
return locale;
}
/**
* Return the flags.
*/
public String getFlags() {
return flags;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
}
@@ -1,4 +0,0 @@
/**
* Provides text search expressions like Match, TextQueryString etc.
*/
package io.ebean.search;
-2
View File
@@ -32,10 +32,8 @@ module io.ebean.api {
exports io.ebean.event;
exports io.ebean.event.changelog;
exports io.ebean.common;
exports io.ebean.docstore;
exports io.ebean.plugin;
exports io.ebean.metric;
exports io.ebean.search;
exports io.ebean.service;
exports io.ebean.text;
exports io.ebean.text.json;
-19
View File
@@ -230,25 +230,6 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<doctitle>Ebean 12</doctitle>
<overview>src/main/java/io/ebean/overview.html</overview>
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform</excludePackageNames>
<linksource>true</linksource>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
@@ -43,5 +43,4 @@ public interface LoadManyBuffer {
void configureQuery(SpiQuery<?> query);
boolean isUseDocStore();
}
@@ -99,7 +99,7 @@ public final class LoadManyRequest extends LoadRequest {
query.where().raw(extraWhere.replace("${ta}", "t0").replace("${mta}", "int_"));
}
query.setLazyLoadForParents(many);
many.addWhereParentIdIn(query, parentIdList(server), loadContext.isUseDocStore());
many.addWhereParentIdIn(query, parentIdList(server));
query.setPersistenceContext(loadContext.persistenceContext());
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
if (lazy) {
@@ -99,11 +99,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
BeanDescriptor<?> descriptorById(String className);
/**
* Return BeanDescriptor using it's unique doc store queueId.
*/
BeanDescriptor<?> descriptorByQueueId(String queueId);
/**
* Return BeanDescriptors mapped to this table.
*/
@@ -3,9 +3,6 @@ package io.ebeaninternal.api;
import io.ebean.Expression;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
/**
@@ -21,16 +18,6 @@ public interface SpiExpression extends Expression {
*/
void simplify();
/**
* Write the expression as an elastic search expression.
*/
void writeDocQuery(DocQueryContext context) throws IOException;
/**
* Return the nested path for this expression.
*/
String nestedPath(BeanDescriptor<?> desc);
/**
* Process "Many" properties populating ManyWhereJoins.
* <p>
@@ -2,7 +2,6 @@ package io.ebeaninternal.api;
import io.ebean.ExpressionList;
import io.ebean.Junction;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
import java.util.List;
@@ -32,11 +31,6 @@ public interface SpiExpressionList<T> extends ExpressionList<T>, SpiExpression {
*/
boolean isEmpty();
/**
* Write the top level where expressions taking into account possible extra idEquals expression.
*/
void writeDocQuery(DocQueryContext context, SpiExpression idEquals) throws IOException;
/**
* Apply firstRow maxRows limits on the filterMany query.
*/
@@ -1,17 +1,10 @@
package io.ebeaninternal.api;
import io.ebean.Junction;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
/**
* SPI methods for Junction.
*/
public interface SpiJunction<T> extends Junction<T> {
/**
* Write the Junction taking into account it is implied.
*/
void writeDocQueryJunction(DocQueryContext context) throws IOException;
}
@@ -285,17 +285,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
SpiRawSql rawSql();
/**
* Return true if this query should be executed against the doc store.
*/
boolean isUseDocStore();
/**
* For doc store query return the document index name to search against.
* This is for partitioned indexes (like daily logstash indexes etc).
*/
String getDocIndexName();
/**
* Return the PersistenceContextScope that this query should use.
* <p>
@@ -498,11 +487,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
NaturalKeyBindParam naturalKeyBindParam();
/**
* Prepare the query for docstore execution with nested paths.
*/
void prepareDocNested();
/**
* Set the query to be a delete query.
*/
@@ -708,11 +692,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
SpiExpressionList<T> havingExpressions();
/**
* Return the text expressions.
*/
SpiExpressionList<T> textExpression();
/**
* Returns true if either firstRow or maxRows has been set.
*/
@@ -9,7 +9,6 @@ import io.ebeaninternal.server.core.PersistDeferredRelationship;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.transaction.ProfileStream;
import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -103,19 +102,6 @@ public interface SpiTransaction extends Transaction {
*/
Boolean isUpdateAllLoadedProperties();
/**
* Return the batchSize specifically set for this transaction or 0.
* <p>
* Returning 0 implies to use the system wide default batch size.
*/
DocStoreMode docStoreMode();
/**
* Return the batch size to us for ElasticSearch Bulk API calls
* as a result of this transaction.
*/
int getDocStoreBatchSize();
/**
* Return the batchSize specifically set for this transaction or 0.
* <p>
@@ -287,11 +273,6 @@ public interface SpiTransaction extends Transaction {
*/
void sendChangeLog(ChangeSet changeSet);
/**
* Return a document store transaction.
*/
DocStoreTransaction docStoreTransaction();
/**
* Set the current Tenant Id.
*/
@@ -2,14 +2,12 @@ package io.ebeaninternal.api;
import io.ebean.ProfileLocation;
import io.ebean.TransactionCallback;
import io.ebean.annotation.DocStoreMode;
import io.ebean.event.changelog.BeanChange;
import io.ebean.event.changelog.ChangeSet;
import io.ebeaninternal.server.core.PersistDeferredRelationship;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.transaction.ProfileStream;
import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -112,32 +110,6 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
return transaction.tenantId();
}
@Override
public DocStoreTransaction docStoreTransaction() {
return transaction.docStoreTransaction();
}
@Override
public DocStoreMode docStoreMode() {
return transaction.docStoreMode();
}
@Override
public void setDocStoreMode(DocStoreMode mode) {
transaction.setDocStoreMode(mode);
}
@Override
public int getDocStoreBatchSize() {
return transaction.getDocStoreBatchSize();
}
@Override
public void setDocStoreBatchSize(int batchSize) {
transaction.setDocStoreBatchSize(batchSize);
}
@Override
public boolean isLogSql() {
return transaction.isLogSql();
@@ -6,7 +6,6 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
import io.ebeaninternal.server.transaction.DeleteByIdMap;
import io.ebeaninternal.server.transaction.TransactionManager;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import java.io.Serializable;
import java.util.ArrayList;
@@ -125,18 +124,6 @@ public final class TransactionEvent implements Serializable {
return changeSet;
}
/**
* Add any relevant PersistRequestBean's to DocStoreUpdates for later processing.
*/
public void addDocStoreUpdates(DocStoreUpdates docStoreUpdates) {
List<PersistRequestBean<?>> requests = listenerNotify();
if (requests != null) {
for (PersistRequestBean<?> persistRequestBean : requests) {
persistRequestBean.addDocStoreUpdates(docStoreUpdates);
}
}
}
/**
* Return the CacheChangeSet that we add cache notification messages to.
* <p>
@@ -78,16 +78,12 @@ public final class DefaultContainer implements SpiContainer {
BootupClasses bootupClasses = bootupClasses(config);
boolean online = true;
if (config.isDocStoreOnly()) {
config.setDatabasePlatform(new DatabasePlatform());
} else {
TenantMode tenantMode = config.getTenantMode();
if (TenantMode.DB != tenantMode) {
setDataSource(config);
if (!tenantMode.isDynamicDataSource()) {
// check the autoCommit and Transaction Isolation
online = checkDataSource(config);
}
TenantMode tenantMode = config.getTenantMode();
if (TenantMode.DB != tenantMode) {
setDataSource(config);
if (!tenantMode.isDynamicDataSource()) {
// check the autoCommit and Transaction Isolation
online = checkDataSource(config);
}
}
@@ -40,7 +40,6 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import io.ebeaninternal.server.transaction.TransactionManager;
import io.ebeaninternal.util.ParamTypeHelper;
import io.ebeaninternal.util.ParamTypeHelper.TypeInfo;
import io.ebeanservice.docstore.api.DocStoreIntegration;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.NonUniqueResultException;
@@ -99,7 +98,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final DefaultBeanLoader beanLoader;
private final EncryptKeyManager encryptKeyManager;
private final SpiJsonContext jsonContext;
private final DocumentStore documentStore;
private final MetaInfoManager metaInfoManager;
private final CurrentTenantProvider currentTenantProvider;
private final SpiLogManager logManager;
@@ -146,9 +144,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.dataTimeZone = config.getDataTimeZone();
this.clockService = config.getClockService();
DocStoreIntegration docStoreComponents = config.createDocStoreIntegration(this);
this.transactionManager = config.createTransactionManager(this, docStoreComponents.updateProcessor());
this.documentStore = docStoreComponents.documentStore();
this.transactionManager = config.createTransactionManager(this);
this.queryPlanManager = config.initQueryPlanManager(transactionManager);
this.metaInfoManager = new DefaultMetaInfoManager(this, this.config.getMetricNaming());
this.serverPlugins = config.getPlugins();
@@ -182,9 +178,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Execute all the plugins with an online flag indicating the DB is up or not.
*/
public void executePlugins(boolean online) {
if (!config.isDocStoreOnly()) {
ddlGenerator.execute(online);
}
ddlGenerator.execute(online);
for (Plugin plugin : serverPlugins) {
plugin.online(online);
}
@@ -992,9 +986,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
SpiOrmQueryRequest<T> request = buildQueryRequest(query);
request.prepareQuery();
if (request.isUseDocStore()) {
return docStore().find(request);
}
try {
request.initTransIfRequired();
return (T) request.findId();
@@ -1282,9 +1273,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (maxRows == 0) {
throw new PersistenceException("maxRows must be specified for findPagedList() query");
}
if (query.isUseDocStore()) {
return docStore().findPagedList(createQueryRequest(Type.LIST, query));
}
return new LimitOffsetPagedList<>(this, query);
}
@@ -1312,10 +1300,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> void findEach(SpiQuery<T> query, Consumer<T> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
if (request.isUseDocStore()) {
docStore().findEach(request, consumer);
return;
}
request.initTransIfRequired();
request.findEach(consumer);
// no try finally - findEach guarantee's cleanup of the transaction if required
@@ -1324,10 +1308,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> void findEach(SpiQuery<T> query, int batch, Consumer<List<T>> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
// if (request.isUseDocStore()) {
// docStore().findEach(request, consumer);
// return;
// }
request.initTransIfRequired();
request.findEach(batch, consumer);
// no try finally - findEach guarantee's cleanup of the transaction if required
@@ -1336,10 +1316,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> void findEachWhile(SpiQuery<T> query, Predicate<T> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
if (request.isUseDocStore()) {
docStore().findEachWhile(request, consumer);
return;
}
request.initTransIfRequired();
request.findEachWhile(consumer);
// no try finally - findEachWhile guarantee's cleanup of the transaction if required
@@ -1374,9 +1350,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (result != null) {
return (List<T>) result;
}
if (request.isUseDocStore()) {
return docStore().findList(request);
}
try {
request.initTransIfRequired();
return request.findList();
@@ -1944,16 +1917,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return descriptorManager.beanTypes(tableName);
}
@Override
public BeanType<?> beanTypeForQueueId(String queueId) {
return descriptorByQueueId(queueId);
}
@Override
public BeanDescriptor<?> descriptorByQueueId(String queueId) {
return descriptorManager.descriptorByQueueId(queueId);
}
/**
* Return the SPI bean types for the given bean class.
*/
@@ -2060,11 +2023,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return callStackFactory.createCallOrigin();
}
@Override
public DocumentStore docStore() {
return documentStore;
}
@Override
public JsonContext json() {
// immutable thread safe so return shared instance
@@ -46,10 +46,6 @@ import io.ebeaninternal.server.json.DJsonContext;
import io.ebeaninternal.server.transaction.*;
import io.ebeaninternal.server.type.DefaultTypeManager;
import io.ebeaninternal.server.type.TypeManager;
import io.ebeanservice.docstore.api.DocStoreFactory;
import io.ebeanservice.docstore.api.DocStoreIntegration;
import io.ebeanservice.docstore.api.DocStoreUpdateProcessor;
import io.ebeanservice.docstore.none.NoneDocStoreFactory;
import java.util.*;
@@ -85,7 +81,6 @@ public final class InternalConfiguration {
private final ExpressionFactory expressionFactory;
private final SpiBackgroundExecutor backgroundExecutor;
private final JsonFactory jsonFactory;
private final DocStoreFactory docStoreFactory;
private final List<Plugin> plugins = new ArrayList<>();
private final MultiValueBind multiValueBind;
private final SpiLogManager logManager;
@@ -102,7 +97,6 @@ public final class InternalConfiguration {
this.clockService = new ClockService(config.getClock());
this.tableModState = new TableModState();
this.logManager = initLogManager();
this.docStoreFactory = initDocStoreFactory(service(DocStoreFactory.class));
this.jsonFactory = config.getJsonFactory();
this.clusterManager = clusterManager;
this.backgroundExecutor = backgroundExecutor;
@@ -159,17 +153,6 @@ public final class InternalConfiguration {
return new DefaultExpressionFactory(config.isExpressionEqualsWithNullAsNoop(), nativeIlike);
}
private DocStoreFactory initDocStoreFactory(DocStoreFactory service) {
return service == null ? new NoneDocStoreFactory() : service;
}
/**
* Return the doc store factory.
*/
public DocStoreFactory getDocStoreFactory() {
return docStoreFactory;
}
ClockService getClockService() {
return clockService;
}
@@ -337,29 +320,19 @@ public final class InternalConfiguration {
return new GeneratedPropertyFactory(offlineMode, config, bootupClasses.getIdGenerators());
}
/**
* Create the DocStoreIntegration components for the given server.
*/
DocStoreIntegration createDocStoreIntegration(SpiServer server) {
return plugin(docStoreFactory.create(server));
}
/**
* Create the TransactionManager taking into account autoCommit mode.
*/
TransactionManager createTransactionManager(SpiServer server, DocStoreUpdateProcessor indexUpdateProcessor) {
TransactionManager createTransactionManager(SpiServer server) {
TransactionScopeManager scopeManager = createTransactionScopeManager();
boolean notifyL2CacheInForeground = cacheManager.isLocalL2Caching() || config.isNotifyL2CacheInForeground();
TransactionManagerOptions options =
new TransactionManagerOptions(server, notifyL2CacheInForeground, config, scopeManager, clusterManager, backgroundExecutor,
indexUpdateProcessor, beanDescriptorManager, dataSource(), profileHandler(), logManager,
beanDescriptorManager, dataSource(), profileHandler(), logManager,
tableModState, cacheNotify, clockService);
if (config.isDocStoreOnly()) {
return new DocStoreTransactionManager(options);
}
return new TransactionManager(options);
}
@@ -116,7 +116,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return server.databasePlatform().escapeLikeString(value);
}
@Override
public void executeSecondaryQueries(boolean forEach) {
// disable lazy loading leaves loadContext null
if (loadContext != null) {
@@ -157,11 +156,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return loadContext;
}
@Override
public boolean isUseDocStore() {
return query.isUseDocStore();
}
/**
* Run BeanQueryAdapter preQuery() if needed.
*/
@@ -257,23 +251,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
}
/**
* Return the JsonReadOptions taking into account lazy loading and persistence context.
*/
@Override
public JsonReadOptions createJsonReadOptions() {
persistenceContext = persistenceContext(query, transaction);
if (query.persistenceContext() == null) {
query.setPersistenceContext(persistenceContext);
}
JsonReadOptions jsonRead = new JsonReadOptions();
jsonRead.setPersistenceContext(persistenceContext);
if (!query.isDisableLazyLoading()) {
loadContext = new DLoadContext(this, secondaryQueries);
jsonRead.setLoadContext(loadContext);
}
return jsonRead;
}
/**
* Get the TransactionContext either explicitly set on the query or
@@ -16,9 +16,6 @@ import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.id.ImportedId;
import io.ebeaninternal.server.persist.*;
import io.ebeaninternal.server.transaction.BeanPersistIdMap;
import io.ebeanservice.docstore.api.DocStoreUpdate;
import io.ebeanservice.docstore.api.DocStoreUpdateContext;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.OptimisticLockException;
@@ -30,7 +27,7 @@ import java.util.*;
/**
* PersistRequest for insert update or delete of a bean.
*/
public final class PersistRequestBean<T> extends PersistRequest implements BeanPersistRequest<T>, DocStoreUpdate, PreGetterCallback, SpiProfileTransactionEvent {
public final class PersistRequestBean<T> extends PersistRequest implements BeanPersistRequest<T>, PreGetterCallback, SpiProfileTransactionEvent {
private final BeanManager<T> beanManager;
private final BeanDescriptor<T> beanDescriptor;
@@ -46,7 +43,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
private final boolean dirty;
private int flags;
private boolean saveRecurse;
private DocStoreMode docStoreMode;
private final ConcurrencyMode concurrencyMode;
/**
* The unique id used for logging summary.
@@ -136,7 +132,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
this.parentBean = parentBean;
this.controller = beanDescriptor.persistController();
this.type = type;
this.docStoreMode = calcDocStoreMode(transaction, type);
this.flags = flags;
if (Flags.isRecurse(flags)) {
this.persistCascade = t.isPersistCascade();
@@ -180,17 +175,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
profileBase(type.profileEventId, offset, beanDescriptor.name(), flushCount);
}
/**
* Return the document store event that should be used for this request.
* <p>
* Used to check if the Transaction has set the mode to IGNORE when doing large batch inserts that we
* don't want to send to the doc store.
*/
private DocStoreMode calcDocStoreMode(SpiTransaction txn, Type type) {
DocStoreMode txnMode = (txn == null) ? null : txn.docStoreMode();
return beanDescriptor.docStoreMode(type, txnMode);
}
@Override
public boolean isCascade() {
return Flags.isRecurse(flags);
@@ -210,9 +194,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Init the transaction and also check for batch on cascade escalation.
*/
public void initTransIfRequiredWithBatchCascade() {
if (createImplicitTransIfRequired()) {
docStoreMode = calcDocStoreMode(transaction, type);
}
createImplicitTransIfRequired();
checkBatchEscalationOnCascade();
}
@@ -412,15 +394,9 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Return true if this change should notify persist listener or doc store (and keep the request).
*/
private boolean isNotifyListeners() {
return isNotifyPersistListener() || isDocStoreNotify();
return isNotifyPersistListener();
}
/**
* Return true if this request should update the document store.
*/
private boolean isDocStoreNotify() {
return docStoreMode != DocStoreMode.IGNORE;
}
private boolean isNotifyPersistListener() {
return beanPersistListener != null;
@@ -448,46 +424,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
}
/**
* Process the persist request updating the document store.
*/
@Override
public void docStoreUpdate(DocStoreUpdateContext txn) throws IOException {
switch (type) {
case INSERT:
beanDescriptor.docStoreInsert(idValue, this, txn);
break;
case UPDATE:
case DELETE_SOFT:
beanDescriptor.docStoreUpdate(idValue, this, txn);
break;
case DELETE:
beanDescriptor.docStoreDeleteById(idValue, txn);
break;
default:
throw new IllegalStateException("Invalid type " + type);
}
}
/**
* Add this event to the queue entries in IndexUpdates.
*/
@Override
public void addToQueue(DocStoreUpdates docStoreUpdates) {
switch (type) {
case INSERT:
case UPDATE:
case DELETE_SOFT:
docStoreUpdates.queueIndex(beanDescriptor.docStoreQueueId(), idValue);
break;
case DELETE:
docStoreUpdates.queueDelete(beanDescriptor.docStoreQueueId(), idValue);
break;
default:
throw new IllegalStateException("Invalid type " + type);
}
}
public void addToPersistMap(BeanPersistIdMap beanPersistMap) {
beanPersistMap.add(beanDescriptor, type, idValue);
}
@@ -821,7 +757,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
setNotifyCache();
boolean isChangeLog = beanDescriptor.isChangeLog();
if (type == Type.UPDATE && (isChangeLog || notifyCache || docStoreMode == DocStoreMode.UPDATE)) {
if (type == Type.UPDATE && (isChangeLog || notifyCache)) {
// get the dirty properties for update notification to the doc store
dirtyProperties = intercept.dirtyProperties();
}
@@ -1030,32 +966,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
}
/**
* For requests that update document store add this event to either the list
* of queue events or list of update events.
*/
public void addDocStoreUpdates(DocStoreUpdates docStoreUpdates) {
if (type == Type.UPDATE) {
beanDescriptor.docStoreUpdateEmbedded(this, docStoreUpdates);
}
switch (docStoreMode) {
case UPDATE: {
docStoreUpdates.addPersist(this);
return;
}
case QUEUE: {
if (type == Type.DELETE) {
docStoreUpdates.queueDelete(beanDescriptor.docStoreQueueId(), idValue);
} else {
docStoreUpdates.queueIndex(beanDescriptor.docStoreQueueId(), idValue);
}
}
break;
default:
break;
}
}
/**
* Determine if all loaded properties should be used for an update.
* <p>
@@ -1173,30 +1083,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return 0;
}
/**
* Persist to the document store now (via buffer, not post commit).
*/
public void docStorePersist() {
idValue = beanDescriptor.getId(entityBean);
if (type == Type.UPDATE) {
dirtyProperties = intercept.dirtyProperties();
}
// processing now so set IGNORE (unlike DB + DocStore processing with post-commit)
docStoreMode = DocStoreMode.IGNORE;
try {
docStoreUpdate(transaction.docStoreTransaction().obtain());
postExecute();
if (type == Type.UPDATE
&& beanDescriptor.isDocStoreEmbeddedInvalidation()
&& transaction.isPersistCascade()) {
// queue embedded/nested updates for later processing
beanDescriptor.docStoreUpdateEmbedded(this, transaction.docStoreTransaction().queue());
}
} catch (IOException e) {
throw new PersistenceException("Error persisting doc store bean", e);
}
}
/**
* Use a common 'now' value across both when created and when updated etc.
*/
@@ -5,7 +5,6 @@ import io.ebean.Version;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeanservice.docstore.api.DocQueryRequest;
import java.util.Collection;
import java.util.List;
@@ -17,7 +16,7 @@ import java.util.function.Predicate;
/**
* Defines the ORM query request api.
*/
public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequest<T> {
public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T> {
/**
* Return the query.
@@ -178,11 +177,6 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
*/
void markNotQueryOnly();
/**
* Return true if this query is expected to use the doc store.
*/
boolean isUseDocStore();
/**
* Return true if delete by statement is allowed for this type given cascade rules etc.
*/
@@ -17,7 +17,6 @@ import io.ebean.event.changelog.ChangeType;
import io.ebean.meta.MetaQueryPlan;
import io.ebean.meta.MetricVisitor;
import io.ebean.meta.QueryPlanInit;
import io.ebean.plugin.BeanDocType;
import io.ebean.plugin.BeanType;
import io.ebean.plugin.ExpressionPath;
import io.ebean.plugin.Property;
@@ -44,12 +43,6 @@ import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import io.ebeaninternal.util.SortByClause;
import io.ebeaninternal.util.SortByClauseParser;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
import io.ebeanservice.docstore.api.DocStoreUpdateContext;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocumentMapping;
import jakarta.persistence.PersistenceException;
import java.io.IOException;
@@ -210,12 +203,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final String name;
private final String baseTableAlias;
private final boolean cacheSharableBeans;
private final String docStoreQueueId;
private final BeanDescriptorCacheHelp<T> cacheHelp;
private final BeanDescriptorJsonHelp<T> jsonHelp;
private DocStoreBeanAdapter<T> docStoreAdapter;
private DocumentMapping docMapping;
private boolean docStoreEmbeddedInvalidation;
private final String defaultSelectClause;
private SpiEbeanServer ebeanServer;
@@ -297,8 +286,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
this.cacheHelp = new BeanDescriptorCacheHelp<>(this, owner.cacheManager(), deploy.getCacheOptions(), cacheSharableBeans, propertiesOneImported);
this.jsonHelp = initJsonHelp();
this.docStoreAdapter = owner.createDocStoreBeanAdapter(this, deploy);
this.docStoreQueueId = docStoreAdapter.queueId();
// Check if there are no cascade save associated beans ( subject to change
// in initialiseOther()). Note that if we are in an inheritance hierarchy
// then we also need to check every BeanDescriptors in the InheritInfo as
@@ -576,7 +563,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
}
docStoreEmbeddedInvalidation = docStoreAdapter.hasEmbeddedInvalidation();
}
private void addUniqueColumns(IndexDefinition indexDef) {
@@ -612,11 +598,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanPropertyAssocOne<?> one : propertiesOne) {
one.initialisePostTarget();
}
if (inheritInfo != null && !inheritInfo.isRoot()) {
docStoreAdapter = (DocStoreBeanAdapter<T>) inheritInfo.getRoot().desc().docStoreAdapter();
}
docMapping = docStoreAdapter.createDocMapping();
docStoreAdapter.registerPaths();
cacheHelp.deriveNotifyFlags();
}
@@ -903,77 +884,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return inheritInfo == null || inheritInfo.isRoot();
}
/**
* Return true if this type maps to a root type of a doc store document (not embedded or ignored).
*/
@Override
public boolean isDocStoreMapped() {
return docStoreAdapter.mapped();
}
/**
* Return true if this bean type has embedded doc store invalidation.
*/
public boolean isDocStoreEmbeddedInvalidation() {
return docStoreEmbeddedInvalidation;
}
/**
* Return the queueId used to uniquely identify this type when queuing an index updateAdd.
*/
@Override
public String docStoreQueueId() {
return docStoreQueueId;
}
@Override
public DocumentMapping docMapping() {
return docMapping;
}
/**
* Return the doc store helper for this bean type.
*/
@Override
public BeanDocType<T> docStore() {
return docStoreAdapter;
}
/**
* Return doc store adapter for internal use for processing persist requests.
*/
public DocStoreBeanAdapter<T> docStoreAdapter() {
return docStoreAdapter;
}
/**
* Build the Document mapping recursively with the given prefix relative to the root of the document.
*/
public void docStoreMapping(final DocMappingBuilder mapping, final String prefix) {
if (prefix != null && idProperty != null) {
// id property not included in the
idProperty.docStoreMapping(mapping, prefix);
}
if (inheritInfo != null) {
String discCol = inheritInfo.getDiscriminatorColumn();
if (Types.VARCHAR == inheritInfo.getDiscriminatorType()) {
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.ENUM));
} else {
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.INTEGER));
}
}
for (BeanProperty prop : propertiesNonTransient) {
prop.docStoreMapping(mapping, prefix);
}
if (inheritInfo != null) {
inheritInfo.visitChildren(inheritInfo1 -> {
for (BeanProperty localProperty : inheritInfo1.localProperties()) {
localProperty.docStoreMapping(mapping, prefix);
}
});
}
}
/**
* Return the root bean type if part of inheritance hierarchy.
*/
@@ -995,33 +905,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return name;
}
/**
* Return the type of DocStoreMode that should occur for this type of persist request
* given the transactions requested mode.
*/
public DocStoreMode docStoreMode(PersistRequest.Type persistType, DocStoreMode txnMode) {
return docStoreAdapter.mode(persistType, txnMode);
}
public void docStoreInsert(Object idValue, PersistRequestBean<T> persistRequest, DocStoreUpdateContext bulkUpdate) throws IOException {
docStoreAdapter.insert(idValue, persistRequest, bulkUpdate);
}
public void docStoreUpdate(Object idValue, PersistRequestBean<T> persistRequest, DocStoreUpdateContext bulkUpdate) throws IOException {
docStoreAdapter.update(idValue, persistRequest, bulkUpdate);
}
/**
* Check if this update invalidates an embedded part of a doc store document.
*/
public void docStoreUpdateEmbedded(PersistRequestBean<T> request, DocStoreUpdates docStoreUpdates) {
docStoreAdapter.updateEmbedded(request, docStoreUpdates);
}
public void docStoreDeleteById(Object idValue, DocStoreUpdateContext txn) throws IOException {
docStoreAdapter.deleteById(idValue, txn);
}
/**
* Prepare the query for multi-tenancy check for document store only use.
*/
@@ -1032,9 +915,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
tenant.addTenant(query, tenantId);
}
}
if (isDocStoreOnly()) {
query.setUseDocStore(true);
}
}
/**
@@ -34,8 +34,6 @@ import io.ebeaninternal.server.properties.BeanPropertiesReader;
import io.ebeaninternal.server.properties.BeanPropertyAccess;
import io.ebeaninternal.server.properties.EnhanceBeanPropertyAccess;
import io.ebeaninternal.server.type.TypeManager;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
import io.ebeanservice.docstore.api.DocStoreFactory;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PersistenceException;
@@ -77,7 +75,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final ChangeLogListener changeLogListener;
private final ChangeLogRegister changeLogRegister;
private final ChangeLogPrepare changeLogPrepare;
private final DocStoreFactory docStoreFactory;
private final MultiValueBind multiValueBind;
private final TypeManager typeManager;
private final BootupClasses bootupClasses;
@@ -85,7 +82,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final List<BeanDescriptor<?>> elementDescriptors = new ArrayList<>();
private final Map<Class<?>, BeanTable> beanTableMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descQueueMap = new HashMap<>();
private final Map<String, BeanManager<?>> beanManagerMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToDescMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToViewDescMap = new HashMap<>();
@@ -119,7 +115,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
this.config = config.getConfig();
this.serverName = InternString.intern(this.config.getName());
this.cacheManager = config.getCacheManager();
this.docStoreFactory = config.getDocStoreFactory();
this.backgroundExecutor = config.getBackgroundExecutor();
this.dataSource = this.config.getDataSource();
this.encryptKeyManager = this.config.getEncryptKeyManager();
@@ -211,15 +206,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
return config;
}
@Override
public <T> DocStoreBeanAdapter<T> createDocStoreBeanAdapter(BeanDescriptor<T> descriptor, DeployBeanDescriptor<T> deploy) {
return docStoreFactory.createAdapter(descriptor, deploy);
}
public BeanDescriptor<?> descriptorByQueueId(String queueId) {
return descQueueMap.get(queueId);
}
@Override
public SpiBeanType beanType(Class<?> entityType) {
return descriptor(entityType);
@@ -553,9 +539,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private void registerDescriptor(DeployBeanInfo<?> info) {
BeanDescriptor<?> desc = new BeanDescriptor<>(this, info.getDescriptor());
descMap.put(desc.type().getName(), desc);
if (desc.isDocStoreMapped()) {
descQueueMap.put(desc.docStoreQueueId(), desc);
}
for (BeanPropertyAssocMany<?> many : desc.propertiesMany()) {
if (many.isElementCollection()) {
elementDescriptors.add(many.elementDescriptor());
@@ -7,7 +7,6 @@ import io.ebean.core.type.ScalarType;
import io.ebeaninternal.server.cache.SpiCacheManager;
import io.ebeaninternal.server.deploy.id.IdBinder;
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
/**
* Provides a method to find a BeanDescriptor.
@@ -57,11 +56,6 @@ public interface BeanDescriptorMap {
*/
IdBinder createIdBinder(BeanProperty id);
/**
* Create a doc store specific adapter for this bean type.
*/
<T> DocStoreBeanAdapter<T> createDocStoreBeanAdapter(BeanDescriptor<T> descriptor, DeployBeanDescriptor<T> deploy);
/**
* Return the scalarType for the given JDBC type.
*/
@@ -36,10 +36,6 @@ import io.ebeaninternal.server.query.SqlBeanLoad;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.type.*;
import io.ebeaninternal.util.ValueUtil;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import io.ebeanservice.docstore.api.support.DocStructure;
import jakarta.persistence.PersistenceException;
import java.io.DataInput;
@@ -143,7 +139,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
@SuppressWarnings("rawtypes")
final ScalarType scalarType;
private final DocPropertyOptions docOptions;
/**
* The length or precision for DB column.
*/
@@ -235,7 +230,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.lob = isLobType(dbType);
this.propertyType = deploy.getPropertyType();
this.field = deploy.getField();
this.docOptions = deploy.getDocPropertyOptions();
this.elPlaceHolder = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), false, null);
this.elPlaceHolderEncrypted = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), dbEncrypted, dbColumn);
this.elPrefix = deploy.getElPrefix();
@@ -326,7 +320,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.lob = isLobType(dbType);
this.propertyType = source.type();
this.field = source.field();
this.docOptions = source.docOptions;
this.unmappedJson = source.unmappedJson;
this.elPrefix = override.replace(source.elPrefix, source.dbColumn);
this.elPlaceHolder = override.replace(source.elPlaceHolder, source.dbColumn);
@@ -1283,15 +1276,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return name;
}
/**
* Append this property to the document store based on includeByDefault setting.
*/
public void docStoreInclude(boolean includeByDefault, DocStructure docStructure) {
if (includeByDefault) {
docStructure.addProperty(name);
}
}
public boolean isJsonSerialize() {
return jsonSerialize;
}
@@ -1401,24 +1385,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
}
}
/**
* Add to the document mapping if this property is included for this index.
*/
public void docStoreMapping(DocMappingBuilder mapping, String prefix) {
if (mapping.includesProperty(prefix, name)) {
DocPropertyType type = scalarType.docType();
DocPropertyOptions options = docOptions.copy();
if (isKeywordType(type, options)) {
type = DocPropertyType.KEYWORD;
}
mapping.add(new DocPropertyMapping(name, type, options));
}
}
private boolean isKeywordType(DocPropertyType type, DocPropertyOptions docOptions) {
return type == DocPropertyType.TEXT && (docOptions.isCode() || id || discriminator);
}
public void merge(EntityBean bean, EntityBean existing) {
// do nothing unless Many property
}
@@ -24,9 +24,6 @@ import io.ebeaninternal.server.query.STreePropertyAssoc;
import io.ebeaninternal.server.query.STreeType;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.support.DocStructure;
import jakarta.persistence.PersistenceException;
import java.util.ArrayList;
@@ -69,7 +66,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
*/
final BeanTable beanTable;
final String mappedBy;
private final String docStoreDoc;
private final String extraWhere;
private final int fetchPreference;
private boolean saveRecurseSkippable;
@@ -83,7 +79,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
this.extraWhere = InternString.intern(deploy.getExtraWhere());
this.beanTable = deploy.getBeanTable();
this.mappedBy = InternString.intern(deploy.getMappedBy());
this.docStoreDoc = deploy.getDocStoreDoc();
this.tableJoin = new TableJoin(deploy.getTableJoin());
this.targetType = deploy.getTargetType();
this.cascadeInfo = deploy.getCascadeInfo();
@@ -100,7 +95,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
extraWhere = source.extraWhere;
beanTable = source.beanTable;
mappedBy = source.mappedBy;
docStoreDoc = source.docStoreDoc;
targetType = source.targetType;
cascadeInfo = source.cascadeInfo;
fetchPreference = source.fetchPreference;
@@ -310,59 +304,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
return extraWhere;
}
/**
* Return the elastic search doc for this embedded property.
*/
private String docStoreDoc() {
return docStoreDoc;
}
/**
* Determine if and how the associated bean is included in the doc store document.
*/
@Override
public void docStoreInclude(boolean includeByDefault, DocStructure docStructure) {
String embeddedDoc = docStoreDoc();
if (embeddedDoc == null) {
// not annotated so use include by default
// which is *ToOne included and *ToMany excluded
if (includeByDefault) {
docStoreIncludeByDefault(docStructure.doc());
}
} else {
// explicitly annotated to be included
if (embeddedDoc.isEmpty()) {
embeddedDoc = "*";
}
// add in a nested way
PathProperties embDoc = PathProperties.parse(embeddedDoc);
docStructure.addNested(name, embDoc);
}
}
/**
* Include the property in the document store by default.
*/
void docStoreIncludeByDefault(PathProperties pathProps) {
pathProps.addToPath(null, name);
}
@Override
public void docStoreMapping(DocMappingBuilder mapping, String prefix) {
if (mapping.includesPath(prefix, name)) {
String fullName = SplitName.add(prefix, name);
DocPropertyType type = isMany() ? DocPropertyType.LIST : DocPropertyType.OBJECT;
DocPropertyMapping nested = new DocPropertyMapping(name, type);
mapping.push(nested);
targetDescriptor.docStoreMapping(mapping, fullName);
mapping.pop();
if (!nested.children().isEmpty()) {
mapping.add(nested);
}
}
}
/**
* Return true if this association is updateable.
*/
@@ -177,11 +177,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return manyToMany && !excludedFromHistory && descriptor.isHistorySupport();
}
@Override
protected void docStoreIncludeByDefault(PathProperties pathProps) {
// by default not including "Many" properties in document store
}
@Override
public void registerColumn(BeanDescriptor<?> desc, String prefix) {
if (targetDescriptor != null) {
@@ -343,13 +338,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
}
}
public void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds, boolean useDocStore) {
if (useDocStore) {
// assumes the ManyToOne property is included
query.where().in(childMasterIdProperty, parentIds);
} else {
sqlHelp.addWhereParentIdIn(query, parentIds);
}
public void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds) {
sqlHelp.addWhereParentIdIn(query, parentIds);
}
/**
@@ -873,10 +863,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return sqlHelp.insertElementCollection();
}
public boolean isTargetDocStoreMapped() {
return targetDescriptor.isDocStoreMapped();
}
void jsonWriteMapEntry(SpiJsonWriter ctx, Map.Entry<?, ?> entry) throws IOException {
if (elementDescriptor != null) {
elementDescriptor.jsonWriteMapEntry(ctx, entry);
@@ -1,78 +0,0 @@
package io.ebeaninternal.server.deploy;
import io.ebean.annotation.DocCode;
import io.ebean.annotation.DocProperty;
import io.ebean.annotation.DocSortable;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
/**
* The options for document property collected when reading deployment mapping.
*/
public final class DeployDocPropertyOptions {
private static final DocPropertyOptions EMPTY = new DocPropertyOptions();
private DocPropertyOptions mapping;
private void createOptions() {
if (mapping == null) {
mapping = new DocPropertyOptions();
}
}
/**
* Read the DocProperty deployment options.
*/
public void setDocProperty(DocProperty doc) {
createOptions();
mapping.apply(doc);
}
/**
* Read the DocSortable deployment options.
*/
public void setDocSortable(DocSortable doc) {
createOptions();
mapping.sortable(true);
setStore(doc.store());
setBoost(doc.boost());
setNullValue(doc.nullValue());
}
/**
* Read the DocCode deployment options.
*/
public void setDocCode(DocCode doc) {
createOptions();
mapping.code(true);
setStore(doc.store());
setBoost(doc.boost());
setNullValue(doc.nullValue());
}
private void setNullValue(String value) {
if (!value.isEmpty()) {
mapping.nullValue(value);
}
}
private void setBoost(float boost) {
if (Float.compare(boost, 1.0F) != 0) {
mapping.boost(boost);
}
}
private void setStore(boolean store) {
if (store) {
mapping.store(true);
}
}
/**
* Return the DocPropertyOptions with the collected options.
*/
public DocPropertyOptions create() {
return (mapping == null) ? EMPTY : mapping;
}
}
@@ -102,19 +102,6 @@ public class DeployBeanDescriptor<T> {
private String dbComment;
private PartitionMeta partitionMeta;
private TablespaceMeta tablespaceMeta;
/**
* One of NONE, INDEX or EMBEDDED.
*/
private boolean docStoreMapped;
private DocStore docStore;
private PathProperties docStorePathProperties;
private String docStoreQueueId;
private String docStoreIndexName;
private String docStoreIndexType;
private DocStoreMode docStorePersist;
private DocStoreMode docStoreInsert;
private DocStoreMode docStoreUpdate;
private DocStoreMode docStoreDelete;
private DeployBeanProperty idProperty;
private TableJoin primaryKeyJoin;
@@ -213,26 +200,6 @@ public class DeployBeanDescriptor<T> {
return tablespaceMeta;
}
/**
* Read the top level doc store deployment information.
*/
public void readDocStore(DocStore docStore) {
this.docStore = docStore;
docStoreMapped = true;
docStoreQueueId = docStore.queueId();
docStoreIndexName = docStore.indexName();
docStoreIndexType = docStore.indexType();
docStorePersist = docStore.persist();
docStoreInsert = docStore.insert();
docStoreUpdate = docStore.update();
docStoreDelete = docStore.delete();
String doc = docStore.doc();
if (!doc.isEmpty()) {
docStorePathProperties = PathProperties.parse(doc);
}
}
public boolean isScalaObject() {
Class<?>[] interfaces = beanType.getInterfaces();
for (Class<?> anInterface : interfaces) {
@@ -915,63 +882,6 @@ public class DeployBeanDescriptor<T> {
}
}
public PathProperties getDocStorePathProperties() {
return docStorePathProperties;
}
/**
* Return true if this type is mapped for a doc store.
*/
public boolean isDocStoreMapped() {
return docStoreMapped;
}
public String getDocStoreQueueId() {
return docStoreQueueId;
}
public String getDocStoreIndexName() {
return docStoreIndexName;
}
public String getDocStoreIndexType() {
return docStoreIndexType;
}
public DocStore getDocStore() {
return docStore;
}
/**
* Return the DocStore index behavior for bean inserts.
*/
public DocStoreMode getDocStoreInsertEvent() {
return getDocStoreIndexEvent(docStoreInsert);
}
/**
* Return the DocStore index behavior for bean updates.
*/
public DocStoreMode getDocStoreUpdateEvent() {
return getDocStoreIndexEvent(docStoreUpdate);
}
/**
* Return the DocStore index behavior for bean deletes.
*/
public DocStoreMode getDocStoreDeleteEvent() {
return getDocStoreIndexEvent(docStoreDelete);
}
private DocStoreMode getDocStoreIndexEvent(DocStoreMode mostSpecific) {
if (!docStoreMapped) {
return DocStoreMode.IGNORE;
}
if (mostSpecific != DocStoreMode.DEFAULT) return mostSpecific;
if (docStorePersist != DocStoreMode.DEFAULT) return docStorePersist;
return config.getDocStoreConfig().getPersist();
}
/**
* Parse the aggregation formula into expressions with table alias placeholders.
*/
@@ -10,13 +10,11 @@ import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import io.ebeaninternal.server.deploy.DeployDocPropertyOptions;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.properties.BeanPropertyGetter;
import io.ebeaninternal.server.properties.BeanPropertySetter;
import io.ebeaninternal.server.type.ScalarTypeWrapper;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.FetchType;
@@ -145,7 +143,6 @@ public class DeployBeanProperty {
* The jdbc data type this maps to.
*/
private int dbType;
private final DeployDocPropertyOptions docMapping = new DeployDocPropertyOptions();
private int propertyIndex;
private BeanPropertyGetter getter;
private BeanPropertySetter setter;
@@ -939,22 +936,6 @@ public class DeployBeanProperty {
return dbComment;
}
public void setDocProperty(DocProperty docProperty) {
docMapping.setDocProperty(docProperty);
}
public void setDocSortable(DocSortable docSortable) {
docMapping.setDocSortable(docSortable);
}
public void setDocCode(DocCode docCode) {
docMapping.setDocCode(docCode);
}
public DocPropertyOptions getDocPropertyOptions() {
return docMapping.create();
}
/**
* Return the DB Column default taking into account literal translation.
*/
@@ -33,7 +33,6 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
* From the deployment mappedBy attribute.
*/
private String mappedBy;
private String docStoreDoc;
private int fetchPreference = 1000;
private PropertyForeignKey foreignKey;
boolean orphanRemoval;
@@ -150,17 +149,6 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
return orphanRemoval;
}
/**
* Set DocStoreEmbedded deployment information.
*/
public void setDocStoreEmbedded(String embeddedDoc) {
this.docStoreDoc = embeddedDoc;
}
public String getDocStoreDoc() {
return docStoreDoc;
}
public int getFetchPreference() {
return fetchPreference;
}
@@ -227,9 +227,6 @@ final class AnnotationAssocOnes extends AnnotationAssoc {
}
private void readEmbedded(DeployBeanPropertyAssocOne<?> prop, Embedded embedded) {
if (descriptor.isDocStoreOnly() && prop.getDocStoreDoc() == null) {
prop.setDocStoreEmbedded("");
}
prop.setEmbedded();
prop.setDbInsertable(true);
prop.setDbUpdateable(true);
@@ -83,7 +83,6 @@ final class AnnotationClass extends AnnotationParser {
// maybe doc store only so check for this before @Entity
DocStore docStore = typeGet(cls, DocStore.class);
if (docStore != null) {
descriptor.readDocStore(docStore);
descriptor.setEntityType(EntityType.DOC);
descriptor.setName(cls.getSimpleName());
}
@@ -78,17 +78,8 @@ final class AnnotationFields extends AnnotationParser {
prop.setEmbedded();
info.setEmbeddedId(prop);
}
DocEmbedded docEmbedded = get(prop, DocEmbedded.class);
if (docEmbedded != null) {
prop.setDocStoreEmbedded(docEmbedded.doc());
if (descriptor.isDocStoreOnly()) {
if (has(prop, ManyToOne.class)) {
prop.setEmbedded();
prop.setDbInsertable(true);
prop.setDbUpdateable(true);
}
}
}
// TODO: Not Supported - DocEmbedded docEmbedded = get(prop, DocEmbedded.class);
if (prop instanceof DeployBeanPropertyAssocOne<?>) {
if (prop.isId() && !prop.isEmbedded()) {
prop.setEmbedded();
@@ -241,18 +232,10 @@ final class AnnotationFields extends AnnotationParser {
}
private void initFormula(DeployBeanProperty prop) {
DocCode docCode = get(prop, DocCode.class);
if (docCode != null) {
prop.setDocCode(docCode);
}
DocSortable docSortable = get(prop, DocSortable.class);
if (docSortable != null) {
prop.setDocSortable(docSortable);
}
DocProperty docProperty = get(prop, DocProperty.class);
if (docProperty != null) {
prop.setDocProperty(docProperty);
}
// TODO: Not Supported - DocCode docCode = get(prop, DocCode.class);
//DocSortable docSortable = get(prop, DocSortable.class);
//DocProperty docProperty = get(prop, DocProperty.class);
Formula formula = prop.getMetaAnnotationFormula(platform);
if (formula != null) {
prop.setSqlFormula(processFormula(formula.select()), processFormula(formula.join()));
@@ -1,7 +1,6 @@
package io.ebeaninternal.server.expression;
import io.ebean.event.BeanQueryRequest;
import io.ebean.util.SplitName;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.el.ElPropertyDeploy;
@@ -45,21 +44,6 @@ abstract class AbstractExpression implements SpiExpression {
return this;
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return propertyNestedPath(propName, desc);
}
protected String propertyNestedPath(String propertyName, BeanDescriptor<?> desc) {
if (propertyName != null) {
ElPropertyDeploy elProp = desc.elPropertyDeploy(propertyName);
if (elProp != null && elProp.containsMany()) {
return SplitName.begin(propName);
}
}
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
propertyContainsMany(propName, desc, manyWhereJoin);
@@ -21,16 +21,6 @@ final class AllEqualsExpression extends NonPrepareExpression {
return propName;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeAllEquals(propMap);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
if (propMap != null) {
@@ -23,23 +23,6 @@ final class ArrayContainsExpression extends AbstractExpression {
}
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (values.length == 1) {
context.writeEqualTo(propName, values[0]);
} else {
if (contains) {
context.startBoolMust();
} else {
context.startBoolMustNot();
}
for (Object value : values) {
context.writeEqualTo(propName, value);
}
context.endBool();
}
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("ArrayContains[").append(propName)
@@ -4,8 +4,6 @@ import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import java.io.IOException;
/**
* IsEmpty expression for ARRAY type.
*/
@@ -18,11 +16,6 @@ final class ArrayIsEmptyExpression extends AbstractExpression {
this.empty = empty;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeExists(!empty, propName);
}
@Override
public void queryPlanHash(StringBuilder builder) {
if (empty) {
@@ -5,8 +5,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class BetweenExpression extends AbstractExpression {
private static final String _BETWEEN = " between ? and ?";
@@ -28,11 +26,6 @@ final class BetweenExpression extends AbstractExpression {
return NamedParamHelp.value(valueHigh);
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeRange(propName, Op.GT_EQ, low(), Op.LT_EQ, high());
}
@Override
public void addBindValues(SpiExpressionRequest request) {
ElPropertyValue prop = getElProp(request);
@@ -1,12 +1,9 @@
package io.ebeaninternal.server.expression;
import io.ebean.util.SplitName;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.el.ElPropertyDeploy;
import java.io.IOException;
/**
* Between expression where a value is between two properties.
*/
@@ -38,24 +35,6 @@ final class BetweenPropertyExpression extends NonPrepareExpression {
return NamedParamHelp.value(value);
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.startBoolMust();
context.writeSimple(Op.LT_EQ, lowProperty, val());
context.writeSimple(Op.GT_EQ, highProperty, val());
context.endBool();
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
ElPropertyDeploy elProp = desc.elPropertyDeploy(name(lowProperty));
if (elProp != null && elProp.containsMany()) {
// assumes highProperty is also nested property which seems reasonable
return SplitName.begin(lowProperty);
}
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
ElPropertyDeploy elProp = desc.elPropertyDeploy(name(lowProperty));
@@ -22,11 +22,6 @@ final class BitwiseExpression extends AbstractExpression {
this.match = match;
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new IllegalStateException("Not supported for document queries");
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("Bitwise[");
@@ -5,8 +5,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class CaseInsensitiveEqualExpression extends AbstractValueExpression {
private final boolean not;
@@ -23,15 +21,6 @@ final class CaseInsensitiveEqualExpression extends AbstractValueExpression {
return strValue().toLowerCase();
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (not) {
context.writeINotEqualTo(propName, val());
} else {
context.writeIEqualTo(propName, val());
}
}
@Override
public void addBindValues(SpiExpressionRequest request) {
ElPropertyValue prop = getElProp(request);
@@ -15,7 +15,6 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
import java.io.IOException;
import java.util.ArrayList;
/**
@@ -107,17 +106,6 @@ final class DefaultExampleExpression implements SpiExpression, ExampleExpression
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (!list.isEmpty()) {
context.startBoolMust();
for (SpiExpression expr : list) {
expr.writeDocQuery(context);
}
context.endBool();
}
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
@@ -129,11 +117,6 @@ final class DefaultExampleExpression implements SpiExpression, ExampleExpression
return new DefaultExampleExpression(list);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins) {
list = buildExpressions(desc);
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.expression;
import io.ebean.*;
import io.ebean.bean.EntityBean;
import io.ebean.search.*;
import io.ebeaninternal.api.SpiExpressionFactory;
import io.ebeaninternal.api.SpiQuery;
@@ -40,31 +39,6 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
return new DefaultExpressionList<>(this);
}
@Override
public Expression textMatch(String propertyName, String search, Match options) {
return new TextMatchExpression(propertyName, search, options);
}
@Override
public Expression textMultiMatch(String query, MultiMatch options) {
return new TextMultiMatchExpression(query, options);
}
@Override
public Expression textSimple(String search, TextSimple options) {
return new TextSimpleExpression(search, options);
}
@Override
public Expression textQueryString(String search, TextQueryString options) {
return new TextQueryStringExpression(search, options);
}
@Override
public Expression textCommonTerms(String search, TextCommonTerms options) {
return new TextCommonTermsExpression(search, options);
}
@Override
public Expression jsonExists(String propertyName, String path) {
return new JsonPathExpression(propertyName, path, Op.EXISTS, null);
@@ -4,11 +4,9 @@ import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.*;
import io.ebean.event.BeanQueryRequest;
import io.ebean.search.*;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.*;
@@ -27,29 +25,12 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
protected final Query<T> query;
private final ExpressionList<T> parentExprList;
protected final ExpressionFactory expr;
String allDocNestedPath;
/**
* Set to true for the "Text" root expression list.
*/
private final boolean textRoot;
/**
* Construct for Text root expression list - this handles implicit Bool Should, Must etc.
*/
public DefaultExpressionList(Query<T> query) {
this(query, query.getExpressionFactory(), null, new ArrayList<>(), true);
}
public DefaultExpressionList(Query<T> query, ExpressionList<T> parentExprList) {
this(query, query.getExpressionFactory(), parentExprList, new ArrayList<>());
}
DefaultExpressionList(Query<T> query, ExpressionFactory expr, ExpressionList<T> parentExprList, List<SpiExpression> list) {
this(query, expr, parentExprList, list, false);
}
private DefaultExpressionList(Query<T> query, ExpressionFactory expr, ExpressionList<T> parentExprList, List<SpiExpression> list, boolean textRoot) {
this.textRoot = textRoot;
this.list = list;
this.query = query;
this.expr = expr;
@@ -64,23 +45,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
this(null, null, null, new ArrayList<>());
}
/**
* Wrap the expression list as a Junction or top level DefaultExpressionList.
*
* @param list The list of expressions grouped by nested path
* @param nestedPath The doc store nested path
* @param type The junction type (or null for top level expression list).
* @return A single SpiExpression that has the nestedPath set
*/
SpiExpression wrap(List<SpiExpression> list, String nestedPath, Junction.Type type) {
DefaultExpressionList<T> wrapper = new DefaultExpressionList<>(query, expr, null, list, false);
wrapper.setAllDocNested(nestedPath);
if (type != null) {
return new JunctionExpression<>(type, wrapper);
} else {
return wrapper;
}
}
void simplifyEntries() {
for (SpiExpression expr : list) {
@@ -111,90 +75,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
simplifyEntries();
}
/**
* Write being aware if it is the Top level "text" expressions.
* <p>
* If this is the Top level "text" expressions then it detects if explicit or implicit Bool Should, Must etc is required
* to wrap the expressions.
* <p>
* If implicit Bool is required SHOULD is used.
*/
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (!textRoot) {
writeDocQuery(context, null);
} else {
// this is a Top level "text" expressions, so we may need to wrap in Bool SHOULD etc.
if (list.isEmpty()) {
throw new IllegalStateException("empty expression list?");
}
if (allDocNestedPath != null) {
context.startNested(allDocNestedPath);
}
int size = list.size();
SpiExpression first = list.get(0);
boolean explicitBool = first instanceof SpiJunction<?>;
boolean implicitBool = !explicitBool && size > 1;
if (implicitBool || explicitBool) {
context.startBoolGroup();
}
if (implicitBool) {
context.startBoolGroupList(Junction.Type.SHOULD);
}
for (SpiExpression expr : list) {
if (explicitBool) {
try {
((SpiJunction<?>) expr).writeDocQueryJunction(context);
} catch (ClassCastException e) {
throw new IllegalStateException("The top level text() expressions should be all be 'Must', 'Should' or 'Must Not' or none of them should be.", e);
}
} else {
expr.writeDocQuery(context);
}
}
if (implicitBool) {
context.endBoolGroupList();
}
if (implicitBool || explicitBool) {
context.endBoolGroup();
}
if (allDocNestedPath != null) {
context.endNested();
}
}
}
@Override
public void writeDocQuery(DocQueryContext context, SpiExpression idEquals) throws IOException {
if (allDocNestedPath != null) {
context.startNested(allDocNestedPath);
}
int size = list.size();
if (size == 1 && idEquals == null) {
// only 1 expression - skip bool
list.get(0).writeDocQuery(context);
} else if (size == 0 && idEquals != null) {
// only idEquals - skip bool
idEquals.writeDocQuery(context);
} else {
// bool must wrap all the children
context.startBoolMust();
if (idEquals != null) {
idEquals.writeDocQuery(context);
}
for (SpiExpression expr : list) {
expr.writeDocQuery(context);
}
context.endBool();
}
if (allDocNestedPath != null) {
context.endNested();
}
}
@Override
public SpiExpressionList<?> trimPath(int prefixTrim) {
throw new IllegalStateException("Only allowed on FilterExpressionList");
@@ -479,11 +359,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.setDistinct(distinct);
}
@Override
public Query<T> setDocIndexName(String indexName) {
return query.setDocIndexName(indexName);
}
@Override
public ExpressionList<T> setFirstRow(int firstRow) {
query.setFirstRow(firstRow);
@@ -521,11 +396,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.setCountDistinct(orderBy);
}
@Override
public Query<T> setUseDocStore(boolean useDocsStore) {
return query.setUseDocStore(useDocsStore);
}
@Override
public Query<T> setDisableLazyLoading(boolean disableLazyLoading) {
return query.setDisableLazyLoading(disableLazyLoading);
@@ -596,12 +466,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("List[");
if (textRoot) {
builder.append("textRoot:true ");
}
if (allDocNestedPath != null) {
builder.append("path:").append(allDocNestedPath).append(' ');
}
for (SpiExpression expr : list) {
expr.queryPlanHash(builder);
builder.append(',');
@@ -1133,46 +997,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return add(expr.startsWith(propertyName, value));
}
@Override
public ExpressionList<T> match(String propertyName, String search) {
return match(propertyName, search, null);
}
@Override
public ExpressionList<T> match(String propertyName, String search, Match options) {
setUseDocStore(true);
return add(expr.textMatch(propertyName, search, options));
}
@Override
public ExpressionList<T> multiMatch(String query, String... fields) {
return multiMatch(query, MultiMatch.fields(fields));
}
@Override
public ExpressionList<T> multiMatch(String query, MultiMatch options) {
setUseDocStore(true);
return add(expr.textMultiMatch(query, options));
}
@Override
public ExpressionList<T> textSimple(String search, TextSimple options) {
setUseDocStore(true);
return add(expr.textSimple(search, options));
}
@Override
public ExpressionList<T> textQueryString(String search, TextQueryString options) {
setUseDocStore(true);
return add(expr.textQueryString(search, options));
}
@Override
public ExpressionList<T> textCommonTerms(String search, TextCommonTerms options) {
setUseDocStore(true);
return add(expr.textCommonTerms(search, options));
}
protected Junction<T> junction(Junction.Type type) {
Junction<T> junction = expr.junction(type, query, this);
add(junction);
@@ -1224,37 +1048,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return junction(Junction.Type.OR);
}
@Override
public Junction<T> must() {
setUseDocStore(true);
return junction(Junction.Type.MUST);
}
@Override
public Junction<T> should() {
setUseDocStore(true);
return junction(Junction.Type.SHOULD);
}
@Override
public Junction<T> mustNot() {
setUseDocStore(true);
return junction(Junction.Type.MUST_NOT);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
// effectively handled by JunctionExpression
return null;
}
/**
* Set the nested path that all contained expressions share.
*/
public void setAllDocNested(String allDocNestedPath) {
this.allDocNestedPath = allDocNestedPath;
}
/**
* Replace the underlying expression list with one organised by nested path.
*/
@@ -1262,13 +1055,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
this.list = groupedByNesting;
}
/**
* Prepare expressions for document store nested path handling.
*/
public void prepareDocNested(BeanDescriptor<T> beanDescriptor) {
PrepareDocNested.prepare(this, beanDescriptor);
}
public Object idEqualTo(String idName) {
if (idName == null) {
return null;
@@ -1,177 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.Junction;
import io.ebean.LikeType;
import io.ebean.plugin.ExpressionPath;
import io.ebean.search.Match;
import io.ebean.search.MultiMatch;
import io.ebean.search.TextCommonTerms;
import io.ebean.search.TextQueryString;
import io.ebean.search.TextSimple;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
/**
* Context for writing a doc store query.
*/
public interface DocQueryContext {
/**
* Start a junction.
*/
void startBool(Junction.Type type) throws IOException;
/**
* Start a conjunction.
*/
void startBoolMust() throws IOException;
/**
* Start a boolean NOT.
*/
void startBoolMustNot() throws IOException;
/**
* End a bool expression/group.
*/
void endBool() throws IOException;
/**
* Write a equalTo expression.
*/
void writeEqualTo(String propertyName, Object value) throws IOException;
/**
* Write a case insensitive equalTo expression.
*/
void writeIEqualTo(String propName, String value) throws IOException;
/**
* Write a case insensitive notEqualTo expression.
*/
default void writeINotEqualTo(String propName, String value) throws IOException {
throw new AbstractMethodError("writeINotEqualTo not implemented");
}
/**
* Write a range operation with one value.
*/
void writeRange(String propertyName, String rangeType, Object value) throws IOException;
/**
* Write a range operation with a lower and upper values.
*/
void writeRange(String propertyName, Op lowOp, Object valueLow, Op highOp, Object valueHigh) throws IOException;
/**
* Write an In expression.
*/
void writeIn(String propertyName, Object[] values, boolean not) throws IOException;
/**
* Write an ID in expression.
*/
void writeIds(Collection<?> idCollection) throws IOException;
/**
* Write an Id equals expression.
*/
void writeId(Object value) throws IOException;
/**
* Write a raw expression with bind values (might not be supported).
*/
void writeRaw(String raw, Object[] values) throws IOException;
/**
* Write an exists expression.
*/
void writeExists(boolean notNull, String propertyName) throws IOException;
/**
* Write one of the base expressions.
*/
void writeSimple(Op type, String propertyName, Object value) throws IOException;
/**
* Write an all equals expression.
*/
void writeAllEquals(Map<String, Object> propMap) throws IOException;
/**
* Write a Like expression.
*/
void writeLike(String propName, String val, LikeType type, boolean caseInsensitive) throws IOException;
/**
* Write a Match expression.
*/
void writeMatch(String propName, String search, Match options) throws IOException;
/**
* Write a Multi-match expression.
*/
void writeMultiMatch(String search, MultiMatch options) throws IOException;
/**
* Write a simple expression.
*/
void writeTextSimple(String search, TextSimple options) throws IOException;
/**
* Write a common terms expression.
*/
void writeTextCommonTerms(String search, TextCommonTerms options) throws IOException;
/**
* Write a query string expression.
*/
void writeTextQueryString(String search, TextQueryString options) throws IOException;
/**
* Start a Bool which may contain Must, Must Not, Should.
*/
void startBoolGroup() throws IOException;
/**
* Start a Must, Must Not or Should list.
*/
void startBoolGroupList(Junction.Type type) throws IOException;
/**
* End a Must, Must Not or Should list.
*/
void endBoolGroupList() throws IOException;
/**
* End the Bool group.
*/
void endBoolGroup() throws IOException;
/**
* Return the expression path for the given property path.
*/
ExpressionPath getExpressionPath(String propName);
/**
* Start nested path expressions.
*/
void startNested(String nestedPath) throws IOException;
/**
* End nested path expressions.
*/
void endNested() throws IOException;
/**
* Start a not wrapping an expression.
*/
void startNot() throws IOException;
/**
* End a not wrapper.
*/
void endNot() throws IOException;
}
@@ -48,11 +48,6 @@ final class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreE
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new IllegalStateException("Not supported");
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
@@ -119,11 +114,6 @@ final class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreE
return true;
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins) {
// Nothing to do for exists expression
@@ -34,11 +34,6 @@ final class ExistsSqlQueryExpression implements SpiExpression, UnsupportedDocSto
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new IllegalStateException("Not supported");
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
@@ -89,11 +84,6 @@ final class ExistsSqlQueryExpression implements SpiExpression, UnsupportedDocSto
return Arrays.equals(bindParams, that.bindParams);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins) {
// Nothing to do for exists expression
@@ -3,8 +3,6 @@ package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.io.IOException;
/**
* Slightly redundant as Query.setId() ultimately also does the same job.
*/
@@ -21,16 +19,6 @@ final class IdExpression extends NonPrepareExpression implements SpiExpression {
throw new IllegalStateException("Not allowed?");
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeId(value);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
/**
* Always returns false.
*/
@@ -6,7 +6,6 @@ import io.ebeaninternal.server.core.BindPadding;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.id.IdBinder;
import java.io.IOException;
import java.util.*;
/**
@@ -41,20 +40,10 @@ public final class IdInExpression extends NonPrepareExpression implements IdInCo
}
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeIds(idCollection);
}
@Override
public void validate(SpiExpressionValidation validation) {
// always valid
@@ -9,7 +9,6 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.persist.MultiValueWrapper;
import java.io.IOException;
import java.util.*;
public final class InExpression extends AbstractExpression implements IdInCommon {
@@ -95,13 +94,6 @@ public final class InExpression extends AbstractExpression implements IdInCommon
}
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (!empty) {
context.writeIn(propName, values().toArray(), not);
}
}
@Override
public void addBindValues(SpiExpressionRequest request) {
if (empty) {
@@ -52,11 +52,6 @@ final class InPairsExpression extends AbstractExpression {
multiValueSupported = request.isMultiValueSupported(String.class);
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new RuntimeException("Not supported with document query");
}
@Override
public void addBindValues(SpiExpressionRequest request) {
@@ -5,8 +5,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class InRangeExpression extends AbstractExpression {
private final Object valueHigh;
@@ -26,11 +24,6 @@ final class InRangeExpression extends AbstractExpression {
return NamedParamHelp.value(valueHigh);
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeRange(propName, Op.GT_EQ, low(), Op.LT, high());
}
@Override
public void addBindValues(SpiExpressionRequest request) {
ElPropertyValue prop = getElProp(request);
@@ -31,11 +31,6 @@ final class InTuplesExpression extends AbstractExpression {
return false;
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new RuntimeException("Not supported with document query");
}
@Override
public void addBindValues(SpiExpressionRequest request) {
for (Object[] entry : entries) {
@@ -8,8 +8,6 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class IsEmptyExpression extends AbstractExpression {
private final boolean empty;
@@ -22,32 +20,6 @@ final class IsEmptyExpression extends AbstractExpression {
this.propertyPath = SplitName.split(propertyName)[0];
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
if (empty) {
// capture the nestedPath as we want to put wrap
// a NOT around the outer of the nested path exists
this.nestedPath = propertyNestedPath(propName, desc);
return null;
} else {
return super.nestedPath(desc);
}
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (nestedPath == null) {
context.writeExists(!empty, propName);
} else {
// wrap bool must not around the outside of nested path exists expression
context.startBoolMustNot();
context.startNested(nestedPath);
context.writeExists(empty, propName);
context.endNested();
context.endBool();
}
}
public String getPropName() {
return propName;
}
@@ -4,7 +4,6 @@ import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import java.io.IOException;
import java.util.Objects;
/**
@@ -60,16 +59,6 @@ final class JsonPathExpression extends AbstractExpression {
this.upperValue = upperValue;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
String fullName = propName + "." + path;
if (operator == Op.BETWEEN) {
context.writeRange(fullName, Op.GT_EQ, value, Op.LT_EQ, upperValue);
} else {
context.writeSimple(operator, fullName, value);
}
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("JsonPath[");
@@ -4,7 +4,6 @@ import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.*;
import io.ebean.event.BeanQueryRequest;
import io.ebean.search.*;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -81,24 +80,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return new JunctionExpression<>(type, exprList.copyForPlanKey());
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.startBool(type);
for (SpiExpression expr : exprList.internalList()) {
expr.writeDocQuery(context);
}
context.endBool();
}
@Override
public void writeDocQueryJunction(DocQueryContext context) throws IOException {
context.startBoolGroupList(type);
for (SpiExpression expr : exprList.internalList()) {
expr.writeDocQuery(context);
}
context.endBoolGroupList();
}
@Override
public Object getIdEqualTo(String idName) {
// always null for this expression
@@ -197,41 +178,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return type == that.type && exprList.isSameByBind(that.exprList);
}
@Override
public ExpressionList<T> match(String propertyName, String search) {
return match(propertyName, search, null);
}
@Override
public ExpressionList<T> match(String propertyName, String search, Match options) {
return exprList.match(propertyName, search, options);
}
@Override
public ExpressionList<T> multiMatch(String query, String... properties) {
return exprList.multiMatch(query, properties);
}
@Override
public ExpressionList<T> multiMatch(String query, MultiMatch options) {
return exprList.multiMatch(query, options);
}
@Override
public ExpressionList<T> textSimple(String search, TextSimple options) {
return exprList.textSimple(search, options);
}
@Override
public ExpressionList<T> textQueryString(String search, TextQueryString options) {
return exprList.textQueryString(search, options);
}
@Override
public ExpressionList<T> textCommonTerms(String search, TextCommonTerms options) {
return exprList.textCommonTerms(search, options);
}
@Override
public ExpressionList<T> allEq(Map<String, Object> propertyMap) {
return exprList.allEq(propertyMap);
@@ -945,11 +891,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return exprList.setDistinct(distinct);
}
@Override
public Query<T> setDocIndexName(String indexName) {
return exprList.setDocIndexName(indexName);
}
@Override
public ExpressionList<T> setFirstRow(int firstRow) {
return exprList.setFirstRow(firstRow);
@@ -980,11 +921,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return exprList.setUseQueryCache(useCache);
}
@Override
public Query<T> setUseDocStore(boolean useDocsStore) {
return exprList.setUseDocStore(useDocsStore);
}
@Override
public Query<T> setDisableLazyLoading(boolean disableLazyLoading) {
return exprList.setDisableLazyLoading(disableLazyLoading);
@@ -1035,21 +971,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return exprList.disjunction();
}
@Override
public Junction<T> must() {
return exprList.must();
}
@Override
public Junction<T> should() {
return exprList.should();
}
@Override
public Junction<T> mustNot() {
return exprList.mustNot();
}
@Override
public ExpressionList<T> endJunction() {
return exprList.endJunction();
@@ -1070,18 +991,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return endJunction();
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
PrepareDocNested.prepare(exprList, desc, type);
String nestedPath = exprList.allDocNestedPath;
if (nestedPath != null) {
// push the nestedPath up to parent
exprList.setAllDocNested(null);
return nestedPath;
}
return null;
}
@Override
public ExpressionList<T> clear() {
return exprList.clear();
@@ -6,8 +6,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class LikeExpression extends AbstractValueExpression {
private final boolean caseInsensitive;
@@ -19,11 +17,6 @@ final class LikeExpression extends AbstractValueExpression {
this.type = type;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeLike(propName, strValue(), type, caseInsensitive);
}
@Override
public void addBindValues(SpiExpressionRequest request) {
ElPropertyValue prop = getElProp(request);
@@ -1,7 +1,6 @@
package io.ebeaninternal.server.expression;
import io.ebean.Expression;
import io.ebean.Junction;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.ManyWhereJoins;
@@ -11,8 +10,6 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiExpressionValidation;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.io.IOException;
/**
* A logical And or, Or for joining two expressions.
*/
@@ -73,35 +70,6 @@ abstract class LogicExpression implements SpiExpression {
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.startBool(conjunction ? Junction.Type.AND : Junction.Type.OR);
expOne.writeDocQuery(context);
expTwo.writeDocQuery(context);
context.endBool();
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
String pathOne = expOne.nestedPath(desc);
String pathTwo = expTwo.nestedPath(desc);
if (pathOne == null && pathTwo == null) {
return null;
}
if (pathOne != null && pathOne.equals(pathTwo)) {
return pathOne;
}
if (pathOne != null) {
expOne = new NestedPathWrapperExpression(pathOne, expOne);
}
if (pathTwo != null) {
expTwo = new NestedPathWrapperExpression(pathTwo, expTwo);
}
return null;
}
@Override
public Object getIdEqualTo(String idName) {
@@ -6,8 +6,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
final class NativeILikeExpression extends AbstractExpression {
private final String val;
@@ -17,11 +15,6 @@ final class NativeILikeExpression extends AbstractExpression {
this.val = value;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeLike(propName, val, LikeType.RAW, true);
}
@Override
public void addBindValues(SpiExpressionRequest request) {
@@ -1,110 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.ManyWhereJoins;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiExpressionValidation;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.api.NaturalKeyQueryData;
import java.io.IOException;
/**
* Wraps a single expression with nestedPath for document queries.
*/
final class NestedPathWrapperExpression implements SpiExpression {
final String nestedPath;
final SpiExpression delegate;
NestedPathWrapperExpression(String nestedPath, SpiExpression delegate) {
this.nestedPath = nestedPath;
this.delegate = delegate;
}
@Override
public void prefixProperty(String path) {
// do nothing
}
@Override
public boolean naturalKey(NaturalKeyQueryData<?> data) {
// can't use naturalKey cache
return false;
}
@Override
public void simplify() {
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.startNested(nestedPath);
delegate.writeDocQuery(context);
context.endNested();
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
return null;
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return nestedPath;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins) {
delegate.containsMany(desc, whereManyJoins);
}
@Override
public void prepareExpression(BeanQueryRequest<?> request) {
delegate.prepareExpression(request);
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("NestedPath[");
if (nestedPath != null) {
builder.append("path:").append(nestedPath).append(' ');
}
delegate.queryPlanHash(builder);
builder.append(']');
}
@Override
public void queryBindKey(BindValuesKey key) {
delegate.queryBindKey(key);
}
@Override
public boolean isSameByBind(SpiExpression other) {
return delegate.isSameByBind(other);
}
@Override
public void addSql(SpiExpressionRequest request) {
delegate.addSql(request);
}
@Override
public void addBindValues(SpiExpressionRequest request) {
delegate.addBindValues(request);
}
@Override
public void validate(SpiExpressionValidation validation) {
delegate.validate(validation);
}
@Override
public SpiExpression copyForPlanKey() {
return new NestedPathWrapperExpression(nestedPath, delegate.copyForPlanKey());
}
}
@@ -32,21 +32,12 @@ final class NoopExpression implements SpiExpression {
return this;
}
@Override
public void writeDocQuery(DocQueryContext context) {
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
return null;
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins) {
// nothing to do
@@ -10,8 +10,6 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiExpressionValidation;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.io.IOException;
final class NotExpression implements SpiExpression {
private static final String NOT_START = "not (";
@@ -39,13 +37,6 @@ final class NotExpression implements SpiExpression {
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.startBoolMustNot();
exp.writeDocQuery(context);
context.endBool();
}
@Override
public Object getIdEqualTo(String idName) {
// always return null for this expression
@@ -57,11 +48,6 @@ final class NotExpression implements SpiExpression {
return new NotExpression(exp.copyForPlanKey());
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return exp.nestedPath(desc);
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
exp.containsMany(desc, manyWhereJoin);
@@ -8,9 +8,6 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
/**
* Null / Not Null expression.
* <p>
@@ -45,11 +42,6 @@ final class NullExpression extends AbstractExpression {
}
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeExists(notNull, propName);
}
@Override
public void addBindValues(SpiExpressionRequest request) {
@@ -1,159 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.Junction;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Prepare nested path expressions for
*/
final class PrepareDocNested {
/**
* Prepare the top level expressions for nested path handling.
*/
static void prepare(DefaultExpressionList<?> expressions, BeanDescriptor<?> beanDescriptor) {
new PrepareDocNested(expressions, beanDescriptor, null).process();
}
/**
* Prepare the Junction expressions for nested path handling.
*/
static void prepare(DefaultExpressionList<?> expressions, BeanDescriptor<?> beanDescriptor, Junction.Type type) {
new PrepareDocNested(expressions, beanDescriptor, type).process();
}
enum Mode {
NONE,
SINGLE,
MIXED
}
private final Junction.Type type;
private final DefaultExpressionList<?> original;
private final BeanDescriptor<?> beanDescriptor;
private final List<SpiExpression> origUnderlying;
private final int origSize;
private boolean hasNesting;
private boolean hasMixedNesting;
private String firstNestedPath;
PrepareDocNested(DefaultExpressionList<?> original, BeanDescriptor<?> beanDescriptor, Junction.Type type) {
this.type = type;
this.beanDescriptor = beanDescriptor;
this.original = original;
this.origUnderlying = original.underlyingList();
this.origSize = origUnderlying.size();
}
void process() {
PrepareDocNested.Mode mode = determineMode();
if (mode == PrepareDocNested.Mode.SINGLE) {
original.setAllDocNested(firstNestedPath);
} else if (mode == PrepareDocNested.Mode.MIXED) {
original.setUnderlying(group());
}
}
/**
* Reorganise the flat list of expressions into a tree grouping expressions by nested path.
* <p>
* Returns the new top level list of expressions.
*/
private List<SpiExpression> group() {
Map<String, Group> groups = new LinkedHashMap<>();
// organise expressions by nestedPath
for (int i = 0; i < origSize; i++) {
SpiExpression expr = origUnderlying.get(i);
String nestedPath = expr.nestedPath(beanDescriptor);
Group group = groups.computeIfAbsent(nestedPath, Group::new);
group.list.add(expr);
}
List<SpiExpression> newList = new ArrayList<>();
Collection<Group> values = groups.values();
for (Group group : values) {
group.addTo(newList);
}
return newList;
}
/**
* Determined the nested path mode.
*/
private Mode determineMode() {
if (!hasNesting()) {
// no nested paths at all
return Mode.NONE;
}
if (!hasMixedNesting) {
// single nested path for all expressions
return Mode.SINGLE;
}
// mixed nested paths to underlying expression list needs re-organising by nested path
return Mode.MIXED;
}
/**
* Return true if the expressions have nested paths.
*/
private boolean hasNesting() {
for (int i = 0; i < origSize; i++) {
SpiExpression expr = origUnderlying.get(i);
String nestedPath = expr.nestedPath(beanDescriptor);
if (nestedPath == null) {
hasMixedNesting = true;
}
if (nestedPath != null) {
hasNesting = true;
if (firstNestedPath == null) {
firstNestedPath = nestedPath;
} else if (hasMixedNesting || !firstNestedPath.equals(nestedPath)) {
hasMixedNesting = true;
return true;
}
}
}
return hasNesting;
}
/**
* List of SpiExpression grouped by nested path.
*/
class Group {
final String nestedPath;
final List<SpiExpression> list = new ArrayList<>();
Group(String nestedPath) {
this.nestedPath = nestedPath;
}
void addTo(List<SpiExpression> newList) {
if (nestedPath == null) {
newList.addAll(list);
} else {
newList.add(original.wrap(list, nestedPath, type));
}
}
}
}
@@ -7,7 +7,6 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
import io.ebeaninternal.server.deploy.DeployPropertyParser;
import io.ebeaninternal.server.persist.MultiValueWrapper;
import java.io.IOException;
import java.util.Collection;
final class RawExpression extends NonPrepareExpression {
@@ -21,16 +20,6 @@ final class RawExpression extends NonPrepareExpression {
this.values = values;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeRaw(sql, values);
}
@Override
public String nestedPath(BeanDescriptor<?> desc) {
return null;
}
@Override
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
@@ -8,9 +8,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.el.ElPropertyValue;
import java.io.IOException;
import java.util.Arrays;
public final class SimpleExpression extends AbstractValueExpression {
private final Op type;
@@ -37,24 +34,6 @@ public final class SimpleExpression extends AbstractValueExpression {
return data.matchEq(propName, bindValue);
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
if (type == Op.BETWEEN) {
throw new IllegalStateException("BETWEEN Not expected in SimpleExpression?");
}
ExpressionPath prop = context.getExpressionPath(propName);
if (prop != null && prop.isAssocId()) {
String idName = prop.assocIdExpression(propName, "");
Object[] ids = prop.assocIdValues((EntityBean) value());
if (ids == null || ids.length != 1) {
throw new IllegalArgumentException("Expecting 1 Id value for " + idName + " but got " + Arrays.toString(ids));
}
context.writeSimple(type, idName, ids[0]);
} else {
context.writeSimple(type, propName, value());
}
}
public String getPropName() {
return propName;
}
@@ -41,11 +41,6 @@ final class SubQueryExpression extends AbstractExpression implements Unsupported
// do nothing
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new IllegalStateException("Not supported");
}
@Override
public void prepareExpression(BeanQueryRequest<?> request) {
CQuery<?> subQuery = compileSubQuery(request);
@@ -22,11 +22,6 @@ final class SubQueryRawExpression extends AbstractExpression implements Unsuppor
this.bindParams = bindParams;
}
@Override
public void writeDocQuery(DocQueryContext context) {
throw new IllegalStateException("Not supported");
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("SubQueryRaw[").append(propName).append(op.expression)
@@ -1,26 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.search.TextCommonTerms;
import java.io.IOException;
/**
* Full text common terms expression.
*/
final class TextCommonTermsExpression extends AbstractTextExpression {
private final String search;
private final TextCommonTerms options;
public TextCommonTermsExpression(String search, TextCommonTerms options) {
super(null);
this.search = search;
this.options = options;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeTextCommonTerms(search, options);
}
}
@@ -1,26 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.search.Match;
import java.io.IOException;
/**
* Full text MATCH expression.
*/
final class TextMatchExpression extends AbstractTextExpression {
private final String search;
private final Match options;
TextMatchExpression(String propertyName, String search, Match options) {
super(propertyName);
this.search = search;
this.options = options;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeMatch(propName, search, options);
}
}
@@ -1,26 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.search.MultiMatch;
import java.io.IOException;
/**
* Full text Multi-Match expression.
*/
final class TextMultiMatchExpression extends AbstractTextExpression {
private final String search;
private final MultiMatch options;
TextMultiMatchExpression(String search, MultiMatch options) {
super(null);
this.search = search;
this.options = options;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeMultiMatch(search, options);
}
}
@@ -1,26 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.search.TextQueryString;
import java.io.IOException;
/**
* Full text query string expression.
*/
final class TextQueryStringExpression extends AbstractTextExpression {
private final String search;
private final TextQueryString options;
TextQueryStringExpression(String search, TextQueryString options) {
super(null);
this.search = search;
this.options = options;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeTextQueryString(search, options);
}
}
@@ -1,26 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.search.TextSimple;
import java.io.IOException;
/**
* Full text Multi-Match expression.
*/
final class TextSimpleExpression extends AbstractTextExpression {
private final String search;
private final TextSimple options;
TextSimpleExpression(String search, TextSimple options) {
super(null);
this.search = search;
this.options = options;
}
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
context.writeTextSimple(search, options);
}
}
@@ -60,7 +60,7 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
query.setBeanCacheMode(CacheMode.ON);
}
setLabel(query);
parent.propagateQueryState(query, desc.isDocStoreMapped());
parent.propagateQueryState(query);
query.setParentNode(objectGraphNode);
query.setLazyLoadProperty(lazyLoadProperty);
if (queryProps != null) {
@@ -31,7 +31,6 @@ public final class DLoadContext implements LoadContext {
private final int defaultBatchSize;
private final boolean disableLazyLoading;
private final boolean includeSoftDeletes;
final boolean useDocStore;
/**
* The path relative to the root of the object graph.
@@ -51,7 +50,6 @@ public final class DLoadContext implements LoadContext {
* Construct for use with JSON marshalling (doc store).
*/
public DLoadContext(BeanDescriptor<?> rootDescriptor, PersistenceContext persistenceContext) {
this.useDocStore = true;
this.rootDescriptor = rootDescriptor;
this.ebeanServer = rootDescriptor.ebeanServer();
this.persistenceContext = persistenceContext;
@@ -82,7 +80,6 @@ public final class DLoadContext implements LoadContext {
this.rootDescriptor = request.descriptor();
SpiQuery<?> query = request.query();
this.useDocStore = query.isUseDocStore();
this.asOf = query.getAsOf();
this.includeSoftDeletes = query.isIncludeSoftDeletes() && query.mode() == SpiQuery.Mode.NORMAL;
this.readOnly = query.isReadOnly();
@@ -310,10 +307,7 @@ public final class DLoadContext implements LoadContext {
/**
* Propagate the original query settings (draft, asOf etc) to the secondary queries.
*/
void propagateQueryState(SpiQuery<?> query, boolean docStoreMapped) {
if (useDocStore && docStoreMapped) {
query.setUseDocStore(true);
}
void propagateQueryState(SpiQuery<?> query) {
if (readOnly != null) {
query.setReadOnly(readOnly);
}
@@ -23,14 +23,12 @@ import java.util.concurrent.locks.ReentrantLock;
final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
private final BeanPropertyAssocMany<?> property;
private final boolean docStoreMapped;
private List<LoadBuffer> bufferList;
private LoadBuffer currentBuffer;
DLoadManyContext(DLoadContext parent, BeanPropertyAssocMany<?> property, String path, OrmQueryProperties queryProps) {
super(parent, property.descriptor(), path, queryProps);
this.property = property;
this.docStoreMapped = property.isTargetDocStoreMapped();
// bufferList only required when using query joins (queryFetch)
this.bufferList = (!queryFetch) ? null : new ArrayList<>();
this.currentBuffer = createBuffer(batchSize);
@@ -56,7 +54,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
private void configureQuery(SpiQuery<?> query) {
setLabel(query);
parent.propagateQueryState(query, docStoreMapped);
parent.propagateQueryState(query);
query.setParentNode(objectGraphNode);
if (queryProps != null) {
queryProps.configureBeanQuery(query);
@@ -129,11 +127,6 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
this.batchSize = batchSize;
}
@Override
public boolean isUseDocStore() {
return context.parent.useDocStore && context.docStoreMapped;
}
@Override
public int batchSize() {
return batchSize;
@@ -24,7 +24,7 @@ public final class DmlBeanPersisterFactory implements BeanPersisterFactory {
@Override
public BeanPersister create(BeanDescriptor<?> desc) {
if (desc.isDocStoreOnly()) {
return new DocStoreBeanPersister(GeneratedProperties.of(desc));
return null;
}
UpdateMeta updMeta = metaFactory.createUpdate(desc);
DeleteMeta delMeta = metaFactory.createDelete(desc);
@@ -1,37 +0,0 @@
package io.ebeaninternal.server.persist.dml;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BeanPersister;
import jakarta.persistence.PersistenceException;
/**
* Document store based BeanPersister.
*/
final class DocStoreBeanPersister implements BeanPersister {
private final GeneratedProperties generatedProperties;
DocStoreBeanPersister(GeneratedProperties generatedProperties) {
this.generatedProperties = generatedProperties;
}
@Override
public void insert(PersistRequestBean<?> request) throws PersistenceException {
//request.setIdValueForDocStore();
generatedProperties.preInsert(request.entityBean(), request.now());
request.docStorePersist();
}
@Override
public void update(PersistRequestBean<?> request) throws PersistenceException {
generatedProperties.preUpdate(request.entityBean(), request.now());
request.docStorePersist();
}
@Override
public int delete(PersistRequestBean<?> request) throws PersistenceException {
request.docStorePersist();
return 0;
}
}
@@ -170,11 +170,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public Query<T> setDocIndexName(String indexName) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public ExpressionFactory getExpressionFactory() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
@@ -411,11 +406,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public ExpressionList<T> text() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public ExpressionList<T> filterMany(String propertyName) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
@@ -491,11 +481,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public Query<T> setUseDocStore(boolean useDocStore) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public Query<T> setReadOnly(boolean readOnly) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");

Some files were not shown because too many files have changed in this diff Show More