@@ -50,6 +50,7 @@ import (
5050
5151 "time"
5252
53+ "github.com/oracle-samples/gorm-oracle/oracle"
5354 . "github.com/oracle-samples/gorm-oracle/tests/utils"
5455
5556 "github.com/stretchr/testify/assert"
@@ -1970,6 +1971,174 @@ func TestOracleSequences(t *testing.T) {
19701971 }
19711972}
19721973
1974+ func TestOracleTypeCreateDrop (t * testing.T ) {
1975+ if DB .Dialector .Name () != "oracle" {
1976+ t .Skip ("Skipping Oracle type test: not running on Oracle" )
1977+ }
1978+
1979+ const (
1980+ typeName = "email_list"
1981+ tableName = "email_varray_tab"
1982+
1983+ objectTypeName = "person_obj"
1984+ objectTableName = "person_obj_tab"
1985+
1986+ incompleteTypeName = "department_t"
1987+ unsupportedTypeName = "unsupported_type_t"
1988+ )
1989+
1990+ // Assert that DB.Migrator() is an oracle.Migrator (so we can use Oracle-specific methods)
1991+ m , ok := DB .Migrator ().(oracle.Migrator )
1992+ if ! ok {
1993+ t .Skip ("Skipping: current dialect migrator is not Oracle-specific" )
1994+ }
1995+
1996+ // Drop types if they exist
1997+ t .Run ("drop_existing_types_if_any" , func (t * testing.T ) {
1998+ if err := m .DropType (typeName ); err != nil && ! strings .Contains (err .Error (), "ORA-04043" ) {
1999+ t .Fatalf ("Unexpected error dropping type %s: %v" , typeName , err )
2000+ }
2001+ if err := m .DropType (objectTypeName ); err != nil && ! strings .Contains (err .Error (), "ORA-04043" ) {
2002+ t .Fatalf ("Unexpected error dropping type %s: %v" , objectTypeName , err )
2003+ }
2004+ if err := m .DropType (incompleteTypeName ); err != nil && ! strings .Contains (err .Error (), "ORA-04043" ) {
2005+ t .Fatalf ("Unexpected error dropping type %s: %v" , incompleteTypeName , err )
2006+ }
2007+ })
2008+
2009+ // Create new VARRAY type
2010+ t .Run ("create_varray_type" , func (t * testing.T ) {
2011+ err := m .CreateType (typeName , "VARRAY(10)" , "VARCHAR2(60)" )
2012+ if err != nil {
2013+ t .Fatalf ("Failed to create Oracle VARRAY type: %v" , err )
2014+ }
2015+
2016+ // Verify it exists via HasType
2017+ if ! m .HasType (typeName ) {
2018+ t .Fatalf ("Expected Oracle VARRAY type %s to exist" , typeName )
2019+ }
2020+ })
2021+
2022+ // Create table using the VARRAY type
2023+ t .Run ("create_table_using_varray_type" , func (t * testing.T ) {
2024+ createTableSQL := fmt .Sprintf (`
2025+ CREATE TABLE "%s" (
2026+ "ID" NUMBER PRIMARY KEY,
2027+ "EMAILS" "%s"
2028+ )` , tableName , typeName )
2029+
2030+ if err := DB .Exec (createTableSQL ).Error ; err != nil {
2031+ t .Fatalf ("Failed to create table using type %s: %v" , typeName , err )
2032+ }
2033+
2034+ // Verify table exists
2035+ if ! m .HasTable (tableName ) {
2036+ t .Fatalf ("Expected table %s to exist" , tableName )
2037+ }
2038+ })
2039+
2040+ // Create ADT (OBJECT) type
2041+ t .Run ("create_object_type" , func (t * testing.T ) {
2042+ err := m .CreateType (objectTypeName , "OBJECT" , `
2043+ first_name VARCHAR2(50),
2044+ last_name VARCHAR2(50),
2045+ age NUMBER
2046+ ` )
2047+ if err != nil {
2048+ t .Fatalf ("Failed to create Oracle OBJECT type: %v" , err )
2049+ }
2050+
2051+ // Verify it exists via HasType
2052+ if ! m .HasType (objectTypeName ) {
2053+ t .Fatalf ("Expected Oracle OBJECT type %s to exist" , objectTypeName )
2054+ }
2055+ })
2056+
2057+ // Create table using the OBJECT type
2058+ t .Run ("create_table_using_object_type" , func (t * testing.T ) {
2059+ createTableSQL := fmt .Sprintf (`
2060+ CREATE TABLE "%s" (
2061+ "ID" NUMBER PRIMARY KEY,
2062+ "PERSON" "%s"
2063+ )` , objectTableName , objectTypeName )
2064+
2065+ if err := DB .Exec (createTableSQL ).Error ; err != nil {
2066+ t .Fatalf ("Failed to create table using object type %s: %v" , objectTypeName , err )
2067+ }
2068+
2069+ // Verify table exists
2070+ if ! m .HasTable (objectTableName ) {
2071+ t .Fatalf ("Expected table %s to exist" , objectTableName )
2072+ }
2073+ })
2074+
2075+ // Create incomplete type (forward declaration)
2076+ t .Run ("create_incomplete_type" , func (t * testing.T ) {
2077+ if err := m .CreateType (incompleteTypeName ); err != nil {
2078+ t .Fatalf ("Failed to create incomplete type %s: %v" , incompleteTypeName , err )
2079+ }
2080+ if ! m .HasType (incompleteTypeName ) {
2081+ t .Fatalf ("Expected incomplete type %s to exist" , incompleteTypeName )
2082+ }
2083+ if err := m .DropType (incompleteTypeName ); err != nil {
2084+ t .Fatalf ("Failed to drop incomplete type %s: %v" , incompleteTypeName , err )
2085+ }
2086+ if m .HasType (incompleteTypeName ) {
2087+ t .Fatalf ("Expected incomplete type %s to be dropped" , incompleteTypeName )
2088+ }
2089+ })
2090+
2091+ // Unsupported type kinds should return an error and not create anything
2092+ t .Run ("create_unsupported_type" , func (t * testing.T ) {
2093+ err := m .CreateType (unsupportedTypeName , "Unsupported" , "Unsupported" )
2094+ if err == nil {
2095+ t .Fatalf ("Expected error when creating unsupported type %s, got nil" , unsupportedTypeName )
2096+ }
2097+
2098+ // Ensure the type was NOT created
2099+ if m .HasType (unsupportedTypeName ) {
2100+ t .Fatalf ("Type %s should not exist after failed creation" , unsupportedTypeName )
2101+ }
2102+
2103+ // Also ensure DropType is safe to call (idempotent)
2104+ if err := m .DropType (unsupportedTypeName ); err != nil {
2105+ if ! strings .Contains (strings .ToLower (err .Error ()), "does not exist" ) {
2106+ t .Fatalf ("Unexpected error dropping type %s: %v" , unsupportedTypeName , err )
2107+ }
2108+ }
2109+
2110+ if m .HasType (unsupportedTypeName ) {
2111+ t .Fatalf ("Expected type %s to be absent after drop" , unsupportedTypeName )
2112+ }
2113+ })
2114+
2115+ // Drop tables and types
2116+ t .Run ("drop_tables_and_types" , func (t * testing.T ) {
2117+ if err := m .DropTable (objectTableName ); err != nil {
2118+ t .Fatalf ("Failed to drop table %s: %v" , objectTableName , err )
2119+ }
2120+ if err := m .DropTable (tableName ); err != nil {
2121+ t .Fatalf ("Failed to drop table %s: %v" , tableName , err )
2122+ }
2123+
2124+ // Drop types
2125+ if err := m .DropType (objectTypeName ); err != nil {
2126+ t .Fatalf ("Failed to drop type %s: %v" , objectTypeName , err )
2127+ }
2128+ if err := m .DropType (typeName ); err != nil {
2129+ t .Fatalf ("Failed to drop type %s: %v" , typeName , err )
2130+ }
2131+
2132+ // Verify types are gone via HasType
2133+ if m .HasType (typeName ) {
2134+ t .Fatalf ("Expected Oracle type %s to be dropped" , typeName )
2135+ }
2136+ if m .HasType (objectTypeName ) {
2137+ t .Fatalf ("Expected Oracle type %s to be dropped" , objectTypeName )
2138+ }
2139+ })
2140+ }
2141+
19732142func TestOracleIndexes (t * testing.T ) {
19742143 if DB .Dialector .Name () != "oracle" {
19752144 return
0 commit comments