| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.testing.tests.customsqlstoredprocedures; |
| |
| import java.sql.Struct; |
| import java.sql.Types; |
| import java.util.Vector; |
| |
| import org.eclipse.persistence.internal.databaseaccess.DatabaseCall; |
| import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField; |
| import org.eclipse.persistence.queries.SQLCall; |
| import org.eclipse.persistence.queries.StoredProcedureCall; |
| import org.eclipse.persistence.sessions.DatabaseRecord; |
| import org.eclipse.persistence.testing.framework.TestErrorException; |
| import org.eclipse.persistence.testing.models.insurance.Address; |
| import org.eclipse.persistence.testing.models.insurance.Phone; |
| |
| /** |
| * This tests using Vectors in stored procedures (through storedprocedurecalls or custom sql) for |
| * ARRAY objects using IN, OUT and INOUT parameter types. Also verifies that if no conversion |
| * is specified for a Struct object, a Struct will be returned. |
| */ |
| public class StoredProcedureVARRAYParametersTest extends StoredProcedureObjectRelationalParameters { |
| |
| Vector phoneNumbers, childrenNames = null; |
| |
| public StoredProcedureVARRAYParametersTest() { |
| super(); |
| } |
| |
| public StoredProcedureVARRAYParametersTest(boolean useCustomSQL) { |
| super(useCustomSQL); |
| } |
| |
| @Override |
| public void setup() { |
| super.setup(); |
| } |
| |
| @Override |
| public void test() { |
| Vector args = new Vector(); |
| |
| childrenNames = new Vector(); |
| childrenNames.add("Mary"); |
| childrenNames.add("Sue"); |
| |
| phoneNumbers= new Vector(); |
| phoneNumbers.add(Phone.example2()); |
| phoneNumbers.add(Phone.example3()); |
| |
| |
| args.addElement(policyHolderIdToUse);//ssn |
| args.addElement(null);//occupation |
| args.addElement(null);//sex |
| args.addElement("Peter");//firstName |
| args.addElement(null);//birthDate |
| args.addElement("Griffin");//lastName |
| |
| args.addElement(originalAddress);//address |
| args.addElement(childrenNames);//childrenNames |
| args.addElement(phoneNumbers);//phones |
| |
| //testing that an exception is not thrown, using IN parameters exclusively |
| result = getSession().executeQuery(getInsertQuery(), args); |
| |
| //using OUT parameters exclusively, verifying policyHolder was created |
| Vector args2 = new Vector(); |
| args2.addElement(policyHolderIdToUse);//ssn |
| results2 = (Vector)getSession().executeQuery(getReadQuery(), args2); |
| |
| //using IN OUT parameters exclusively, deleting a policyholder |
| results3 = (Vector)getSession().executeQuery(getDeleteQuery(), args); |
| } |
| |
| @Override |
| public void verify() { |
| if ((results2.size()!=1) &&(results3.size()!=1)){ |
| throw new TestErrorException("Collections returned did not contain expected number of results"); |
| } |
| //check that a Struct was returned for address |
| Object addressOut = ((DatabaseRecord)results2.get(0)).get("address"); |
| if ((addressOut==null)||(! (addressOut instanceof Struct))){ |
| throw new TestErrorException("Address returned by SProc_Read_PHolders was null or not a Struct :"+addressOut); |
| } |
| //This is an Address instance instead of struct since it picks up the address class from the value passed in. |
| Address addressInOut = ((Address)((DatabaseRecord)results3.get(0)).get("address")); |
| if ((addressInOut==null)|| !originalAddress.getStreet().equals(addressInOut.getStreet())){ |
| throw new TestErrorException("Address in did not equal the address returned out by SProc_Delete_PHolders "+addressInOut); |
| } |
| |
| Vector childrenRead = ((Vector)((DatabaseRecord)results2.get(0)).get("childrenNames")); |
| if ( (childrenNames.size() != childrenRead.size()) && |
| (!childrenNames.get(0).equals(childrenRead.get(0))) ){ |
| throw new TestErrorException("First Child's Name did not match what was returned out by SProc_Read_PHolders"); |
| } |
| childrenRead = ((Vector)((DatabaseRecord)results3.get(0)).get("childrenNames")); |
| if ( (childrenNames.size() != childrenRead.size()) && |
| (!childrenNames.get(0).equals(childrenRead.get(0))) ){ |
| throw new TestErrorException("First Child's Name did not match what was returned out by SProc_Delete_PHolders"); |
| } |
| |
| Vector phonesRead = ((Vector)((DatabaseRecord)results2.get(0)).get("phones")); |
| if ( (phoneNumbers.size() != phonesRead.size()) && |
| (!phoneNumbers.get(0).equals(childrenRead.get(0))) ){ |
| throw new TestErrorException("First phone did not match what was returned out by SProc_Read_PHolders"); |
| } |
| |
| phonesRead = ((Vector)((DatabaseRecord)results3.get(0)).get("phones")); |
| if ( (phoneNumbers.size() != phonesRead.size()) && |
| (!phoneNumbers.get(0).equals(phonesRead.get(0))) ){ |
| throw new TestErrorException("First phone did not match what was returned out by SProc_Delete_PHolders"); |
| } |
| } |
| |
| |
| @Override |
| public DatabaseCall getInsertCall(){ |
| DatabaseCall call = null; |
| |
| ObjectRelationalDatabaseField ordf = new ObjectRelationalDatabaseField(""); |
| ordf.setSqlType(Types.STRUCT); |
| ordf.setSqlTypeName("PHONE_TYPE"); |
| ordf.setType(Phone.class); |
| |
| if (useCustomSQL){ |
| String sqlString = "BEGIN SProc_Insert_PHolders(#ssn, #occupation, #sex, "+ |
| "#firstName, #birthDate, #lastName, #address, #childrenNames, #phones); END;"; |
| SQLCall sqlcall = new SQLCall(sqlString); |
| sqlcall.setCustomSQLArgumentType("ssn", Long.class); |
| sqlcall.setCustomSQLArgumentType("occupation", String.class); |
| sqlcall.setCustomSQLArgumentType("sex", Character.class); |
| sqlcall.setCustomSQLArgumentType("firstName", String.class); |
| sqlcall.setCustomSQLArgumentType("birthDate", java.sql.Date.class); |
| sqlcall.setCustomSQLArgumentType("lastName", String.class); |
| sqlcall.setCustomSQLArgumentType("address", Types.STRUCT, "ADDRESS_TYPE"); |
| sqlcall.setCustomSQLArgumentType("childrenNames", Types.ARRAY, "NAMELIST_TYPE"); |
| sqlcall.setCustomSQLArgumentType("phones", Types.ARRAY, "PHONELIST_TYPE", ordf); |
| call = sqlcall; |
| }else { |
| StoredProcedureCall spcall = new StoredProcedureCall(); |
| spcall.setProcedureName("SProc_Insert_PHolders"); |
| spcall.addUnamedArgument("ssn", Long.class); |
| spcall.addUnamedArgument("occupation", String.class); |
| spcall.addUnamedArgument("sex", Character.class); |
| spcall.addUnamedArgument("firstName", String.class); |
| spcall.addUnamedArgument("birthDate", java.sql.Date.class); |
| spcall.addUnamedArgument("lastName", String.class); |
| |
| spcall.addUnamedArgument("address", Types.STRUCT, "ADDRESS_TYPE");//Address.class |
| spcall.addUnamedArgument("childrenNames", Types.ARRAY, "NAMELIST_TYPE"); |
| spcall.addUnamedArgument("phones", Types.ARRAY, "PHONELIST_TYPE", ordf); |
| call = spcall; |
| } |
| return call; |
| } |
| |
| @Override |
| public DatabaseCall getReadCall(){ |
| DatabaseCall call = null; |
| ObjectRelationalDatabaseField ordf = new ObjectRelationalDatabaseField(""); |
| ordf.setSqlType(Types.STRUCT); |
| ordf.setSqlTypeName("PHONE_TYPE"); |
| ordf.setType(Phone.class); |
| if (useCustomSQL){ |
| String sqlString = "BEGIN SProc_Read_PHolders(####ssn, ###occupation, ###sex, "+ |
| "###firstName, ###birthDate, ###lastName, ###address, ###childrenNames, ###phones); END;"; |
| SQLCall sqlcall = new SQLCall(sqlString); |
| sqlcall.setCustomSQLArgumentType("ssn", Long.class); |
| sqlcall.setCustomSQLArgumentType("occupation", String.class); |
| sqlcall.setCustomSQLArgumentType("sex", Character.class); |
| sqlcall.setCustomSQLArgumentType("firstName", String.class); |
| sqlcall.setCustomSQLArgumentType("birthDate", java.sql.Date.class); |
| sqlcall.setCustomSQLArgumentType("lastName", String.class); |
| sqlcall.setCustomSQLArgumentType("address", Types.STRUCT, "ADDRESS_TYPE"); |
| sqlcall.setCustomSQLArgumentType("childrenNames", Types.ARRAY, "NAMELIST_TYPE", Vector.class); |
| sqlcall.setCustomSQLArgumentType("phones", Types.ARRAY, "PHONELIST_TYPE", Vector.class, ordf); |
| call = sqlcall; |
| }else{ |
| StoredProcedureCall spcall = new StoredProcedureCall(); |
| spcall.setProcedureName("SProc_Read_PHolders"); |
| spcall.addUnamedInOutputArgument("ssn", Long.class); |
| spcall.addUnamedOutputArgument("occupation", String.class); |
| spcall.addUnamedOutputArgument("sex", Character.class); |
| spcall.addUnamedOutputArgument("firstName", String.class); |
| spcall.addUnamedOutputArgument("birthDate", java.sql.Date.class); |
| spcall.addUnamedOutputArgument("lastName", String.class); |
| spcall.addUnamedOutputArgument("address", Types.STRUCT, "ADDRESS_TYPE"); |
| spcall.addUnamedOutputArgument("childrenNames", Types.ARRAY, "NAMELIST_TYPE", Vector.class); |
| spcall.addUnamedOutputArgument("phones", Types.ARRAY, "PHONELIST_TYPE", Vector.class, ordf); |
| call = spcall; |
| } |
| return call; |
| } |
| |
| @Override |
| public DatabaseCall getDeleteCall(){ |
| DatabaseCall call = null; |
| ObjectRelationalDatabaseField ordf = new ObjectRelationalDatabaseField(""); |
| ordf.setSqlType(Types.STRUCT); |
| ordf.setSqlTypeName("PHONE_TYPE"); |
| ordf.setType(Phone.class); |
| |
| if (useCustomSQL){ |
| String sqlString = "BEGIN SProc_Delete_PHolders(####ssn, ####occupation, ####sex, "+ |
| "####firstName, ####birthDate, ####lastName, ####address, ####childrenNames, ####phones); END;"; |
| SQLCall sqlcall = new SQLCall(sqlString); |
| sqlcall.setCustomSQLArgumentType("ssn", Long.class); |
| sqlcall.setCustomSQLArgumentType("occupation", String.class); |
| sqlcall.setCustomSQLArgumentType("sex", Character.class); |
| sqlcall.setCustomSQLArgumentType("firstName", String.class); |
| sqlcall.setCustomSQLArgumentType("birthDate", java.sql.Date.class); |
| sqlcall.setCustomSQLArgumentType("lastName", String.class); |
| sqlcall.setCustomSQLArgumentType("address", Types.STRUCT, "ADDRESS_TYPE"); |
| sqlcall.setCustomSQLArgumentType("childrenNames", Types.ARRAY, "NAMELIST_TYPE", Vector.class); |
| sqlcall.setCustomSQLArgumentType("phones", Types.ARRAY, "PHONELIST_TYPE", Vector.class, ordf); |
| call = sqlcall; |
| }else{ |
| StoredProcedureCall sqlcall = new StoredProcedureCall(); |
| sqlcall.setProcedureName("SProc_Delete_PHolders"); |
| sqlcall.addUnamedInOutputArgument("ssn", Long.class); |
| sqlcall.addUnamedInOutputArgument("occupation", String.class); |
| sqlcall.addUnamedInOutputArgument("sex", Character.class); |
| sqlcall.addUnamedInOutputArgument("firstName", String.class); |
| sqlcall.addUnamedInOutputArgument("birthDate", java.sql.Date.class); |
| sqlcall.addUnamedInOutputArgument("lastName", String.class); |
| |
| sqlcall.addUnamedInOutputArgument("address", "address", Types.STRUCT, "ADDRESS_TYPE"); |
| sqlcall.addUnamedInOutputArgument("childrenNames", "childrenNames", Types.ARRAY, "NAMELIST_TYPE", Vector.class); |
| sqlcall.addUnamedInOutputArgument("phones", "phones", Types.ARRAY, "PHONELIST_TYPE", Vector.class, ordf); |
| call = sqlcall; |
| } |
| return call; |
| } |
| } |