001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.kernel;
020:
021: import java.io.Serializable;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: import org.apache.commons.collections.map.LinkedMap;
026: import org.apache.openjpa.kernel.exps.AggregateListener;
027: import org.apache.openjpa.kernel.exps.Constant;
028: import org.apache.openjpa.kernel.exps.FilterListener;
029: import org.apache.openjpa.lib.rop.ResultObjectProvider;
030: import org.apache.openjpa.meta.ClassMetaData;
031: import org.apache.openjpa.meta.FieldMetaData;
032:
033: /**
034: * Component that executes queries against the datastore. For
035: * expression-based queries, consider subclassing
036: * {@link ExpressionStoreManagerQuery}.
037: *
038: * @author Abe White
039: * @since 0.4.0
040: */
041: public interface StoreQuery extends QueryOperations, Serializable {
042:
043: // linkedmap doesn't allow a size of 0, so use 1
044: public static final LinkedMap EMPTY_PARAMS = new LinkedMap(1, 1F);
045: public static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
046: public static final String[] EMPTY_STRINGS = new String[0];
047: public static final Object[] EMPTY_OBJECTS = new Object[0];
048: public static final Class[] EMPTY_CLASSES = new Class[0];
049: public static final boolean[] EMPTY_BOOLEANS = new boolean[0];
050:
051: /**
052: * Return the query context that has been set.
053: */
054: public QueryContext getContext();
055:
056: /**
057: * Set the current query context. This will be called before use.
058: */
059: public void setContext(QueryContext ctx);
060:
061: /**
062: * This is invoked when the user or a facade creates a new query with
063: * an object that the system does not recognize. Return true if
064: * the object is recognized by the store, false otherwise.
065: */
066: public boolean setQuery(Object query);
067:
068: /**
069: * Return the standard filter listener for the given tag, or null.
070: */
071: public FilterListener getFilterListener(String tag);
072:
073: /**
074: * Return the standard filter listener for the given tag, or null.
075: */
076: public AggregateListener getAggregateListener(String tag);
077:
078: /**
079: * Create a new key for caching compiled query information. May be null.
080: */
081: public Object newCompilationKey();
082:
083: /**
084: * Create a new compilation for this query. May be null.
085: */
086: public Object newCompilation();
087:
088: /**
089: * Populate internal data from compilation.
090: */
091: public void populateFromCompilation(Object comp);
092:
093: /**
094: * Invalidate any internal compilation state.
095: */
096: public void invalidateCompilation();
097:
098: /**
099: * True if this query supports datastore execution, false if it
100: * can only run in memory.
101: */
102: public boolean supportsDataStoreExecution();
103:
104: /**
105: * True if this query supports in-memory execution, false if it
106: * can only run against the datastore.
107: */
108: public boolean supportsInMemoryExecution();
109:
110: /**
111: * Return an executor for in-memory execution of this query.
112: * Executors must be cachable and thread safe. If this class returns
113: * true from {@link #supportsAbstractExecutors}, the given metadata
114: * will always be for the candidate class of this query, or possibly
115: * null if the candidate class is not itself persistence capable (like
116: * an interface or abstract base class). Otherwise, the given type will
117: * be a mapped class.
118: *
119: * @param subs whether to include dependent mapped subclasses in the
120: * results; independent subclasses should never be included
121: */
122: public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs);
123:
124: /**
125: * Return an executor for datastore execution of this query.
126: * Executors must be cachable and thread safe. If this class returns
127: * true from {@link #supportsAbstractExecutors}, the given metadata
128: * will always be for the candidate class of this query, or possibly
129: * null if the candidate class is not itself persistence capable (like
130: * an interface or abstract base class). Otherwise, the given type will
131: * be a mapped class.
132: *
133: * @param subs whether to include dependent mapped subclasses in the
134: * results; independent subclasses should never be included
135: */
136: public Executor newDataStoreExecutor(ClassMetaData meta,
137: boolean subs);
138:
139: /**
140: * Return true if this query supports execution against abstract or
141: * interface types. Returns false by default, meaning we will only
142: * request executors for persistent classes. In this case, we will
143: * automatically combine the results of the executors for all
144: * implementing classes if we execute a query for an interface for
145: * abstract type.
146: */
147: public boolean supportsAbstractExecutors();
148:
149: /**
150: * Whether this query requires a candidate class.
151: */
152: public boolean requiresCandidateType();
153:
154: /**
155: * Whether this query requires parameters to be declared.
156: */
157: public boolean requiresParameterDeclarations();
158:
159: /**
160: * Whether this query supports declared parameters.
161: */
162: public boolean supportsParameterDeclarations();
163:
164: /**
165: * A query result range.
166: */
167: public static class Range {
168: public long start = 0L;
169: public long end = Long.MAX_VALUE;
170: public boolean lrs = false;
171:
172: public Range() {
173: }
174:
175: public Range(long start, long end) {
176: this .start = start;
177: this .end = end;
178: }
179: }
180:
181: /**
182: * An executor provides a uniform interface to the mechanism for executing
183: * either an in-memory or datastore query. In the common case, the
184: * {@link #executeQuery} method will be called before other methods,
185: * though this is not guaranteed.
186: *
187: * @author Marc Prud'hommeaux
188: */
189: public static interface Executor {
190:
191: /**
192: * Return the result of executing this query with the given parameter
193: * values. If this query is a projection and this executor does not
194: * pack results itself, each element of the returned result object
195: * provider should be an object array containing the projection values.
196: *
197: * @param lrs true if the query result should be treated as a
198: * large result set, assuming the query is not an
199: * aggregate and does not have grouping
200: * @see #isPacking
201: */
202: public ResultObjectProvider executeQuery(StoreQuery q,
203: Object[] params, Range range);
204:
205: /**
206: * Deleted the objects that result from the execution of the
207: * query, retuning the number of objects that were deleted.
208: */
209: public Number executeDelete(StoreQuery q, Object[] params);
210:
211: /**
212: * Updates the objects that result from the execution of the
213: * query, retuning the number of objects that were updated.
214: */
215: public Number executeUpdate(StoreQuery q, Object[] params);
216:
217: /**
218: * Return a description of the commands that will be sent to
219: * the datastore in order to execute the query.
220: */
221: public String[] getDataStoreActions(StoreQuery q,
222: Object[] params, Range range);
223:
224: /**
225: * Validate components of query.
226: */
227: public void validate(StoreQuery q);
228:
229: /**
230: * Mutate the given range to set any range information stored in
231: * the query string and/or parameters.
232: */
233: public void getRange(StoreQuery q, Object[] params, Range range);
234:
235: /**
236: * Extract the value of the <code>orderIndex</code>th ordering
237: * expression in {@link Query#getOrderingClauses} from the
238: * given result object. The result object will be an object from
239: * the result object provider returned from {@link #executeQuery}.
240: * This method is used when several result lists have to be merged
241: * in memory. If this exeuctor's parent query supports executors on
242: * abstract or interface classes, this method will not be used.
243: *
244: * @see StoreQuery#supportsAbstractExecutors
245: */
246: public Object getOrderingValue(StoreQuery q, Object[] params,
247: Object resultObject, int orderIndex);
248:
249: /**
250: * Return the ordering direction for all ordering clauses, or empty
251: * array if none.
252: */
253: public boolean[] getAscending(StoreQuery q);
254:
255: /**
256: * Return true if this executor packs projections into the result
257: * class itself. Executors for query languages that allow projections
258: * without result clauses must return true and perform the result
259: * packing themselves.
260: */
261: public boolean isPacking(StoreQuery q);
262:
263: /**
264: * If this is not a projection but the candidate results are placed
265: * into a result class with an alias, return that alias.
266: */
267: public String getAlias(StoreQuery q);
268:
269: /**
270: * Return the alias for each projection element, or empty array
271: * if not a projection.
272: */
273: public String[] getProjectionAliases(StoreQuery q);
274:
275: /**
276: * Return the expected types of the projections used by this query,
277: * or an empty array if not a projection.
278: */
279: public Class[] getProjectionTypes(StoreQuery q);
280:
281: /**
282: * Return an array of all persistent classes used in this query, or
283: * empty array if unknown.
284: */
285: public ClassMetaData[] getAccessPathMetaDatas(StoreQuery q);
286:
287: /**
288: * Returns the operation this executor is meant to execute.
289: *
290: * @see QueryOperations
291: */
292: public int getOperation(StoreQuery q);
293:
294: /**
295: * Return true if the compiled query is an aggregate.
296: */
297: public boolean isAggregate(StoreQuery q);
298:
299: /**
300: * Whether the compiled query has grouping.
301: */
302: public boolean hasGrouping(StoreQuery q);
303:
304: /**
305: * Return a map of parameter names to types. The returned
306: * {@link Map#entrySet}'s {@link Iterator} must return values in the
307: * order in which they were declared or used.
308: */
309: public LinkedMap getParameterTypes(StoreQuery q);
310:
311: /**
312: * Returns the result class, if any.
313: */
314: public Class getResultClass(StoreQuery q);
315:
316: /**
317: * Return a map of {@link FieldMetaData} to update
318: * {@link Constant}s, in cases where this query is for a bulk update.
319: */
320: public Map getUpdates(StoreQuery q);
321: }
322: }
|