Introduce AbstractNamedEnumTest

This commit is contained in:
Yanming Zhou 2024-05-27 10:59:29 +08:00 committed by Christian Beikov
parent 0705ffd3b1
commit 11da1ec25a
4 changed files with 124 additions and 140 deletions

View File

@ -6,6 +6,16 @@
*/ */
package org.hibernate.orm.test.type; package org.hibernate.orm.test.type;
import java.sql.ResultSet;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import jakarta.persistence.CascadeType; import jakarta.persistence.CascadeType;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
@ -13,25 +23,16 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType; import jakarta.persistence.GenerationType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.type.SqlTypes;
import org.junit.jupiter.api.Test;
import java.sql.ResultSet;
import java.sql.Statement;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Yanming Zhou
*/
@SessionFactory @SessionFactory
@DomainModel(annotatedClasses = {OracleEnumTest.Timeslot.class, OracleEnumTest.Activity.class, OracleEnumTest.Weather.class, OracleEnumTest.Sky.class}) @DomainModel(annotatedClasses = { AbstractNamedEnumTest.Timeslot.class, AbstractNamedEnumTest.Activity.class, AbstractNamedEnumTest.Weather.class, AbstractNamedEnumTest.Sky.class})
@RequiresDialect(value = OracleDialect.class, majorVersion = 23) public abstract class AbstractNamedEnumTest {
public class OracleEnumTest {
@Test public void testNamedEnum(SessionFactoryScope scope) { @Test public void testNamedEnum(SessionFactoryScope scope) {
Timeslot timeslot = new Timeslot(); Timeslot timeslot = new Timeslot();
@ -60,49 +61,17 @@ public class OracleEnumTest {
boolean namedEnumFound = false; boolean namedEnumFound = false;
boolean namedOrdinalEnumFound = false; boolean namedOrdinalEnumFound = false;
try(Statement stmt = c.createStatement()) { ResultSet tableInfo = c.getMetaData().getColumns(null, null, normalizeNameForQueryingMetadata("Activity"), normalizeNameForQueryingMetadata("ActivityType"));
try(ResultSet typeInfo = stmt.executeQuery("select name, decode(instr(data_display,'WHEN '''),0,'NUMBER','VARCHAR2') from user_domains where type='ENUMERATED'")) {
while (typeInfo.next()) {
String name = typeInfo.getString(1);
String baseType = typeInfo.getString(2);
if (name.equalsIgnoreCase("ActivityType") && baseType.equals("VARCHAR2")) {
namedEnumFound = true;
continue;
}
if (name.equalsIgnoreCase("SkyType") && baseType.equals("NUMBER")) {
namedOrdinalEnumFound = true;
continue;
}
}
}
}
if (!namedEnumFound) {
fail("named enum type not exported");
}
if (!namedOrdinalEnumFound) {
fail("named ordinal enum type not exported");
}
}
);
});
scope.inSession( s -> {
s.doWork(
c -> {
boolean namedEnumFound = false;
boolean namedOrdinalEnumFound = false;
ResultSet tableInfo = c.getMetaData().getColumns(null, null, "ACTIVITY", "ACTIVITYTYPE" );
while ( tableInfo.next() ) { while ( tableInfo.next() ) {
String type = tableInfo.getString(6); String type = tableInfo.getString(6);
assertEquals( "VARCHAR2", type ); assertEquals( getDataTypeForNamedEnum( "ActivityType"), type );
namedEnumFound = true; namedEnumFound = true;
break; break;
} }
tableInfo = c.getMetaData().getColumns(null, null, "SKY", "SKYTYPE" ); tableInfo = c.getMetaData().getColumns(null, null, normalizeNameForQueryingMetadata("Sky"), normalizeNameForQueryingMetadata("SkyType"));
while ( tableInfo.next() ) { while ( tableInfo.next() ) {
String type = tableInfo.getString(6); String type = tableInfo.getString(6);
assertEquals( "NUMBER", type ); assertEquals( getDataTypeForNamedOrdinalEnum("SkyType"), type );
namedOrdinalEnumFound = true; namedOrdinalEnumFound = true;
break; break;
} }
@ -118,6 +87,12 @@ public class OracleEnumTest {
}); });
} }
protected abstract String normalizeNameForQueryingMetadata(String name);
protected abstract String getDataTypeForNamedEnum(String namedEnum);
protected abstract String getDataTypeForNamedOrdinalEnum(String namedEnum);
public enum ActivityType {Work, Play, Sleep } public enum ActivityType {Work, Play, Sleep }
@Entity(name = "Activity") @Entity(name = "Activity")

