@@ -51,6 +51,7 @@ import (
5151 "testing"
5252 "time"
5353
54+ "github.com/godror/godror"
5455 . "github.com/oracle-samples/gorm-oracle/tests/utils"
5556
5657 "gorm.io/gorm"
@@ -106,22 +107,24 @@ func TestScannerValuer(t *testing.T) {
106107}
107108
108109func TestScannerValuerWithFirstOrCreate (t * testing.T ) {
109- t .Skip ()
110110 DB .Migrator ().DropTable (& ScannerValuerStruct {})
111111 if err := DB .Migrator ().AutoMigrate (& ScannerValuerStruct {}); err != nil {
112112 t .Errorf ("no error should happen when migrate scanner, valuer struct" )
113113 }
114114
115- data := ScannerValuerStruct {
116- Name : sql.NullString {String : "name" , Valid : true },
117- Gender : & sql.NullString {String : "M" , Valid : true },
118- Age : sql.NullInt64 {Int64 : 18 , Valid : true },
115+ cond := ScannerValuerStruct {
116+ Name : sql.NullString {String : "name" , Valid : true },
117+ Gender : & sql.NullString {String : "M" , Valid : true },
118+ Age : sql.NullInt64 {Int64 : 18 , Valid : true },
119+ }
120+
121+ attrs := ScannerValuerStruct {
119122 ExampleStruct : ExampleStruct {"name" , "value1" },
120123 ExampleStructPtr : & ExampleStruct {"name" , "value2" },
121124 }
122125
123126 var result ScannerValuerStruct
124- tx := DB .Where (data ).FirstOrCreate (& result )
127+ tx := DB .Where (cond ). Attrs ( attrs ).FirstOrCreate (& result )
125128
126129 if tx .RowsAffected != 1 {
127130 t .Errorf ("RowsAffected should be 1 after create some record" )
@@ -131,9 +134,9 @@ func TestScannerValuerWithFirstOrCreate(t *testing.T) {
131134 t .Errorf ("Should not raise any error, but got %v" , tx .Error )
132135 }
133136
134- tests .AssertObjEqual (t , result , data , "Name" , "Gender" , "Age" )
137+ tests .AssertObjEqual (t , result , cond , "Name" , "Gender" , "Age" )
135138
136- if err := DB .Where (data ).Assign (ScannerValuerStruct {Age : sql.NullInt64 {Int64 : 18 , Valid : true }}).FirstOrCreate (& result ).Error ; err != nil {
139+ if err := DB .Where (cond ).Assign (ScannerValuerStruct {Age : sql.NullInt64 {Int64 : 18 , Valid : true }}).FirstOrCreate (& result ).Error ; err != nil {
137140 t .Errorf ("Should not raise any error, but got %v" , err )
138141 }
139142
@@ -251,17 +254,44 @@ func (data EncryptedData) Value() (driver.Value, error) {
251254
252255type Num int64
253256
254- func (i * Num ) Scan (src interface {}) error {
255- switch s := src .(type ) {
256- case []byte :
257- n , _ := strconv .Atoi (string (s ))
258- * i = Num (n )
257+ func (n * Num ) Scan (val interface {}) error {
258+ if val == nil {
259+ * n = 0
260+ return nil
261+ }
262+
263+ switch x := val .(type ) {
259264 case int64 :
260- * i = Num (s )
265+ * n = Num (x )
266+ return nil
267+
268+ case godror.Number :
269+ i , err := strconv .ParseInt (string (x ), 10 , 64 )
270+ if err != nil {
271+ return fmt .Errorf ("Num.Scan: cannot parse godror.Number %q: %w" , string (x ), err )
272+ }
273+ * n = Num (i )
274+ return nil
275+
276+ case string :
277+ i , err := strconv .ParseInt (x , 10 , 64 )
278+ if err != nil {
279+ return fmt .Errorf ("Num.Scan: cannot parse string %q: %w" , x , err )
280+ }
281+ * n = Num (i )
282+ return nil
283+
284+ case []byte :
285+ i , err := strconv .ParseInt (string (x ), 10 , 64 )
286+ if err != nil {
287+ return fmt .Errorf ("Num.Scan: cannot parse []byte %q: %w" , string (x ), err )
288+ }
289+ * n = Num (i )
290+ return nil
291+
261292 default :
262- return errors . New ( "Cannot scan NamedInt from " + reflect . ValueOf ( src ). String () )
293+ return fmt . Errorf ( "Num.Scan: unsupported type %T" , val )
263294 }
264- return nil
265295}
266296
267297type StringsSlice []string
0 commit comments