Search in sources :

Example 1 with StoredFunctionCall

use of org.eclipse.persistence.queries.StoredFunctionCall in project eclipselink by eclipse-ee4j.

the class NamedStoredFunctionQueryMetadata method process.

/**
 * INTERNAL:
 */
@Override
public void process(AbstractSession session) {
    // Build the stored procedure call.
    StoredFunctionCall call = new StoredFunctionCall();
    // Process the stored procedure parameters.
    boolean callByIndex = callByIndex();
    for (StoredProcedureParameterMetadata parameter : getParameters()) {
        parameter.processArgument(call, callByIndex, -1);
    }
    if (getReturnParameter() != null) {
        getReturnParameter().processResult(call, -1);
    }
    // Process the procedure name.
    call.setProcedureName(getProcedureName());
    // Create a JPA query to store internally on the session.
    JPAQuery query = new JPAQuery(getName(), call, processQueryHints(session));
    // Process the result class.
    if (!getResultClass().isVoid()) {
        query.setResultClassName(getJavaClassName(getResultClass()));
    } else if (hasResultSetMapping(session)) {
        query.addResultSetMapping(getResultSetMapping());
    }
    addJPAQuery(query, session);
}
Also used : StoredFunctionCall(org.eclipse.persistence.queries.StoredFunctionCall) JPAQuery(org.eclipse.persistence.internal.jpa.JPAQuery)

Example 2 with StoredFunctionCall

use of org.eclipse.persistence.queries.StoredFunctionCall in project eclipselink by eclipse-ee4j.

the class OracleHelper method buildQueryForProcedureType.

