blob: 2ffefd177d0213c81ef7fa0230aa259cacbccc05 [file] [log] [blame]
/*
* Copyright (c) 2018, 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
*/
// Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
package org.eclipse.persistence.testing.tests.plsqlrecord;
// javase imports
import java.io.FileInputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.Properties;
import org.w3c.dom.Document;
// JUnit imports
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
// TopLink imports
import org.eclipse.persistence.internal.sessions.factories.ObjectPersistenceWorkbenchXMLProject;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.platform.database.jdbc.JDBCTypes;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLrecord;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
// other imports
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.CONSTANT_PROJECT_BUILD_VERSION;
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.TEST_DOT_PROPERTIES_KEY;
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.buildTestProject;
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.buildWorkbenchXMLProject;
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.comparer;
import static org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLrecordTestHelper.xmlParser;
public class PLSQLrecordOutTestSet {
// testsuite fixture(s)
static ObjectPersistenceWorkbenchXMLProject workbenchXMLProject;
static Project project = null;
@BeforeClass
public static void setUpProjects() {
try {
Properties p = new Properties();
String testPropertiesPath = System.getProperty(TEST_DOT_PROPERTIES_KEY);
p.load(new FileInputStream(testPropertiesPath));
project = buildTestProject(p);
workbenchXMLProject = buildWorkbenchXMLProject();
}
catch (Exception e) {
fail("error setting up Project's database properties " + e.getMessage());
}
}
@Test
public void writeToXml() {
PLSQLrecord r1 = new PLSQLrecord();
r1.setTypeName("emp%ROWTYPE");
r1.addField("EMPNO", JDBCTypes.NUMERIC_TYPE, 4, 0);
r1.addField("ENAME", JDBCTypes.VARCHAR_TYPE, 10);
r1.addField("JOB", JDBCTypes.VARCHAR_TYPE, 9);
r1.addField("MGR", JDBCTypes.NUMERIC_TYPE, 4, 0);
r1.addField("HIREDATE", JDBCTypes.DATE_TYPE);
r1.addField("SAL", JDBCTypes.DOUBLE_TYPE, 7, 2);
r1.addField("COMM", JDBCTypes.NUMERIC_TYPE, 7, 2);
r1.addField("DEPTNO", JDBCTypes.NUMERIC_TYPE, 2, 0);
// PROCEDURE REC_TEST_OUT(Z OUT EMP%ROWTYPE)
PLSQLStoredProcedureCall call = new PLSQLStoredProcedureCall();
call.setProcedureName("REC_TEST_OUT");
call.addNamedOutputArgument("Z", r1);
DataModifyQuery query = new DataModifyQuery();
query.setCall(call);
project.getDescriptor(PLSQLEmployeeType.class).getQueryManager().addQuery("PLSQLrecordOut", query);
Project projectToXml = project.clone();
// trim off login 'cause it changes under test - this way, a comparison
// can be done to a control document
projectToXml.setDatasourceLogin(null);
XMLContext context = new XMLContext(workbenchXMLProject);
XMLMarshaller marshaller = context.createMarshaller();
Document doc = marshaller.objectToXML(projectToXml);
Document controlDoc = xmlParser.parse(new StringReader(PLSQLRECORD_OUT_PROJECT_XML));
assertTrue("control document not same as instance document",
comparer.isNodeEqual(controlDoc, doc));
}
public static final String PLSQLRECORD_OUT_PROJECT_XML =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<eclipselink:object-persistence version=\"" + CONSTANT_PROJECT_BUILD_VERSION + "\"" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + " xmlns:eclipselink=\"http://xmlns.oracle.com/ias/xsds/eclipselink\">" +
"<eclipselink:name>PLSQLrecordProject</eclipselink:name>" +
"<eclipselink:class-mapping-descriptors>" +
"<eclipselink:class-mapping-descriptor xsi:type=\"eclipselink:object-relational-class-mapping-descriptor\">" +
"<eclipselink:class>org.eclipse.persistence.testing.tests.plsqlrecord.PLSQLEmployeeType</eclipselink:class>" +
"<eclipselink:alias>PLSQLEmployeeType</eclipselink:alias>" +
"<eclipselink:primary-key>" +
"<eclipselink:field name=\"EMPNO\" xsi:type=\"eclipselink:column\"/>" +
"</eclipselink:primary-key>" +
"<eclipselink:events xsi:type=\"eclipselink:event-policy\"/>" +
"<eclipselink:querying xsi:type=\"eclipselink:query-policy\">" +
"<eclipselink:queries>" +
"<eclipselink:query name=\"PLSQLrecordOut\" xsi:type=\"eclipselink:data-modify-query\">" +
"<eclipselink:call xsi:type=\"eclipselink:plsql-stored-procedure-call\">" +
"<eclipselink:procedure-name>REC_TEST_OUT</eclipselink:procedure-name>" +
"<eclipselink:arguments>" +
"<eclipselink:argument xsi:type=\"eclipselink:plsql-record\">" +
"<eclipselink:name>Z</eclipselink:name>" +
"<eclipselink:index>0</eclipselink:index>" +
"<eclipselink:direction>OUT</eclipselink:direction>" +
"<eclipselink:record-name>Z</eclipselink:record-name>" +
"<eclipselink:type-name>emp%ROWTYPE</eclipselink:type-name>" +
"<eclipselink:fields>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"NUMERIC_TYPE\">" +
"<eclipselink:name>EMPNO</eclipselink:name>" +
"<eclipselink:precision>4</eclipselink:precision>" +
"<eclipselink:scale>0</eclipselink:scale>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"VARCHAR_TYPE\">" +
"<eclipselink:name>ENAME</eclipselink:name>" +
"<eclipselink:length>10</eclipselink:length>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"VARCHAR_TYPE\">" +
"<eclipselink:name>JOB</eclipselink:name>" +
"<eclipselink:length>9</eclipselink:length>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"NUMERIC_TYPE\">" +
"<eclipselink:name>MGR</eclipselink:name>" +
"<eclipselink:precision>4</eclipselink:precision>" +
"<eclipselink:scale>0</eclipselink:scale>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"DATE_TYPE\">" +
"<eclipselink:name>HIREDATE</eclipselink:name>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"DOUBLE_TYPE\">" +
"<eclipselink:name>SAL</eclipselink:name>" +
"<eclipselink:precision>7</eclipselink:precision>" +
"<eclipselink:scale>2</eclipselink:scale>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"NUMERIC_TYPE\">" +
"<eclipselink:name>COMM</eclipselink:name>" +
"<eclipselink:precision>7</eclipselink:precision>" +
"<eclipselink:scale>2</eclipselink:scale>" +
"</eclipselink:field>" +
"<eclipselink:field xsi:type=\"eclipselink:jdbc-type\" type-name=\"NUMERIC_TYPE\">" +
"<eclipselink:name>DEPTNO</eclipselink:name>" +
"<eclipselink:precision>2</eclipselink:precision>" +
"<eclipselink:scale>0</eclipselink:scale>" +
"</eclipselink:field>" +
"</eclipselink:fields>" +
"</eclipselink:argument>" +
"</eclipselink:arguments>" +
"</eclipselink:call>" +
"</eclipselink:query>" +
"</eclipselink:queries>" +
"</eclipselink:querying>" +
"<eclipselink:attribute-mappings>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>employeeNumber</eclipselink:attribute-name>" +
"<eclipselink:field name=\"EMPNO\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:attribute-classification>java.math.BigDecimal</eclipselink:attribute-classification>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>name</eclipselink:attribute-name>" +
"<eclipselink:field name=\"ENAME\" xsi:type=\"eclipselink:column\"/>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>job</eclipselink:attribute-name>" +
"<eclipselink:field name=\"JOB\" xsi:type=\"eclipselink:column\"/>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>manager</eclipselink:attribute-name>" +
"<eclipselink:field name=\"MGR\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:attribute-classification>java.math.BigDecimal</eclipselink:attribute-classification>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>hireDate</eclipselink:attribute-name>" +
"<eclipselink:field name=\"HIREDATE\" xsi:type=\"eclipselink:column\"/>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>salary</eclipselink:attribute-name>" +
"<eclipselink:field name=\"SAL\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:attribute-classification>java.lang.Float</eclipselink:attribute-classification>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>commission</eclipselink:attribute-name>" +
"<eclipselink:field name=\"COMM\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:attribute-classification>java.lang.Float</eclipselink:attribute-classification>" +
"</eclipselink:attribute-mapping>" +
"<eclipselink:attribute-mapping xsi:type=\"eclipselink:direct-mapping\">" +
"<eclipselink:attribute-name>department</eclipselink:attribute-name>" +
"<eclipselink:field name=\"DEPTNO\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:attribute-classification>java.math.BigDecimal</eclipselink:attribute-classification>" +
"</eclipselink:attribute-mapping>" +
"</eclipselink:attribute-mappings>" +
"<eclipselink:descriptor-type>independent</eclipselink:descriptor-type>" +
"<eclipselink:instantiation/>" +
"<eclipselink:copying xsi:type=\"eclipselink:instantiation-copy-policy\"/>" +
"<eclipselink:tables>" +
"<eclipselink:table name=\"EMP\"/>" +
"</eclipselink:tables>" +
"<eclipselink:structure>EMP_TYPE</eclipselink:structure>" +
"<eclipselink:field-order>" +
"<eclipselink:field name=\"EMPNO\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"ENAME\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"JOB\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"MGR\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"HIREDATE\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"SAL\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"COMM\" xsi:type=\"eclipselink:column\"/>" +
"<eclipselink:field name=\"DEPTNO\" xsi:type=\"eclipselink:column\"/>" +
"</eclipselink:field-order>" +
"</eclipselink:class-mapping-descriptor>" +
"</eclipselink:class-mapping-descriptors>" +
"</eclipselink:object-persistence>";
@Test
public void readFromXml() {
Project projectFromXML = XMLProjectReader.read(new StringReader(PLSQLRECORD_OUT_PROJECT_XML),
this.getClass().getClassLoader());
projectFromXML.setDatasourceLogin(project.getDatasourceLogin());
project = projectFromXML;
}
@Test
public void runQuery() {
DatabaseSession s = project.createDatabaseSession();
s.dontLogMessages();
s.login();
OutputRowSessionEventAdapter outputParametersDetected
= new OutputRowSessionEventAdapter();
s.getEventManager().addListener(outputParametersDetected);
boolean worked = false;
String msg = null;
Object result = null;
Object outputRow = null;
try {
result = s.executeQuery("PLSQLrecordOut", PLSQLEmployeeType.class);
worked = true;
outputRow = outputParametersDetected.getEventResult();
}
catch (Exception e) {
msg = e.getMessage();
}
assertTrue("invocation rec_test_out failed: " + msg, worked);
assertNotNull("result is supposed to be not-null", result);
DatabaseRecord record = (DatabaseRecord)outputRow;
assertTrue("incorrect EMPNO" ,
record.get("EMPNO").equals(new BigDecimal(1234)));
assertTrue("incorrect ENAME" ,
record.get("ENAME").equals("GOOFY"));
assertTrue("incorrect JOB" ,
record.get("JOB").equals("ACTOR"));
assertNull("MGR is supposed to be null", record.get("MGR"));
assertNull("HIREDATE is supposed to be null", record.get("HIREDATE"));
assertTrue("incorrect SAL" ,
record.get("SAL").equals(6000.0));
assertNull("COMM is supposed to be null", record.get("COMM"));
assertTrue("incorrect DEPTNO" ,
record.get("DEPTNO").equals(new BigDecimal(20)));
s.logout();
}
}