mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-06 08:33:18 +00:00
#566 - Refactor internals - Initial tidy on OrmQueryDetail and OrmQueryDetailProperties - internals for fetch paths etc
This commit is contained in:
1 parent
2fcaab44c6
commit
5c6d6608ef
12 files changed
+397
-145
No files matched your search
@@ -110,7 +110,7 @@ public class ProfileOrigin {
|
||||
Collection<Props> pathProperties = pathProps.getPathProps();
|
||||
for (Props props : pathProperties) {
|
||||
if (!props.isEmpty()) {
|
||||
detail.addFetch(props.getPath(), props.getPropertiesAsString(), null);
|
||||
detail.fetch(props.getPath(), props.getPropertiesAsString(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1252,7 +1252,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, SpiBeanType<T> {
|
||||
|
||||
OrmQueryDetail detail = query.getDetail();
|
||||
for (int i = 0; i < propertiesMany.length; i++) {
|
||||
if (detail.includes(propertiesMany[i].getName())) {
|
||||
if (detail.includesPath(propertiesMany[i].getName())) {
|
||||
return propertiesMany[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ public class CQueryBuilder {
|
||||
|
||||
// transfer PathProperties into OrmQueryDetail
|
||||
for (String path : pathProps.getPaths()) {
|
||||
detail.getChunk(path, true).setDefaultProperties(null, pathProps.get(path));
|
||||
detail.fetch(path, pathProps.get(path));
|
||||
}
|
||||
|
||||
// check if @Id property included in RawSql
|
||||
|
||||
@@ -140,7 +140,7 @@ public class SqlTreeBuilder {
|
||||
boolean includeJoins = (alias == null) ? false : alias.isIncludeJoins();
|
||||
|
||||
return new SqlTree(summary.toString(), rootNode, selectSql, fromSql, inheritanceWhereSql, encryptedProps,
|
||||
manyProperty, queryDetail.getIncludes(), includeJoins);
|
||||
manyProperty, queryDetail.getFetchPaths(), includeJoins);
|
||||
}
|
||||
|
||||
private String buildSelectClause() {
|
||||
@@ -183,7 +183,7 @@ public class SqlTreeBuilder {
|
||||
rootNode = buildSelectChain(null, null, desc, null);
|
||||
|
||||
if (!rawSql) {
|
||||
alias.addJoin(queryDetail.getIncludes(), desc);
|
||||
alias.addJoin(queryDetail.getFetchPaths(), desc);
|
||||
alias.addJoin(predicates.getPredicateIncludes(), desc);
|
||||
alias.addManyWhereJoins(manyWhereJoins.getPropertyNames());
|
||||
|
||||
@@ -471,7 +471,7 @@ public class SqlTreeBuilder {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryDetail.includes(propName)) {
|
||||
if (queryDetail.includesPath(propName)) {
|
||||
|
||||
if (manyProperty != null) {
|
||||
// only one many associated allowed to be included in fetch
|
||||
@@ -498,7 +498,7 @@ public class SqlTreeBuilder {
|
||||
*/
|
||||
private boolean isIncludeBean(String prefix) {
|
||||
|
||||
if (queryDetail.includes(prefix)) {
|
||||
if (queryDetail.includesPath(prefix)) {
|
||||
// explicitly included
|
||||
summary.append(", ").append(prefix);
|
||||
String[] splitNames = SplitName.split(prefix);
|
||||
|
||||
@@ -1008,7 +1008,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
}
|
||||
|
||||
public DefaultOrmQuery<T> fetch(String property, String columns, FetchConfig config) {
|
||||
detail.addFetch(property, columns, config);
|
||||
detail.fetch(property, columns, config);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ import javax.persistence.PersistenceException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents the internal structure of an Object Relational query.
|
||||
@@ -46,8 +46,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
*/
|
||||
private LinkedHashMap<String, OrmQueryProperties> fetchPaths = new LinkedHashMap<String, OrmQueryProperties>(8);
|
||||
|
||||
private LinkedHashSet<String> includes = new LinkedHashSet<String>(8);
|
||||
|
||||
/**
|
||||
* Return a deep copy of the OrmQueryDetail.
|
||||
*/
|
||||
@@ -57,7 +55,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
for (Map.Entry<String, OrmQueryProperties> entry : fetchPaths.entrySet()) {
|
||||
copy.fetchPaths.put(entry.getKey(), entry.getValue().copy());
|
||||
}
|
||||
copy.includes = new LinkedHashSet<String>(includes);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -170,7 +167,7 @@ public class OrmQueryDetail implements Serializable {
|
||||
* set the properties to include on the base / root entity.
|
||||
*/
|
||||
public void select(String columns) {
|
||||
baseProps = new OrmQueryProperties(null, columns);
|
||||
baseProps = new OrmQueryProperties(null, columns, null);
|
||||
}
|
||||
|
||||
public boolean containsProperty(String property) {
|
||||
@@ -215,7 +212,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
|
||||
for (int i = 0; i < matchingPaths.size(); i++) {
|
||||
String path = matchingPaths.get(i);
|
||||
includes.remove(path);
|
||||
OrmQueryProperties secQuery = fetchPaths.remove(path);
|
||||
if (secQuery != null) {
|
||||
props.add(secQuery);
|
||||
@@ -228,7 +224,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
// remove join to secondary query from the main query
|
||||
// and add to this secondary query
|
||||
pass2It.remove();
|
||||
includes.remove(pass2Prop.getPath());
|
||||
secQuery.add(pass2Prop);
|
||||
}
|
||||
}
|
||||
@@ -257,29 +252,24 @@ public class OrmQueryDetail implements Serializable {
|
||||
OrmQueryProperties tunedRoot = tunedDetail.getChunk(null, false);
|
||||
if (tunedRoot != null) {
|
||||
tuned = true;
|
||||
baseProps.setTunedProperties(tunedRoot);
|
||||
|
||||
baseProps = tunedRoot;
|
||||
for (OrmQueryProperties tunedChunk : tunedDetail.fetchPaths.values()) {
|
||||
OrmQueryProperties chunk = getChunk(tunedChunk.getPath(), false);
|
||||
if (chunk != null) {
|
||||
// set the properties to select
|
||||
chunk.setTunedProperties(tunedChunk);
|
||||
} else {
|
||||
// add a missing join
|
||||
putFetchPath(tunedChunk.copy());
|
||||
}
|
||||
fetch(tunedChunk.copy());
|
||||
}
|
||||
}
|
||||
return tuned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a join() method of the query.
|
||||
* Add or replace the fetch detail.
|
||||
*/
|
||||
public void putFetchPath(OrmQueryProperties chunk) {
|
||||
protected void fetch(OrmQueryProperties chunk) {
|
||||
String path = chunk.getPath();
|
||||
fetchPaths.put(path, chunk);
|
||||
includes.add(path);
|
||||
if (path == null) {
|
||||
baseProps = chunk;
|
||||
} else {
|
||||
fetchPaths.put(path, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +279,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
* </p>
|
||||
*/
|
||||
public void clear() {
|
||||
includes.clear();
|
||||
fetchPaths.clear();
|
||||
}
|
||||
|
||||
@@ -299,11 +288,16 @@ public class OrmQueryDetail implements Serializable {
|
||||
* @param path the property to join
|
||||
* @param partialProps the properties on the join property to include
|
||||
*/
|
||||
public void addFetch(String path, String partialProps, FetchConfig fetchConfig) {
|
||||
public void fetch(String path, String partialProps, FetchConfig fetchConfig) {
|
||||
|
||||
OrmQueryProperties chunk = getChunk(path, true);
|
||||
chunk.setProperties(partialProps);
|
||||
chunk.setFetchConfig(fetchConfig);
|
||||
fetch(new OrmQueryProperties(path, partialProps, fetchConfig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add for raw sql etc when the properties are already parsed into a set.
|
||||
*/
|
||||
public void fetch(String path, LinkedHashSet<String> properties) {
|
||||
fetch(new OrmQueryProperties(path, properties));
|
||||
}
|
||||
|
||||
public void sortFetchPaths(BeanDescriptor<?> d) {
|
||||
@@ -438,15 +432,14 @@ public class OrmQueryDetail implements Serializable {
|
||||
public void setDefaultSelectClause(BeanDescriptor<?> desc) {
|
||||
|
||||
if (desc.hasDefaultSelectClause() && !hasSelectClause()) {
|
||||
baseProps.setDefaultProperties(desc.getDefaultSelectClause(), desc.getDefaultSelectClauseSet());
|
||||
baseProps = new OrmQueryProperties(null, desc.getDefaultSelectClause());
|
||||
}
|
||||
|
||||
for (OrmQueryProperties joinProps : fetchPaths.values()) {
|
||||
if (!joinProps.hasSelectClause()) {
|
||||
BeanDescriptor<?> assocDesc = desc.getBeanDescriptor(joinProps.getPath());
|
||||
if (assocDesc.hasDefaultSelectClause()) {
|
||||
// use the default select clause
|
||||
joinProps.setDefaultProperties(assocDesc.getDefaultSelectClause(), assocDesc.getDefaultSelectClauseSet());
|
||||
fetch(joinProps.getPath(), assocDesc.getDefaultSelectClause(), joinProps.getFetchConfig());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,7 +482,7 @@ public class OrmQueryDetail implements Serializable {
|
||||
OrmQueryProperties props = fetchPaths.get(path);
|
||||
if (create && props == null) {
|
||||
props = new OrmQueryProperties(path);
|
||||
putFetchPath(props);
|
||||
fetch(props);
|
||||
return props;
|
||||
|
||||
} else {
|
||||
@@ -498,9 +491,9 @@ public class OrmQueryDetail implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the property is included.
|
||||
* Return true if the fetch path is included.
|
||||
*/
|
||||
public boolean includes(String path) {
|
||||
public boolean includesPath(String path) {
|
||||
|
||||
OrmQueryProperties chunk = fetchPaths.get(path);
|
||||
|
||||
@@ -509,9 +502,9 @@ public class OrmQueryDetail implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property includes for this detail.
|
||||
* Return the fetch paths for this detail.
|
||||
*/
|
||||
public HashSet<String> getIncludes() {
|
||||
return includes;
|
||||
public Set<String> getFetchPaths() {
|
||||
return fetchPaths.keySet();
|
||||
}
|
||||
}
|
||||
@@ -64,8 +64,7 @@ public class OrmQueryDetailParser {
|
||||
|
||||
private void process() {
|
||||
if (isFetch()) {
|
||||
OrmQueryProperties props = readFindFetch();
|
||||
detail.putFetchPath(props);
|
||||
detail.fetch(readFindFetch());
|
||||
|
||||
} else if (parser.isMatch("where")) {
|
||||
readWhere();
|
||||
@@ -157,7 +156,7 @@ public class OrmQueryDetailParser {
|
||||
private void readSelect() {
|
||||
String path = null;
|
||||
String props = parser.nextWord();
|
||||
if (props != null && props.startsWith("(")) {
|
||||
if (props.startsWith("(")) {
|
||||
props = props.substring(1, props.length() - 1);
|
||||
OrmQueryProperties base = new OrmQueryProperties(path, props);
|
||||
detail.setBase(base);
|
||||
|
||||
@@ -28,11 +28,11 @@ public class OrmQueryProperties implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8785582703966455658L;
|
||||
|
||||
private String parentPath;
|
||||
private String path;
|
||||
private final String parentPath;
|
||||
private final String path;
|
||||
|
||||
private String rawProperties;
|
||||
private String trimmedProperties;
|
||||
private final String rawProperties;
|
||||
private final String trimmedProperties;
|
||||
|
||||
/**
|
||||
* NB: -1 means no +query, 0 means use the default batch size.
|
||||
@@ -55,7 +55,7 @@ public class OrmQueryProperties implements Serializable {
|
||||
* Note this SHOULD be a LinkedHashSet to preserve order of the properties. This is to make using
|
||||
* SqlSelect easier with predictable property/column ordering.
|
||||
*/
|
||||
private LinkedHashSet<String> included;
|
||||
private final LinkedHashSet<String> included;
|
||||
|
||||
/**
|
||||
* Included bean joins.
|
||||
@@ -83,25 +83,110 @@ public class OrmQueryProperties implements Serializable {
|
||||
private SpiExpressionList filterMany;
|
||||
|
||||
/**
|
||||
* Construct with a given path (null == root path).
|
||||
* Construct for root so path (and parentPath) are null.
|
||||
*/
|
||||
public OrmQueryProperties() {
|
||||
this((String)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a given path.
|
||||
*/
|
||||
public OrmQueryProperties(String path) {
|
||||
this.path = path;
|
||||
this.parentPath = SplitName.parent(path);
|
||||
this.rawProperties = null;
|
||||
this.trimmedProperties = null;
|
||||
this.included = null;
|
||||
}
|
||||
|
||||
public OrmQueryProperties(String path, String rawProperties) {
|
||||
this(path, rawProperties, null);
|
||||
}
|
||||
|
||||
public OrmQueryProperties(String path, String rawProperties, FetchConfig fetchConfig) {
|
||||
|
||||
OrmQueryPropertiesParser.Response response = OrmQueryPropertiesParser.parse(rawProperties);
|
||||
|
||||
this.path = path;
|
||||
this.parentPath = SplitName.parent(path);
|
||||
this.rawProperties = rawProperties;
|
||||
this.trimmedProperties = response.properties;
|
||||
this.included = response.included;
|
||||
this.lazyFetchBatch = response.lazyFetchBatch;
|
||||
this.queryFetchBatch = response.queryFetchBatch;
|
||||
this.cache = response.cache;
|
||||
this.readOnly = response.readOnly;
|
||||
|
||||
if (fetchConfig != null) {
|
||||
this.fetchConfig = fetchConfig;
|
||||
lazyFetchBatch = fetchConfig.getLazyBatchSize();
|
||||
queryFetchBatch = fetchConfig.getQueryBatchSize();
|
||||
queryFetchAll = fetchConfig.isQueryAll();
|
||||
}
|
||||
}
|
||||
|
||||
public OrmQueryProperties(String path, LinkedHashSet<String> parsedProperties) {
|
||||
if (parsedProperties == null) {
|
||||
throw new IllegalArgumentException("parsedProperties is null");
|
||||
}
|
||||
|
||||
this.path = path;
|
||||
this.parentPath = SplitName.parent(path);
|
||||
// for rawSql parsedProperties can be empty (when only fetching Id property)
|
||||
this.included = parsedProperties;
|
||||
this.rawProperties = join(parsedProperties);
|
||||
this.trimmedProperties = rawProperties;
|
||||
this.lazyFetchBatch = -1;
|
||||
this.queryFetchBatch = -1;
|
||||
this.cache = false;
|
||||
this.readOnly = false;
|
||||
this.queryFetchAll = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for root so path (and parentPath) are null.
|
||||
* Join the set of properties into a comma delimited string.
|
||||
*/
|
||||
public OrmQueryProperties() {
|
||||
private String join(LinkedHashSet<String> parsedProperties) {
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
boolean first = true;
|
||||
for (String property : parsedProperties) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(property);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by query language parser.
|
||||
* Copy constructor.
|
||||
*/
|
||||
public OrmQueryProperties(String path, String properties) {
|
||||
this(path);
|
||||
setProperties(properties);
|
||||
private OrmQueryProperties(OrmQueryProperties source) {
|
||||
|
||||
this.parentPath = source.parentPath;
|
||||
this.path = source.path;
|
||||
this.rawProperties = source.rawProperties;
|
||||
this.trimmedProperties = source.trimmedProperties;
|
||||
this.cache = source.cache;
|
||||
this.readOnly = source.readOnly;
|
||||
this.queryFetchAll = source.queryFetchAll;
|
||||
this.queryFetchBatch = source.queryFetchBatch;
|
||||
this.lazyFetchBatch = source.lazyFetchBatch;
|
||||
this.filterMany = source.filterMany;
|
||||
this.included = (source.included == null) ? null : new LinkedHashSet<String>(source.included);
|
||||
if (includedBeanJoin != null) {
|
||||
this.includedBeanJoin = new HashSet<String>(source.includedBeanJoin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the OrmQueryProperties.
|
||||
*/
|
||||
public OrmQueryProperties copy() {
|
||||
return new OrmQueryProperties(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,41 +200,10 @@ public class OrmQueryProperties implements Serializable {
|
||||
orderBy.add(orderProp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Fetch configuration options for this path.
|
||||
*/
|
||||
public void setFetchConfig(FetchConfig fetchConfig) {
|
||||
if (fetchConfig != null) {
|
||||
this.fetchConfig = fetchConfig;
|
||||
lazyFetchBatch = fetchConfig.getLazyBatchSize();
|
||||
queryFetchBatch = fetchConfig.getQueryBatchSize();
|
||||
queryFetchAll = fetchConfig.isQueryAll();
|
||||
}
|
||||
}
|
||||
|
||||
public FetchConfig getFetchConfig() {
|
||||
return fetchConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comma delimited properties to fetch for this path.
|
||||
* <p>
|
||||
* This can include the +query and +lazy type hints.
|
||||
* </p>
|
||||
*/
|
||||
public void setProperties(String rawProperties) {
|
||||
|
||||
OrmQueryPropertiesParser.Response response = OrmQueryPropertiesParser.parse(rawProperties);
|
||||
|
||||
this.rawProperties = rawProperties;
|
||||
this.trimmedProperties = response.properties;
|
||||
this.included = response.included;
|
||||
this.lazyFetchBatch = response.lazyFetchBatch;
|
||||
this.queryFetchBatch = response.queryFetchBatch;
|
||||
this.cache = response.cache;
|
||||
this.readOnly = response.readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the expressions used to filter on this path. This should be a many path to use this
|
||||
* method.
|
||||
@@ -193,28 +247,6 @@ public class OrmQueryProperties implements Serializable {
|
||||
this.filterMany = filterMany;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the properties from deployment default FetchTypes.
|
||||
*/
|
||||
public void setDefaultProperties(String properties, LinkedHashSet<String> included) {
|
||||
this.rawProperties = properties;
|
||||
this.trimmedProperties = properties;
|
||||
this.included = included;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the properties from a matching AutoTune tuned properties.
|
||||
*/
|
||||
public void setTunedProperties(OrmQueryProperties tunedProperties) {
|
||||
if (tunedProperties.hasProperties()) {
|
||||
this.rawProperties = tunedProperties.rawProperties;
|
||||
this.trimmedProperties = tunedProperties.trimmedProperties;
|
||||
this.included = tunedProperties.included;
|
||||
this.queryFetchBatch = Math.max(queryFetchBatch, tunedProperties.queryFetchBatch);
|
||||
this.lazyFetchBatch = Math.max(lazyFetchBatch, tunedProperties.lazyFetchBatch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the select and joins for this query.
|
||||
*/
|
||||
@@ -249,30 +281,6 @@ public class OrmQueryProperties implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the OrmQueryProperties.
|
||||
*/
|
||||
public OrmQueryProperties copy() {
|
||||
OrmQueryProperties copy = new OrmQueryProperties();
|
||||
copy.parentPath = parentPath;
|
||||
copy.path = path;
|
||||
copy.rawProperties = rawProperties;
|
||||
copy.trimmedProperties = trimmedProperties;
|
||||
copy.cache = cache;
|
||||
copy.readOnly = readOnly;
|
||||
copy.queryFetchAll = queryFetchAll;
|
||||
copy.queryFetchBatch = queryFetchBatch;
|
||||
copy.lazyFetchBatch = lazyFetchBatch;
|
||||
copy.filterMany = filterMany;
|
||||
if (included != null) {
|
||||
copy.included = new LinkedHashSet<String>(included);
|
||||
}
|
||||
if (includedBeanJoin != null) {
|
||||
copy.includedBeanJoin = new HashSet<String>(includedBeanJoin);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
public boolean hasSelectClause() {
|
||||
if ("*".equals(trimmedProperties)) {
|
||||
// explicitly selected all properties
|
||||
|
||||
Reference in new issue
Block a user