/**
 * Build a Query for the given ProcedureType instance and add
 * it to the given OR project's list of queries.
 */
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void buildQueryForProcedureType(ProcedureType procType, Project orProject, Project oxProject, ProcedureOperationModel opModel, boolean hasPLSQLArgs) {
    // if there are one or more PL/SQL args, then we need a PLSQLStoredProcedureCall
    StoredProcedureCall call;
    ArgumentType returnArg = procType.isFunctionType() ? ((FunctionType) procType).getReturnArgument() : null;
    // check for PL/SQL cursor arg
    boolean hasCursor = hasPLSQLCursorArg(getArgumentListForProcedureType(procType));
    hasPLSQLArgs = hasPLSQLArgs || hasCursor || opModel.isPLSQLProcedureOperation();
    if (hasPLSQLArgs) {
        if (procType.isFunctionType()) {
            org.eclipse.persistence.internal.helper.DatabaseType dType = buildDatabaseTypeFromMetadataType(returnArg, procType.getCatalogName());
            if (hasCursor) {
                call = new PLSQLStoredFunctionCall();
                // constructor by default adds a RETURN argument, so remove it
                ((PLSQLStoredFunctionCall) call).getArguments().remove(0);
                ((PLSQLStoredFunctionCall) call).useNamedCursorOutputAsResultSet(CURSOR_STR, dType);
            } else {
                Class wrapperClass = getWrapperClass(dType);
                if (wrapperClass != null) {
                    ((ComplexDatabaseType) dType).setJavaType(wrapperClass);
                }
                call = new PLSQLStoredFunctionCall(dType);
                // check for non-associative collection
                if (returnArg.getEnclosedType().isPLSQLCollectionType() && !((PLSQLCollectionType) returnArg.getEnclosedType()).isIndexed()) {
                    PLSQLargument plsqlArg = ((PLSQLStoredFunctionCall) call).getArguments().get(0);
                    ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                }
            }
        } else {
            call = new PLSQLStoredProcedureCall();
        }
    } else {
        if (procType.isFunctionType()) {
            String javaTypeName = returnArg.getTypeName();
            ClassDescriptor desc = oxProject.getDescriptorForAlias(getGeneratedAlias(javaTypeName));
            if (desc != null) {
                javaTypeName = desc.getJavaClassName();
            }
            if (returnArg.isComposite()) {
                DatabaseType dataType = returnArg.getEnclosedType();
                if (dataType.isVArrayType() || dataType.isObjectTableType()) {
                    call = new StoredFunctionCall(Types.ARRAY, returnArg.getTypeName(), javaTypeName, buildFieldForNestedType(dataType));
                } else {
                    // assumes ObjectType
                    call = new StoredFunctionCall(Types.STRUCT, returnArg.getTypeName(), javaTypeName);
                }
            } else {
                // scalar
                call = new StoredFunctionCall();
                if (returnArg.getEnclosedType().isBlobType()) {
                    // handle BLOBs
                    ((StoredFunctionCall) call).setResult(null, ClassConstants.BLOB);
                } else {
                    int resultType = Util.getJDBCTypeFromTypeName(javaTypeName);
                    // need special handling for Date types
                    if (resultType == Types.DATE || resultType == Types.TIME || resultType == Types.TIMESTAMP) {
                        ((StoredFunctionCall) call).setResult(null, ClassConstants.TIMESTAMP);
                    } else if (returnArg.getEnclosedType() == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                        // special handling for XMLType types
                        ((StoredFunctionCall) call).setResult(getJDBCTypeForTypeName(XMLTYPE_STR), XMLTYPE_STR, ClassConstants.OBJECT);
                    } else if (resultType == Types.OTHER || resultType == Types.CLOB) {
                        // default to OBJECT for OTHER, CLOB and LONG types
                        ((StoredFunctionCall) call).setResult(null, ClassConstants.OBJECT);
                    } else {
                        ((StoredFunctionCall) call).setResult(null, resultType);
                    }
                }
            }
        } else {
            call = new StoredProcedureCall();
        }
    }
    String cat = procType.getCatalogName();
    String catalogPrefix = (cat == null || cat.length() == 0) ? EMPTY_STRING : cat + DOT;
    call.setProcedureName(catalogPrefix + procType.getProcedureName());
    String returnType = opModel.getReturnType();
    boolean hasResponse = returnType != null;
    DatabaseQuery dq = null;
    if (hasCursor || (hasResponse && opModel.isCollection())) {
        dq = new DataReadQuery();
    } else {
        dq = new ValueReadQuery();
    }
    dq.bindAllParameters();
    dq.setName(getNameForQueryOperation(opModel, procType));
    dq.setCall(call);
    for (ArgumentType arg : procType.getArguments()) {
        // handle optional arg
        if (arg.optional()) {
            call.addOptionalArgument(arg.getArgumentName());
        }
        DatabaseType argType = arg.getEnclosedType();
        ArgumentTypeDirection direction = arg.getDirection();
        // for PL/SQL
        org.eclipse.persistence.internal.helper.DatabaseType databaseType = null;
        // for Advanced JDBC
        String javaTypeName = null;
        if (hasPLSQLArgs) {
            databaseType = buildDatabaseTypeFromMetadataType(argType, cat);
        } else {
            javaTypeName = argType.getTypeName();
            ClassDescriptor desc = oxProject.getDescriptorForAlias(getGeneratedAlias(javaTypeName));
            if (desc != null) {
                // anything there's a descriptor for will include "packagename." in the class name
                javaTypeName = desc.getJavaClassName();
            }
        }
        if (direction == IN) {
            if (hasPLSQLArgs) {
                Class wrapperClass = getWrapperClass(databaseType);
                if (wrapperClass != null) {
                    ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                }
                ((PLSQLStoredProcedureCall) call).addNamedArgument(arg.getArgumentName(), databaseType);
                // check for non-associative collection
                if (argType.isPLSQLCollectionType() && !((PLSQLCollectionType) argType).isIndexed()) {
                    PLSQLargument plsqlArg = ((PLSQLStoredProcedureCall) call).getArguments().get(((PLSQLStoredProcedureCall) call).getArguments().size() - 1);
                    ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                }
            } else {
                if (argType.isVArrayType()) {
                    dq.addArgument(arg.getArgumentName());
                    call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), javaTypeName);
                } else if (argType.isObjectType()) {
                    dq.addArgument(arg.getArgumentName());
                    call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName(), javaTypeName);
                } else if (argType.isObjectTableType()) {
                    dq.addArgument(arg.getArgumentName(), java.sql.Array.class);
                    call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), getWrapperClass(javaTypeName), buildFieldForNestedType(argType));
                } else {
                    dq.addArgument(arg.getArgumentName());
                    call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()));
                }
            }
        } else if (direction == OUT) {
            if (hasPLSQLArgs) {
                if (arg.isPLSQLCursorType()) {
                    ((PLSQLStoredProcedureCall) call).useNamedCursorOutputAsResultSet(arg.getArgumentName(), databaseType);
                } else {
                    Class wrapperClass = getWrapperClass(databaseType);
                    if (wrapperClass != null) {
                        ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                    }
                    ((PLSQLStoredProcedureCall) call).addNamedOutputArgument(arg.getArgumentName(), databaseType);
                }
            } else {
                if (argType.isComposite()) {
                    Class wrapperClass = getWrapperClass(javaTypeName);
                    if (argType.isVArrayType() || argType.isObjectTableType()) {
                        call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), wrapperClass, buildFieldForNestedType(argType));
                    } else {
                        // assumes ObjectType
                        call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName(), wrapperClass);
                    }
                } else {
                    // need special handling for XMLType - we want the type code to be 'OPAQUE' (2007)
                    if (argType == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                        call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), getJDBCTypeForTypeName(XMLTYPE_STR), XMLTYPE_STR);
                    } else if (argType == ScalarDatabaseTypeEnum.SYS_REFCURSOR_TYPE) {
                        call.addNamedCursorOutputArgument(arg.getArgumentName());
                    } else {
                        call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()));
                    }
                }
            }
        } else {
            // INOUT
            if (hasPLSQLArgs) {
                Class wrapperClass = getWrapperClass(databaseType);
                if (wrapperClass != null) {
                    ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                }
                ((PLSQLStoredProcedureCall) call).addNamedInOutputArgument(arg.getArgumentName(), databaseType);
                // check for non-associative collection
                if (argType.isPLSQLCollectionType() && !((PLSQLCollectionType) argType).isIndexed()) {
                    PLSQLargument plsqlArg = ((PLSQLStoredProcedureCall) call).getArguments().get(((PLSQLStoredProcedureCall) call).getArguments().size() - 1);
                    ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                }
            } else {
                dq.addArgument(arg.getArgumentName());
                if (argType.isComposite()) {
                    Class wrapperClass = getWrapperClass(javaTypeName);
                    if (argType.isVArrayType() || argType.isObjectTableType()) {
                        call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), wrapperClass, buildFieldForNestedType(argType));
                    } else {
                        // assumes ObjectType
                        call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName());
                    }
                } else {
                    // for some reason setting "java.lang.String" as the java type causes problems at runtime
                    Class javaType = getClassFromJDBCType(argType.getTypeName(), dbwsBuilder.getDatabasePlatform());
                    if (shouldSetJavaType(javaType.getName())) {
                        call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()), argType.getTypeName(), javaType);
                    } else {
                        call.addNamedInOutputArgument(arg.getArgumentName());
                    }
                }
            }
        }
        if (hasPLSQLArgs && (direction == IN || direction == INOUT)) {
            ClassDescriptor xdesc = null;
            if (hasResponse) {
                int idx = returnType.indexOf(COLON);
                if (idx == -1) {
                    idx = returnType.indexOf(CLOSE_PAREN);
                }
                if (idx > 0) {
                    String typ = returnType.substring(idx + 1);
                    for (XMLDescriptor xd : (List<XMLDescriptor>) (List) oxProject.getOrderedDescriptors()) {
                        if (xd.getSchemaReference() != null) {
                            String context = xd.getSchemaReference().getSchemaContext();
                            if (context.substring(1).equals(typ)) {
                                xdesc = xd;
                                break;
                            }
                        }
                    }
                }
            }
            if (xdesc != null) {
                dq.addArgumentByTypeName(arg.getArgumentName(), xdesc.getJavaClassName());
            } else {
                if (databaseType instanceof PLSQLCollection || databaseType instanceof VArrayType) {
                    dq.addArgument(arg.getArgumentName(), Array.class);
                } else if (databaseType instanceof PLSQLrecord || databaseType instanceof OracleObjectType) {
                    dq.addArgument(arg.getArgumentName(), Struct.class);
                } else {
                    dq.addArgument(arg.getArgumentName(), JDBCTypes.getClassForCode(databaseType.getConversionCode()));
                }
            }
        }
    }
    orProject.getQueries().add(dq);
}
Also used : PLSQLStoredFunctionCall(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredFunctionCall) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) CompositeDatabaseType(org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType) ComplexDatabaseType(org.eclipse.persistence.internal.helper.ComplexDatabaseType) DatabaseType(org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType) Util.getAttributeClassForDatabaseType(org.eclipse.persistence.tools.dbws.Util.getAttributeClassForDatabaseType) DataReadQuery(org.eclipse.persistence.queries.DataReadQuery) Util.qNameFromString(org.eclipse.persistence.tools.dbws.Util.qNameFromString) ArgumentType(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType) PLSQLargument(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLargument) Struct(java.sql.Struct) XMLDescriptor(org.eclipse.persistence.oxm.XMLDescriptor) VArrayType(org.eclipse.persistence.tools.oracleddl.metadata.VArrayType) OracleObjectType(org.eclipse.persistence.platform.database.oracle.jdbc.OracleObjectType) PLSQLrecord(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLrecord) ArrayList(java.util.ArrayList) List(java.util.List) ArgumentTypeDirection(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection) PLSQLStoredProcedureCall(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall) StoredProcedureCall(org.eclipse.persistence.queries.StoredProcedureCall) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) ValueReadQuery(org.eclipse.persistence.queries.ValueReadQuery) StoredFunctionCall(org.eclipse.persistence.queries.StoredFunctionCall) PLSQLStoredFunctionCall(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredFunctionCall) ComplexDatabaseType(org.eclipse.persistence.internal.helper.ComplexDatabaseType) PLSQLCollectionType(org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType) PLSQLStoredProcedureCall(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall) PLSQLCollection(org.eclipse.persistence.platform.database.oracle.plsql.PLSQLCollection)

