Skip to content

Commit 4604d39

Browse files
authored
Merge pull request #876 from Shivam010/master
feature: inbuilt support for for int32/float32/[]byte slices in pq.Array
2 parents 11a44e2 + d726827 commit 4604d39

File tree

3 files changed

+482
-0
lines changed

3 files changed

+482
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
*.test
33
*~
44
*.swp
5+
.idea
6+
.vscode

array.go

+139
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,31 @@ func Array(a interface{}) interface {
3535
return (*BoolArray)(&a)
3636
case []float64:
3737
return (*Float64Array)(&a)
38+
case []float32:
39+
return (*Float32Array)(&a)
3840
case []int64:
3941
return (*Int64Array)(&a)
42+
case []int32:
43+
return (*Int32Array)(&a)
4044
case []string:
4145
return (*StringArray)(&a)
46+
case [][]byte:
47+
return (*ByteaArray)(&a)
4248

4349
case *[]bool:
4450
return (*BoolArray)(a)
4551
case *[]float64:
4652
return (*Float64Array)(a)
53+
case *[]float32:
54+
return (*Float32Array)(a)
4755
case *[]int64:
4856
return (*Int64Array)(a)
57+
case *[]int32:
58+
return (*Int32Array)(a)
4959
case *[]string:
5060
return (*StringArray)(a)
61+
case *[][]byte:
62+
return (*ByteaArray)(a)
5163
}
5264

5365
return GenericArray{a}
@@ -267,6 +279,70 @@ func (a Float64Array) Value() (driver.Value, error) {
267279
return "{}", nil
268280
}
269281

282+
// Float32Array represents a one-dimensional array of the PostgreSQL double
283+
// precision type.
284+
type Float32Array []float32
285+
286+
// Scan implements the sql.Scanner interface.
287+
func (a *Float32Array) Scan(src interface{}) error {
288+
switch src := src.(type) {
289+
case []byte:
290+
return a.scanBytes(src)
291+
case string:
292+
return a.scanBytes([]byte(src))
293+
case nil:
294+
*a = nil
295+
return nil
296+
}
297+
298+
return fmt.Errorf("pq: cannot convert %T to Float32Array", src)
299+
}
300+
301+
func (a *Float32Array) scanBytes(src []byte) error {
302+
elems, err := scanLinearArray(src, []byte{','}, "Float32Array")
303+
if err != nil {
304+
return err
305+
}
306+
if *a != nil && len(elems) == 0 {
307+
*a = (*a)[:0]
308+
} else {
309+
b := make(Float32Array, len(elems))
310+
for i, v := range elems {
311+
var x float64
312+
if x, err = strconv.ParseFloat(string(v), 32); err != nil {
313+
return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
314+
}
315+
b[i] = float32(x)
316+
}
317+
*a = b
318+
}
319+
return nil
320+
}
321+
322+
// Value implements the driver.Valuer interface.
323+
func (a Float32Array) Value() (driver.Value, error) {
324+
if a == nil {
325+
return nil, nil
326+
}
327+
328+
if n := len(a); n > 0 {
329+
// There will be at least two curly brackets, N bytes of values,
330+
// and N-1 bytes of delimiters.
331+
b := make([]byte, 1, 1+2*n)
332+
b[0] = '{'
333+
334+
b = strconv.AppendFloat(b, float64(a[0]), 'f', -1, 32)
335+
for i := 1; i < n; i++ {
336+
b = append(b, ',')
337+
b = strconv.AppendFloat(b, float64(a[i]), 'f', -1, 32)
338+
}
339+
340+
return string(append(b, '}')), nil
341+
}
342+
343+
return "{}", nil
344+
}
345+
270346
// GenericArray implements the driver.Valuer and sql.Scanner interfaces for
271347
// an array or slice of any dimension.
272348
type GenericArray struct{ A interface{} }
@@ -483,6 +559,69 @@ func (a Int64Array) Value() (driver.Value, error) {
483559
return "{}", nil
484560
}
485561

562+
// Int32Array represents a one-dimensional array of the PostgreSQL integer types.
563+
type Int32Array []int32
564+
565+
// Scan implements the sql.Scanner interface.
566+
func (a *Int32Array) Scan(src interface{}) error {
567+
switch src := src.(type) {
568+
case []byte:
569+
return a.scanBytes(src)
570+
case string:
571+
return a.scanBytes([]byte(src))
572+
case nil:
573+
*a = nil
574+
return nil
575+
}
576+
577+
return fmt.Errorf("pq: cannot convert %T to Int32Array", src)
578+
}
579+
580+
func (a *Int32Array) scanBytes(src []byte) error {
581+
elems, err := scanLinearArray(src, []byte{','}, "Int32Array")
582+
if err != nil {
583+
return err
584+
}
585+
if *a != nil && len(elems) == 0 {
586+
*a = (*a)[:0]
587+
} else {
588+
b := make(Int32Array, len(elems))
589+
for i, v := range elems {
590+
var x int
591+
if x, err = strconv.Atoi(string(v)); err != nil {
592+
return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
593+
}
594+
b[i] = int32(x)
595+
}
596+
*a = b
597+
}
598+
return nil
599+
}
600+
601+
// Value implements the driver.Valuer interface.
602+
func (a Int32Array) Value() (driver.Value, error) {
603+
if a == nil {
604+
return nil, nil
605+
}
606+
607+
if n := len(a); n > 0 {
608+
// There will be at least two curly brackets, N bytes of values,
609+
// and N-1 bytes of delimiters.
610+
b := make([]byte, 1, 1+2*n)
611+
b[0] = '{'
612+
613+
b = strconv.AppendInt(b, int64(a[0]), 10)
614+
for i := 1; i < n; i++ {
615+
b = append(b, ',')
616+
b = strconv.AppendInt(b, int64(a[i]), 10)
617+
}
618+
619+
return string(append(b, '}')), nil
620+
}
621+
622+
return "{}", nil
623+
}
624+
486625
// StringArray represents a one-dimensional array of the PostgreSQL character types.
487626
type StringArray []string
488627

0 commit comments

Comments
 (0)