View File

@ -0,0 +1,73 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.type;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.fail;
@RequiresDialect(value = OracleDialect.class, majorVersion = 23)
public class OracleNamedEnumTest extends AbstractNamedEnumTest {
@Override
protected String normalizeNameForQueryingMetadata(String name) {
return name.toUpperCase(Locale.ROOT);
}
@Override
protected String getDataTypeForNamedEnum(String namedEnum) {
return "VARCHAR2";
}
@Override
protected String getDataTypeForNamedOrdinalEnum(String namedEnum) {
return "NUMBER";
}
@Test public void testUserDomains(SessionFactoryScope scope) {
scope.inSession( s -> {
s.doWork(
c -> {
boolean namedEnumFound = false;
boolean namedOrdinalEnumFound = false;
try(Statement stmt = c.createStatement()) {
try(ResultSet typeInfo = stmt.executeQuery("select name, decode(instr(data_display,'WHEN '''),0,'NUMBER','VARCHAR2') from user_domains where type='ENUMERATED'")) {
while (typeInfo.next()) {
String name = typeInfo.getString(1);
String baseType = typeInfo.getString(2);
if (name.equalsIgnoreCase("ActivityType") && baseType.equals(
getDataTypeForNamedEnum("ActivityType"))) {
namedEnumFound = true;
continue;
}
if (name.equalsIgnoreCase("SkyType") && baseType.equals(
getDataTypeForNamedOrdinalEnum("SkyType"))) {
namedOrdinalEnumFound = true;
}
}
}
}
if (!namedEnumFound) {
fail("named enum type not exported");
}
if (!namedOrdinalEnumFound) {
fail("named ordinal enum type not exported");
}
}
);
});
}
}

View File

@ -1,90 +0,0 @@
package org.hibernate.orm.test.type;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.type.SqlTypes;
import org.junit.jupiter.api.Test;
import java.sql.ResultSet;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@SessionFactory
@DomainModel(annotatedClasses = {PostgresEnumTest.Timeslot.class, PostgresEnumTest.Activity.class})
@RequiresDialect(PostgreSQLDialect.class)
public class PostgresEnumTest {
@Test public void test(SessionFactoryScope scope) {
Timeslot timeslot = new Timeslot();
Activity activity = new Activity();
activity.activityType = ActivityType.Play;
timeslot.activity = activity;
scope.inTransaction( s -> s.persist( timeslot ) );
Timeslot ts = scope.fromTransaction( s-> s.createQuery("from Timeslot where activity.activityType = Play", Timeslot.class ).getSingleResult() );
assertEquals( ts.activity.activityType, ActivityType.Play );
}
@Test public void testSchema(SessionFactoryScope scope) {
scope.inSession( s -> {
s.doWork(
c -> {
ResultSet typeInfo = c.getMetaData().getTypeInfo();
while ( typeInfo.next() ) {
String name = typeInfo.getString(1);
if ( name.equalsIgnoreCase("ActivityType") ) {
return;
}
}
fail("named enum type not exported");
}
);
});
scope.inSession( s -> {
s.doWork(
c -> {
ResultSet tableInfo = c.getMetaData().getColumns(null, null, "activity", "activitytype" );
while ( tableInfo.next() ) {
String type = tableInfo.getString(6);
assertEquals( "activitytype", type );
return;
}
fail("named enum column not exported");
}
);
});
}
public enum ActivityType {Work, Play, Sleep }
@Entity(name = "Activity")
public static class Activity {
@Id
@JdbcTypeCode(SqlTypes.NAMED_ENUM)
ActivityType activityType;
}
@Entity(name = "Timeslot")
public static class Timeslot {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@ManyToOne(cascade = CascadeType.PERSIST)
Activity activity;
}
}

View File

@ -0,0 +1,26 @@
package org.hibernate.orm.test.type;
import java.util.Locale;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.testing.orm.junit.RequiresDialect;
@RequiresDialect(PostgreSQLDialect.class)
public class PostgresNamedEnumTest extends AbstractNamedEnumTest {
@Override
protected String normalizeNameForQueryingMetadata(String name) {
return name.toLowerCase(Locale.ROOT);
}
@Override
protected String getDataTypeForNamedEnum(String namedEnum) {
return namedEnum.toLowerCase(Locale.ROOT);
}
@Override
protected String getDataTypeForNamedOrdinalEnum(String namedEnum) {
return namedEnum.toLowerCase(Locale.ROOT);
}
}