use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class LOBValueWriter method buildAndExecuteCall.
protected void buildAndExecuteCall(DatabaseCall dbCall, AbstractSession session) {
DatabaseQuery query = dbCall.getQuery();
if (!query.isWriteObjectQuery()) {
// if not writequery, should not go through the locator writing..
return;
}
WriteObjectQuery writeQuery = (WriteObjectQuery) query;
writeQuery.setAccessor(accessor);
// build a select statement form the query
SQLSelectStatement selectStatement = buildSelectStatementForLocator(writeQuery, dbCall, session);
// then build a call from the statement
DatabaseCall call = buildCallFromSelectStatementForLocator(selectStatement, writeQuery, dbCall, session);
accessor.executeCall(call, call.getQuery().getTranslationRow(), session);
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class RemoteSessionController method executeQuery.
/**
* A remote query after serialization is executed locally.
*/
public Transporter executeQuery(Transporter remoteTransporter) {
remoteTransporter.expand(this.session);
DatabaseQuery query = (DatabaseQuery) remoteTransporter.getObject();
Transporter transporter = new Transporter();
try {
AbstractRecord argumentRow = query.getTranslationRow();
query.setTranslationRow(null);
Object result;
// Clear the unit of work, as the client unit of work may have been cleared.
this.unitOfWork = null;
AbstractSession executionSession = getExecutionSession();
if (argumentRow == null) {
result = executionSession.executeQuery(query);
} else {
result = executionSession.executeQuery(query, argumentRow);
}
transporter.setObjectDescriptors(query.replaceValueHoldersIn(result, this));
transporter.setObject(result);
} catch (RuntimeException exception) {
transporter.setException(exception);
}
transporter.prepare(this.session);
return transporter;
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class AdvancedJPAJunitTest method testTransparentIndirectionQuerySessionReset.
/**
* Bug 489898 - RepeatableWriteUnitOfWork linked by QueryBasedValueHolder in shared cache in specific scenario
*
* Complex scenario: In a transaction, associate an existing object to a new object, refresh the existing object.
* In a second transaction, read the new object and traverse relationships to the existing object, and trigger
* an indirect relationship. The existing wrapped indirection query on the indirect relationship should
* ensure that the UnitOfWork (RepeatableWriteUnitOfWork) used for the query is unreferenced correctly, to
* avoid referencing it within the shared cache, via the existing referenced query.
*/
public void testTransparentIndirectionQuerySessionReset() {
Bill bill = null;
BillLine billLine = null;
BillLineItem billLineItem = null;
BillAction billAction = null;
// setup
EntityManager em = createEntityManager();
try {
beginTransaction(em);
bill = new Bill();
bill.setOrderIdentifier("Test Bill");
billLine = new BillLine();
billLine.setQuantity(6);
bill.addBillLine(billLine);
billLineItem = new BillLineItem();
billLineItem.setItemName("Test Widget");
billLine.addBillLineItem(billLineItem);
em.persist(bill);
em.persist(billLine);
em.persist(billLineItem);
commitTransaction(em);
assertNotNull("bill should be non-null", bill);
assertNotNull("bill's id should be non-null", bill.getId());
assertNotNull("billLine should be non-null", billLine);
assertNotNull("billLine's id should be non-null", billLine.getId());
assertNotNull("billLineItem should be non-null", billLineItem);
assertNotNull("billLineItem's id should be non-null", billLineItem.getId());
} finally {
closeEntityManager(em);
// start test with an empty cache
clearCache();
}
try {
// test - txn #1 : read, modify, persist, refresh related Entity
em = createEntityManager();
try {
beginTransaction(em);
Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult();
assertNotNull(billReRead);
BillLine billLineReRead = billReRead.getBillLines().get(0);
assertNotNull(billLineReRead);
billAction = new BillAction();
billAction.setBillLine(billLineReRead);
billAction.setPriority(2);
em.persist(billAction);
// refresh
em.refresh(billLineReRead);
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
// test - txn #2 : read, modify and trigger relationship on related Entity
em = createEntityManager();
try {
beginTransaction(em);
Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult();
// DM: if there is no update to Order, issue doesn't occur
billReRead.setStatus(Bill.STATUS_PROCESSING);
BillAction billActionReRead = em.createQuery("SELECT a FROM BillAction a where a.id=" + billAction.getId(), BillAction.class).getSingleResult();
assertNotNull(billActionReRead);
BillLine billLineReRead = billActionReRead.getBillLine();
assertNotNull(billLineReRead);
// Access & trigger BillLine -> BillLineItems list
billLineReRead.getBillLineItems().size();
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
// verify
// Failure case: non-null session (a UnitOfWork/RepeatableWriteUnitOfWork) referenced in the wrapped ValueHolder's query.
ServerSession srv = getServerSession();
ClassDescriptor descriptor = srv.getDescriptor(billLine);
Long blId = billLine.getId();
BillLine cachedBillLine = (BillLine) srv.getIdentityMapAccessor().getFromIdentityMap(blId, BillLine.class);
assertNotNull("BillLine from shared cache is null with id: " + blId, cachedBillLine);
OneToManyMapping mapping = (OneToManyMapping) srv.getDescriptor(cachedBillLine).getMappingForAttributeName("billLineItems");
IndirectContainer billLineItemsVH = (IndirectContainer) mapping.getAttributeValueFromObject(cachedBillLine);
assertNotNull("BillLineItems ValueHolder should not be null", billLineItemsVH);
ValueHolderInterface wrappedVH = billLineItemsVH.getValueHolder();
assertNotNull("Wrapped ValueHolder should not be null", wrappedVH);
if (wrappedVH instanceof QueryBasedValueHolder) {
DatabaseQuery query = ((QueryBasedValueHolder) wrappedVH).getQuery();
if (query.getSession() != null && query.getSession().isUnitOfWork()) {
fail("UnitOfWork referenced in Query from wrapped QueryBasedValueHolder in shared cache");
}
}
} finally {
// reset
em = createEntityManager();
try {
beginTransaction(em);
bill = em.find(Bill.class, bill.getId());
if (bill != null) {
em.remove(bill);
}
billLine = em.find(BillLine.class, billLine.getId());
if (billLine != null) {
em.remove(billLine);
}
billLineItem = em.find(BillLineItem.class, billLineItem.getId());
if (billLineItem != null) {
em.remove(billLineItem);
}
if (billAction != null) {
billAction = em.find(BillAction.class, billAction.getId());
if (billAction != null) {
em.remove(billAction);
}
}
commitTransaction(em);
} finally {
closeEntityManager(em);
}
}
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class XmlEntityMappingsGenerator method generateXmlEntityMappings.
/**
* Generate an XMLEntityMappings instance based on a given OR Project's Queries and Descriptors.
*
* @param orProject the ORM Project instance containing Queries and Descriptors to be used to generate an XMLEntityMappings
* @param complexTypes list of composite database types used to generate metadata for advanced Oracle and PL/SQL types
* @param crudOperations map of maps keyed on table name - the second map are operation name to SQL string entries
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static XMLEntityMappings generateXmlEntityMappings(Project orProject, List<CompositeDatabaseType> complexTypes, Map<String, Map<String, String>> crudOperations) {
List<ClassDescriptor> descriptors = orProject.getOrderedDescriptors();
List<DatabaseQuery> queries = orProject.getQueries();
XMLEntityMappings xmlEntityMappings = new XMLEntityMappings();
xmlEntityMappings.setEmbeddables(new ArrayList<EmbeddableAccessor>());
xmlEntityMappings.setEntities(new ArrayList<EntityAccessor>());
xmlEntityMappings.setPLSQLRecords(new ArrayList<PLSQLRecordMetadata>());
xmlEntityMappings.setPLSQLTables(new ArrayList<PLSQLTableMetadata>());
xmlEntityMappings.setOracleObjectTypes(new ArrayList<OracleObjectTypeMetadata>());
xmlEntityMappings.setOracleArrayTypes(new ArrayList<OracleArrayTypeMetadata>());
// process PL/SQL records and collections, and Oracle advanced JDBC types
List<PLSQLRecordMetadata> plsqlRecords = null;
List<PLSQLTableMetadata> plsqlTables = null;
List<OracleObjectTypeMetadata> objectTypes = null;
List<OracleArrayTypeMetadata> arrayTypes = null;
// generate metadata for each of the composite types
List<ComplexTypeMetadata> complexTypeMetadata = processCompositeTypes(complexTypes, orProject);
for (ComplexTypeMetadata cTypeMetadata : complexTypeMetadata) {
if (cTypeMetadata.isOracleComplexTypeMetadata()) {
OracleComplexTypeMetadata octMetadata = (OracleComplexTypeMetadata) cTypeMetadata;
if (octMetadata.isOracleArrayTypeMetadata()) {
if (arrayTypes == null) {
arrayTypes = new ArrayList<OracleArrayTypeMetadata>();
}
arrayTypes.add((OracleArrayTypeMetadata) octMetadata);
} else {
// assumes OracleObjectTypeMetadata
if (objectTypes == null) {
objectTypes = new ArrayList<OracleObjectTypeMetadata>();
}
objectTypes.add((OracleObjectTypeMetadata) octMetadata);
}
} else {
// assumes PL/SQL complex type metadata
PLSQLComplexTypeMetadata plsqlctMetadata = (PLSQLComplexTypeMetadata) cTypeMetadata;
if (plsqlctMetadata.isPLSQLRecordMetadata()) {
if (plsqlRecords == null) {
plsqlRecords = new ArrayList<PLSQLRecordMetadata>();
}
plsqlRecords.add((PLSQLRecordMetadata) plsqlctMetadata);
} else {
// assumes PLSQLTableMetadata
if (plsqlTables == null) {
plsqlTables = new ArrayList<PLSQLTableMetadata>();
}
plsqlTables.add((PLSQLTableMetadata) plsqlctMetadata);
}
}
}
// add generated metadata
xmlEntityMappings.setPLSQLRecords(plsqlRecords);
xmlEntityMappings.setPLSQLTables(plsqlTables);
xmlEntityMappings.setOracleObjectTypes(objectTypes);
xmlEntityMappings.setOracleArrayTypes(arrayTypes);
// process stored procedures/functions
List<NamedPLSQLStoredProcedureQueryMetadata> plsqlStoredProcs = null;
List<NamedPLSQLStoredFunctionQueryMetadata> plsqlStoredFuncs = null;
List<NamedStoredProcedureQueryMetadata> storedProcs = null;
List<NamedStoredFunctionQueryMetadata> storedFuncs = null;
List<NamedNativeQueryMetadata> namedNativeQueries = null;
// process database queries set on the descriptor
for (DatabaseQuery query : queries) {
if (query.getCall().isStoredFunctionCall()) {
if (query.getCall() instanceof PLSQLStoredFunctionCall) {
PLSQLStoredFunctionCall call = (PLSQLStoredFunctionCall) query.getCall();
NamedPLSQLStoredFunctionQueryMetadata metadata = new NamedPLSQLStoredFunctionQueryMetadata();
metadata.setName(query.getName());
metadata.setProcedureName(call.getProcedureName());
List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
if (plsqlStoredFuncs == null) {
plsqlStoredFuncs = new ArrayList<NamedPLSQLStoredFunctionQueryMetadata>();
}
PLSQLargument arg;
PLSQLParameterMetadata param;
List<PLSQLargument> types = call.getArguments();
for (int i = 0; i < types.size(); i++) {
arg = types.get(i);
param = new PLSQLParameterMetadata();
param.setName(arg.name);
String dbType = arg.databaseType.getTypeName();
if (arg.databaseType == XMLType) {
dbType = XMLType.name();
} else if (arg.databaseType == PLSQLBoolean) {
dbType = PLSQLBoolean.name();
} else {
if (!(getJDBCTypeFromTypeName(dbType) == Types.OTHER)) {
dbType = dbType.concat(_TYPE_STR);
}
}
param.setDatabaseType(dbType);
if (i == 0) {
// first arg is the return arg
metadata.setReturnParameter(param);
if (arg.cursorOutput) {
param.setDirection(CURSOR_STR);
}
} else {
param.setDirection(getDirectionAsString(arg.direction));
params.add(param);
}
}
if (params.size() > 0) {
metadata.setParameters(params);
}
plsqlStoredFuncs.add(metadata);
} else {
StoredFunctionCall call = (StoredFunctionCall) query.getCall();
NamedStoredFunctionQueryMetadata metadata = new NamedStoredFunctionQueryMetadata();
metadata.setName(query.getName());
metadata.setProcedureName(call.getProcedureName());
List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
if (storedFuncs == null) {
storedFuncs = new ArrayList<NamedStoredFunctionQueryMetadata>();
}
DatabaseField arg;
StoredProcedureParameterMetadata param;
List<DatabaseField> paramFields = call.getParameters();
List<Integer> types = call.getParameterTypes();
for (int i = 0; i < paramFields.size(); i++) {
arg = paramFields.get(i);
param = new StoredProcedureParameterMetadata();
param.setTypeName(arg.getTypeName());
if (arg.getSqlType() != DatabaseField.NULL_SQL_TYPE) {
param.setJdbcType(arg.getSqlType());
}
if (arg.isObjectRelationalDatabaseField()) {
param.setJdbcTypeName(((ObjectRelationalDatabaseField) arg).getSqlTypeName());
}
if (i == 0) {
// first arg is the return arg
metadata.setReturnParameter(param);
// handle CURSOR types - want name/value pairs returned
if (types.get(i) == 8) {
addQueryHint(metadata);
}
} else {
param.setName(arg.getName());
param.setMode(getParameterModeAsString(types.get(i)));
params.add(param);
}
}
if (params.size() > 0) {
metadata.setParameters(params);
}
storedFuncs.add(metadata);
}
} else if (query.getCall().isStoredProcedureCall()) {
if (query.getCall() instanceof PLSQLStoredProcedureCall) {
PLSQLStoredProcedureCall call = (PLSQLStoredProcedureCall) query.getCall();
if (plsqlStoredProcs == null) {
plsqlStoredProcs = new ArrayList<NamedPLSQLStoredProcedureQueryMetadata>();
}
NamedPLSQLStoredProcedureQueryMetadata metadata = new NamedPLSQLStoredProcedureQueryMetadata();
metadata.setName(query.getName());
metadata.setProcedureName(call.getProcedureName());
PLSQLParameterMetadata param;
List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
List<PLSQLargument> types = call.getArguments();
for (PLSQLargument arg : types) {
param = new PLSQLParameterMetadata();
param.setName(arg.name);
String dbType = processTypeName(arg.databaseType.getTypeName());
if (arg.cursorOutput) {
param.setDirection(CURSOR_STR);
} else {
param.setDirection(getDirectionAsString(arg.direction));
}
if (arg.databaseType == XMLType) {
param.setDatabaseType(XMLType.name());
} else if (arg.databaseType == PLSQLBoolean) {
param.setDatabaseType(PLSQLBoolean.name());
} else {
param.setDatabaseType(dbType);
}
params.add(param);
}
if (params.size() > 0) {
metadata.setParameters(params);
}
plsqlStoredProcs.add(metadata);
} else {
StoredProcedureCall call = (StoredProcedureCall) query.getCall();
NamedStoredProcedureQueryMetadata metadata = new NamedStoredProcedureQueryMetadata();
metadata.setName(query.getName());
metadata.setProcedureName(call.getProcedureName());
metadata.setReturnsResultSet(false);
List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
DatabaseField arg;
StoredProcedureParameterMetadata param;
List paramFields = call.getParameters();
List<Integer> types = call.getParameterTypes();
for (int i = 0; i < paramFields.size(); i++) {
if (types.get(i) == DatabaseCall.INOUT) {
// for INOUT we get Object[IN, OUT]
arg = (DatabaseField) ((Object[]) paramFields.get(i))[1];
} else {
arg = (DatabaseField) paramFields.get(i);
}
param = new StoredProcedureParameterMetadata();
param.setName(arg.getName());
param.setTypeName(arg.getTypeName());
if (arg.getSqlType() != DatabaseField.NULL_SQL_TYPE) {
param.setJdbcType(arg.getSqlType());
}
if (arg.isObjectRelationalDatabaseField()) {
param.setJdbcTypeName(((ObjectRelationalDatabaseField) arg).getSqlTypeName());
}
param.setMode(getParameterModeAsString(types.get(i)));
// handle CURSOR types - want name/value pairs returned
if (types.get(i) == 8) {
addQueryHint(metadata);
}
params.add(param);
}
if (params.size() > 0) {
metadata.setParameters(params);
}
if (storedProcs == null) {
storedProcs = new ArrayList<NamedStoredProcedureQueryMetadata>();
}
storedProcs.add(metadata);
}
} else {
// named native query
NamedNativeQueryMetadata namedQuery = new NamedNativeQueryMetadata();
namedQuery.setName(query.getName());
namedQuery.setQuery(query.getSQLString());
namedQuery.setResultClassName(query.getReferenceClassName());
if (namedNativeQueries == null) {
namedNativeQueries = new ArrayList<NamedNativeQueryMetadata>();
}
namedNativeQueries.add(namedQuery);
}
}
// add generated metadata
if (plsqlStoredProcs != null) {
xmlEntityMappings.setNamedPLSQLStoredProcedureQueries(plsqlStoredProcs);
}
if (plsqlStoredFuncs != null) {
xmlEntityMappings.setNamedPLSQLStoredFunctionQueries(plsqlStoredFuncs);
}
if (storedProcs != null) {
xmlEntityMappings.setNamedStoredProcedureQueries(storedProcs);
}
if (storedFuncs != null) {
xmlEntityMappings.setNamedStoredFunctionQueries(storedFuncs);
}
if (namedNativeQueries != null) {
xmlEntityMappings.setNamedNativeQueries(namedNativeQueries);
}
// generate a ClassAccessor for each Descriptor, keeping track of Embeddables
List<String> embeddables = new ArrayList<String>();
Map<String, ClassAccessor> accessors = new HashMap<String, ClassAccessor>();
for (ClassDescriptor cdesc : descriptors) {
boolean embeddable = false;
ClassAccessor classAccessor;
if (cdesc.isAggregateDescriptor()) {
embeddable = true;
classAccessor = new EmbeddableAccessor();
embeddables.add(cdesc.getJavaClassName());
} else {
classAccessor = new EntityAccessor();
}
classAccessor.setClassName(cdesc.getJavaClassName());
classAccessor.setAccess(EL_ACCESS_VIRTUAL);
// may need add STRUCT metadata to the classAccessor to ensure correct field ordering
if (cdesc.isObjectRelationalDataTypeDescriptor()) {
ObjectRelationalDataTypeDescriptor odesc = (ObjectRelationalDataTypeDescriptor) cdesc;
if (odesc.getOrderedFields().size() > 0) {
StructMetadata struct = new StructMetadata();
struct.setName(odesc.getStructureName());
struct.setFields(odesc.getOrderedFields());
classAccessor.setStruct(struct);
}
}
if (!embeddable && cdesc.getTableName() != null) {
TableMetadata table = new TableMetadata();
table.setName(cdesc.getTableName());
((EntityAccessor) classAccessor).setTable(table);
}
if (!embeddable) {
List<NamedNativeQueryMetadata> namedNatQueries = new ArrayList<NamedNativeQueryMetadata>();
NamedNativeQueryMetadata namedQuery;
DatabaseQuery dbQuery;
// process findAll and findByPk queries
for (Iterator<DatabaseQuery> queryIt = cdesc.getQueryManager().getAllQueries().iterator(); queryIt.hasNext(); ) {
dbQuery = queryIt.next();
namedQuery = new NamedNativeQueryMetadata();
namedQuery.setName(dbQuery.getName());
namedQuery.setQuery(dbQuery.getSQLString());
namedQuery.setResultClassName(dbQuery.getReferenceClassName());
namedNatQueries.add(namedQuery);
}
// now create/update/delete operations
Map<String, String> crudOps = crudOperations.get(cdesc.getTableName());
if (!crudOps.isEmpty()) {
for (String opName : crudOps.keySet()) {
String crudSql = crudOps.get(opName);
NamedNativeQueryMetadata crudQuery = new NamedNativeQueryMetadata();
crudQuery.setName(opName);
crudQuery.setQuery(crudSql);
namedNatQueries.add(crudQuery);
}
}
if (namedNatQueries.size() > 0) {
((EntityAccessor) classAccessor).setNamedNativeQueries(namedNatQueries);
}
}
classAccessor.setAttributes(new XMLAttributes());
classAccessor.getAttributes().setIds(new ArrayList<IdAccessor>());
classAccessor.getAttributes().setBasics(new ArrayList<BasicAccessor>());
classAccessor.getAttributes().setArrays(new ArrayList<ArrayAccessor>());
classAccessor.getAttributes().setStructures(new ArrayList<StructureAccessor>());
classAccessor.getAttributes().setEmbeddeds(new ArrayList<EmbeddedAccessor>());
if (embeddable) {
xmlEntityMappings.getEmbeddables().add((EmbeddableAccessor) classAccessor);
} else {
xmlEntityMappings.getEntities().add((EntityAccessor) classAccessor);
}
accessors.put(cdesc.getJavaClassName(), classAccessor);
}
// now the we know what the embeddables are, we can process mappings
for (ClassDescriptor cdesc : descriptors) {
ClassAccessor classAccessor = accessors.get(cdesc.getJavaClassName());
MappingAccessor mapAccessor;
// generate a MappingAccessor for each mapping
for (DatabaseMapping dbMapping : cdesc.getMappings()) {
mapAccessor = generateMappingAccessor(dbMapping, embeddables);
if (mapAccessor == null) {
continue;
}
if (mapAccessor.isId()) {
classAccessor.getAttributes().getIds().add((IdAccessor) mapAccessor);
} else if (mapAccessor.isBasic()) {
classAccessor.getAttributes().getBasics().add((BasicAccessor) mapAccessor);
} else if (mapAccessor instanceof ArrayAccessor) {
classAccessor.getAttributes().getArrays().add((ArrayAccessor) mapAccessor);
} else if (mapAccessor instanceof StructureAccessor) {
classAccessor.getAttributes().getStructures().add((StructureAccessor) mapAccessor);
} else {
// assumes EmbeddedAccessor
classAccessor.getAttributes().getEmbeddeds().add((EmbeddedAccessor) mapAccessor);
}
}
}
return xmlEntityMappings;
}
use of org.eclipse.persistence.queries.DatabaseQuery in project eclipselink by eclipse-ee4j.
the class OracleHelper method buildProcedureOperation.
/**
* Builds query operations for a given ProcedureOperationModel.
*/
@Override
public void buildProcedureOperation(ProcedureOperationModel procedureOperationModel) {
for (ProcedureType storedProcedure : procedureOperationModel.getDbStoredProcedures()) {
boolean hasComplexArgs = hasComplexArgs(storedProcedure);
QueryOperation qo = new QueryOperation();
qo.setName(getNameForQueryOperation(procedureOperationModel, storedProcedure));
String qualifiedProcName = getQualifiedProcedureName(procedureOperationModel, storedProcedure);
dbwsBuilder.logMessage(FINEST, BUILDING_QUERYOP_FOR + qualifiedProcName);
QueryHandler qh = null;
// before assigning queryHandler, check for named query in OR project
List<DatabaseQuery> queries = dbwsBuilder.getOrProject().getQueries();
if (queries.size() > 0) {
for (DatabaseQuery q : queries) {
if (q.getName().equals(qo.getName())) {
qh = new NamedQueryHandler();
((NamedQueryHandler) qh).setName(qo.getName());
}
}
}
if (qh == null) {
if (storedProcedure.isFunctionType()) {
qh = new StoredFunctionQueryHandler();
} else {
qh = new StoredProcedureQueryHandler();
}
((StoredProcedureQueryHandler) qh).setName(qualifiedProcName);
}
qo.setQueryHandler(qh);
String returnType = procedureOperationModel.getReturnType();
boolean isCollection = procedureOperationModel.isCollection();
boolean isSimpleXMLFormat = procedureOperationModel.isSimpleXMLFormat();
Result result = null;
/**
* For multiple OUT args as well as a stored function with OUT args, we want
* the result to be a collection and the type to be "xsd:any". We will
* force SimpleXMLFormat for now as well.
*/
int outArgCount = 0;
for (ArgumentType argument : storedProcedure.getArguments()) {
ArgumentTypeDirection argDirection = argument.getDirection();
if (argDirection == OUT) {
outArgCount++;
}
}
if (outArgCount > 1 || (outArgCount > 0 && storedProcedure.isFunctionType())) {
isCollection = true;
isSimpleXMLFormat = true;
result = new CollectionResult();
result.setType(ANY_QNAME);
} else {
if (storedProcedure.isFunctionType()) {
ArgumentType returnArg = ((FunctionType) storedProcedure).getReturnArgument();
result = buildResultForStoredFunction(returnArg, returnType);
// tags to better represent the PL/SQL record/table/column type
if (returnArg.getEnclosedType().isPLSQLCursorType()) {
customizeSimpleXMLTagNames((PLSQLCursorType) returnArg.getEnclosedType(), procedureOperationModel);
}
} else if (hasComplexArgs) {
if (Util.noOutArguments(storedProcedure)) {
result = new Result();
// rowcount
result.setType(new QName(SCHEMA_URL, INT, SCHEMA_PREFIX));
}
} else {
// if user overrides returnType, assume they're right
if (returnType != null) {
result = new Result();
result.setType(buildCustomQName(returnType, dbwsBuilder));
} else {
if (isCollection) {
result = new CollectionResult();
if (isSimpleXMLFormat) {
result.setType(SXF_QNAME_CURSOR);
}
} else {
result = new Result();
result.setType(SXF_QNAME);
}
}
}
}
for (ArgumentType arg : storedProcedure.getArguments()) {
String argName = arg.getArgumentName();
if (argName != null) {
QName xmlType = null;
ProcedureArgument pa = null;
// for INOUT's
ProcedureArgument paShadow = null;
Parameter parm = null;
ArgumentTypeDirection direction = arg.getDirection();
if (!hasComplexArgs) {
if (arg.getEnclosedType().isPLSQLCursorType()) {
PLSQLCursorType cursorType = (PLSQLCursorType) arg.getEnclosedType();
if (cursorType.isWeaklyTyped()) {
xmlType = buildCustomQName("SYS_REFCURSOR", dbwsBuilder);
}
} else {
xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
}
} else {
// handle PL/SQL records and collections
if (arg.getEnclosedType().isPLSQLType()) {
String packageName = ((PLSQLType) arg.getEnclosedType()).getParentType().getPackageName();
// may need to prepend package name
String typeString = (packageName != null && packageName.length() > 0) ? packageName + UNDERSCORE + arg.getTypeName() : arg.getTypeName();
// may need to strip off %
typeString = typeString.contains(PERCENT) ? typeString.replace(PERCENT, UNDERSCORE) : typeString;
xmlType = buildCustomQName(nct.generateSchemaAlias(typeString), dbwsBuilder);
} else if (arg.getEnclosedType().isVArrayType() || arg.getEnclosedType().isObjectType() || arg.getEnclosedType().isObjectTableType()) {
// handle advanced JDBC types
xmlType = buildCustomQName(nct.generateSchemaAlias(arg.getTypeName()), dbwsBuilder);
} else {
switch(Util.getJDBCTypeFromTypeName(arg.getTypeName())) {
case STRUCT:
case ARRAY:
String typeString = nct.generateSchemaAlias(arg.getTypeName());
xmlType = buildCustomQName(typeString, dbwsBuilder);
break;
default:
xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
break;
}
}
}
if (direction == null || direction == IN) {
parm = new Parameter();
parm.setName(argName);
parm.setType(xmlType);
// handle optional arg
parm.setOptional(arg.optional());
pa = new ProcedureArgument();
pa.setName(argName);
pa.setParameterName(argName);
if (qh instanceof StoredProcedureQueryHandler) {
((StoredProcedureQueryHandler) qh).getInArguments().add(pa);
}
} else {
// the first OUT/INOUT arg determines singleResult vs. collectionResult
pa = new ProcedureOutputArgument();
ProcedureOutputArgument pao = (ProcedureOutputArgument) pa;
pao.setName(argName);
pao.setParameterName(argName);
boolean isCursor = arg.isPLSQLCursorType() || arg.getTypeName().contains(CURSOR_STR);
// tags to better represent the PL/SQL record/table/column type
if (arg.isPLSQLCursorType()) {
customizeSimpleXMLTagNames((PLSQLCursorType) arg.getEnclosedType(), procedureOperationModel);
}
if (isCursor && returnType == null) {
// if user overrides returnType, assume they're right
pao.setResultType(SXF_QNAME_CURSOR);
if (result == null) {
result = new CollectionResult();
result.setType(SXF_QNAME_CURSOR);
}
} else {
// Hmm, multiple OUT's gonna be a problem - later!
if (returnType != null && !isSimpleXMLFormat) {
xmlType = qNameFromString(OPEN_PAREN + dbwsBuilder.getTargetNamespace() + CLOSE_PAREN + returnType, dbwsBuilder.getSchema());
}
if (isCursor) {
pao.setResultType(new QName(EMPTY_STRING, CURSOR_OF_STR + returnType));
Result newResult = new CollectionResult();
newResult.setType(result.getType());
result = newResult;
} else {
pao.setResultType(xmlType);
}
if (result == null) {
if (isCollection) {
result = new CollectionResult();
} else {
result = new Result();
}
result.setType(xmlType);
}
}
if (direction == INOUT) {
parm = new Parameter();
parm.setName(argName);
parm.setType(xmlType);
result.setType(xmlType);
if (qh instanceof StoredProcedureQueryHandler) {
((StoredProcedureQueryHandler) qh).getInOutArguments().add(pao);
}
paShadow = new ProcedureArgument();
paShadow.setName(argName);
paShadow.setParameterName(argName);
} else {
// OUT arg
if (qh instanceof StoredProcedureQueryHandler) {
((StoredProcedureQueryHandler) qh).getOutArguments().add(pao);
}
}
}
// for XMLType, we want the type code to be 'OPAQUE' (2007)
if (arg.getEnclosedType() == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
pa.setJdbcType(getJDBCTypeForTypeName(XMLTYPE_STR));
}
if (hasComplexArgs && arg.getEnclosedType().isPLSQLType()) {
pa.setComplexTypeName(storedProcedure.getCatalogName() + UNDERSCORE + arg.getTypeName());
if (paShadow != null) {
paShadow.setComplexTypeName(pa.getComplexTypeName());
}
}
if (parm != null) {
qo.getParameters().add(parm);
}
}
}
if (procedureOperationModel.getBinaryAttachment()) {
Attachment attachment = new Attachment();
attachment.setMimeType(APP_OCTET_STREAM);
result.setAttachment(attachment);
}
// the user may want simpleXMLFormat
handleSimpleXMLFormat(isSimpleXMLFormat, result, procedureOperationModel);
qo.setResult(result);
dbwsBuilder.getXrServiceModel().getOperations().put(qo.getName(), qo);
}
finishProcedureOperation();
}
Aggregations