use of org.datanucleus.store.query.QueryManager in project datanucleus-rdbms by datanucleus.
the class JDOQLQuery method compileInternal.
/**
* Method to compile the JDOQL query.
* Uses the superclass to compile the generic query populating the "compilation", and then generates
* the datastore-specific "datastoreCompilation".
* @param parameterValues Map of param values keyed by param name (if available at compile time)
*/
protected synchronized void compileInternal(Map parameterValues) {
if (isCompiled()) {
return;
}
if (getExtension(EXTENSION_INCLUDE_SOFT_DELETES) != null) {
// If using an extension that can change the datastore query then evict any existing compilation
QueryManager qm = getQueryManager();
qm.removeQueryCompilation(Query.LANGUAGE_JDOQL, getQueryCacheKey());
}
// Compile the generic query expressions
super.compileInternal(parameterValues);
boolean inMemory = evaluateInMemory();
if (candidateCollection != null && inMemory) {
// TODO Maybe apply the result class checks ?
return;
}
// Create the SQL statement, and its result/parameter definitions
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
if (candidateClass == null) {
throw new NucleusUserException(Localiser.msg("021009", candidateClassName));
}
// Make sure any persistence info is loaded
ec.hasPersistenceInformationForClass(candidateClass);
if (parameterValues != null) {
// Check for null values on primitive parameters
Set paramNames = parameterValues.entrySet();
Iterator<Map.Entry> iter = paramNames.iterator();
while (iter.hasNext()) {
Map.Entry entry = iter.next();
Object paramName = entry.getKey();
if (paramName instanceof String) {
Symbol sym = compilation.getSymbolTable().getSymbol((String) paramName);
Object value = entry.getValue();
if (value == null) {
// so omit the check for that case
if (sym != null && sym.getValueType() != null && sym.getValueType().isPrimitive()) {
throw new NucleusUserException(Localiser.msg("021117", paramName, sym.getValueType().getName()));
}
}
}
}
}
QueryManager qm = getQueryManager();
String datastoreKey = storeMgr.getQueryCacheKey();
String queryCacheKey = getQueryCacheKey();
if (useCaching() && queryCacheKey != null) {
// Check if we have any parameters set to null, since this can invalidate a datastore compilation
// e.g " field == :val" can be "COL IS NULL" or "COL = <val>"
boolean nullParameter = false;
if (parameterValues != null) {
Iterator iter = parameterValues.values().iterator();
while (iter.hasNext()) {
Object val = iter.next();
if (val == null) {
nullParameter = true;
break;
}
}
}
if (!nullParameter) {
// Allowing caching so try to find compiled (datastore) query
datastoreCompilation = (RDBMSQueryCompilation) qm.getDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey);
if (datastoreCompilation != null) {
// Cached compilation exists for this datastore so reuse it
setResultDistinct(compilation.getResultDistinct());
return;
}
}
}
// Compile the query for the datastore since not cached
AbstractClassMetaData acmd = getCandidateClassMetaData();
if (type == QueryType.BULK_UPDATE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryUpdate(parameterValues, acmd);
} else if (type == QueryType.BULK_DELETE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryDelete(parameterValues, acmd);
} else {
datastoreCompilation = new RDBMSQueryCompilation();
synchronized (datastoreCompilation) {
if (inMemory) {
// Generate statement to just retrieve all candidate objects for later processing
compileQueryToRetrieveCandidates(parameterValues, acmd);
} else {
// Generate statement to perform the full query in the datastore
compileQueryFull(parameterValues, acmd);
if (result != null) {
// Check existence of invalid selections in the result
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = idx.getMapping().getMemberMetaData();
if (mmd != null) {
if (idx.getMapping() instanceof AbstractContainerMapping && idx.getMapping().getNumberOfColumnMappings() != 1) {
throw new NucleusUserException(Localiser.msg("021213"));
}
}
}
}
if (resultClass != null) {
if (// Don't apply checks when user has specified the default (no result class)
!resultClass.getName().equals(Object[].class.getName())) {
// Check validity of resultClass for the result (PrivilegedAction since uses reflection)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// Check that this class has the necessary constructor/setters/fields to be used
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
if (QueryUtils.resultClassIsSimple(resultClass.getName())) {
if (resultMapping.getNumberOfResultExpressions() > 1) {
// Invalid number of result expressions
throw new NucleusUserException(Localiser.msg("021201", resultClass.getName()));
}
Object stmtMap = resultMapping.getMappingForResultExpression(0);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
Class exprType = idx.getMapping().getJavaType();
boolean typeConsistent = false;
if (exprType == resultClass) {
typeConsistent = true;
} else if (exprType.isPrimitive()) {
Class resultClassPrimitive = ClassUtils.getPrimitiveTypeForType(resultClass);
if (resultClassPrimitive == exprType) {
typeConsistent = true;
}
}
if (!typeConsistent) {
// Inconsistent expression type not matching the result class type
throw new NucleusUserException(Localiser.msg("021202", resultClass.getName(), exprType));
}
} else {
// TODO Handle StatementNewObjectMapping
throw new NucleusUserException("Don't support result clause of " + result + " with resultClass of " + resultClass.getName());
}
} else if (QueryUtils.resultClassIsUserType(resultClass.getName())) {
// Check for valid constructor (either using param types, or using default ctr)
Class[] ctrTypes = new Class[resultMapping.getNumberOfResultExpressions()];
for (int i = 0; i < ctrTypes.length; i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
ctrTypes[i] = ((StatementMappingIndex) stmtMap).getMapping().getJavaType();
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
Constructor ctr = ClassUtils.getConstructorWithArguments(resultClass, ctrTypes);
if (ctr == null && !ClassUtils.hasDefaultConstructor(resultClass)) {
// No valid constructor found!
throw new NucleusUserException(Localiser.msg("021205", resultClass.getName()));
} else if (ctr == null) {
// We are using default constructor, so check the types of the result expressions for means of input
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex mapIdx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = mapIdx.getMapping().getMemberMetaData();
String fieldName = mapIdx.getColumnAlias();
Class fieldType = mapIdx.getMapping().getJavaType();
if (fieldName == null && mmd != null) {
fieldName = mmd.getName();
}
if (fieldName != null) {
// Check for the field of that name in the result class
Class resultFieldType = null;
boolean publicField = true;
try {
Field fld = resultClass.getDeclaredField(fieldName);
resultFieldType = fld.getType();
// Check the type of the field
if (!ClassUtils.typesAreCompatible(fieldType, resultFieldType) && !ClassUtils.typesAreCompatible(resultFieldType, fieldType)) {
throw new NucleusUserException(Localiser.msg("021211", fieldName, fieldType.getName(), resultFieldType.getName()));
}
if (!Modifier.isPublic(fld.getModifiers())) {
publicField = false;
}
} catch (NoSuchFieldException nsfe) {
publicField = false;
}
// Check for a public set method
if (!publicField) {
Method setMethod = QueryUtils.getPublicSetMethodForFieldOfResultClass(resultClass, fieldName, resultFieldType);
if (setMethod == null) {
// No setter, so check for a public put(Object, Object) method
Method putMethod = QueryUtils.getPublicPutMethodForResultClass(resultClass);
if (putMethod == null) {
throw new NucleusUserException(Localiser.msg("021212", resultClass.getName(), fieldName));
}
}
}
}
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
}
}
return null;
}
});
}
}
}
}
boolean hasParams = false;
if (explicitParameters != null) {
hasParams = true;
} else if (parameterValues != null && parameterValues.size() > 0) {
hasParams = true;
}
if (!statementReturnsEmpty && queryCacheKey != null && useCaching()) {
// TODO Allow caching of queries with subqueries
if (!datastoreCompilation.isPrecompilable() || (datastoreCompilation.getSQL().indexOf('?') < 0 && hasParams)) {
// Some parameters had their clauses evaluated during compilation so the query didn't gain any parameters, so don't cache it
NucleusLogger.QUERY.debug(Localiser.msg("021075"));
} else {
qm.addDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey, datastoreCompilation);
}
}
}
}
}
use of org.datanucleus.store.query.QueryManager in project datanucleus-rdbms by datanucleus.
the class JPQLQuery method compileInternal.
/**
* Method to compile the JPQL query.
* Uses the superclass to compile the generic query populating the "compilation", and then generates
* the datastore-specific "datastoreCompilation".
* @param parameterValues Map of param values keyed by param name (if available at compile time)
*/
protected synchronized void compileInternal(Map parameterValues) {
if (isCompiled()) {
return;
}
if (getExtension(EXTENSION_INCLUDE_SOFT_DELETES) != null) {
// If using an extension that can change the datastore query then evict any existing compilation
QueryManager qm = getQueryManager();
qm.removeQueryCompilation(Query.LANGUAGE_JPQL, getQueryCacheKey());
}
// Compile the generic query expressions
super.compileInternal(parameterValues);
boolean inMemory = evaluateInMemory();
if (candidateCollection != null) {
// TODO Maybe apply the result class checks ?
return;
}
if (candidateClass == null || candidateClassName == null) {
candidateClass = compilation.getCandidateClass();
candidateClassName = candidateClass.getName();
}
// Create the SQL statement, and its result/parameter definitions
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
QueryManager qm = getQueryManager();
String datastoreKey = storeMgr.getQueryCacheKey();
String queryCacheKey = getQueryCacheKey();
if (useCaching() && queryCacheKey != null) {
// Check if we have any parameters set to null, since this can invalidate a datastore compilation
// e.g " field == :val" can be "COL IS NULL" or "COL = <val>"
boolean nullParameter = false;
if (parameterValues != null) {
Iterator iter = parameterValues.values().iterator();
while (iter.hasNext()) {
Object val = iter.next();
if (val == null) {
nullParameter = true;
break;
}
}
}
if (!nullParameter) {
// Allowing caching so try to find compiled (datastore) query
datastoreCompilation = (RDBMSQueryCompilation) qm.getDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey);
if (datastoreCompilation != null) {
// Cached compilation exists for this datastore so reuse it
return;
}
}
}
// No cached compilation for this query in this datastore so compile it
AbstractClassMetaData acmd = getCandidateClassMetaData();
if (type == QueryType.BULK_INSERT) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryInsert(parameterValues, acmd);
} else if (type == QueryType.BULK_UPDATE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryUpdate(parameterValues, acmd);
} else if (type == QueryType.BULK_DELETE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryDelete(parameterValues, acmd);
} else {
datastoreCompilation = new RDBMSQueryCompilation();
if (inMemory) {
// Generate statement to just retrieve all candidate objects for later processing
compileQueryToRetrieveCandidates(parameterValues, acmd);
} else {
// Generate statement to perform the full query in the datastore
compileQueryFull(parameterValues, acmd);
if (result != null) {
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = idx.getMapping().getMemberMetaData();
if (mmd != null) {
if (idx.getMapping() instanceof AbstractContainerMapping && idx.getMapping().getNumberOfColumnMappings() != 1) {
throw new NucleusUserException(Localiser.msg("021213"));
}
}
}
}
}
}
if (resultClass != null && result != null) {
// Do as PrivilegedAction since uses reflection
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// Check that this class has the necessary constructor/setters/fields to be used
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
if (QueryUtils.resultClassIsSimple(resultClass.getName())) {
if (resultMapping.getNumberOfResultExpressions() > 1) {
// Invalid number of result expressions
throw new NucleusUserException(Localiser.msg("021201", resultClass.getName()));
}
Object stmtMap = resultMapping.getMappingForResultExpression(0);
// TODO Handle StatementNewObjectMapping
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
Class exprType = idx.getMapping().getJavaType();
boolean typeConsistent = false;
if (exprType == resultClass) {
typeConsistent = true;
} else if (exprType.isPrimitive()) {
Class resultClassPrimitive = ClassUtils.getPrimitiveTypeForType(resultClass);
if (resultClassPrimitive == exprType) {
typeConsistent = true;
}
}
if (!typeConsistent) {
// Inconsistent expression type not matching the result class type
throw new NucleusUserException(Localiser.msg("021202", resultClass.getName(), exprType));
}
} else if (QueryUtils.resultClassIsUserType(resultClass.getName())) {
// Check for valid constructor (either using param types, or using default ctr)
Class[] ctrTypes = new Class[resultMapping.getNumberOfResultExpressions()];
for (int i = 0; i < ctrTypes.length; i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
ctrTypes[i] = ((StatementMappingIndex) stmtMap).getMapping().getJavaType();
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
Constructor ctr = ClassUtils.getConstructorWithArguments(resultClass, ctrTypes);
if (ctr == null && !ClassUtils.hasDefaultConstructor(resultClass)) {
// No valid constructor found!
throw new NucleusUserException(Localiser.msg("021205", resultClass.getName()));
} else if (ctr == null) {
// We are using default constructor, so check the types of the result expressions for means of input
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex mapIdx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = mapIdx.getMapping().getMemberMetaData();
String fieldName = mapIdx.getColumnAlias();
Class fieldType = mapIdx.getMapping().getJavaType();
if (fieldName == null && mmd != null) {
fieldName = mmd.getName();
}
if (fieldName != null) {
// Check for the field of that name in the result class
Class resultFieldType = null;
boolean publicField = true;
try {
Field fld = resultClass.getDeclaredField(fieldName);
resultFieldType = fld.getType();
// Check the type of the field
if (!ClassUtils.typesAreCompatible(fieldType, resultFieldType) && !ClassUtils.typesAreCompatible(resultFieldType, fieldType)) {
throw new NucleusUserException(Localiser.msg("021211", fieldName, fieldType.getName(), resultFieldType.getName()));
}
if (!Modifier.isPublic(fld.getModifiers())) {
publicField = false;
}
} catch (NoSuchFieldException nsfe) {
publicField = false;
}
// Check for a public set method
if (!publicField) {
Method setMethod = QueryUtils.getPublicSetMethodForFieldOfResultClass(resultClass, fieldName, resultFieldType);
if (setMethod == null) {
// No setter, so check for a public put(Object, Object) method
Method putMethod = QueryUtils.getPublicPutMethodForResultClass(resultClass);
if (putMethod == null) {
throw new NucleusUserException(Localiser.msg("021212", resultClass.getName(), fieldName));
}
}
}
}
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
}
}
return null;
}
});
}
boolean hasParams = false;
if (explicitParameters != null) {
hasParams = true;
} else if (parameterValues != null && parameterValues.size() > 0) {
hasParams = true;
}
if (!datastoreCompilation.isPrecompilable() || (datastoreCompilation.getSQL().indexOf('?') < 0 && hasParams)) {
// Some parameters had their clauses evaluated during compilation so the query didn't gain any parameters, so don't cache it
NucleusLogger.QUERY.debug(Localiser.msg("021075"));
} else {
if (!statementReturnsEmpty && useCaching() && queryCacheKey != null) {
qm.addDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey, datastoreCompilation);
}
}
}
}
Aggregations