mirror of https://github.com/jackc/pgx.git
Restored more optimised array type conversions for a few select 1D-slice types.
Results of calls to the reflect lib are now stored as local variables for small performance gains.non-blocking
parent
449a8a4f8e
commit
b90570feb5
188
aclitem_array.go
188
aclitem_array.go
|
@ -29,56 +29,110 @@ func (dst *ACLItemArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = ACLItemArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for ACLItemArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = ACLItemArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to ACLItemArray", src)
|
||||
}
|
||||
|
||||
*dst = ACLItemArray{
|
||||
Elements: make([]ACLItem, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = ACLItemArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = ACLItemArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]ACLItem, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]ACLItem, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = ACLItemArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = ACLItemArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = ACLItemArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]ACLItem, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = ACLItemArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []ACLItem:
|
||||
if value == nil {
|
||||
*dst = ACLItemArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = ACLItemArray{Status: Present}
|
||||
} else {
|
||||
*dst = ACLItemArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = ACLItemArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for ACLItemArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = ACLItemArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to ACLItemArray", src)
|
||||
}
|
||||
|
||||
*dst = ACLItemArray{
|
||||
Elements: make([]ACLItem, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]ACLItem, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to ACLItemArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to ACLItemArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -93,10 +147,11 @@ func (dst *ACLItemArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -131,6 +186,30 @@ func (dst ACLItemArray) Get() interface{} {
|
|||
func (src *ACLItemArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -169,10 +248,12 @@ func (src *ACLItemArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -190,11 +271,14 @@ func (src *ACLItemArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from ACLItemArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from ACLItemArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
bool_array.go
188
bool_array.go
|
@ -31,56 +31,110 @@ func (dst *BoolArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = BoolArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for BoolArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = BoolArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to BoolArray", src)
|
||||
}
|
||||
|
||||
*dst = BoolArray{
|
||||
Elements: make([]Bool, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []bool:
|
||||
if value == nil {
|
||||
*dst = BoolArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BoolArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Bool, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Bool, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = BoolArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*bool:
|
||||
if value == nil {
|
||||
*dst = BoolArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BoolArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Bool, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = BoolArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Bool:
|
||||
if value == nil {
|
||||
*dst = BoolArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BoolArray{Status: Present}
|
||||
} else {
|
||||
*dst = BoolArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = BoolArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for BoolArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = BoolArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to BoolArray", src)
|
||||
}
|
||||
|
||||
*dst = BoolArray{
|
||||
Elements: make([]Bool, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Bool, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to BoolArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to BoolArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *BoolArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst BoolArray) Get() interface{} {
|
|||
func (src *BoolArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]bool:
|
||||
*v = make([]bool, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*bool:
|
||||
*v = make([]*bool, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *BoolArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *BoolArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from BoolArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from BoolArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
bpchar_array.go
188
bpchar_array.go
|
@ -31,56 +31,110 @@ func (dst *BPCharArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = BPCharArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for BPCharArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = BPCharArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to BPCharArray", src)
|
||||
}
|
||||
|
||||
*dst = BPCharArray{
|
||||
Elements: make([]BPChar, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = BPCharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BPCharArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]BPChar, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]BPChar, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = BPCharArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = BPCharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BPCharArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]BPChar, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = BPCharArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []BPChar:
|
||||
if value == nil {
|
||||
*dst = BPCharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = BPCharArray{Status: Present}
|
||||
} else {
|
||||
*dst = BPCharArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = BPCharArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for BPCharArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = BPCharArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to BPCharArray", src)
|
||||
}
|
||||
|
||||
*dst = BPCharArray{
|
||||
Elements: make([]BPChar, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]BPChar, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to BPCharArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to BPCharArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *BPCharArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst BPCharArray) Get() interface{} {
|
|||
func (src *BPCharArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *BPCharArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *BPCharArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from BPCharArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from BPCharArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
160
bytea_array.go
160
bytea_array.go
|
@ -31,56 +31,91 @@ func (dst *ByteaArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = ByteaArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for ByteaArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = ByteaArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to ByteaArray", src)
|
||||
}
|
||||
|
||||
*dst = ByteaArray{
|
||||
Elements: make([]Bytea, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case [][]byte:
|
||||
if value == nil {
|
||||
*dst = ByteaArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = ByteaArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Bytea, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Bytea, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = ByteaArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Bytea:
|
||||
if value == nil {
|
||||
*dst = ByteaArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = ByteaArray{Status: Present}
|
||||
} else {
|
||||
*dst = ByteaArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = ByteaArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for ByteaArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = ByteaArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to ByteaArray", src)
|
||||
}
|
||||
|
||||
*dst = ByteaArray{
|
||||
Elements: make([]Bytea, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Bytea, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to ByteaArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to ByteaArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +130,11 @@ func (dst *ByteaArray) setRecursive(value reflect.Value, index, dimension int) (
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +169,21 @@ func (dst ByteaArray) Get() interface{} {
|
|||
func (src *ByteaArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[][]byte:
|
||||
*v = make([][]byte, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +222,12 @@ func (src *ByteaArray) assignToRecursive(value reflect.Value, index, dimension i
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +245,14 @@ func (src *ByteaArray) assignToRecursive(value reflect.Value, index, dimension i
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from ByteaArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from ByteaArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
217
cidr_array.go
217
cidr_array.go
|
@ -5,6 +5,7 @@ package pgtype
|
|||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"reflect"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
|
@ -31,56 +32,129 @@ func (dst *CIDRArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for CIDRArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to CIDRArray", src)
|
||||
}
|
||||
|
||||
*dst = CIDRArray{
|
||||
Elements: make([]CIDR, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []*net.IPNet:
|
||||
if value == nil {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]CIDR, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]CIDR, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = CIDRArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []net.IP:
|
||||
if value == nil {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]CIDR, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = CIDRArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*net.IP:
|
||||
if value == nil {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]CIDR, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = CIDRArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []CIDR:
|
||||
if value == nil {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
} else {
|
||||
*dst = CIDRArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = CIDRArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for CIDRArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = CIDRArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to CIDRArray", src)
|
||||
}
|
||||
|
||||
*dst = CIDRArray{
|
||||
Elements: make([]CIDR, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]CIDR, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to CIDRArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to CIDRArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +169,11 @@ func (dst *CIDRArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +208,39 @@ func (dst CIDRArray) Get() interface{} {
|
|||
func (src *CIDRArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]*net.IPNet:
|
||||
*v = make([]*net.IPNet, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]net.IP:
|
||||
*v = make([]net.IP, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*net.IP:
|
||||
*v = make([]*net.IP, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +279,12 @@ func (src *CIDRArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +302,14 @@ func (src *CIDRArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from CIDRArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from CIDRArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
189
date_array.go
189
date_array.go
|
@ -6,6 +6,7 @@ import (
|
|||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
errors "golang.org/x/xerrors"
|
||||
|
@ -31,56 +32,110 @@ func (dst *DateArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = DateArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for DateArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = DateArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to DateArray", src)
|
||||
}
|
||||
|
||||
*dst = DateArray{
|
||||
Elements: make([]Date, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []time.Time:
|
||||
if value == nil {
|
||||
*dst = DateArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = DateArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Date, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Date, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = DateArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*time.Time:
|
||||
if value == nil {
|
||||
*dst = DateArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = DateArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Date, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = DateArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Date:
|
||||
if value == nil {
|
||||
*dst = DateArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = DateArray{Status: Present}
|
||||
} else {
|
||||
*dst = DateArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = DateArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for DateArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = DateArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to DateArray", src)
|
||||
}
|
||||
|
||||
*dst = DateArray{
|
||||
Elements: make([]Date, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Date, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to DateArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to DateArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +150,11 @@ func (dst *DateArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +189,30 @@ func (dst DateArray) Get() interface{} {
|
|||
func (src *DateArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]time.Time:
|
||||
*v = make([]time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*time.Time:
|
||||
*v = make([]*time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +251,12 @@ func (src *DateArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +274,14 @@ func (src *DateArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from DateArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from DateArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
enum_array.go
188
enum_array.go
|
@ -29,56 +29,110 @@ func (dst *EnumArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = EnumArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for EnumArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = EnumArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to EnumArray", src)
|
||||
}
|
||||
|
||||
*dst = EnumArray{
|
||||
Elements: make([]GenericText, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = EnumArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = EnumArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]GenericText, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]GenericText, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = EnumArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = EnumArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = EnumArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]GenericText, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = EnumArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []GenericText:
|
||||
if value == nil {
|
||||
*dst = EnumArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = EnumArray{Status: Present}
|
||||
} else {
|
||||
*dst = EnumArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = EnumArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for EnumArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = EnumArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to EnumArray", src)
|
||||
}
|
||||
|
||||
*dst = EnumArray{
|
||||
Elements: make([]GenericText, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]GenericText, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to EnumArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to EnumArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -93,10 +147,11 @@ func (dst *EnumArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -131,6 +186,30 @@ func (dst EnumArray) Get() interface{} {
|
|||
func (src *EnumArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -169,10 +248,12 @@ func (src *EnumArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -190,11 +271,14 @@ func (src *EnumArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from EnumArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from EnumArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
float4_array.go
188
float4_array.go
|
@ -31,56 +31,110 @@ func (dst *Float4Array) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = Float4Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Float4Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Float4Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Float4Array", src)
|
||||
}
|
||||
|
||||
*dst = Float4Array{
|
||||
Elements: make([]Float4, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []float32:
|
||||
if value == nil {
|
||||
*dst = Float4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Float4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Float4, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = Float4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*float32:
|
||||
if value == nil {
|
||||
*dst = Float4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Float4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Float4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Float4:
|
||||
if value == nil {
|
||||
*dst = Float4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float4Array{Status: Present}
|
||||
} else {
|
||||
*dst = Float4Array{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = Float4Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Float4Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Float4Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Float4Array", src)
|
||||
}
|
||||
|
||||
*dst = Float4Array{
|
||||
Elements: make([]Float4, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Float4, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Float4Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Float4Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *Float4Array) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst Float4Array) Get() interface{} {
|
|||
func (src *Float4Array) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]float32:
|
||||
*v = make([]float32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*float32:
|
||||
*v = make([]*float32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *Float4Array) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *Float4Array) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from Float4Array")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from Float4Array")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
float8_array.go
188
float8_array.go
|
@ -31,56 +31,110 @@ func (dst *Float8Array) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = Float8Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Float8Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Float8Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Float8Array", src)
|
||||
}
|
||||
|
||||
*dst = Float8Array{
|
||||
Elements: make([]Float8, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []float64:
|
||||
if value == nil {
|
||||
*dst = Float8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Float8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Float8, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = Float8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*float64:
|
||||
if value == nil {
|
||||
*dst = Float8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Float8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Float8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Float8:
|
||||
if value == nil {
|
||||
*dst = Float8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Float8Array{Status: Present}
|
||||
} else {
|
||||
*dst = Float8Array{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = Float8Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Float8Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Float8Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Float8Array", src)
|
||||
}
|
||||
|
||||
*dst = Float8Array{
|
||||
Elements: make([]Float8, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Float8, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Float8Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Float8Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *Float8Array) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst Float8Array) Get() interface{} {
|
|||
func (src *Float8Array) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]float64:
|
||||
*v = make([]float64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*float64:
|
||||
*v = make([]*float64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *Float8Array) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *Float8Array) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from Float8Array")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from Float8Array")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
160
hstore_array.go
160
hstore_array.go
|
@ -31,56 +31,91 @@ func (dst *HstoreArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = HstoreArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for HstoreArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = HstoreArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to HstoreArray", src)
|
||||
}
|
||||
|
||||
*dst = HstoreArray{
|
||||
Elements: make([]Hstore, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []map[string]string:
|
||||
if value == nil {
|
||||
*dst = HstoreArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = HstoreArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Hstore, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Hstore, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = HstoreArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Hstore:
|
||||
if value == nil {
|
||||
*dst = HstoreArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = HstoreArray{Status: Present}
|
||||
} else {
|
||||
*dst = HstoreArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = HstoreArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for HstoreArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = HstoreArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to HstoreArray", src)
|
||||
}
|
||||
|
||||
*dst = HstoreArray{
|
||||
Elements: make([]Hstore, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Hstore, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to HstoreArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to HstoreArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +130,11 @@ func (dst *HstoreArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +169,21 @@ func (dst HstoreArray) Get() interface{} {
|
|||
func (src *HstoreArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]map[string]string:
|
||||
*v = make([]map[string]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +222,12 @@ func (src *HstoreArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +245,14 @@ func (src *HstoreArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from HstoreArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from HstoreArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
217
inet_array.go
217
inet_array.go
|
@ -5,6 +5,7 @@ package pgtype
|
|||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"reflect"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
|
@ -31,56 +32,129 @@ func (dst *InetArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = InetArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for InetArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to InetArray", src)
|
||||
}
|
||||
|
||||
*dst = InetArray{
|
||||
Elements: make([]Inet, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []*net.IPNet:
|
||||
if value == nil {
|
||||
*dst = InetArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Inet, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Inet, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = InetArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []net.IP:
|
||||
if value == nil {
|
||||
*dst = InetArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Inet, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = InetArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*net.IP:
|
||||
if value == nil {
|
||||
*dst = InetArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Inet, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = InetArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Inet:
|
||||
if value == nil {
|
||||
*dst = InetArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
} else {
|
||||
*dst = InetArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = InetArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for InetArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = InetArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to InetArray", src)
|
||||
}
|
||||
|
||||
*dst = InetArray{
|
||||
Elements: make([]Inet, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Inet, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to InetArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to InetArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +169,11 @@ func (dst *InetArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +208,39 @@ func (dst InetArray) Get() interface{} {
|
|||
func (src *InetArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]*net.IPNet:
|
||||
*v = make([]*net.IPNet, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]net.IP:
|
||||
*v = make([]net.IP, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*net.IP:
|
||||
*v = make([]*net.IP, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +279,12 @@ func (src *InetArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +302,14 @@ func (src *InetArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from InetArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from InetArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
580
int2_array.go
580
int2_array.go
|
@ -31,56 +31,376 @@ func (dst *Int2Array) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = Int2Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int2Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int2Array", src)
|
||||
}
|
||||
|
||||
*dst = Int2Array{
|
||||
Elements: make([]Int2, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []int16:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int2, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int16:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint16:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint16:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int32:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int32:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint32:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint32:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int64:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int64:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint64:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint64:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int2, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int2Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Int2:
|
||||
if value == nil {
|
||||
*dst = Int2Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
} else {
|
||||
*dst = Int2Array{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = Int2Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int2Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int2Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int2Array", src)
|
||||
}
|
||||
|
||||
*dst = Int2Array{
|
||||
Elements: make([]Int2, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int2, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int2Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int2Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +415,11 @@ func (dst *Int2Array) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +454,156 @@ func (dst Int2Array) Get() interface{} {
|
|||
func (src *Int2Array) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]int16:
|
||||
*v = make([]int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int16:
|
||||
*v = make([]*int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint16:
|
||||
*v = make([]uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint16:
|
||||
*v = make([]*uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int32:
|
||||
*v = make([]int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int32:
|
||||
*v = make([]*int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint32:
|
||||
*v = make([]uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint32:
|
||||
*v = make([]*uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int64:
|
||||
*v = make([]int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int64:
|
||||
*v = make([]*int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint64:
|
||||
*v = make([]uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint64:
|
||||
*v = make([]*uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int:
|
||||
*v = make([]int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int:
|
||||
*v = make([]*int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint:
|
||||
*v = make([]uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint:
|
||||
*v = make([]*uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +642,12 @@ func (src *Int2Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +665,14 @@ func (src *Int2Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int2Array")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int2Array")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
580
int4_array.go
580
int4_array.go
|
@ -31,56 +31,376 @@ func (dst *Int4Array) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = Int4Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int4Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int4Array", src)
|
||||
}
|
||||
|
||||
*dst = Int4Array{
|
||||
Elements: make([]Int4, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []int16:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int4, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int16:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint16:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint16:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int32:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int32:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint32:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint32:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int64:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int64:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint64:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint64:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int4, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int4Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Int4:
|
||||
if value == nil {
|
||||
*dst = Int4Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
} else {
|
||||
*dst = Int4Array{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = Int4Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int4Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int4Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int4Array", src)
|
||||
}
|
||||
|
||||
*dst = Int4Array{
|
||||
Elements: make([]Int4, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int4, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int4Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int4Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +415,11 @@ func (dst *Int4Array) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +454,156 @@ func (dst Int4Array) Get() interface{} {
|
|||
func (src *Int4Array) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]int16:
|
||||
*v = make([]int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int16:
|
||||
*v = make([]*int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint16:
|
||||
*v = make([]uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint16:
|
||||
*v = make([]*uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int32:
|
||||
*v = make([]int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int32:
|
||||
*v = make([]*int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint32:
|
||||
*v = make([]uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint32:
|
||||
*v = make([]*uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int64:
|
||||
*v = make([]int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int64:
|
||||
*v = make([]*int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint64:
|
||||
*v = make([]uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint64:
|
||||
*v = make([]*uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int:
|
||||
*v = make([]int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int:
|
||||
*v = make([]*int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint:
|
||||
*v = make([]uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint:
|
||||
*v = make([]*uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +642,12 @@ func (src *Int4Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +665,14 @@ func (src *Int4Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int4Array")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int4Array")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
580
int8_array.go
580
int8_array.go
|
@ -31,56 +31,376 @@ func (dst *Int8Array) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = Int8Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int8Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int8Array", src)
|
||||
}
|
||||
|
||||
*dst = Int8Array{
|
||||
Elements: make([]Int8, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []int16:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int8, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int16:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint16:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint16:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int32:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int32:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint32:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint32:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int64:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int64:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint64:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint64:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
elements := make([]Int8, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = Int8Array{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Int8:
|
||||
if value == nil {
|
||||
*dst = Int8Array{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
} else {
|
||||
*dst = Int8Array{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = Int8Array{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for Int8Array", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = Int8Array{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to Int8Array", src)
|
||||
}
|
||||
|
||||
*dst = Int8Array{
|
||||
Elements: make([]Int8, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Int8, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int8Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to Int8Array, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +415,11 @@ func (dst *Int8Array) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +454,156 @@ func (dst Int8Array) Get() interface{} {
|
|||
func (src *Int8Array) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]int16:
|
||||
*v = make([]int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int16:
|
||||
*v = make([]*int16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint16:
|
||||
*v = make([]uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint16:
|
||||
*v = make([]*uint16, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int32:
|
||||
*v = make([]int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int32:
|
||||
*v = make([]*int32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint32:
|
||||
*v = make([]uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint32:
|
||||
*v = make([]*uint32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int64:
|
||||
*v = make([]int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int64:
|
||||
*v = make([]*int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint64:
|
||||
*v = make([]uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint64:
|
||||
*v = make([]*uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int:
|
||||
*v = make([]int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int:
|
||||
*v = make([]*int, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint:
|
||||
*v = make([]uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint:
|
||||
*v = make([]*uint, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +642,12 @@ func (src *Int8Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +665,14 @@ func (src *Int8Array) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int8Array")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from Int8Array")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
160
jsonb_array.go
160
jsonb_array.go
|
@ -31,56 +31,91 @@ func (dst *JSONBArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = JSONBArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for JSONBArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = JSONBArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to JSONBArray", src)
|
||||
}
|
||||
|
||||
*dst = JSONBArray{
|
||||
Elements: make([]Text, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = JSONBArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = JSONBArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Text, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Text, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = JSONBArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Text:
|
||||
if value == nil {
|
||||
*dst = JSONBArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = JSONBArray{Status: Present}
|
||||
} else {
|
||||
*dst = JSONBArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = JSONBArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for JSONBArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = JSONBArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to JSONBArray", src)
|
||||
}
|
||||
|
||||
*dst = JSONBArray{
|
||||
Elements: make([]Text, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Text, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to JSONBArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to JSONBArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +130,11 @@ func (dst *JSONBArray) setRecursive(value reflect.Value, index, dimension int) (
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +169,21 @@ func (dst JSONBArray) Get() interface{} {
|
|||
func (src *JSONBArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +222,12 @@ func (src *JSONBArray) assignToRecursive(value reflect.Value, index, dimension i
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +245,14 @@ func (src *JSONBArray) assignToRecursive(value reflect.Value, index, dimension i
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from JSONBArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from JSONBArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
189
macaddr_array.go
189
macaddr_array.go
|
@ -5,6 +5,7 @@ package pgtype
|
|||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"reflect"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
|
@ -31,56 +32,110 @@ func (dst *MacaddrArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = MacaddrArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for MacaddrArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = MacaddrArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to MacaddrArray", src)
|
||||
}
|
||||
|
||||
*dst = MacaddrArray{
|
||||
Elements: make([]Macaddr, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []net.HardwareAddr:
|
||||
if value == nil {
|
||||
*dst = MacaddrArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = MacaddrArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Macaddr, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Macaddr, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = MacaddrArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*net.HardwareAddr:
|
||||
if value == nil {
|
||||
*dst = MacaddrArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = MacaddrArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Macaddr, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = MacaddrArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Macaddr:
|
||||
if value == nil {
|
||||
*dst = MacaddrArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = MacaddrArray{Status: Present}
|
||||
} else {
|
||||
*dst = MacaddrArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = MacaddrArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for MacaddrArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = MacaddrArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to MacaddrArray", src)
|
||||
}
|
||||
|
||||
*dst = MacaddrArray{
|
||||
Elements: make([]Macaddr, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Macaddr, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to MacaddrArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to MacaddrArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +150,11 @@ func (dst *MacaddrArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +189,30 @@ func (dst MacaddrArray) Get() interface{} {
|
|||
func (src *MacaddrArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]net.HardwareAddr:
|
||||
*v = make([]net.HardwareAddr, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*net.HardwareAddr:
|
||||
*v = make([]*net.HardwareAddr, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +251,12 @@ func (src *MacaddrArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +274,14 @@ func (src *MacaddrArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from MacaddrArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from MacaddrArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
356
numeric_array.go
356
numeric_array.go
|
@ -31,56 +31,224 @@ func (dst *NumericArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = NumericArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for NumericArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to NumericArray", src)
|
||||
}
|
||||
|
||||
*dst = NumericArray{
|
||||
Elements: make([]Numeric, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []float32:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Numeric, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*float32:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []float64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*float64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []int64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*int64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []uint64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*uint64:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Numeric, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = NumericArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Numeric:
|
||||
if value == nil {
|
||||
*dst = NumericArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
} else {
|
||||
*dst = NumericArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = NumericArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for NumericArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = NumericArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to NumericArray", src)
|
||||
}
|
||||
|
||||
*dst = NumericArray{
|
||||
Elements: make([]Numeric, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Numeric, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to NumericArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to NumericArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +263,11 @@ func (dst *NumericArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +302,84 @@ func (dst NumericArray) Get() interface{} {
|
|||
func (src *NumericArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]float32:
|
||||
*v = make([]float32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*float32:
|
||||
*v = make([]*float32, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]float64:
|
||||
*v = make([]float64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*float64:
|
||||
*v = make([]*float64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]int64:
|
||||
*v = make([]int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*int64:
|
||||
*v = make([]*int64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]uint64:
|
||||
*v = make([]uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*uint64:
|
||||
*v = make([]*uint64, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +418,12 @@ func (src *NumericArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +441,14 @@ func (src *NumericArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from NumericArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from NumericArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
text_array.go
188
text_array.go
|
@ -31,56 +31,110 @@ func (dst *TextArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = TextArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TextArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TextArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TextArray", src)
|
||||
}
|
||||
|
||||
*dst = TextArray{
|
||||
Elements: make([]Text, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = TextArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TextArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Text, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Text, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = TextArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = TextArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TextArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Text, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = TextArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Text:
|
||||
if value == nil {
|
||||
*dst = TextArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TextArray{Status: Present}
|
||||
} else {
|
||||
*dst = TextArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = TextArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TextArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TextArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TextArray", src)
|
||||
}
|
||||
|
||||
*dst = TextArray{
|
||||
Elements: make([]Text, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Text, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TextArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TextArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *TextArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst TextArray) Get() interface{} {
|
|||
func (src *TextArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *TextArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *TextArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from TextArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from TextArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
errors "golang.org/x/xerrors"
|
||||
|
@ -31,56 +32,110 @@ func (dst *TimestampArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = TimestampArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TimestampArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TimestampArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TimestampArray", src)
|
||||
}
|
||||
|
||||
*dst = TimestampArray{
|
||||
Elements: make([]Timestamp, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []time.Time:
|
||||
if value == nil {
|
||||
*dst = TimestampArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestampArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Timestamp, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Timestamp, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = TimestampArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*time.Time:
|
||||
if value == nil {
|
||||
*dst = TimestampArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestampArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Timestamp, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = TimestampArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Timestamp:
|
||||
if value == nil {
|
||||
*dst = TimestampArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestampArray{Status: Present}
|
||||
} else {
|
||||
*dst = TimestampArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = TimestampArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TimestampArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TimestampArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TimestampArray", src)
|
||||
}
|
||||
|
||||
*dst = TimestampArray{
|
||||
Elements: make([]Timestamp, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Timestamp, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TimestampArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TimestampArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +150,11 @@ func (dst *TimestampArray) setRecursive(value reflect.Value, index, dimension in
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +189,30 @@ func (dst TimestampArray) Get() interface{} {
|
|||
func (src *TimestampArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]time.Time:
|
||||
*v = make([]time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*time.Time:
|
||||
*v = make([]*time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +251,12 @@ func (src *TimestampArray) assignToRecursive(value reflect.Value, index, dimensi
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +274,14 @@ func (src *TimestampArray) assignToRecursive(value reflect.Value, index, dimensi
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from TimestampArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from TimestampArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgio"
|
||||
errors "golang.org/x/xerrors"
|
||||
|
@ -31,56 +32,110 @@ func (dst *TimestamptzArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = TimestamptzArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TimestamptzArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TimestamptzArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TimestamptzArray", src)
|
||||
}
|
||||
|
||||
*dst = TimestamptzArray{
|
||||
Elements: make([]Timestamptz, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []time.Time:
|
||||
if value == nil {
|
||||
*dst = TimestamptzArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestamptzArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Timestamptz, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Timestamptz, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = TimestamptzArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*time.Time:
|
||||
if value == nil {
|
||||
*dst = TimestamptzArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestamptzArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Timestamptz, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = TimestamptzArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Timestamptz:
|
||||
if value == nil {
|
||||
*dst = TimestamptzArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TimestamptzArray{Status: Present}
|
||||
} else {
|
||||
*dst = TimestamptzArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = TimestamptzArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TimestamptzArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TimestamptzArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TimestamptzArray", src)
|
||||
}
|
||||
|
||||
*dst = TimestamptzArray{
|
||||
Elements: make([]Timestamptz, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Timestamptz, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TimestamptzArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TimestamptzArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +150,11 @@ func (dst *TimestamptzArray) setRecursive(value reflect.Value, index, dimension
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +189,30 @@ func (dst TimestamptzArray) Get() interface{} {
|
|||
func (src *TimestamptzArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]time.Time:
|
||||
*v = make([]time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*time.Time:
|
||||
*v = make([]*time.Time, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +251,12 @@ func (src *TimestamptzArray) assignToRecursive(value reflect.Value, index, dimen
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +274,14 @@ func (src *TimestamptzArray) assignToRecursive(value reflect.Value, index, dimen
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from TimestamptzArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from TimestamptzArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
|
@ -31,56 +31,72 @@ func (dst *TstzrangeArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = TstzrangeArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TstzrangeArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TstzrangeArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TstzrangeArray", src)
|
||||
}
|
||||
|
||||
*dst = TstzrangeArray{
|
||||
Elements: make([]Tstzrange, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
case []Tstzrange:
|
||||
if value == nil {
|
||||
*dst = TstzrangeArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = TstzrangeArray{Status: Present}
|
||||
} else {
|
||||
*dst = TstzrangeArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
dst.Elements = make([]Tstzrange, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = TstzrangeArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for TstzrangeArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = TstzrangeArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to TstzrangeArray", src)
|
||||
}
|
||||
|
||||
*dst = TstzrangeArray{
|
||||
Elements: make([]Tstzrange, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Tstzrange, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TstzrangeArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to TstzrangeArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +111,11 @@ func (dst *TstzrangeArray) setRecursive(value reflect.Value, index, dimension in
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +150,21 @@ func (dst TstzrangeArray) Get() interface{} {
|
|||
func (src *TstzrangeArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]Tstzrange:
|
||||
*v = make([]Tstzrange, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +203,12 @@ func (src *TstzrangeArray) assignToRecursive(value reflect.Value, index, dimensi
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +226,14 @@ func (src *TstzrangeArray) assignToRecursive(value reflect.Value, index, dimensi
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from TstzrangeArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from TstzrangeArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
|
@ -30,56 +30,93 @@ func (dst *<%= pgtype_array_type %>) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = <%= pgtype_array_type %>{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for <%= pgtype_array_type %>", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = <%= pgtype_array_type %>{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to <%= pgtype_array_type %>", src)
|
||||
}
|
||||
|
||||
*dst = <%= pgtype_array_type %> {
|
||||
Elements: make([]<%= pgtype_element_type %>, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
switch value := src.(type) {
|
||||
<% go_array_types.split(",").each do |t| %>
|
||||
<% if t != "[]#{pgtype_element_type}" %>
|
||||
case <%= t %>:
|
||||
if value == nil {
|
||||
*dst = <%= pgtype_array_type %>{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = <%= pgtype_array_type %>{Status: Present}
|
||||
} else {
|
||||
elements := make([]<%= pgtype_element_type %>, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]<%= pgtype_element_type %>, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = <%= pgtype_array_type %>{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
<% end %>
|
||||
<% end %>
|
||||
case []<%= pgtype_element_type %>:
|
||||
if value == nil {
|
||||
*dst = <%= pgtype_array_type %>{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = <%= pgtype_array_type %>{Status: Present}
|
||||
} else {
|
||||
*dst = <%= pgtype_array_type %>{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status : Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = <%= pgtype_array_type %>{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for <%= pgtype_array_type %>", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = <%= pgtype_array_type %>{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to <%= pgtype_array_type %>", src)
|
||||
}
|
||||
|
||||
*dst = <%= pgtype_array_type %> {
|
||||
Elements: make([]<%= pgtype_element_type %>, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]<%= pgtype_element_type %>, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to <%= pgtype_array_type %>, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to <%= pgtype_array_type %>, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -94,10 +131,11 @@ func (dst *<%= pgtype_array_type %>) setRecursive(value reflect.Value, index, di
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -132,6 +170,21 @@ func (dst <%= pgtype_array_type %>) Get() interface{} {
|
|||
func (src *<%= pgtype_array_type %>) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1{
|
||||
switch v := dst.(type) {
|
||||
<% go_array_types.split(",").each do |t| %>
|
||||
case *<%= t %>:
|
||||
*v = make(<%= t %>, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
<% end %>
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -170,10 +223,12 @@ func (src *<%= pgtype_array_type %>) assignToRecursive(value reflect.Value, inde
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -191,11 +246,14 @@ func (src *<%= pgtype_array_type %>) assignToRecursive(value reflect.Value, inde
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr(){
|
||||
return 0, errors.Errorf("cannot assign all values from <%= pgtype_array_type %>")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from <%= pgtype_array_type %>")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
erb pgtype_array_type=Int2Array pgtype_element_type=Int2 element_type_name=int2 text_null=NULL binary_format=true typed_array.go.erb > int2_array.go
|
||||
erb pgtype_array_type=Int4Array pgtype_element_type=Int4 element_type_name=int4 text_null=NULL binary_format=true typed_array.go.erb > int4_array.go
|
||||
erb pgtype_array_type=Int8Array pgtype_element_type=Int8 element_type_name=int8 text_null=NULL binary_format=true typed_array.go.erb > int8_array.go
|
||||
erb pgtype_array_type=BoolArray pgtype_element_type=Bool element_type_name=bool text_null=NULL binary_format=true typed_array.go.erb > bool_array.go
|
||||
erb pgtype_array_type=DateArray pgtype_element_type=Date element_type_name=date text_null=NULL binary_format=true typed_array.go.erb > date_array.go
|
||||
erb pgtype_array_type=TimestamptzArray pgtype_element_type=Timestamptz element_type_name=timestamptz text_null=NULL binary_format=true typed_array.go.erb > timestamptz_array.go
|
||||
erb pgtype_array_type=TstzrangeArray pgtype_element_type=Tstzrange element_type_name=tstzrange text_null=NULL binary_format=true typed_array.go.erb > tstzrange_array.go
|
||||
erb pgtype_array_type=TimestampArray pgtype_element_type=Timestamp element_type_name=timestamp text_null=NULL binary_format=true typed_array.go.erb > timestamp_array.go
|
||||
erb pgtype_array_type=Float4Array pgtype_element_type=Float4 element_type_name=float4 text_null=NULL binary_format=true typed_array.go.erb > float4_array.go
|
||||
erb pgtype_array_type=Float8Array pgtype_element_type=Float8 element_type_name=float8 text_null=NULL binary_format=true typed_array.go.erb > float8_array.go
|
||||
erb pgtype_array_type=InetArray pgtype_element_type=Inet element_type_name=inet text_null=NULL binary_format=true typed_array.go.erb > inet_array.go
|
||||
erb pgtype_array_type=MacaddrArray pgtype_element_type=Macaddr element_type_name=macaddr text_null=NULL binary_format=true typed_array.go.erb > macaddr_array.go
|
||||
erb pgtype_array_type=CIDRArray pgtype_element_type=CIDR element_type_name=cidr text_null=NULL binary_format=true typed_array.go.erb > cidr_array.go
|
||||
erb pgtype_array_type=TextArray pgtype_element_type=Text element_type_name=text text_null=NULL binary_format=true typed_array.go.erb > text_array.go
|
||||
erb pgtype_array_type=VarcharArray pgtype_element_type=Varchar element_type_name=varchar text_null=NULL binary_format=true typed_array.go.erb > varchar_array.go
|
||||
erb pgtype_array_type=BPCharArray pgtype_element_type=BPChar element_type_name=bpchar text_null=NULL binary_format=true typed_array.go.erb > bpchar_array.go
|
||||
erb pgtype_array_type=ByteaArray pgtype_element_type=Bytea element_type_name=bytea text_null=NULL binary_format=true typed_array.go.erb > bytea_array.go
|
||||
erb pgtype_array_type=ACLItemArray pgtype_element_type=ACLItem element_type_name=aclitem text_null=NULL binary_format=false typed_array.go.erb > aclitem_array.go
|
||||
erb pgtype_array_type=HstoreArray pgtype_element_type=Hstore element_type_name=hstore text_null=NULL binary_format=true typed_array.go.erb > hstore_array.go
|
||||
erb pgtype_array_type=NumericArray pgtype_element_type=Numeric element_type_name=numeric text_null=NULL binary_format=true typed_array.go.erb > numeric_array.go
|
||||
erb pgtype_array_type=UUIDArray pgtype_element_type=UUID element_type_name=uuid text_null=NULL binary_format=true typed_array.go.erb > uuid_array.go
|
||||
erb pgtype_array_type=JSONBArray pgtype_element_type=Text element_type_name=text text_null=NULL binary_format=true typed_array.go.erb > jsonb_array.go
|
||||
erb pgtype_array_type=Int2Array pgtype_element_type=Int2 go_array_types=[]int16,[]*int16,[]uint16,[]*uint16,[]int32,[]*int32,[]uint32,[]*uint32,[]int64,[]*int64,[]uint64,[]*uint64,[]int,[]*int,[]uint,[]*uint element_type_name=int2 text_null=NULL binary_format=true typed_array.go.erb > int2_array.go
|
||||
erb pgtype_array_type=Int4Array pgtype_element_type=Int4 go_array_types=[]int16,[]*int16,[]uint16,[]*uint16,[]int32,[]*int32,[]uint32,[]*uint32,[]int64,[]*int64,[]uint64,[]*uint64,[]int,[]*int,[]uint,[]*uint element_type_name=int4 text_null=NULL binary_format=true typed_array.go.erb > int4_array.go
|
||||
erb pgtype_array_type=Int8Array pgtype_element_type=Int8 go_array_types=[]int16,[]*int16,[]uint16,[]*uint16,[]int32,[]*int32,[]uint32,[]*uint32,[]int64,[]*int64,[]uint64,[]*uint64,[]int,[]*int,[]uint,[]*uint element_type_name=int8 text_null=NULL binary_format=true typed_array.go.erb > int8_array.go
|
||||
erb pgtype_array_type=BoolArray pgtype_element_type=Bool go_array_types=[]bool,[]*bool element_type_name=bool text_null=NULL binary_format=true typed_array.go.erb > bool_array.go
|
||||
erb pgtype_array_type=DateArray pgtype_element_type=Date go_array_types=[]time.Time,[]*time.Time element_type_name=date text_null=NULL binary_format=true typed_array.go.erb > date_array.go
|
||||
erb pgtype_array_type=TimestamptzArray pgtype_element_type=Timestamptz go_array_types=[]time.Time,[]*time.Time element_type_name=timestamptz text_null=NULL binary_format=true typed_array.go.erb > timestamptz_array.go
|
||||
erb pgtype_array_type=TstzrangeArray pgtype_element_type=Tstzrange go_array_types=[]Tstzrange element_type_name=tstzrange text_null=NULL binary_format=true typed_array.go.erb > tstzrange_array.go
|
||||
erb pgtype_array_type=TimestampArray pgtype_element_type=Timestamp go_array_types=[]time.Time,[]*time.Time element_type_name=timestamp text_null=NULL binary_format=true typed_array.go.erb > timestamp_array.go
|
||||
erb pgtype_array_type=Float4Array pgtype_element_type=Float4 go_array_types=[]float32,[]*float32 element_type_name=float4 text_null=NULL binary_format=true typed_array.go.erb > float4_array.go
|
||||
erb pgtype_array_type=Float8Array pgtype_element_type=Float8 go_array_types=[]float64,[]*float64 element_type_name=float8 text_null=NULL binary_format=true typed_array.go.erb > float8_array.go
|
||||
erb pgtype_array_type=InetArray pgtype_element_type=Inet go_array_types=[]*net.IPNet,[]net.IP,[]*net.IP element_type_name=inet text_null=NULL binary_format=true typed_array.go.erb > inet_array.go
|
||||
erb pgtype_array_type=MacaddrArray pgtype_element_type=Macaddr go_array_types=[]net.HardwareAddr,[]*net.HardwareAddr element_type_name=macaddr text_null=NULL binary_format=true typed_array.go.erb > macaddr_array.go
|
||||
erb pgtype_array_type=CIDRArray pgtype_element_type=CIDR go_array_types=[]*net.IPNet,[]net.IP,[]*net.IP element_type_name=cidr text_null=NULL binary_format=true typed_array.go.erb > cidr_array.go
|
||||
erb pgtype_array_type=TextArray pgtype_element_type=Text go_array_types=[]string,[]*string element_type_name=text text_null=NULL binary_format=true typed_array.go.erb > text_array.go
|
||||
erb pgtype_array_type=VarcharArray pgtype_element_type=Varchar go_array_types=[]string,[]*string element_type_name=varchar text_null=NULL binary_format=true typed_array.go.erb > varchar_array.go
|
||||
erb pgtype_array_type=BPCharArray pgtype_element_type=BPChar go_array_types=[]string,[]*string element_type_name=bpchar text_null=NULL binary_format=true typed_array.go.erb > bpchar_array.go
|
||||
erb pgtype_array_type=ByteaArray pgtype_element_type=Bytea go_array_types=[][]byte element_type_name=bytea text_null=NULL binary_format=true typed_array.go.erb > bytea_array.go
|
||||
erb pgtype_array_type=ACLItemArray pgtype_element_type=ACLItem go_array_types=[]string,[]*string element_type_name=aclitem text_null=NULL binary_format=false typed_array.go.erb > aclitem_array.go
|
||||
erb pgtype_array_type=HstoreArray pgtype_element_type=Hstore go_array_types=[]map[string]string element_type_name=hstore text_null=NULL binary_format=true typed_array.go.erb > hstore_array.go
|
||||
erb pgtype_array_type=NumericArray pgtype_element_type=Numeric go_array_types=[]float32,[]*float32,[]float64,[]*float64,[]int64,[]*int64,[]uint64,[]*uint64 element_type_name=numeric text_null=NULL binary_format=true typed_array.go.erb > numeric_array.go
|
||||
erb pgtype_array_type=UUIDArray pgtype_element_type=UUID go_array_types=[][16]byte,[][]byte,[]string,[]*string element_type_name=uuid text_null=NULL binary_format=true typed_array.go.erb > uuid_array.go
|
||||
erb pgtype_array_type=JSONBArray pgtype_element_type=Text go_array_types=[]string element_type_name=text text_null=NULL binary_format=true typed_array.go.erb > jsonb_array.go
|
||||
|
||||
# While the binary format is theoretically possible it is only practical to use the text format.
|
||||
erb pgtype_array_type=EnumArray pgtype_element_type=GenericText text_null=NULL binary_format=false typed_array.go.erb > enum_array.go
|
||||
erb pgtype_array_type=EnumArray pgtype_element_type=GenericText go_array_types=[]string,[]*string text_null=NULL binary_format=false typed_array.go.erb > enum_array.go
|
||||
|
||||
goimports -w *_array.go
|
||||
|
|
244
uuid_array.go
244
uuid_array.go
|
@ -31,56 +31,148 @@ func (dst *UUIDArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for UUIDArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to UUIDArray", src)
|
||||
}
|
||||
|
||||
*dst = UUIDArray{
|
||||
Elements: make([]UUID, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case [][16]byte:
|
||||
if value == nil {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]UUID, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]UUID, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = UUIDArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case [][]byte:
|
||||
if value == nil {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]UUID, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = UUIDArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]UUID, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = UUIDArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]UUID, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = UUIDArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []UUID:
|
||||
if value == nil {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
} else {
|
||||
*dst = UUIDArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = UUIDArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for UUIDArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = UUIDArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to UUIDArray", src)
|
||||
}
|
||||
|
||||
*dst = UUIDArray{
|
||||
Elements: make([]UUID, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]UUID, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to UUIDArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to UUIDArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +187,11 @@ func (dst *UUIDArray) setRecursive(value reflect.Value, index, dimension int) (i
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +226,48 @@ func (dst UUIDArray) Get() interface{} {
|
|||
func (src *UUIDArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[][16]byte:
|
||||
*v = make([][16]byte, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[][]byte:
|
||||
*v = make([][]byte, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +306,12 @@ func (src *UUIDArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +329,14 @@ func (src *UUIDArray) assignToRecursive(value reflect.Value, index, dimension in
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from UUIDArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from UUIDArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
188
varchar_array.go
188
varchar_array.go
|
@ -31,56 +31,110 @@ func (dst *VarcharArray) Set(src interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(src)
|
||||
if !value.IsValid() || value.IsZero() {
|
||||
*dst = VarcharArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
switch value := src.(type) {
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflect.ValueOf(src), nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for VarcharArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = VarcharArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to VarcharArray", src)
|
||||
}
|
||||
|
||||
*dst = VarcharArray{
|
||||
Elements: make([]Varchar, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
case []string:
|
||||
if value == nil {
|
||||
*dst = VarcharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = VarcharArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Varchar, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Varchar, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflect.ValueOf(src), 0, 0)
|
||||
if err != nil {
|
||||
*dst = VarcharArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []*string:
|
||||
if value == nil {
|
||||
*dst = VarcharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = VarcharArray{Status: Present}
|
||||
} else {
|
||||
elements := make([]Varchar, len(value))
|
||||
for i := range value {
|
||||
if err := elements[i].Set(value[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*dst = VarcharArray{
|
||||
Elements: elements,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
|
||||
case []Varchar:
|
||||
if value == nil {
|
||||
*dst = VarcharArray{Status: Null}
|
||||
} else if len(value) == 0 {
|
||||
*dst = VarcharArray{Status: Present}
|
||||
} else {
|
||||
*dst = VarcharArray{
|
||||
Elements: value,
|
||||
Dimensions: []ArrayDimension{{Length: int32(len(value)), LowerBound: 1}},
|
||||
Status: Present,
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflectedValue := reflect.ValueOf(src)
|
||||
if !reflectedValue.IsValid() || reflectedValue.IsZero() {
|
||||
*dst = VarcharArray{Status: Null}
|
||||
return nil
|
||||
}
|
||||
|
||||
dimensions, elementsLength, ok := findDimensionsFromValue(reflectedValue, nil, 0)
|
||||
if !ok {
|
||||
return errors.Errorf("cannot find dimensions of %v for VarcharArray", src)
|
||||
}
|
||||
if elementsLength == 0 {
|
||||
*dst = VarcharArray{Status: Present}
|
||||
return nil
|
||||
}
|
||||
if len(dimensions) == 0 {
|
||||
if originalSrc, ok := underlyingSliceType(src); ok {
|
||||
return dst.Set(originalSrc)
|
||||
}
|
||||
return errors.Errorf("cannot convert %v to VarcharArray", src)
|
||||
}
|
||||
|
||||
*dst = VarcharArray{
|
||||
Elements: make([]Varchar, elementsLength),
|
||||
Dimensions: dimensions,
|
||||
Status: Present,
|
||||
}
|
||||
elementCount, err := dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
// Maybe the target was one dimension too far, try again:
|
||||
if len(dst.Dimensions) > 1 {
|
||||
dst.Dimensions = dst.Dimensions[:len(dst.Dimensions)-1]
|
||||
elementsLength = 0
|
||||
for _, dim := range dst.Dimensions {
|
||||
if elementsLength == 0 {
|
||||
elementsLength = int(dim.Length)
|
||||
} else {
|
||||
elementsLength *= int(dim.Length)
|
||||
}
|
||||
}
|
||||
dst.Elements = make([]Varchar, elementsLength)
|
||||
elementCount, err = dst.setRecursive(reflectedValue, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to VarcharArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
if elementCount != len(dst.Elements) {
|
||||
return errors.Errorf("cannot convert %v to VarcharArray, expected %d dst.Elements, but got %d instead", src, len(dst.Elements), elementCount)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -95,10 +149,11 @@ func (dst *VarcharArray) setRecursive(value reflect.Value, index, dimension int)
|
|||
break
|
||||
}
|
||||
|
||||
if int32(value.Len()) != dst.Dimensions[dimension].Length {
|
||||
valueLen := value.Len()
|
||||
if int32(valueLen) != dst.Dimensions[dimension].Length {
|
||||
return 0, errors.Errorf("multidimensional arrays must have array expressions with matching dimensions")
|
||||
}
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
for i := 0; i < valueLen; i++ {
|
||||
var err error
|
||||
index, err = dst.setRecursive(value.Index(i), index, dimension+1)
|
||||
if err != nil {
|
||||
|
@ -133,6 +188,30 @@ func (dst VarcharArray) Get() interface{} {
|
|||
func (src *VarcharArray) AssignTo(dst interface{}) error {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
if len(src.Dimensions) == 1 {
|
||||
switch v := dst.(type) {
|
||||
|
||||
case *[]string:
|
||||
*v = make([]string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case *[]*string:
|
||||
*v = make([]*string, len(src.Elements))
|
||||
for i := range src.Elements {
|
||||
if err := src.Elements[i].AssignTo(&((*v)[i])); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(dst)
|
||||
if value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
|
@ -171,10 +250,12 @@ func (src *VarcharArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
|
||||
length := int(src.Dimensions[dimension].Length)
|
||||
if reflect.Array == kind {
|
||||
if value.Type().Len() != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, value.Type(), value.Type().Len())
|
||||
typ := value.Type()
|
||||
typLen := typ.Len()
|
||||
if typLen != length {
|
||||
return 0, errors.Errorf("expected size %d array, but %s has size %d array", length, typ, typLen)
|
||||
}
|
||||
value.Set(reflect.New(value.Type()).Elem())
|
||||
value.Set(reflect.New(typ).Elem())
|
||||
} else {
|
||||
value.Set(reflect.MakeSlice(value.Type(), length, length))
|
||||
}
|
||||
|
@ -192,11 +273,14 @@ func (src *VarcharArray) assignToRecursive(value reflect.Value, index, dimension
|
|||
if len(src.Dimensions) != dimension {
|
||||
return 0, errors.Errorf("incorrect dimensions, expected %d, found %d", len(src.Dimensions), dimension)
|
||||
}
|
||||
if !value.CanAddr() || !value.Addr().CanInterface() {
|
||||
if !value.CanAddr() {
|
||||
return 0, errors.Errorf("cannot assign all values from VarcharArray")
|
||||
}
|
||||
err := src.Elements[index].AssignTo(value.Addr().Interface())
|
||||
if err != nil {
|
||||
addr := value.Addr()
|
||||
if !addr.CanInterface() {
|
||||
return 0, errors.Errorf("cannot assign all values from VarcharArray")
|
||||
}
|
||||
if err := src.Elements[index].AssignTo(addr.Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
index++
|
||||
|
|
Loading…
Reference in New Issue