Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.7] Oracle 23C platform - backport from master #2000

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions buildsystem/compdeps/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
<!-- CQ #21122 -->
<org.jgroups.version>4.1.8.Final</org.jgroups.version>
<!-- CQ #21154 -->
<oracle.jdbc.version>21.7.0.0</oracle.jdbc.version>
<oracle.apapi.version>21.3.0.0</oracle.apapi.version>
<oracle.jdbc.version>23.3.0.23.09</oracle.jdbc.version>
<oracle.apapi.version>23.2.0.0</oracle.apapi.version>
<!-- CQ #21141 -->
<oracle.nosql.version>18.3.10</oracle.nosql.version>
<!-- CQ #22994 -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1998, 2019 IBM Corporation. All rights reserved.
#
# This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -36,13 +36,15 @@
# to platform class entries should be placed before less specific entries. Each
# platform entry must be on its own line, an entry cannot span multiple lines.

(?is)oracle.*23.*=org.eclipse.persistence.platform.database.oracle.Oracle23Platform
(?is)oracle.*21.*=org.eclipse.persistence.platform.database.oracle.Oracle21Platform
(?is)oracle.*19.*=org.eclipse.persistence.platform.database.oracle.Oracle19Platform
(?is)oracle.*18.*=org.eclipse.persistence.platform.database.oracle.Oracle18Platform
(?is)oracle.*12.*=org.eclipse.persistence.platform.database.oracle.Oracle12Platform
(?is)oracle.*11.*=org.eclipse.persistence.platform.database.oracle.Oracle11Platform
(?is)oracle.*10.*=org.eclipse.persistence.platform.database.oracle.Oracle10Platform
(?is)oracle.*9.*=org.eclipse.persistence.platform.database.oracle.Oracle9Platform
(?is)core.oracle.*23.*=org.eclipse.persistence.platform.database.Oracle23Platform
(?is)core.oracle.*21.*=org.eclipse.persistence.platform.database.Oracle21Platform
(?is)core.oracle.*19.*=org.eclipse.persistence.platform.database.Oracle19Platform
(?is)core.oracle.*18.*=org.eclipse.persistence.platform.database.Oracle18Platform
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023 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
Expand All @@ -14,7 +14,9 @@
// Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.core.databaseaccess;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.core.helper.CoreConversionManager;
import org.eclipse.persistence.internal.sessions.AbstractSession;

