use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class QueryHandler method initializeDatabaseQuery.
/**
* <p><b>INTERNAL</b>: Initialize this <code>QueryHandler</code>'s <code>DatabaseQuery</code>
* @param xrService the given <code>DBWSService</code>
* @param queryOperation the given <code>QueryOperation</code>
*/
public void initializeDatabaseQuery(XRServiceAdapter xrService, QueryOperation queryOperation) {
DatabaseQuery databaseQueryToInitialize;
if (queryOperation.hasResponse()) {
QName type = queryOperation.getResult().getType();
if (queryOperation.isCollection()) {
if (queryOperation.isSimpleXMLFormat() || (xrService.descriptorsByQName.containsKey(type) && xrService.getORSession().getClassDescriptorForAlias(xrService.descriptorsByQName.get(type).getAlias()).isAggregateDescriptor() && !xrService.getORSession().getClassDescriptorForAlias(xrService.descriptorsByQName.get(type).getAlias()).isObjectRelationalDataTypeDescriptor())) {
// data-read query
databaseQueryToInitialize = new DataReadQuery();
} else {
if (!xrService.descriptorsByQName.containsKey(type)) {
// data-read query
databaseQueryToInitialize = new DataReadQuery();
} else {
// read-all query for the class mapped to the type
databaseQueryToInitialize = new ReadAllQuery(xrService.getTypeClass(type));
}
}
} else {
if (queryOperation.isSimpleXMLFormat() || (xrService.descriptorsByQName.containsKey(type) && xrService.getORSession().getClassDescriptorForAlias(xrService.descriptorsByQName.get(type).getAlias()).isAggregateDescriptor() && !xrService.getORSession().getClassDescriptorForAlias(xrService.descriptorsByQName.get(type).getAlias()).isObjectRelationalDataTypeDescriptor())) {
// data-read query
databaseQueryToInitialize = new DataReadQuery();
} else if (!xrService.descriptorsByQName.containsKey(type)) {
// value read query
databaseQueryToInitialize = new ValueReadQuery();
} else {
// read object query for the class mapped to the type
databaseQueryToInitialize = new ReadObjectQuery(xrService.getTypeClass(type));
}
}
} else {
databaseQueryToInitialize = new DataModifyQuery();
}
databaseQueryToInitialize.bindAllParameters();
setDatabaseQuery(databaseQueryToInitialize);
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class QueryOperation method invoke.
/**
* Execute <code>SELECT</code> operation on the database
* @param xrService parent <code>XRService</code> that owns this <code>Operation</code>
* @param invocation contains runtime argument values to be bound to the list of
* {@link Parameter}'s.
* @return result - the result of the underlying <code>SELECT</code> operation on
* the database, or <code>null</code>.
*
* @see Operation
*/
@Override
@SuppressWarnings({ "unchecked" })
public Object invoke(XRServiceAdapter xrService, Invocation invocation) {
DatabaseQuery query = queryHandler.getDatabaseQuery();
if (query.getProperty(DATABASEQUERY_STR) != null) {
query = (DatabaseQuery) query.getProperty(DATABASEQUERY_STR);
}
// a named query created via ORM metadata processing does not have
// parameters set, however, the operation should
List<Object> argVals = new ArrayList<>();
if (query.getArguments().size() == 0) {
int idx = 0;
for (Parameter param : getParameters()) {
// for custom SQL query (as configured via ORM metadata
// processing) we add args by position
query.addArgument(Integer.toString(++idx), Util.SCHEMA_2_CLASS.get(param.getType()));
argVals.add(invocation.getParameter(param.getName()));
}
} else {
// need to set argument values
for (Parameter param : getParameters()) {
argVals.add(invocation.getParameter(param.getName()));
}
}
// for SimpleXML + DataReadQuery we need to set MAP result type
if (isSimpleXMLFormat() && query.isDataReadQuery()) {
((DataReadQuery) query).setResultType(DataReadQuery.MAP);
}
// now execute the query
Object value = xrService.getORSession().getActiveSession().executeQuery(query, argVals);
if (value != null) {
// where before we'd expect an int value (typically 1) - need to handle this
if (result != null && (result.getType() == INT_QNAME || result.getType().equals(SXF_QNAME))) {
if (value instanceof ArrayList && ((ArrayList<?>) value).isEmpty()) {
((ArrayList<Integer>) value).add(1);
} else if (value instanceof Vector && ((Vector<?>) value).isEmpty()) {
((Vector<Integer>) value).add(1);
}
}
// Note that for legacy deployment XML projects this is not the case.
if (value instanceof ArrayList) {
ArrayList<?> returnedList = (ArrayList<?>) value;
if (returnedList.size() > 0 && returnedList.get(0) instanceof Object[]) {
Object[] objs = (Object[]) returnedList.get(0);
if (isCollection()) {
value = new ArrayList<>();
for (Object obj : objs) {
((ArrayList<Object>) value).add(obj);
}
} else {
value = objs[0];
}
}
}
// handle SimpleXML
if (isSimpleXMLFormat()) {
value = createSimpleXMLFormat(xrService, value);
} else {
if (!isCollection() && value instanceof Vector) {
// JPAQuery will return a single result in a Vector
if (((Vector<?>) value).isEmpty()) {
return null;
}
value = ((Vector<?>) value).firstElement();
}
QName resultType = getResultType();
if (resultType != null) {
// handle binary content
if (isAttachment() || (!isCollection() && resultType.equals(BASE_64_BINARY_QNAME))) {
String mimeType = DEFAULT_ATTACHMENT_MIMETYPE;
if (isAttachment() && result.getAttachment().getMimeType() != null) {
mimeType = result.getAttachment().getMimeType();
}
// handle BLOB types
if (value instanceof Blob) {
value = xrService.getOXSession().getDatasourcePlatform().getConversionManager().convertObject(value, ClassConstants.APBYTE);
}
return AttachmentHelper.buildAttachmentHandler((byte[]) value, mimeType);
}
if (resultType.getNamespaceURI().equals(SCHEMA_URL)) {
// handle primitive types
ValueObject vo = new ValueObject();
vo.value = value;
value = vo;
} else {
Object targetObject = value;
if (xrService.descriptorsByQName.containsKey(resultType)) {
XMLDescriptor xdesc = xrService.descriptorsByQName.get(resultType);
ClassDescriptor desc = xrService.getORSession().getDescriptorForAlias(xdesc.getAlias());
if (desc.isAggregateDescriptor() && !desc.isObjectRelationalDataTypeDescriptor() && !desc.isRelationalDescriptor()) {
if (isCollection()) {
XRDynamicEntity_CollectionWrapper xrCollWrapper = new XRDynamicEntity_CollectionWrapper();
Vector<AbstractRecord> results = (Vector<AbstractRecord>) value;
for (int i = 0, len = results.size(); i < len; i++) {
Object o = desc.getObjectBuilder().buildNewInstance();
populateTargetObjectFromRecord(desc.getMappings(), results.get(i), o, (AbstractSession) xrService.getORSession());
xrCollWrapper.add(o);
}
targetObject = xrCollWrapper;
} else {
targetObject = desc.getObjectBuilder().buildNewInstance();
populateTargetObjectFromRecord(desc.getMappings(), (AbstractRecord) value, targetObject, (AbstractSession) xrService.getORSession());
}
} else if (isCollection() && value instanceof Vector) {
// could be a collection of populated objects, in which case we just return it
if (((Vector<?>) value).size() > 0 && !(((Vector<?>) value).get(0) instanceof AbstractRecord)) {
return value;
}
XRDynamicEntity_CollectionWrapper xrCollWrapper = new XRDynamicEntity_CollectionWrapper();
Vector<AbstractRecord> results = (Vector<AbstractRecord>) value;
for (int i = 0, len = results.size(); i < len; i++) {
Object o = desc.getObjectBuilder().buildNewInstance();
populateTargetObjectFromRecord(desc.getMappings(), results.get(i), o, (AbstractSession) xrService.getORSession());
xrCollWrapper.add(o);
}
targetObject = xrCollWrapper;
} else if (value instanceof AbstractRecord) {
targetObject = desc.getObjectBuilder().buildNewInstance();
populateTargetObjectFromRecord(desc.getMappings(), (AbstractRecord) value, targetObject, (AbstractSession) xrService.getORSession());
}
}
if (value instanceof ArrayList) {
XMLDescriptor xdesc = xrService.descriptorsByQName.get(resultType);
ClassDescriptor desc = xrService.getORSession().getDescriptorForAlias(xdesc.getAlias());
targetObject = desc.getObjectBuilder().buildNewInstance();
Object[] objs = new Object[1];
objs[0] = ((ArrayList<?>) value).get(0);
DatabaseRecord dr = new DatabaseRecord();
dr.add(new DatabaseField(ITEMS_STR), objs);
populateTargetObjectFromRecord(desc.getMappings(), dr, targetObject, (AbstractSession) xrService.getORSession());
}
value = targetObject;
}
}
}
}
return value;
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class PLSQLcollectionTestSuite method fromProjectXML.
@Test
public void fromProjectXML() {
XRDynamicClassLoader xrdecl = new XRDynamicClassLoader(PLSQLcollectionTestSuite.class.getClassLoader());
Project projectFromXML = XMLProjectReader.read(new StringReader(TEST_PROJECT_CONTROL_DOC), xrdecl);
DatabaseLogin login = new DatabaseLogin();
login.setUserName(username);
login.setPassword(password);
login.setConnectionString(url);
login.setDriverClassName("oracle.jdbc.OracleDriver");
Platform platform = new Oracle10Platform();
ConversionManager cm = platform.getConversionManager();
cm.setLoader(xrdecl);
login.setDatasourcePlatform(platform);
login.bindAllParameters();
projectFromXML.setDatasourceLogin(login);
ProjectHelper.fixOROXAccessors(projectFromXML, null);
xrdecl.dontGenerateSubclasses();
ClassDescriptor t1Descriptor = projectFromXML.getDescriptorForAlias("T1");
DatabaseQuery query = t1Descriptor.getQueryManager().getQuery(QUERY_NAME);
assertTrue(QUERY_NAME + " is wrong type of query: " + query.getClass().getSimpleName(), query.isDataModifyQuery());
session = projectFromXML.createDatabaseSession();
session.dontLogMessages();
t1Descriptor = session.getDescriptorForAlias("T1");
Class<?> t1Clz = t1Descriptor.getJavaClass();
((DatabaseSession) session).login();
String[] elements = { "first string", "second string", "third string" };
NonSynchronizedVector<Object> queryArgs = new NonSynchronizedVector<>();
queryArgs.add(elements);
queryArgs.add("barf");
boolean worked = false;
String msg = null;
try {
session.executeQuery(QUERY_NAME, t1Clz, queryArgs);
worked = true;
} catch (Exception e) {
msg = e.getMessage();
}
assertTrue("invocation somePackage.p1 failed: " + msg, worked);
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class NamedQueryHandler method validate.
@Override
public void validate(XRServiceAdapter xrService, QueryOperation queryOperation) {
if (descriptor != null) {
if (!xrService.getORSession().getProject().getAliasDescriptors().containsKey(descriptor)) {
throw DBWSException.couldNotLocateDescriptorForOperation(descriptor, getName());
}
ClassDescriptor cd = xrService.getORSession().getProject().getDescriptorForAlias(descriptor);
if (cd.getQueryManager().getQuery(name) == null) {
boolean foundQuery = false;
for (DatabaseQuery q : xrService.getORSession().getProject().getJPAQueries()) {
if (q.getName().equals(name)) {
foundQuery = true;
cd.getQueryManager().addQuery(name, q);
break;
}
}
if (!foundQuery) {
throw DBWSException.couldNotLocateQueryForDescriptor(name, descriptor);
}
}
} else if (xrService.getORSession().getQuery(name) == null) {
boolean foundQuery = false;
for (DatabaseQuery q : xrService.getORSession().getJPAQueries()) {
if (q.getName().equals(name)) {
foundQuery = true;
break;
}
}
if (!foundQuery) {
throw DBWSException.couldNotLocateQueryForSession(name, xrService.getORSession().getName());
}
}
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class FunctionExpression method prepareObjectAttributeCount.
/**
* INTERNAL:
* JPQL allows count([distinct] e), where e can be an object, not just a single field,
* however the database only allows a single field, so object needs to be translated to a single field.
* If the descriptor has a single pk, it is used, otherwise any pk is used if distinct, otherwise a subselect is used.
* If the object was obtained through an outer join, then the subselect also will not work, so an error is thrown.
*/
public void prepareObjectAttributeCount(ExpressionNormalizer normalizer, ReportItem item, ReportQuery query, Map clonedExpressions) {
// ** Note that any of the arguments may be null depending on the caller.
if (getOperator().getSelector() == ExpressionOperator.Count) {
Expression baseExp = getBaseExpression();
boolean distinctUsed = false;
if (baseExp.isFunctionExpression() && (baseExp.getOperator().getSelector() == ExpressionOperator.Distinct)) {
distinctUsed = true;
baseExp = ((FunctionExpression) baseExp).getBaseExpression();
}
boolean outerJoin = false;
ClassDescriptor newDescriptor = null;
AbstractSession session = null;
if (query != null) {
session = query.getSession();
} else {
session = normalizer.getSession();
}
if (baseExp.isQueryKeyExpression()) {
// now need to find out if it is a direct to field or something else.
ClassDescriptor descriptor = null;
if (query == null) {
descriptor = ((QueryKeyExpression) baseExp).getDescriptor();
} else {
descriptor = query.getDescriptor();
}
DatabaseMapping mapping = baseExp.getLeafMapping(query, descriptor, session);
if ((mapping != null) && !mapping.isAbstractDirectMapping()) {
outerJoin = ((QueryKeyExpression) baseExp).shouldUseOuterJoin();
if (mapping.isAggregateMapping()) {
newDescriptor = mapping.getDescriptor();
baseExp = ((QueryKeyExpression) baseExp).getBaseExpression();
} else {
newDescriptor = mapping.getReferenceDescriptor();
}
} else {
QueryKey queryKey = getLeafQueryKeyFor(query, baseExp, descriptor, session);
if ((queryKey != null) && queryKey.isForeignReferenceQueryKey()) {
outerJoin = ((QueryKeyExpression) baseExp).shouldUseOuterJoin();
newDescriptor = session.getDescriptor(((ForeignReferenceQueryKey) queryKey).getReferenceClass());
}
}
} else if (baseExp.isExpressionBuilder()) {
if (((ExpressionBuilder) baseExp).getQueryClass() == null) {
if (item != null) {
item.setResultType(ClassConstants.INTEGER);
}
} else {
newDescriptor = session.getDescriptor(((ExpressionBuilder) baseExp).getQueryClass());
}
}
if (newDescriptor != null) {
// At this point we are committed to rewriting the query.
if ((newDescriptor.getPrimaryKeyFields().size() == 1) || !distinctUsed) {
// case 1: single PK =>
// treat COUNT(entity) as COUNT(entity.pk)
Expression countArg = baseExp.getField(newDescriptor.getPrimaryKeyFields().get(0));
if (distinctUsed) {
countArg = countArg.distinct();
}
setBaseExpression(countArg);
getChildren().set(0, countArg);
} else if (((DatabasePlatform) session.getPlatform(newDescriptor.getJavaClass())).supportsCountDistinctWithMultipleFields()) {
// case 3, is database allows multiple fields, then just print them
// treat COUNT(distinct entity) as COUNT(distinct entity.pk1, entity.pk2)
List args = new ArrayList(newDescriptor.getPrimaryKeyFields().size());
Expression firstField = null;
for (DatabaseField field : newDescriptor.getPrimaryKeyFields()) {
if (firstField == null) {
firstField = baseExp.getField(field);
} else {
args.add(baseExp.getField(field));
}
}
ExpressionOperator anOperator = new ExpressionOperator();
anOperator.setType(ExpressionOperator.FunctionOperator);
Vector v = NonSynchronizedVector.newInstance(args.size());
v.addElement("DISTINCT ");
for (int index = 0; index < args.size(); index++) {
v.add(", ");
}
v.add("");
anOperator.printsAs(v);
anOperator.bePrefix();
anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
Expression distinctFunction = anOperator.expressionForArguments(firstField, args);
setBaseExpression(distinctFunction);
getChildren().set(0, distinctFunction);
} else if (!outerJoin && (query != null)) {
// and will miss out if moved now from items into a selection criteria.
if (clonedExpressions != null) {
if (clonedExpressions.get(baseExp.getBuilder()) != null) {
baseExp = baseExp.copiedVersionFrom(clonedExpressions);
} else {
baseExp = baseExp.rebuildOn(query.getExpressionBuilder());
}
}
// Now the reference class of the query needs to be reversed.
// See the bug description for an explanation.
ExpressionBuilder countBuilder = baseExp.getBuilder();
ExpressionBuilder outerBuilder;
ReportQuery subSelect = new ReportQuery(query.getReferenceClass(), countBuilder);
query.getSession().getPlatform().retrieveFirstPrimaryKeyOrOne(subSelect);
// Putting a builder on the left is desirable to trigger an optimization.
if (query.getSelectionCriteria() != null) {
outerBuilder = new ExpressionBuilder(newDescriptor.getJavaClass());
query.setExpressionBuilder(outerBuilder);
subSelect.setSelectionCriteria(baseExp.equal(outerBuilder).and(query.getSelectionCriteria()));
} else {
outerBuilder = new ExpressionBuilder(newDescriptor.getJavaClass());
query.setExpressionBuilder(outerBuilder);
subSelect.setSelectionCriteria(baseExp.equal(outerBuilder));
}
query.setNonFetchJoinAttributeExpressions(null);
query.setSelectionCriteria(outerBuilder.exists(subSelect));
setBaseExpression(outerBuilder);
getChildren().set(0, outerBuilder);
query.setReferenceClass(newDescriptor.getJavaClass());
query.changeDescriptor(session);
} else {
// case 4: composite PK, DISTINCT, outer join =>
// not supported, throw exception
DatabaseQuery reportQuery = query;
if (query == null) {
reportQuery = normalizer.getStatement().getQuery();
}
throw QueryException.distinctCountOnOuterJoinedCompositePK(newDescriptor, reportQuery);
}
}
}
}
Aggregations