18 package com.mysql.clusterj.core.query;
20 import com.mysql.clusterj.ClusterJException;
21 import com.mysql.clusterj.ClusterJFatalInternalException;
22 import com.mysql.clusterj.ClusterJUserException;
23 import com.mysql.clusterj.Query;
25 import com.mysql.clusterj.core.query.PredicateImpl.ScanType;
26 import com.mysql.clusterj.core.spi.DomainFieldHandler;
27 import com.mysql.clusterj.core.spi.DomainTypeHandler;
28 import com.mysql.clusterj.core.spi.QueryExecutionContext;
29 import com.mysql.clusterj.core.spi.SessionSPI;
30 import com.mysql.clusterj.core.spi.ValueHandler;
32 import com.mysql.clusterj.core.store.Index;
33 import com.mysql.clusterj.core.store.IndexOperation;
34 import com.mysql.clusterj.core.store.IndexScanOperation;
35 import com.mysql.clusterj.core.store.Operation;
36 import com.mysql.clusterj.core.store.ResultData;
37 import com.mysql.clusterj.core.store.ScanOperation;
39 import com.mysql.clusterj.core.util.I18NHelper;
40 import com.mysql.clusterj.core.util.Logger;
41 import com.mysql.clusterj.core.util.LoggerFactoryService;
43 import com.mysql.clusterj.query.Predicate;
44 import com.mysql.clusterj.query.PredicateOperand;
45 import com.mysql.clusterj.query.QueryDefinition;
46 import com.mysql.clusterj.query.QueryDomainType;
48 import java.util.ArrayList;
49 import java.util.HashMap;
50 import java.util.List;
53 public class QueryDomainTypeImpl<T>
implements QueryDomainType<T> {
62 protected Class<T>
cls;
71 protected Map<String, ParameterImpl> parameters =
72 new HashMap<String, ParameterImpl>();
75 protected Map<String, PropertyImpl> properties =
76 new HashMap<String, PropertyImpl>();
78 public QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler, Class<T> cls) {
80 this.domainTypeHandler = domainTypeHandler;
83 public QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler) {
84 this.domainTypeHandler = domainTypeHandler;
87 public PredicateOperand
get(
String propertyName) {
94 DomainFieldHandler fmd = domainTypeHandler.getFieldHandler(propertyName);
96 properties.put(propertyName,
property);
106 if (predicate == null) {
108 local.message(
"ERR_Query_Where_Must_Not_Be_Null"));
111 throw new UnsupportedOperationException(
112 local.message(
"ERR_NotImplemented"));
116 where.unmarkParameters();
119 this.where = (PredicateImpl)predicate;
120 where.markParameters();
125 final ParameterImpl parameter = parameters.get(parameterName);
126 if (parameter != null) {
129 ParameterImpl result =
new ParameterImpl(
this, parameterName);
130 parameters.put(parameterName, result);
140 return predicate.
not();
148 assertAllParametersBound(context);
151 session.startAutoTransaction();
153 List<T> resultList =
new ArrayList<T>();
156 ResultData resultData = getResultData(context);
158 while (resultData.next()) {
162 domainTypeHandler.objectSetValues(resultData, handler);
165 session.endAutoTransaction();
168 session.failAutoTransaction();
170 }
catch (Exception ex) {
171 session.failAutoTransaction();
173 local.message(
"ERR_Exception_On_Query"), ex);
191 where.getBestCandidateIndex(context);
192 ScanType scanType = index.getScanType();
193 Map<String, Object> explain = newExplain(index, scanType);
194 context.setExplain(explain);
202 Operation op = session.getSelectOperation(domainTypeHandler.getStoreTable());
204 index.operationSetKeys(context, op);
206 domainTypeHandler.operationGetValues(op);
208 result = op.resultData();
213 storeIndex = index.getStoreIndex();
214 if (logger.isDetailEnabled()) logger.detail(
"Using index scan with index " + index.getIndexName());
217 if (index.isMultiRange()) {
218 op = session.getIndexScanOperationMultiRange(storeIndex, domainTypeHandler.getStoreTable());
221 op = session.getIndexScanOperation(storeIndex, domainTypeHandler.getStoreTable());
225 domainTypeHandler.operationGetValues(op);
227 index.operationSetBounds(context, op);
229 where.filterCmpValue(context, op);
231 result = op.resultData();
236 if (logger.isDetailEnabled()) logger.detail(
"Using table scan");
238 ScanOperation op = session.getTableScanOperation(domainTypeHandler.getStoreTable());
240 domainTypeHandler.operationGetValues(op);
243 where.filterCmpValue(context, op);
246 result = op.resultData();
251 storeIndex = index.getStoreIndex();
252 if (logger.isDetailEnabled()) logger.detail(
"Using unique lookup with index " + index.getIndexName());
254 IndexOperation op = session.getUniqueIndexOperation(storeIndex, domainTypeHandler.getStoreTable());
256 where.operationEqual(context, op);
259 domainTypeHandler.operationGetValues(op);
261 result = op.resultData();
266 session.failAutoTransaction();
268 local.message(
"ERR_Illegal_Scan_Type", scanType));
270 context.deleteFilters();
289 where.getBestCandidateIndex(context);
290 ScanType scanType = index.getScanType();
291 Map<String, Object> explain = newExplain(index, scanType);
292 context.setExplain(explain);
296 session.startAutoTransaction();
303 if (logger.isDetailEnabled()) logger.detail(
"Using delete by primary key.");
304 Operation op = session.getDeleteOperation(domainTypeHandler.getStoreTable());
306 index.operationSetKeys(context, op);
308 session.executeNoCommit(
false,
true);
309 errorCode = op.errorCode();
311 result = (errorCode == 0?1:0);
316 storeIndex = index.getStoreIndex();
317 if (logger.isDetailEnabled()) logger.detail(
318 "Using delete by unique key " + index.getIndexName());
320 IndexOperation op = session.getUniqueIndexDeleteOperation(storeIndex,
321 domainTypeHandler.getStoreTable());
323 where.operationEqual(context, op);
325 session.executeNoCommit(
false,
true);
326 errorCode = op.errorCode();
328 result = (errorCode == 0?1:0);
333 storeIndex = index.getStoreIndex();
334 if (logger.isDetailEnabled()) logger.detail(
335 "Using delete by index scan with index " + index.getIndexName());
338 domainTypeHandler.getStoreTable());
340 domainTypeHandler.operationGetValues(op);
342 index.operationSetBounds(context, op);
344 where.filterCmpValue(context, op);
346 result = session.deletePersistentAll(op,
false);
351 if (logger.isDetailEnabled()) logger.detail(
"Using delete by table scan");
353 ScanOperation op = session.getTableScanDeleteOperation(domainTypeHandler.getStoreTable());
355 domainTypeHandler.operationGetValues(op);
358 where.filterCmpValue(context, op);
361 result = session.deletePersistentAll(op,
false);
367 local.message(
"ERR_Illegal_Scan_Type", scanType));
369 context.deleteFilters();
370 session.endAutoTransaction();
373 session.failAutoTransaction();
375 }
catch (Exception e) {
376 session.failAutoTransaction();
382 return domainTypeHandler.createCandidateIndexes();
391 assertAllParametersBound(context);
394 where.getBestCandidateIndex(context);
395 ScanType scanType = index.getScanType();
396 Map<String, Object> explain = newExplain(index, scanType);
397 context.setExplain(explain);
407 Map<String, Object> explain =
new HashMap<String, Object>();
408 explain.put(Query.SCAN_TYPE, scanType.toString());
409 explain.put(Query.INDEX_USED, index.getIndexName());
421 if (param.isMarkedAndUnbound(context)) {
423 local.message(
"ERR_Parameter_Not_Bound", param.getName()));
429 public Class<T> getType() {