public interface CorePlatform<CONVERSION_MANAGER extends CoreConversionManager> {

Expand All @@ -28,6 +30,17 @@ public interface CorePlatform<CONVERSION_MANAGER extends CoreConversionManager>
*/
Object convertObject(Object sourceObject, Class javaClass);

/**
* Convert the object to the appropriate type by invoking the appropriate
* ConversionManager method.
* @param sourceObject the object that must be converted
* @param javaClass the class that the object must be converted to
* @param session current database session
* @exception ConversionException all exceptions will be thrown as this type.
* @return the newly converted object
*/
Object convertObject(Object sourceObject, Class javaClass, AbstractSession session) throws ConversionException;

/**
* The platform hold its own instance of conversion manager to allow customization.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,20 @@ public Object convertObject(Object sourceObject, Class javaClass) throws Convers
return getConversionManager().convertObject(sourceObject, javaClass);
}

/**
* Convert the object to the appropriate type by invoking the appropriate
* ConversionManager method.
* @param sourceObject the object that must be converted
* @param javaClass the class that the object must be converted to
* @param session current database session
* @exception ConversionException all exceptions will be thrown as this type.
* @return the newly converted object
*/
@Override
public Object convertObject(Object sourceObject, Class javaClass, AbstractSession session) throws ConversionException {
return convertObject(sourceObject, javaClass);
}

/**
* Copy the state into the new platform.
*/
Expand Down Expand Up @@ -286,6 +300,13 @@ public void setConversionManager(ConversionManager conversionManager) {
this.conversionManager = conversionManager;
}

/**
* Return the driver version.
*/
public String getDriverVersion() {
return "";
}

/**
* Delimiter to use for fields and tables using spaces or other special values.
*
Expand Down Expand Up @@ -645,6 +666,11 @@ public boolean isOracle9() {
return false;
}

@Override
public boolean isOracle23() {
return false;
}

public boolean isPervasive(){
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -47,6 +47,17 @@ public interface Platform extends CorePlatform<ConversionManager>, Serializable,
*/
public Object convertObject(Object sourceObject, Class javaClass) throws ConversionException;

/**
* Convert the object to the appropriate type by invoking the appropriate
* ConversionManager method.
* @param sourceObject the object that must be converted
* @param javaClass the class that the object must be converted to
* @param session current database session
* @exception ConversionException all exceptions will be thrown as this type.
* @return the newly converted object
*/
public Object convertObject(Object sourceObject, Class javaClass, AbstractSession session) throws ConversionException;

/**
* Copy the state into the new platform.
*/
Expand All @@ -63,6 +74,11 @@ public interface Platform extends CorePlatform<ConversionManager>, Serializable,
*/
public void setConversionManager(ConversionManager conversionManager);

/**
* Return the driver version.
*/
public String getDriverVersion();

/**
* Return the qualifier for the table. Required by some
* databases such as Oracle and DB2
Expand Down Expand Up @@ -113,6 +129,8 @@ public interface Platform extends CorePlatform<ConversionManager>, Serializable,

public boolean isOracle9();

public boolean isOracle23();

public boolean isPointBase();

public boolean isSQLAnywhere();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 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
Expand Down Expand Up @@ -207,7 +207,12 @@ public void setObjectClassName(String objectClassName) {
*/
public Object convertObjectValueToDataValue(Object attributeValue, Session session) {
try {
return ((AbstractSession)session).getDatasourcePlatform().convertObject(attributeValue, getDataClass());
if (session.isConnected()) {
//Should handle conversions where DB connection is needed like String -> java.sql.Clob
return session.getDatasourcePlatform().convertObject(attributeValue, getDataClass(), (AbstractSession)session);
} else {
return session.getDatasourcePlatform().convertObject(attributeValue, getDataClass());
}
} catch (ConversionException e) {
throw ConversionException.couldNotBeConverted(mapping, mapping.getDescriptor(), e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2023 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
package org.eclipse.persistence.platform.database;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.sessions.AbstractSession;

import java.sql.Clob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;

import static org.eclipse.persistence.internal.helper.StringHelper.EMPTY_STRING;

public class Oracle23Platform extends Oracle21Platform {
public Oracle23Platform() {
super();
}

@Override
protected Hashtable<Class<?>, FieldTypeDefinition> buildFieldTypes() {
Hashtable<Class<?>, FieldTypeDefinition> fieldTypes = super.buildFieldTypes();
fieldTypes.put(java.time.LocalDateTime.class, new FieldTypeDefinition("TIMESTAMP", 9));
fieldTypes.put(java.time.LocalTime.class, new FieldTypeDefinition("TIMESTAMP", 9));
return fieldTypes;
}

/**
* INTERNAL:
* Check whether current platform is Oracle 23c or later.
* @return Always returns {@code true} for instances of Oracle 23c platform.
* @since 2.7.14
*/
@Override
public boolean isOracle23() {
return true;
}

/**
* INTERNAL:
* Allow for conversion from the Oracle type to the Java type. Used in cases when DB connection is needed like BLOB, CLOB.
*/
@Override
public Object convertObject(Object sourceObject, Class javaClass, AbstractSession session) throws ConversionException, DatabaseException {
//Handle special case when empty String ("") is passed from the entity into CLOB type column
if (ClassConstants.CLOB.equals(javaClass) && sourceObject instanceof String && EMPTY_STRING.equals(sourceObject)) {
Connection connection = session.getAccessor().getConnection();
Clob clob = null;
try {
clob = connection.createClob();
clob.setString(1, (String)sourceObject);
} catch (SQLException e) {
throw ConversionException.couldNotBeConvertedToClass(sourceObject, ClassConstants.CLOB, e);
}
return clob;
}
return super.convertObject(sourceObject, javaClass);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -56,6 +56,8 @@
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.platform.database.jdbc.JDBCTypes;
import org.eclipse.persistence.platform.database.oracle.jdbc.OracleArrayType;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sessions.DatabaseRecord;
Expand Down Expand Up @@ -488,6 +490,7 @@ public void useNamedCursorOutputAsResultSet(String argumentName, DatabaseType da
protected void assignIndices() {
List<PLSQLargument> inArguments = getArguments(arguments, ParameterType.IN);
List<PLSQLargument> inOutArguments = getArguments(arguments, ParameterType.INOUT);
DatabasePlatform platform = this.getQuery().getSession().getPlatform();
inArguments.addAll(inOutArguments);
int newIndex = 1;
List<PLSQLargument> expandedArguments = new ArrayList<PLSQLargument>();
Expand All @@ -509,6 +512,10 @@ protected void assignIndices() {
}
for (PLSQLargument inArg : inArguments) {
DatabaseType type = inArg.databaseType;
if (platform.isOracle23() && type == OraclePLSQLTypes.PLSQLBoolean && Helper.compareVersions(platform.getDriverVersion(), "23.0.0") >= 0) {
type = JDBCTypes.BOOLEAN_TYPE;
inArg.databaseType = JDBCTypes.BOOLEAN_TYPE;
}
String inArgName = inArg.name;
if (!type.isComplexDatabaseType()) {
// for XMLType, we need to set type name parameter (will be "XMLTYPE")
Expand Down Expand Up @@ -562,6 +569,10 @@ protected void assignIndices() {
super.useNamedCursorOutputAsResultSet(outArgName);
} else {
DatabaseType type = outArg.databaseType;
if (platform.isOracle23() && type == OraclePLSQLTypes.PLSQLBoolean && Helper.compareVersions(platform.getDriverVersion(), "23.0.0") >= 0) {
type = JDBCTypes.BOOLEAN_TYPE;
outArg.databaseType = JDBCTypes.BOOLEAN_TYPE;
}
if (!type.isComplexDatabaseType()) {
// for XMLType, we need to set type name parameter (will be "XMLTYPE")
if (type == XMLType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2023 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
package org.eclipse.persistence.platform.database.oracle;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.sessions.AbstractSession;

import java.sql.Clob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;

import static org.eclipse.persistence.internal.helper.StringHelper.EMPTY_STRING;

/**
* <p><b>Purpose:</b>
* Supports certain new Oracle 23c data types, and usage of certain Oracle JDBC specific APIs.
* <p> Supports Oracle JSON data type.
* <p> Supports Oracle OracleJsonValue derived Java types.
*/
public class Oracle23Platform extends Oracle21Platform {

/**
* Creates an instance of Oracle 23c database platform.
*/
public Oracle23Platform() {
super();
}

/**
* INTERNAL:
* Check whether current platform is Oracle 23c or later.
* @return Always returns {@code true} for instances of Oracle 23c platform.
* @since 4.0.2
*/
@Override
public boolean isOracle23() {
return true;
}

@Override
protected Hashtable<Class<?>, FieldTypeDefinition> buildFieldTypes() {
Hashtable<Class<?>, FieldTypeDefinition> fieldTypes = super.buildFieldTypes();
fieldTypes.put(java.time.LocalDateTime.class, new FieldTypeDefinition("TIMESTAMP", 9));
fieldTypes.put(java.time.LocalTime.class, new FieldTypeDefinition("TIMESTAMP", 9));
return fieldTypes;
}

/**
* INTERNAL:
* Allow for conversion from the Oracle type to the Java type. Used in cases when DB connection is needed like BLOB, CLOB.
*/
@Override
public Object convertObject(Object sourceObject, Class javaClass, AbstractSession session) throws ConversionException, DatabaseException {
//Handle special case when empty String ("") is passed from the entity into CLOB type column
if (ClassConstants.CLOB.equals(javaClass) && sourceObject instanceof String && EMPTY_STRING.equals(sourceObject)) {
Connection connection = session.getAccessor().getConnection();
Clob clob = null;
try {
clob = connection.createClob();
clob.setString(1, (String)sourceObject);
} catch (SQLException e) {
throw ConversionException.couldNotBeConvertedToClass(sourceObject, ClassConstants.CLOB, e);
}
return clob;
}
return super.convertObject(sourceObject, javaClass);
}
}
Loading
Loading