Skip to content

Commit 9d8deb8

Browse files
committed
refactor Type name
1 parent cf031e5 commit 9d8deb8

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

oracle/varray.go

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import (
44
"context"
55
"database/sql/driver"
66
"fmt"
7+
"reflect"
8+
"regexp"
9+
"strings"
710

811
"github.com/godror/godror"
912
)
1013

1114
var DB godror.Execer // set in tests
1215

1316
// EmailList is a Go wrapper for Oracle VARRAY type EMAIL_LIST_ARR.
14-
type EmailList []string
17+
type StringList []string
1518

1619
// Scan implements sql.Scanner (Oracle -> Go)
17-
func (e *EmailList) Scan(src interface{}) error {
20+
func (e *StringList) Scan(src interface{}) error {
1821
obj, ok := src.(*godror.Object)
1922
if !ok {
2023
return fmt.Errorf("expected *godror.Object, got %T", src)
@@ -50,8 +53,8 @@ func (e *EmailList) Scan(src interface{}) error {
5053
}
5154

5255
// Value implements driver.Valuer (Go -> Oracle)
53-
func (e EmailList) Value() (driver.Value, error) {
54-
if e == nil {
56+
func (s StringList) Value() (driver.Value, error) {
57+
if s == nil {
5558
return nil, nil
5659
}
5760
if DB == nil {
@@ -60,9 +63,15 @@ func (e EmailList) Value() (driver.Value, error) {
6063

6164
ctx := context.Background()
6265

63-
objType, err := godror.GetObjectType(ctx, DB, "\"email_list_arr\"")
66+
// Try to detect Oracle type name dynamically via reflection
67+
typeName, err := detectOracleTypeName(s)
6468
if err != nil {
65-
return nil, fmt.Errorf("get object type: %w", err)
69+
return nil, err
70+
}
71+
72+
objType, err := godror.GetObjectType(ctx, DB, fmt.Sprintf("\"%s\"", typeName))
73+
if err != nil {
74+
return nil, fmt.Errorf("get object type %q: %w", typeName, err)
6675
}
6776
defer objType.Close()
6877

@@ -72,12 +81,37 @@ func (e EmailList) Value() (driver.Value, error) {
7281
}
7382
coll := obj.Collection()
7483

75-
for _, s := range e {
76-
if err := coll.Append(s); err != nil {
84+
for _, v := range s {
85+
if err := coll.Append(v); err != nil {
7786
obj.Close()
7887
return nil, fmt.Errorf("append: %w", err)
7988
}
8089
}
8190

8291
return obj, nil
8392
}
93+
94+
// detectOracleTypeName uses reflection to look up the `gorm:"type:..."` tag.
95+
func detectOracleTypeName(value interface{}) (string, error) {
96+
val := reflect.ValueOf(value)
97+
if val.Kind() == reflect.Ptr {
98+
val = val.Elem()
99+
}
100+
101+
// walk up the call stack and look for the struct field tag
102+
// (GORM provides the value as part of the struct — this works during model serialization)
103+
rt := reflect.TypeOf(value)
104+
for i := 0; i < rt.NumField(); i++ {
105+
field := rt.Field(i)
106+
if tag := field.Tag.Get("gorm"); strings.Contains(tag, "type:") {
107+
re := regexp.MustCompile(`type:"?([a-zA-Z0-9_]+)"?`)
108+
match := re.FindStringSubmatch(tag)
109+
if len(match) > 1 {
110+
return strings.ToUpper(match[1]), nil
111+
}
112+
}
113+
}
114+
115+
// fallback
116+
return "", fmt.Errorf("cannot detect Oracle type name for %T", value)
117+
}

tests/varray_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ type DeptPhoneList struct {
6060

6161
// Struct for table with email VARRAY
6262
type EmailVarrayTable struct {
63-
ID uint `gorm:"column:ID;primaryKey"`
64-
Emails oracle.EmailList `gorm:"column:EMAILS;type:\"email_list_arr\""`
63+
ID uint `gorm:"column:ID;primaryKey"`
64+
Emails oracle.StringList `gorm:"column:EMAILS;type:\"email_list_arr\""`
6565
}
6666

6767
func TestStringVarray(t *testing.T) {
@@ -123,7 +123,7 @@ func TestStringVarray(t *testing.T) {
123123
if err := DB.First(&updated, 1).Error; err != nil {
124124
t.Fatalf("Failed to reload updated EmailVarrayTable: %v", err)
125125
}
126-
if !reflect.DeepEqual(updated.Emails, oracle.EmailList(newEmails)) {
126+
if !reflect.DeepEqual(updated.Emails, oracle.StringList(newEmails)) {
127127
t.Errorf("String VARRAY update failed: got %v, want %v", updated.Emails, newEmails)
128128
}
129129

0 commit comments

Comments
 (0)