Skip to content

Commit d61f051

Browse files
committed
add tests for varry and nested table
1 parent 606787c commit d61f051

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

tests/varray_test.go

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
/*
2+
** Copyright (c) 2025 Oracle and/or its affiliates.
3+
**
4+
** The Universal Permissive License (UPL), Version 1.0
5+
**
6+
** Subject to the condition set forth below, permission is hereby granted to any
7+
** person obtaining a copy of this software, associated documentation and/or data
8+
** (collectively the "Software"), free of charge and under any and all copyright
9+
** rights in the Software, and any and all patent rights owned or freely
10+
** licensable by each licensor hereunder covering either (i) the unmodified
11+
** Software as contributed to or provided by such licensor, or (ii) the Larger
12+
** Works (as defined below), to deal in both
13+
**
14+
** (a) the Software, and
15+
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
** one is included with the Software (each a "Larger Work" to which the Software
17+
** is contributed by such licensors),
18+
**
19+
** without restriction, including without limitation the rights to copy, create
20+
** derivative works of, display, perform, and distribute the Software and make,
21+
** use, sell, offer for sale, import, export, have made, and have sold the
22+
** Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
** either these or other terms.
24+
**
25+
** This license is subject to the following condition:
26+
** The above copyright notice and either this complete permission notice or at
27+
** a minimum a reference to the UPL must be included in all copies or
28+
** substantial portions of the Software.
29+
**
30+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
** SOFTWARE.
37+
*/
38+
39+
package tests
40+
41+
import (
42+
"reflect"
43+
"testing"
44+
)
45+
46+
// Struct mapping to phone_typ object
47+
type Phone struct {
48+
CountryCode string `gorm:"column:country_code"`
49+
AreaCode string `gorm:"column:area_code"`
50+
PhNumber string `gorm:"column:ph_number"`
51+
}
52+
53+
// Struct for table with VARRAY of OBJECT
54+
type DeptPhoneList struct {
55+
DeptNo int `gorm:"column:dept_no;primaryKey"`
56+
PhoneList []Phone `gorm:"column:phone_list;type:\"phone_varray_typ\""`
57+
}
58+
59+
// Struct for table with email VARRAY
60+
type EmailVarrayTable struct {
61+
ID uint `gorm:"column:ID;primaryKey"`
62+
Emails []string `gorm:"column:EMAILS;type:\"email_list_arr\""`
63+
}
64+
65+
func TestStringVarray(t *testing.T) {
66+
t.Skip("Skipping due to issue #87")
67+
dropTable := `
68+
BEGIN
69+
EXECUTE IMMEDIATE 'DROP TABLE "email_varray_tables"';
70+
EXCEPTION WHEN OTHERS THEN NULL; END;`
71+
if err := DB.Exec(dropTable).Error; err != nil {
72+
t.Fatalf("Failed to drop email_varray_tables: %v", err)
73+
}
74+
dropType := `
75+
BEGIN
76+
EXECUTE IMMEDIATE 'DROP TYPE "email_list_arr"';
77+
EXCEPTION WHEN OTHERS THEN NULL; END;`
78+
if err := DB.Exec(dropType).Error; err != nil {
79+
t.Fatalf("Failed to drop email_list_arr: %v", err)
80+
}
81+
createType := `CREATE OR REPLACE TYPE "email_list_arr" AS VARRAY(10) OF VARCHAR2(80)`
82+
if err := DB.Exec(createType).Error; err != nil {
83+
t.Fatalf("Failed to create email_list_arr: %v", err)
84+
}
85+
createTable := `CREATE TABLE "email_varray_tables" (
86+
"ID" NUMBER PRIMARY KEY,
87+
"EMAILS" "email_list_arr"
88+
)`
89+
if err := DB.Exec(createTable).Error; err != nil {
90+
t.Fatalf("Failed to create email_varray_tables: %v", err)
91+
}
92+
93+
// Insert initial data via raw SQL
94+
insertRaw := `INSERT INTO "email_varray_tables" VALUES (1, "email_list_arr"('[email protected]','[email protected]','[email protected]'))`
95+
if err := DB.Exec(insertRaw).Error; err != nil {
96+
t.Fatalf("Failed to insert row via raw SQL: %v", err)
97+
}
98+
99+
// Query
100+
var got EmailVarrayTable
101+
if err := DB.First(&got, 1).Error; err != nil {
102+
t.Fatalf("Failed to fetch varray: %v", err)
103+
}
104+
105+
if !reflect.DeepEqual(expected, got.Emails) {
106+
t.Errorf("String VARRAY roundtrip failed: got %v, want %v", got.Emails, expected)
107+
}
108+
109+
// Update
110+
newEmails := []string{"[email protected]", "[email protected]"}
111+
if err := DB.Model(&got).Update("Emails", newEmails).Error; err != nil {
112+
t.Fatalf("Failed to update emails: %v", err)
113+
}
114+
var updated EmailVarrayTable
115+
if err := DB.First(&updated, 1).Error; err != nil {
116+
t.Fatalf("Failed to reload updated EmailVarrayTable: %v", err)
117+
}
118+
if !reflect.DeepEqual(updated.Emails, newEmails) {
119+
t.Errorf("String VARRAY update failed: got %v, want %v", updated.Emails, newEmails)
120+
}
121+
122+
// Insert
123+
item := EmailVarrayTable{
124+
ID: 1,
125+
126+
}
127+
if err := DB.Create(&item).Error; err != nil {
128+
t.Fatalf("Failed to insert varray: %v", err)
129+
}
130+
}
131+
132+
func TestVarrayOfObject(t *testing.T) {
133+
t.Skip("Skipping due to issue #87")
134+
dropTable := `
135+
BEGIN
136+
EXECUTE IMMEDIATE 'DROP TABLE "dept_phone_lists"';
137+
EXCEPTION WHEN OTHERS THEN NULL; END;`
138+
if err := DB.Exec(dropTable).Error; err != nil {
139+
t.Fatalf("Failed to drop table: %v", err)
140+
}
141+
dropVarray := `
142+
BEGIN
143+
EXECUTE IMMEDIATE 'DROP TYPE "phone_varray_typ"';
144+
EXCEPTION WHEN OTHERS THEN NULL; END;`
145+
DB.Exec(dropVarray)
146+
dropObj := `
147+
BEGIN
148+
EXECUTE IMMEDIATE 'DROP TYPE "phone_typ"';
149+
EXCEPTION WHEN OTHERS THEN NULL; END;`
150+
DB.Exec(dropObj)
151+
152+
createObj := `CREATE OR REPLACE TYPE "phone_typ" AS OBJECT (
153+
"country_code" VARCHAR2(2),
154+
"area_code" VARCHAR2(3),
155+
"ph_number" VARCHAR2(7))`
156+
if err := DB.Exec(createObj).Error; err != nil {
157+
t.Fatalf("Failed to create phone_typ: %v", err)
158+
}
159+
createVarray := `CREATE OR REPLACE TYPE "phone_varray_typ" AS VARRAY(5) OF "phone_typ"`
160+
if err := DB.Exec(createVarray).Error; err != nil {
161+
t.Fatalf("Failed to create phone_varray_typ: %v", err)
162+
}
163+
createTable := `CREATE TABLE "dept_phone_lists"("dept_no" NUMBER(5) PRIMARY KEY, "phone_list" "phone_varray_typ")`
164+
if err := DB.Exec(createTable).Error; err != nil {
165+
t.Fatalf("Failed to create dept_phone_lists: %v", err)
166+
}
167+
168+
// Insert initial data using raw SQL
169+
insertRaw := `INSERT INTO "dept_phone_lists" VALUES (
170+
100,
171+
"phone_varray_typ"( "phone_typ" ('01', '650', '5550123'),
172+
"phone_typ" ('01', '650', '5550148'),
173+
"phone_typ" ('01', '650', '5550192')))
174+
`
175+
if err := DB.Exec(insertRaw).Error; err != nil {
176+
t.Fatalf("Failed to insert example row: %v", err)
177+
}
178+
179+
// Query
180+
var got DeptPhoneList
181+
if err := DB.First(&got, 100).Error; err != nil {
182+
t.Fatalf("failed to query: %v", err)
183+
}
184+
want := []Phone{
185+
{CountryCode: "01", AreaCode: "650", PhNumber: "5550123"},
186+
{CountryCode: "01", AreaCode: "650", PhNumber: "5550148"},
187+
{CountryCode: "01", AreaCode: "650", PhNumber: "5550192"},
188+
}
189+
if !reflect.DeepEqual(got.PhoneList, want) {
190+
t.Errorf("Select phone_varray_typ roundtrip failed: got %v, want %v", got.PhoneList, want)
191+
}
192+
193+
// Insert
194+
item := DeptPhoneList{
195+
DeptNo: 200,
196+
PhoneList: []Phone{
197+
{CountryCode: "86", AreaCode: "10", PhNumber: "1234567"},
198+
{CountryCode: "49", AreaCode: "89", PhNumber: "7654321"},
199+
},
200+
}
201+
err := DB.Create(&item).Error
202+
if err != nil {
203+
t.Errorf("Failed to insert: %v", err)
204+
} else {
205+
var read DeptPhoneList
206+
if err := DB.First(&read, 200).Error; err != nil {
207+
t.Errorf("Could not fetch inserted row: %v", err)
208+
} else if !reflect.DeepEqual(read.PhoneList, item.PhoneList) {
209+
t.Errorf("Inserted VARRAY<OBJECT> mismatch: got %v want %v", read.PhoneList, item.PhoneList)
210+
}
211+
}
212+
213+
// Update
214+
newPhones := []Phone{
215+
{CountryCode: "07", AreaCode: "312", PhNumber: "2000044"},
216+
}
217+
if err := DB.Model(&DeptPhoneList{}).Where("\"dept_no\" = ?", 200).
218+
Update("PhoneList", newPhones).Error; err != nil {
219+
t.Errorf("Failed to update varray<obj>: %v", err)
220+
}
221+
var updated DeptPhoneList
222+
if err := DB.First(&updated, 200).Error; err != nil {
223+
t.Errorf("Could not fetch updated row: %v", err)
224+
} else if !reflect.DeepEqual(updated.PhoneList, newPhones) {
225+
t.Errorf("Updated VARRAY<OBJECT> mismatch: got %v want %v", updated.PhoneList, newPhones)
226+
}
227+
}

0 commit comments

Comments
 (0)