mirror of
https://github.com/jackc/pgx.git
synced 2025-05-29 18:53:50 +00:00
Make array helpers private
This commit is contained in:
parent
1c90746cf5
commit
cc7de81d3b
@ -97,6 +97,7 @@ This matches the convention set by `database/sql`. In addition, for comparable t
|
||||
* Renamed `pgtype.DataType` to `pgtype.Type`.
|
||||
* Renamed `pgtype.None` to `pgtype.Finite`.
|
||||
* `RegisterType` now accepts a `*Type` instead of `Type`.
|
||||
* Assorted array helper methods and types made private.
|
||||
|
||||
## stdlib
|
||||
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
// src/include/utils/array.h and src/backend/utils/adt/arrayfuncs.c. Of
|
||||
// particular interest is the array_send function.
|
||||
|
||||
type ArrayHeader struct {
|
||||
type arrayHeader struct {
|
||||
ContainsNull bool
|
||||
ElementOID uint32
|
||||
Dimensions []ArrayDimension
|
||||
@ -42,7 +42,7 @@ func cardinality(dimensions []ArrayDimension) int {
|
||||
return elementCount
|
||||
}
|
||||
|
||||
func (dst *ArrayHeader) DecodeBinary(m *Map, src []byte) (int, error) {
|
||||
func (dst *arrayHeader) DecodeBinary(m *Map, src []byte) (int, error) {
|
||||
if len(src) < 12 {
|
||||
return 0, fmt.Errorf("array header too short: %d", len(src))
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (dst *ArrayHeader) DecodeBinary(m *Map, src []byte) (int, error) {
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
func (src ArrayHeader) EncodeBinary(buf []byte) []byte {
|
||||
func (src arrayHeader) EncodeBinary(buf []byte) []byte {
|
||||
buf = pgio.AppendInt32(buf, int32(len(src.Dimensions)))
|
||||
|
||||
var containsNull int32
|
||||
@ -92,14 +92,14 @@ func (src ArrayHeader) EncodeBinary(buf []byte) []byte {
|
||||
return buf
|
||||
}
|
||||
|
||||
type UntypedTextArray struct {
|
||||
type untypedTextArray struct {
|
||||
Elements []string
|
||||
Quoted []bool
|
||||
Dimensions []ArrayDimension
|
||||
}
|
||||
|
||||
func ParseUntypedTextArray(src string) (*UntypedTextArray, error) {
|
||||
dst := &UntypedTextArray{
|
||||
func parseUntypedTextArray(src string) (*untypedTextArray, error) {
|
||||
dst := &untypedTextArray{
|
||||
Elements: []string{},
|
||||
Quoted: []bool{},
|
||||
Dimensions: []ArrayDimension{},
|
||||
@ -333,7 +333,7 @@ func arrayParseInteger(buf *bytes.Buffer) (int32, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func EncodeTextArrayDimensions(buf []byte, dimensions []ArrayDimension) []byte {
|
||||
func encodeTextArrayDimensions(buf []byte, dimensions []ArrayDimension) []byte {
|
||||
var customDimensions bool
|
||||
for _, dim := range dimensions {
|
||||
if dim.LowerBound != 1 {
|
||||
@ -367,7 +367,7 @@ func isSpace(ch byte) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\f'
|
||||
}
|
||||
|
||||
func QuoteArrayElementIfNeeded(src string) string {
|
||||
func quoteArrayElementIfNeeded(src string) string {
|
||||
if src == "" || (len(src) == 4 && strings.ToLower(src) == "null") || isSpace(src[0]) || isSpace(src[len(src)-1]) || strings.ContainsAny(src, `{},"\`) {
|
||||
return quoteArrayElement(src)
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (p *encodePlanArrayCodecText) Encode(value any, buf []byte) (newBuf []byte,
|
||||
return append(buf, '{', '}'), nil
|
||||
}
|
||||
|
||||
buf = EncodeTextArrayDimensions(buf, dimensions)
|
||||
buf = encodeTextArrayDimensions(buf, dimensions)
|
||||
|
||||
// dimElemCounts is the multiples of elements that each array lies on. For
|
||||
// example, a single dimension array of length 4 would have a dimElemCounts of
|
||||
@ -138,7 +138,7 @@ func (p *encodePlanArrayCodecText) Encode(value any, buf []byte) (newBuf []byte,
|
||||
if elemBuf == nil {
|
||||
buf = append(buf, `NULL`...)
|
||||
} else {
|
||||
buf = append(buf, QuoteArrayElementIfNeeded(string(elemBuf))...)
|
||||
buf = append(buf, quoteArrayElementIfNeeded(string(elemBuf))...)
|
||||
}
|
||||
|
||||
for _, dec := range dimElemCounts {
|
||||
@ -165,7 +165,7 @@ func (p *encodePlanArrayCodecBinary) Encode(value any, buf []byte) (newBuf []byt
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
arrayHeader := ArrayHeader{
|
||||
arrayHeader := arrayHeader{
|
||||
Dimensions: dimensions,
|
||||
ElementOID: p.ac.ElementType.OID,
|
||||
}
|
||||
@ -232,7 +232,7 @@ func (c *ArrayCodec) PlanScan(m *Map, oid uint32, format int16, target any) Scan
|
||||
}
|
||||
|
||||
func (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte, array ArraySetter) error {
|
||||
var arrayHeader ArrayHeader
|
||||
var arrayHeader arrayHeader
|
||||
rp, err := arrayHeader.DecodeBinary(m, src)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -272,7 +272,7 @@ func (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte, array Arr
|
||||
}
|
||||
|
||||
func (c *ArrayCodec) decodeText(m *Map, arrayOID uint32, src []byte, array ArraySetter) error {
|
||||
uta, err := ParseUntypedTextArray(string(src))
|
||||
uta, err := parseUntypedTextArray(string(src))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,79 +1,77 @@
|
||||
package pgtype_test
|
||||
package pgtype
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func TestParseUntypedTextArray(t *testing.T) {
|
||||
tests := []struct {
|
||||
source string
|
||||
result pgtype.UntypedTextArray
|
||||
result untypedTextArray
|
||||
}{
|
||||
{
|
||||
source: "{}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{},
|
||||
Quoted: []bool{},
|
||||
Dimensions: []pgtype.ArrayDimension{},
|
||||
Dimensions: []ArrayDimension{},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: "{1}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"1"},
|
||||
Quoted: []bool{false},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: "{a,b}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"a", "b"},
|
||||
Quoted: []bool{false, false},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 2, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: `{"NULL"}`,
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"NULL"},
|
||||
Quoted: []bool{true},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: `{""}`,
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{""},
|
||||
Quoted: []bool{true},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: `{"He said, \"Hello.\""}`,
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{`He said, "Hello."`},
|
||||
Quoted: []bool{true},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 1, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: "{{a,b},{c,d},{e,f}}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"a", "b", "c", "d", "e", "f"},
|
||||
Quoted: []bool{false, false, false, false, false, false},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}},
|
||||
Dimensions: []ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: "{{{a,b},{c,d},{e,f}},{{a,b},{c,d},{e,f}}}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"},
|
||||
Quoted: []bool{false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
Dimensions: []pgtype.ArrayDimension{
|
||||
Dimensions: []ArrayDimension{
|
||||
{Length: 2, LowerBound: 1},
|
||||
{Length: 3, LowerBound: 1},
|
||||
{Length: 2, LowerBound: 1},
|
||||
@ -82,18 +80,18 @@ func TestParseUntypedTextArray(t *testing.T) {
|
||||
},
|
||||
{
|
||||
source: "[4:4]={1}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"1"},
|
||||
Quoted: []bool{false},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 1, LowerBound: 4}},
|
||||
Dimensions: []ArrayDimension{{Length: 1, LowerBound: 4}},
|
||||
},
|
||||
},
|
||||
{
|
||||
source: "[4:5][2:3]={{a,b},{c,d}}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"a", "b", "c", "d"},
|
||||
Quoted: []bool{false, false, false, false},
|
||||
Dimensions: []pgtype.ArrayDimension{
|
||||
Dimensions: []ArrayDimension{
|
||||
{Length: 2, LowerBound: 4},
|
||||
{Length: 2, LowerBound: 2},
|
||||
},
|
||||
@ -101,16 +99,16 @@ func TestParseUntypedTextArray(t *testing.T) {
|
||||
},
|
||||
{
|
||||
source: "[-4:-2]={1,2,3}",
|
||||
result: pgtype.UntypedTextArray{
|
||||
result: untypedTextArray{
|
||||
Elements: []string{"1", "2", "3"},
|
||||
Quoted: []bool{false, false, false},
|
||||
Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: -4}},
|
||||
Dimensions: []ArrayDimension{{Length: 3, LowerBound: -4}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
r, err := pgtype.ParseUntypedTextArray(tt.source)
|
||||
r, err := parseUntypedTextArray(tt.source)
|
||||
if err != nil {
|
||||
t.Errorf("%d: %v", i, err)
|
||||
continue
|
||||
|
@ -13,7 +13,7 @@ pgtype automatically marshals and unmarshals data from json and jsonb PostgreSQL
|
||||
Array Support
|
||||
|
||||
ArrayCodec implements support for arrays. If pgtype supports type T then it can easily support []T by registering an
|
||||
ArrayCodec for the appropriate PostgreSQL OID.
|
||||
ArrayCodec for the appropriate PostgreSQL OID. In addition, Array[T] type can support multi-dimensional arrays.
|
||||
|
||||
Composite Support
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user