3939package tests
4040
4141import (
42+ "context"
43+ "fmt"
4244 "reflect"
45+ "strings"
4346 "testing"
4447
45- "github.com/oracle-samples/gorm-oracle/oracle"
48+ "github.com/godror/godror"
49+ "gorm.io/gorm"
50+ "gorm.io/gorm/clause"
4651)
4752
53+ // custom data type
54+ type StringList []string
55+
56+ // Scan implements sql.Scanner (Oracle -> Go)
57+ func (e * StringList ) Scan (src interface {}) error {
58+ obj , ok := src .(* godror.Object )
59+ if ! ok {
60+ return fmt .Errorf ("expected *godror.Object, got %T" , src )
61+ }
62+ defer obj .Close ()
63+
64+ coll := obj .Collection ()
65+ length , err := coll .Len ()
66+ if err != nil {
67+ return fmt .Errorf ("get collection length: %w" , err )
68+ }
69+
70+ var list []string
71+ for i := 0 ; i < length ; i ++ {
72+ var data godror.Data
73+ if err := coll .GetItem (& data , i ); err != nil {
74+ return fmt .Errorf ("GetItem %d: %w" , i , err )
75+ }
76+ val := data .Get ()
77+ switch v := val .(type ) {
78+ case string :
79+ list = append (list , v )
80+ case []byte :
81+ list = append (list , string (v ))
82+ default :
83+ if v != nil {
84+ list = append (list , fmt .Sprint (v ))
85+ }
86+ }
87+ }
88+ * e = list
89+ return nil
90+ }
91+
92+ // Implement GormValue interface
93+ func (e StringList ) GormValue (ctx context.Context , db * gorm.DB ) clause.Expr {
94+ if len (e ) == 0 {
95+ return gorm .Expr (`"email_list_arr"()` )
96+ }
97+ vals := "'" + strings .Join (e , "','" ) + "'"
98+ return gorm .Expr (fmt .Sprintf (`"email_list_arr"(%s)` , vals ))
99+ }
100+
48101// Struct mapping to phone_typ object
49102type Phone struct {
50103 CountryCode string `gorm:"column:country_code"`
@@ -60,8 +113,8 @@ type DeptPhoneList struct {
60113
61114// Struct for table with email VARRAY
62115type EmailVarrayTable struct {
63- ID uint `gorm:"column:ID;primaryKey"`
64- Emails oracle. StringList `gorm:"column:EMAILS;type:\"email_list_arr\""`
116+ ID uint `gorm:"column:ID;primaryKey"`
117+ Emails StringList `gorm:"column:EMAILS;type:\"email_list_arr\""`
65118}
66119
67120func TestStringVarray (t * testing.T ) {
@@ -91,13 +144,6 @@ func TestStringVarray(t *testing.T) {
91144 t .Fatalf ("Failed to create email_varray_tables: %v" , err )
92145 }
93146
94- // expose raw *sql.DB to oracle package for godror.GetObjectType
95- sqlDB , err := DB .DB ()
96- if err != nil {
97- t .Fatalf ("cannot get *sql.DB from GORM: %v" , err )
98- }
99- oracle .DB = sqlDB
100-
101147 // Insert initial data via raw SQL
102148 insertRaw := `INSERT INTO "email_varray_tables" VALUES (1, "email_list_arr"('[email protected] ','[email protected] ','[email protected] '))` 103149 if err := DB .Exec (insertRaw ).Error ; err != nil {
@@ -116,20 +162,20 @@ func TestStringVarray(t *testing.T) {
116162
117163 // Update
118164119- if err := DB .Model (& got ).Update ("Emails" , newEmails ).Error ; err != nil {
165+ if err := DB .Model (& got ).Update ("Emails" , StringList ( newEmails ) ).Error ; err != nil {
120166 t .Fatalf ("Failed to update emails: %v" , err )
121167 }
122168 var updated EmailVarrayTable
123169 if err := DB .First (& updated , 1 ).Error ; err != nil {
124170 t .Fatalf ("Failed to reload updated EmailVarrayTable: %v" , err )
125171 }
126- if ! reflect .DeepEqual (updated .Emails , oracle . StringList (newEmails )) {
172+ if ! reflect .DeepEqual (updated .Emails , StringList (newEmails )) {
127173 t .Errorf ("String VARRAY update failed: got %v, want %v" , updated .Emails , newEmails )
128174 }
129175
130176 // Insert
131177 item := EmailVarrayTable {
132- ID : 1 ,
178+ ID : 2 ,
133179134180 }
135181 if err := DB .Create (& item ).Error ; err != nil {
0 commit comments