Example 3 with StoredFunctionCall

use of org.eclipse.persistence.queries.StoredFunctionCall in project eclipselink by eclipse-ee4j.

the class EmployeeCustomSQLMWIntegrationSystem method buildNamedQueryWithStoredFunctionIntoDescriptor.

public void buildNamedQueryWithStoredFunctionIntoDescriptor() {
    /*
        StoredFunctionDefinition func = new StoredFunctionDefinition();
        func.setName("StoredFunction_InOut_Out_In");
        func.addInOutputArgument("P_INOUT", Long.class);
        func.addOutputArgument("P_OUT", Long.class);
        func.addArgument("P_IN", Long.class);
        func.setReturnType(Long.class);
        func.addStatement("P_OUT := P_INOUT");
        func.addStatement("P_INOUT := P_IN");
        func.addStatement("RETURN P_OUT");
       */
    DataReadQuery drq = new DataReadQuery();
    drq.setName("StoredFunctionCallInNamedQuery");
    drq.addArgument("P_INOUT", Long.class);
    drq.addArgument("P_IN", Long.class);
    StoredFunctionCall sfc = new StoredFunctionCall();
    sfc.setProcedureName("StoredFunction_InOut_Out_In");
    sfc.addNamedInOutputArgument("P_INOUT", "P_INOUT", Long.class);
    sfc.addNamedOutputArgument("P_OUT", "P_OUT", Long.class);
    sfc.addNamedArgument("P_IN", "P_IN", Long.class);
    sfc.setResult("", Long.class);
    drq.addCall(sfc);
    employeeDescriptor.getQueryManager().addQuery("StoredFunctionCallInNamedQuery", drq);
}
Also used : DataReadQuery(org.eclipse.persistence.queries.DataReadQuery) StoredFunctionCall(org.eclipse.persistence.queries.StoredFunctionCall)

