Rename execution package to qrm (Query Result Mapping).
This commit is contained in:
parent
92de03d4b3
commit
29f43e5fe8
7 changed files with 29 additions and 28 deletions
263
qrm/internal/null_types.go
Normal file
263
qrm/internal/null_types.go
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullByteArray struct
|
||||
type NullByteArray struct {
|
||||
ByteArray []byte
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (nb *NullByteArray) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
nb.Valid = false
|
||||
return nil
|
||||
case []byte:
|
||||
nb.ByteArray = append(v[:0:0], v...)
|
||||
nb.Valid = true
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("can't scan []byte from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (nb NullByteArray) Value() (driver.Value, error) {
|
||||
if !nb.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return nb.ByteArray, nil
|
||||
}
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullTime struct
|
||||
type NullTime struct {
|
||||
Time time.Time
|
||||
Valid bool // Valid is true if Time is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (nt *NullTime) Scan(value interface{}) (err error) {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
nt.Valid = false
|
||||
return
|
||||
case time.Time:
|
||||
nt.Time, nt.Valid = v, true
|
||||
return
|
||||
case []byte:
|
||||
nt.Time, nt.Valid = parseTime(string(v))
|
||||
return
|
||||
case string:
|
||||
nt.Time, nt.Valid = parseTime(v)
|
||||
return
|
||||
default:
|
||||
return fmt.Errorf("can't scan time.Time from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (nt NullTime) Value() (driver.Value, error) {
|
||||
if !nt.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return nt.Time, nil
|
||||
}
|
||||
|
||||
const formatTime = "2006-01-02 15:04:05.999999"
|
||||
|
||||
func parseTime(timeStr string) (t time.Time, valid bool) {
|
||||
|
||||
var format string
|
||||
|
||||
switch len(timeStr) {
|
||||
case 8:
|
||||
format = formatTime[11:19]
|
||||
case 10, 19, 21, 22, 23, 24, 25, 26:
|
||||
format = formatTime[:len(timeStr)]
|
||||
default:
|
||||
return t, false
|
||||
}
|
||||
|
||||
t, err := time.Parse(format, timeStr)
|
||||
return t, err == nil
|
||||
}
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullInt8 struct
|
||||
type NullInt8 struct {
|
||||
Int8 int8
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt8) Scan(value interface{}) (err error) {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
n.Valid = false
|
||||
return
|
||||
case int64:
|
||||
n.Int8, n.Valid = int8(v), true
|
||||
return
|
||||
case int8:
|
||||
n.Int8, n.Valid = v, true
|
||||
return
|
||||
case []byte:
|
||||
intV, err := strconv.ParseInt(string(v), 10, 8)
|
||||
if err == nil {
|
||||
n.Int8, n.Valid = int8(intV), true
|
||||
}
|
||||
return err
|
||||
default:
|
||||
return fmt.Errorf("can't scan int8 from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt8) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Int8, nil
|
||||
}
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullInt16 struct
|
||||
type NullInt16 struct {
|
||||
Int16 int16
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt16) Scan(value interface{}) error {
|
||||
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
n.Valid = false
|
||||
return nil
|
||||
case int64:
|
||||
n.Int16, n.Valid = int16(v), true
|
||||
return nil
|
||||
case int16:
|
||||
n.Int16, n.Valid = v, true
|
||||
return nil
|
||||
case int8:
|
||||
n.Int16, n.Valid = int16(v), true
|
||||
return nil
|
||||
case uint8:
|
||||
n.Int16, n.Valid = int16(v), true
|
||||
return nil
|
||||
case []byte:
|
||||
intV, err := strconv.ParseInt(string(v), 10, 16)
|
||||
if err == nil {
|
||||
n.Int16, n.Valid = int16(intV), true
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("can't scan int16 from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt16) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Int16, nil
|
||||
}
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullInt32 struct
|
||||
type NullInt32 struct {
|
||||
Int32 int32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt32) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
n.Valid = false
|
||||
return nil
|
||||
case int64:
|
||||
n.Int32, n.Valid = int32(v), true
|
||||
return nil
|
||||
case int32:
|
||||
n.Int32, n.Valid = v, true
|
||||
return nil
|
||||
case int16:
|
||||
n.Int32, n.Valid = int32(v), true
|
||||
return nil
|
||||
case uint16:
|
||||
n.Int32, n.Valid = int32(v), true
|
||||
return nil
|
||||
case int8:
|
||||
n.Int32, n.Valid = int32(v), true
|
||||
return nil
|
||||
case uint8:
|
||||
n.Int32, n.Valid = int32(v), true
|
||||
return nil
|
||||
case []byte:
|
||||
intV, err := strconv.ParseInt(string(v), 10, 32)
|
||||
if err == nil {
|
||||
n.Int32, n.Valid = int32(intV), true
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("can't scan int32 from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Int32, nil
|
||||
}
|
||||
|
||||
//===============================================================//
|
||||
|
||||
// NullFloat32 struct
|
||||
type NullFloat32 struct {
|
||||
Float32 float32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullFloat32) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
n.Valid = false
|
||||
return nil
|
||||
case float64:
|
||||
n.Float32, n.Valid = float32(v), true
|
||||
return nil
|
||||
case float32:
|
||||
n.Float32, n.Valid = v, true
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("can't scan float32 from %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullFloat32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.Float32, nil
|
||||
}
|
||||
147
qrm/internal/null_types_test.go
Normal file
147
qrm/internal/null_types_test.go
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNullByteArray(t *testing.T) {
|
||||
var array NullByteArray
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
assert.NilError(t, array.Scan([]byte("bytea")))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
assert.Equal(t, string(array.ByteArray), string([]byte("bytea")))
|
||||
|
||||
assert.Error(t, array.Scan(12), "can't scan []byte from 12")
|
||||
}
|
||||
|
||||
func TestNullTime(t *testing.T) {
|
||||
var array NullTime
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
time := time.Now()
|
||||
assert.NilError(t, array.Scan(time))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ := array.Value()
|
||||
assert.Equal(t, value, time)
|
||||
|
||||
assert.NilError(t, array.Scan([]byte("13:10:11")))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, fmt.Sprintf("%v", value), "0000-01-01 13:10:11 +0000 UTC")
|
||||
|
||||
assert.NilError(t, array.Scan("13:10:11"))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, fmt.Sprintf("%v", value), "0000-01-01 13:10:11 +0000 UTC")
|
||||
|
||||
assert.Error(t, array.Scan(12), "can't scan time.Time from 12")
|
||||
}
|
||||
|
||||
func TestNullInt8(t *testing.T) {
|
||||
var array NullInt8
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
assert.NilError(t, array.Scan(int64(11)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ := array.Value()
|
||||
assert.Equal(t, value, int8(11))
|
||||
|
||||
assert.Error(t, array.Scan("text"), "can't scan int8 from text")
|
||||
}
|
||||
|
||||
func TestNullInt16(t *testing.T) {
|
||||
var array NullInt16
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
assert.NilError(t, array.Scan(int64(11)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ := array.Value()
|
||||
assert.Equal(t, value, int16(11))
|
||||
|
||||
assert.NilError(t, array.Scan(int16(20)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int16(20))
|
||||
|
||||
assert.NilError(t, array.Scan(int8(30)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int16(30))
|
||||
|
||||
assert.NilError(t, array.Scan(uint8(30)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int16(30))
|
||||
|
||||
assert.Error(t, array.Scan("text"), "can't scan int16 from text")
|
||||
}
|
||||
|
||||
func TestNullInt32(t *testing.T) {
|
||||
var array NullInt32
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
assert.NilError(t, array.Scan(int64(11)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ := array.Value()
|
||||
assert.Equal(t, value, int32(11))
|
||||
|
||||
assert.NilError(t, array.Scan(int32(32)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int32(32))
|
||||
|
||||
assert.NilError(t, array.Scan(int16(20)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int32(20))
|
||||
|
||||
assert.NilError(t, array.Scan(uint16(16)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int32(16))
|
||||
|
||||
assert.NilError(t, array.Scan(int8(30)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int32(30))
|
||||
|
||||
assert.NilError(t, array.Scan(uint8(30)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, int32(30))
|
||||
|
||||
assert.Error(t, array.Scan("text"), "can't scan int32 from text")
|
||||
}
|
||||
|
||||
func TestNullFloat32(t *testing.T) {
|
||||
var array NullFloat32
|
||||
|
||||
assert.NilError(t, array.Scan(nil))
|
||||
assert.Equal(t, array.Valid, false)
|
||||
|
||||
assert.NilError(t, array.Scan(float64(64)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ := array.Value()
|
||||
assert.Equal(t, value, float32(64))
|
||||
|
||||
assert.NilError(t, array.Scan(float32(32)))
|
||||
assert.Equal(t, array.Valid, true)
|
||||
value, _ = array.Value()
|
||||
assert.Equal(t, value, float32(32))
|
||||
|
||||
assert.Error(t, array.Scan(12), "can't scan float32 from 12")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue