From 1e947afa4b660a23a2dcb57463dd810fb73e6030 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 3 Sep 2006 21:48:14 +0000 Subject: Manage ordering properties with lists. --- .../com/amazon/carbonado/qe/AbstractQuery.java | 16 -- .../com/amazon/carbonado/qe/CompositeScore.java | 44 +++- .../java/com/amazon/carbonado/qe/EmptyQuery.java | 29 ++- .../amazon/carbonado/qe/IndexedQueryAnalyzer.java | 13 +- .../java/com/amazon/carbonado/qe/OrderingList.java | 227 +++++++++++++++++++++ .../com/amazon/carbonado/qe/OrderingScore.java | 49 ++++- .../amazon/carbonado/qe/SortedQueryExecutor.java | 2 + .../com/amazon/carbonado/qe/StandardQuery.java | 67 +++--- .../amazon/carbonado/qe/UnionQueryAnalyzer.java | 18 +- .../java/com/amazon/carbonado/spi/BaseQuery.java | 15 ++ 10 files changed, 393 insertions(+), 87 deletions(-) create mode 100644 src/main/java/com/amazon/carbonado/qe/OrderingList.java (limited to 'src/main') diff --git a/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java b/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java index eb2e977..74d6e8d 100644 --- a/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java @@ -44,22 +44,6 @@ import com.amazon.carbonado.util.Appender; * @author Brian S O'Neill */ public abstract class AbstractQuery implements Query, Appender { - // FIXME: remove this - protected static final String[] EMPTY_ORDERINGS = {}; - - // FIXME: remove this - protected static String[] extractOrderingNames(OrderedProperty[] orderings) { - String[] orderingStrings; - if (orderings == null || orderings.length == 0) { - return EMPTY_ORDERINGS; - } - orderingStrings = new String[orderings.length]; - for (int i=0; i { + /** + * Evaluates the given index for its filtering and ordering capabilities + * against the given filter and order-by properties. + * + * @param index index to evaluate + * @param filter optional filter which cannot contain any logical 'or' operations. + * @throws IllegalArgumentException if index is null or filter is not supported + */ + public static CompositeScore evaluate + (StorableIndex index, + Filter filter) + { + return evaluate(index, filter, null); + } + /** * Evaluates the given index for its filtering and ordering capabilities * against the given filter and order-by properties. @@ -47,9 +63,10 @@ public class CompositeScore { * @param orderings properties which define desired ordering * @throws IllegalArgumentException if index is null or filter is not supported */ - public static CompositeScore evaluate(StorableIndex index, - Filter filter, - OrderedProperty... orderings) + public static CompositeScore evaluate + (StorableIndex index, + Filter filter, + List> orderings) { if (index == null) { throw new IllegalArgumentException("Index required"); @@ -62,6 +79,25 @@ public class CompositeScore { orderings); } + /** + * Evaluates the given index properties for its filtering and ordering + * capabilities against the given filter and order-by properties. + * + * @param indexProperties index properties to evaluate + * @param unique true if index is unique + * @param clustered true if index is clustered + * @param filter optional filter which cannot contain any logical 'or' operations. + * @throws IllegalArgumentException if index is null or filter is not supported + */ + public static CompositeScore evaluate + (OrderedProperty[] indexProperties, + boolean unique, + boolean clustered, + Filter filter) + { + return evaluate(indexProperties, unique, clustered, filter, null); + } + /** * Evaluates the given index properties for its filtering and ordering * capabilities against the given filter and order-by properties. @@ -78,7 +114,7 @@ public class CompositeScore { boolean unique, boolean clustered, Filter filter, - OrderedProperty... orderings) + List> orderings) { FilteringScore filteringScore = FilteringScore .evaluate(indexProperties, unique, clustered, filter); diff --git a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java index ba18531..4918f08 100644 --- a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java @@ -44,31 +44,29 @@ public final class EmptyQuery extends AbstractQuery { private final Storage mStorage; // Properties that this query is ordered by. - private final String[] mOrderings; + private final OrderingList mOrderings; /** * @param storage required storage object * @param orderings optional order-by properties */ - // FIXME: remove this - public EmptyQuery(Storage storage, OrderedProperty[] orderings) { + public EmptyQuery(Storage storage, OrderingList orderings) { if (storage == null) { throw new IllegalArgumentException(); } mStorage = storage; - mOrderings = extractOrderingNames(orderings); + if (orderings == null) { + orderings = OrderingList.emptyList(); + } + mOrderings = orderings; } /** * @param storage required storage object * @param orderings optional order-by properties */ - public EmptyQuery(Storage storage, String[] orderings) { - if (storage == null) { - throw new IllegalArgumentException(); - } - mStorage = storage; - mOrderings = orderings == null ? EMPTY_ORDERINGS : orderings; + public EmptyQuery(Storage storage, String... orderings) { + this(storage, OrderingList.get(storage.getStorableType(), orderings)); } public Class getStorableType() { @@ -182,9 +180,8 @@ public final class EmptyQuery extends AbstractQuery { public Query not() throws FetchException { Query query = mStorage.query(); - String[] orderings = mOrderings; - if (orderings.length > 0) { - query = query.orderBy(orderings); + if (mOrderings.size() > 0) { + query = query.orderBy(mOrderings.asStringArray()); } return query; } @@ -246,13 +243,13 @@ public final class EmptyQuery extends AbstractQuery { app.append(", filter="); getFilter().appendTo(app); - if (mOrderings != null && mOrderings.length > 0) { + if (mOrderings != null && mOrderings.size() > 0) { app.append(", orderBy=["); - for (int i=0; i 0) { app.append(", "); } - app.append(mOrderings[i]); + app.append(mOrderings.get(i).toString()); } app.append(']'); } diff --git a/src/main/java/com/amazon/carbonado/qe/IndexedQueryAnalyzer.java b/src/main/java/com/amazon/carbonado/qe/IndexedQueryAnalyzer.java index dfe13cc..92c21dd 100644 --- a/src/main/java/com/amazon/carbonado/qe/IndexedQueryAnalyzer.java +++ b/src/main/java/com/amazon/carbonado/qe/IndexedQueryAnalyzer.java @@ -76,10 +76,19 @@ public class IndexedQueryAnalyzer { /** * @param filter optional filter which which must be {@link Filter#isBound * bound} and cannot contain any logical 'or' operations. - * @param orderings properties which define desired ordering * @throws IllegalArgumentException if filter is not supported */ - public Result analyze(Filter filter, OrderedProperty... orderings) { + public Result analyze(Filter filter) { + return analyze(filter, null); + } + + /** + * @param filter optional filter which which must be {@link Filter#isBound + * bound} and cannot contain any logical 'or' operations. + * @param orderings optional properties which define desired ordering + * @throws IllegalArgumentException if filter is not supported + */ + public Result analyze(Filter filter, List> orderings) { if (!filter.isBound()) { // Strictly speaking, this is not required, but it detects the // mistake of not properly calling initialFilterValues. diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingList.java b/src/main/java/com/amazon/carbonado/qe/OrderingList.java new file mode 100644 index 0000000..907453d --- /dev/null +++ b/src/main/java/com/amazon/carbonado/qe/OrderingList.java @@ -0,0 +1,227 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.amazon.carbonado.qe; + +import java.util.AbstractList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.cojen.util.SoftValuedHashMap; + +import com.amazon.carbonado.Storable; + +import com.amazon.carbonado.info.OrderedProperty; +import com.amazon.carbonado.info.StorableIntrospector; + +/** + * Produces unmodifiable lists of {@link OrderedProperty orderings}. Instances + * are immutable, canonical and cached. Calls to "equals" and "hashCode" are + * fast. + * + * @author Brian S O'Neill + */ +public class OrderingList extends AbstractList> { + private static final OrderingList EMPTY_LIST = new OrderingList(); + + private static final Map cCache; + + static { + cCache = new SoftValuedHashMap(); + } + + /** + * Returns a canonical empty instance. + */ + public static OrderingList emptyList() { + return EMPTY_LIST; + } + + /** + * Returns a canonical instance composed of the given ordering. + * + * @throws IllegalArgumentException if ordering property is not in S + */ + public static OrderingList get(Class type, String property) { + if (property == null) { + return EMPTY_LIST; + } + return getListNode(type).nextNode(type, property); + } + + /** + * Returns a canonical instance composed of the given orderings. + * + * @throws IllegalArgumentException if any ordering property is not in S + */ + public static OrderingList get(Class type, String... orderings) { + if (orderings == null || orderings.length == 0) { + return EMPTY_LIST; + } + + OrderingList node = getListNode(type); + for (String property : orderings) { + node = node.nextNode(type, property); + } + + return node; + } + + /** + * Returns a canonical instance composed of the given orderings. + */ + public static OrderingList get(OrderedProperty... orderings) { + if (orderings == null || orderings.length == 0) { + return EMPTY_LIST; + } + + Class type = orderings[0].getChainedProperty().getPrimeProperty().getEnclosingType(); + + OrderingList node = getListNode(type); + for (OrderedProperty property : orderings) { + node = node.nextNode(property); + } + + return node; + } + + private static OrderingList getListNode(Class type) { + OrderingList node; + synchronized (cCache) { + node = (OrderingList) cCache.get(type); + if (node == null) { + node = new OrderingList(); + cCache.put(type, node); + } + } + return node; + } + + private final OrderingList mParent; + private final OrderedProperty mProperty; + private final int mSize; + + private Map> mNextNode; + + private OrderedProperty[] mOrderings; + private String[] mOrderingStrings; + + private OrderingList() { + mParent = null; + mProperty = null; + mSize = 0; + } + + private OrderingList(OrderingList parent, OrderedProperty property) { + if (property == null) { + throw new IllegalArgumentException("Ordering property is null"); + } + mParent = parent; + mProperty = property; + mSize = parent.mSize + 1; + } + + public int size() { + return mSize; + } + + public OrderedProperty get(int index) { + return asArray()[index]; + } + + private OrderedProperty[] asArray() { + if (mOrderings == null) { + OrderedProperty[] orderings = new OrderedProperty[mSize]; + OrderingList node = this; + for (int i=mSize; --i>=0; ) { + orderings[i] = node.mProperty; + node = node.mParent; + } + mOrderings = orderings; + } + return mOrderings; + } + + /** + * Returns the orderings as qualified string property names. Each is + * prefixed with a '+' or '-'. + */ + String[] asStringArray() { + if (mOrderingStrings == null) { + String[] orderings = new String[mSize]; + OrderingList node = this; + for (int i=mSize; --i>=0; ) { + orderings[i] = node.mProperty.toString(); + node = node.mParent; + } + mOrderingStrings = orderings; + } + return mOrderingStrings; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + return super.equals(other); + } + + private synchronized OrderingList nextNode(Class type, String property) { + OrderingList node; + if (mNextNode == null) { + mNextNode = new HashMap>(); + node = null; + } else { + node = mNextNode.get(property); + } + + if (node == null) { + OrderedProperty op = OrderedProperty + .parse(StorableIntrospector.examine(type), property); + + node = nextNode(op); + mNextNode.put(property, node); + } + + return node; + } + + private synchronized OrderingList nextNode(OrderedProperty property) { + OrderingList node; + if (mNextNode == null) { + mNextNode = new HashMap>(); + node = null; + } else { + node = mNextNode.get(property); + } + + if (node == null) { + node = new OrderingList(this, property); + mNextNode.put(property, node); + } + + return node; + } +} diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java index 76b273f..67edcdd 100644 --- a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java +++ b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java @@ -62,6 +62,21 @@ import com.amazon.carbonado.info.StorableIndex; * @see CompositeScore */ public class OrderingScore { + /** + * Evaluates the given index for its ordering capabilities against the + * given filter and order-by properties. + * + * @param index index to evaluate + * @param filter optional filter which cannot contain any logical 'or' operations. + * @throws IllegalArgumentException if index is null or filter is not supported + */ + public static OrderingScore evaluate + (StorableIndex index, + Filter filter) + { + return evaluate(index, filter, null); + } + /** * Evaluates the given index for its ordering capabilities against the * given filter and order-by properties. @@ -71,9 +86,10 @@ public class OrderingScore { * @param orderings properties which define desired ordering * @throws IllegalArgumentException if index is null or filter is not supported */ - public static OrderingScore evaluate(StorableIndex index, - Filter filter, - OrderedProperty... orderings) + public static OrderingScore evaluate + (StorableIndex index, + Filter filter, + List> orderings) { if (index == null) { throw new IllegalArgumentException("Index required"); @@ -86,6 +102,25 @@ public class OrderingScore { orderings); } + /** + * Evaluates the given index properties for its ordering capabilities + * against the given filter and order-by properties. + * + * @param indexProperties index properties to evaluate + * @param unique true if index is unique + * @param clustered true if index is clustered + * @param filter optional filter which cannot contain any logical 'or' operations. + * @throws IllegalArgumentException if index is null or filter is not supported + */ + public static OrderingScore evaluate + (OrderedProperty[] indexProperties, + boolean unique, + boolean clustered, + Filter filter) + { + return evaluate(indexProperties, unique, clustered, filter, null); + } + /** * Evaluates the given index properties for its ordering capabilities * against the given filter and order-by properties. @@ -102,7 +137,7 @@ public class OrderingScore { boolean unique, boolean clustered, Filter filter, - OrderedProperty... orderings) + List> orderings) { if (indexProperties == null) { throw new IllegalArgumentException("Index properties required"); @@ -111,7 +146,7 @@ public class OrderingScore { // Get filter list early to detect errors. List> filterList = PropertyFilterList.get(filter); - if (orderings == null || orderings.length == 0) { + if (orderings == null || orderings.size() == 0) { return new OrderingScore(clustered, indexProperties.length, null, null, false); } @@ -154,8 +189,8 @@ public class OrderingScore { int indexPos = 0; calcScore: - for (int i=0; i property = orderings[i]; + for (int i=0; i property = orderings.get(i); ChainedProperty chained = property.getChainedProperty(); if (seen.contains(chained)) { diff --git a/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java index 822cde8..48defa7 100644 --- a/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/SortedQueryExecutor.java @@ -54,6 +54,8 @@ public abstract class SortedQueryExecutor extends AbstractQu /** * @param executor executor to wrap + * @param handledOrderings optional handled orderings + * @param remainderOrderings required remainder orderings * @throws IllegalArgumentException if executor is null or if remainder * orderings is empty */ diff --git a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java index 7152e55..8c423e6 100644 --- a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java @@ -38,6 +38,7 @@ import com.amazon.carbonado.filter.FilterValues; import com.amazon.carbonado.filter.OpenFilter; import com.amazon.carbonado.filter.RelOp; +import com.amazon.carbonado.info.Direction; import com.amazon.carbonado.info.OrderedProperty; import com.amazon.carbonado.util.Appender; @@ -53,27 +54,27 @@ public abstract class StandardQuery extends AbstractQuery // Values for this query, which may be null. private final FilterValues mValues; // Properties that this query is ordered by. - private final String[] mOrderings; + private final OrderingList mOrderings; private volatile QueryExecutor mExecutor; /** * @param values optional values object, defaults to open filter if null - * @param orderings optional order-by properties */ - // FIXME: remove this - protected StandardQuery(FilterValues values, OrderedProperty... orderings) { - this(values, extractOrderingNames(orderings)); + protected StandardQuery(FilterValues values) { + this(values, null); } /** * @param values optional values object, defaults to open filter if null - * @param orderings optional order-by properties, not cloned, which may be - * prefixed with '+' or '-' + * @param orderings optional order-by properties */ - protected StandardQuery(FilterValues values, String... orderings) { + protected StandardQuery(FilterValues values, OrderingList orderings) { mValues = values; - mOrderings = orderings == null ? EMPTY_ORDERINGS : orderings; + if (orderings == null) { + orderings = OrderingList.emptyList(); + } + mOrderings = orderings; } public Class getStorableType() { @@ -148,7 +149,7 @@ public abstract class StandardQuery extends AbstractQuery newQuery = getStorage().query(values.getFilter().and(filter)); newQuery = newQuery.withValues(values.getValues()); } - return mOrderings.length == 0 ? newQuery : newQuery.orderBy(mOrderings); + return mOrderings.size() == 0 ? newQuery : newQuery.orderBy(mOrderings.asStringArray()); } public Query or(Filter filter) throws FetchException { @@ -158,7 +159,7 @@ public abstract class StandardQuery extends AbstractQuery } Query newQuery = getStorage().query(values.getFilter().or(filter)); newQuery = newQuery.withValues(values.getValues()); - return mOrderings.length == 0 ? newQuery : newQuery.orderBy(mOrderings); + return mOrderings.size() == 0 ? newQuery : newQuery.orderBy(mOrderings.asStringArray()); } public Query not() throws FetchException { @@ -168,21 +169,15 @@ public abstract class StandardQuery extends AbstractQuery } Query newQuery = getStorage().query(values.getFilter().not()); newQuery = newQuery.withValues(values.getSuppliedValues()); - return mOrderings.length == 0 ? newQuery : newQuery.orderBy(mOrderings); + return mOrderings.size() == 0 ? newQuery : newQuery.orderBy(mOrderings.asStringArray()); } public Query orderBy(String property) throws FetchException { - StandardQuery query = newInstance(mValues, property); - // Get executor to ensure order property is correct. - query.executor(); - return query; + return newInstance(mValues, OrderingList.get(getStorableType(), property)); } public Query orderBy(String... properties) throws FetchException { - StandardQuery query = newInstance(mValues, properties); - // Get executor to ensure order properties are correct. - query.executor(); - return query; + return newInstance(mValues, OrderingList.get(getStorableType(), properties)); } public Cursor fetch() throws FetchException { @@ -190,8 +185,8 @@ public abstract class StandardQuery extends AbstractQuery } public Cursor fetchAfter(S start) throws FetchException { - String[] orderings; - if (start == null || (orderings = mOrderings).length == 0) { + OrderingList orderings; + if (start == null || (orderings = mOrderings).size() == 0) { return fetch(); } @@ -200,24 +195,21 @@ public abstract class StandardQuery extends AbstractQuery Filter lastSubFilter = Filter.getOpenFilter(storableType); BeanPropertyAccessor accessor = BeanPropertyAccessor.forClass(storableType); - Object[] values = new Object[orderings.length]; + Object[] values = new Object[orderings.size()]; for (int i=0;;) { - String propertyName = orderings[i]; + OrderedProperty property = orderings.get(i); RelOp operator = RelOp.GT; - char c = propertyName.charAt(0); - if (c == '-') { - propertyName = propertyName.substring(1); + if (property.getDirection() == Direction.DESCENDING) { operator = RelOp.LT; - } else if (c == '+') { - propertyName = propertyName.substring(1); } + String propertyName = property.getChainedProperty().toString(); values[i] = accessor.getPropertyValue(start, propertyName); orderFilter = orderFilter.or(lastSubFilter.and(propertyName, operator)); - if (++i >= orderings.length) { + if (++i >= orderings.size()) { break; } @@ -336,13 +328,13 @@ public abstract class StandardQuery extends AbstractQuery app.append('"'); } - if (mOrderings != null && mOrderings.length > 0) { + if (mOrderings != null && mOrderings.size() > 0) { app.append(", orderBy=["); - for (int i=0; i 0) { app.append(", "); } - app.append(mOrderings[i]); + app.append(mOrderings.get(i).toString()); } app.append(']'); } @@ -375,10 +367,10 @@ public abstract class StandardQuery extends AbstractQuery * Return a new or cached executor. * * @param values optional values object, defaults to open filter if null - * @param orderings optional order-by properties, which may be prefixed - * with '+' or '-' + * @param orderings order-by properties, never null */ - protected abstract QueryExecutor getExecutor(FilterValues values, String... orderings); + protected abstract QueryExecutor getExecutor(FilterValues values, + OrderingList orderings); /** * Return a new or cached instance of StandardQuery implementation, using @@ -388,7 +380,8 @@ public abstract class StandardQuery extends AbstractQuery * @param values optional values object, defaults to open filter if null * @param orderings order-by properties, never null */ - protected abstract StandardQuery newInstance(FilterValues values, String... orderings); + protected abstract StandardQuery newInstance(FilterValues values, + OrderingList orderings); private StandardQuery newInstance(FilterValues values) { return newInstance(values, mOrderings); diff --git a/src/main/java/com/amazon/carbonado/qe/UnionQueryAnalyzer.java b/src/main/java/com/amazon/carbonado/qe/UnionQueryAnalyzer.java index 9563097..b4e45fa 100644 --- a/src/main/java/com/amazon/carbonado/qe/UnionQueryAnalyzer.java +++ b/src/main/java/com/amazon/carbonado/qe/UnionQueryAnalyzer.java @@ -19,6 +19,7 @@ package com.amazon.carbonado.qe; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.amazon.carbonado.Storable; @@ -58,9 +59,16 @@ public class UnionQueryAnalyzer { /** * @param filter optional filter which must be {@link Filter#isBound bound} - * @param orderings properties which define desired ordering */ - public Result analyze(Filter filter, OrderedProperty... orderings) { + public Result analyze(Filter filter) { + return analyze(filter, null); + } + + /** + * @param filter optional filter which must be {@link Filter#isBound bound} + * @param orderings optional properties which define desired ordering + */ + public Result analyze(Filter filter, List> orderings) { if (!filter.isBound()) { // Strictly speaking, this is not required, but it detects the // mistake of not properly calling initialFilterValues. @@ -87,7 +95,7 @@ public class UnionQueryAnalyzer { } private List.Result> - splitIntoSubResults(Filter filter, OrderedProperty... orderings) + splitIntoSubResults(Filter filter, List> orderings) { Splitter splitter = new Splitter(orderings); filter.accept(splitter, null); @@ -174,11 +182,11 @@ public class UnionQueryAnalyzer { * only contain 'and' operations. */ private class Splitter extends Visitor { - private final OrderedProperty[] mOrderings; + private final List> mOrderings; final List.Result> mSubResults; - Splitter(OrderedProperty... orderings) { + Splitter(List> orderings) { mOrderings = orderings; mSubResults = new ArrayList.Result>(); } diff --git a/src/main/java/com/amazon/carbonado/spi/BaseQuery.java b/src/main/java/com/amazon/carbonado/spi/BaseQuery.java index e1117cd..b1a1d45 100644 --- a/src/main/java/com/amazon/carbonado/spi/BaseQuery.java +++ b/src/main/java/com/amazon/carbonado/spi/BaseQuery.java @@ -49,6 +49,7 @@ import com.amazon.carbonado.qe.EmptyQuery; * BaseQuery supports binding filters to values. * * @author Brian S O'Neill + * @deprecated Use {@link com.amazon.carbonado.qe.StandardQuery} */ public abstract class BaseQuery extends AbstractQuery implements Appender { /** @@ -61,6 +62,20 @@ public abstract class BaseQuery extends AbstractQuery imp } } + protected static final String[] EMPTY_ORDERINGS = {}; + + protected static String[] extractOrderingNames(OrderedProperty[] orderings) { + String[] orderingStrings; + if (orderings == null || orderings.length == 0) { + return EMPTY_ORDERINGS; + } + orderingStrings = new String[orderings.length]; + for (int i=0; i mStorage; // Values for this query. -- cgit v1.2.3