Example 4 with StoredFunctionCall

use of org.eclipse.persistence.queries.StoredFunctionCall in project eclipselink by eclipse-ee4j.

the class StoredFunctionXMLTypeTest method test.

@Override
public void test() throws Exception {
    // 12.1 works with both OracleTypes.OPAQUE and Types.SQLXML
    // 11.2.0.3 - only with OracleTypes.OPAQUE
    // 11.2.0.2 - with both OracleTypes.OPAQUE and Types.SQLXML
    // int sqlType = Types.SQLXML;
    int sqlType = OracleTypes.OPAQUE;
    // see the stored function definition in XMLTypeEmployeeSystem
    StoredFunctionCall call = new StoredFunctionCall(sqlType, "XMLTYPE", String.class);
    call.setProcedureName("STOREDFUNCTION_XMLTYPE");
    if (sqlType == OracleTypes.OPAQUE && (getAbstractSession().isClientSession() || getAbstractSession().getDatasourceLogin().shouldUseExternalConnectionPooling())) {
        // UnwrapConnectionXDBTestModel uses external connection pooling. In this case transaction is required to keep the same connection open until the string is extracted.
        getAbstractSession().beginTransaction();
    }
    try {
        List result = getSession().executeSelectingCall(call);
        Object xmlResult = ((AbstractRecord) result.get(0)).getValues().get(0);
        String str;
        if (xmlResult instanceof OPAQUE) {
            str = ((XMLTypeFactory) Class.forName("org.eclipse.persistence.internal.platform.database.oracle.xdb.XMLTypeFactoryImpl").getConstructor().newInstance()).getString((OPAQUE) xmlResult);
        } else {
            str = JavaPlatform.getStringAndFreeSQLXML(xmlResult);
        }
        StringBuffer strBuffer = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (charsToIgnore.indexOf(ch) == -1) {
                strBuffer.append(ch);
            }
        }
        String strWithoutSpaces = strBuffer.toString();
        if (!strWithoutSpaces.equals("<jb><data>BLAH</data></jb>")) {
            throw new TestErrorException("unexpected string: " + str);
        }
    } finally {
        if (getAbstractSession().isInTransaction()) {
            getAbstractSession().rollbackTransaction();
        }
    }
}
Also used : OPAQUE(oracle.sql.OPAQUE) TestErrorException(org.eclipse.persistence.testing.framework.TestErrorException) List(java.util.List) StoredFunctionCall(org.eclipse.persistence.queries.StoredFunctionCall)

