More work to support nullable foreign keys

Adds nullable int/uint types
This commit is contained in:
Jamie Curnow
2023-05-30 22:26:44 +10:00
parent 88f3953f92
commit 4a57956093
14 changed files with 387 additions and 256 deletions

View File

@ -0,0 +1,63 @@
package types
import (
"database/sql/driver"
"encoding/json"
"strconv"
)
// NullableDBInt works with database values that can be null or an integer value
type NullableDBInt struct {
Int int
}
// Value encodes the type ready for the database
func (d NullableDBInt) Value() (driver.Value, error) {
if d.Int == 0 {
return nil, nil
}
// According to current database/sql docs, the sql has four builtin functions that
// returns driver.Value, and the underlying types are `int64`, `float64`, `string` and `bool`
return driver.Value(int64(d.Int)), nil
}
// Scan takes data from the database and modifies it for Go Types
func (d *NullableDBInt) Scan(src interface{}) error {
var i int
switch v := src.(type) {
case int:
i = v
case int64:
i = int(v)
case float32:
i = int(v)
case float64:
i = int(v)
case string:
i, _ = strconv.Atoi(v)
}
d.Int = i
return nil
}
// UnmarshalJSON will unmarshal both database and post given values
func (d *NullableDBInt) UnmarshalJSON(data []byte) error {
// total_deploy_time: 10,
// total_deploy_time: null,
var i int
if err := json.Unmarshal(data, &i); err != nil {
i = 0
return nil
}
d.Int = i
return nil
}
// MarshalJSON will marshal for output in api responses
func (d NullableDBInt) MarshalJSON() ([]byte, error) {
if d.Int == 0 {
return json.Marshal(nil)
}
return json.Marshal(d.Int)
}

View File

@ -0,0 +1,64 @@
package types
import (
"database/sql/driver"
"encoding/json"
"strconv"
)
// NullableDBUint works with database values that can be null or an integer value
type NullableDBUint struct {
Uint uint
}
// Value encodes the type ready for the database
func (d NullableDBUint) Value() (driver.Value, error) {
if d.Uint == 0 {
return nil, nil
}
// According to current database/sql docs, the sql has four builtin functions that
// returns driver.Value, and the underlying types are `int64`, `float64`, `string` and `bool`
return driver.Value(int64(d.Uint)), nil
}
// Scan takes data from the database and modifies it for Go Types
func (d *NullableDBUint) Scan(src interface{}) error {
var i uint
switch v := src.(type) {
case int:
i = uint(v)
case int64:
i = uint(v)
case float32:
i = uint(v)
case float64:
i = uint(v)
case string:
a, _ := strconv.Atoi(v)
i = uint(a)
}
d.Uint = i
return nil
}
// UnmarshalJSON will unmarshal both database and post given values
func (d *NullableDBUint) UnmarshalJSON(data []byte) error {
// total_deploy_time: 10,
// total_deploy_time: null,
var i uint
if err := json.Unmarshal(data, &i); err != nil {
i = 0
return nil
}
d.Uint = i
return nil
}
// MarshalJSON will marshal for output in api responses
func (d NullableDBUint) MarshalJSON() ([]byte, error) {
if d.Uint == 0 {
return json.Marshal(nil)
}
return json.Marshal(d.Uint)
}

View File

@ -17,6 +17,8 @@ func (d NullableDBDate) Value() (driver.Value, error) {
if d.Time == nil {
return nil, nil
}
// According to current database/sql docs, the sql has four builtin functions that
// returns driver.Value, and the underlying types are `int64`, `float64`, `string` and `bool`
return driver.Value(d.Time.Unix()), nil
}