Example 5 with StoredFunctionCall

use of org.eclipse.persistence.queries.StoredFunctionCall in project eclipselink by eclipse-ee4j.

the class StoredFunctionQueryHandler method setSingleResult.

@Override
protected void setSingleResult(XRServiceAdapter xrService, StoredProcedureCall spCall, QName resultType) {
    if (isCursorType(xrService, resultType)) {
        spCall.useUnnamedCursorOutputAsResultSet();
    } else {
        StoredFunctionCall sfCall = (StoredFunctionCall) spCall;
        Class<?> clz = SCHEMA_2_CLASS.get(resultType);
        if (clz != null) {
            sfCall.setResult("", clz);
        } else {
            sfCall.setResult("", OBJECT);
        }
        DatabasePlatform platform = xrService.getORSession().getPlatform();
        if (platform == null) {
            platform = new DatabasePlatform();
        }
        // StoredFunction's return value is the first parameter
        ((DatabaseField) sfCall.getParameters().get(0)).setSqlType(platform.getJDBCType(clz));
    }
}
Also used : DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) DatabasePlatform(org.eclipse.persistence.platform.database.DatabasePlatform) StoredFunctionCall(org.eclipse.persistence.queries.StoredFunctionCall)

Aggregations

StoredFunctionCall (org.eclipse.persistence.queries.StoredFunctionCall)7 List (java.util.List)3 ArrayList (java.util.ArrayList)2 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)2 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)2 PLSQLStoredFunctionCall (org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredFunctionCall)2 PLSQLStoredProcedureCall (org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall)2 PLSQLargument (org.eclipse.persistence.platform.database.oracle.plsql.PLSQLargument)2 DataReadQuery (org.eclipse.persistence.queries.DataReadQuery)2 Struct (java.sql.Struct)1 HashMap (java.util.HashMap)1 OPAQUE (oracle.sql.OPAQUE)1 ComplexDatabaseType (org.eclipse.persistence.internal.helper.ComplexDatabaseType)1 JPAQuery (org.eclipse.persistence.internal.jpa.JPAQuery)1 ClassAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor)1 EmbeddableAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor)1 EntityAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor)1 XMLAttributes (org.eclipse.persistence.internal.jpa.metadata.accessors.classes.XMLAttributes)1 BasicAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor)1 EmbeddedAccessor (org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedAccessor)1