diff --git a/CHANGELOG.md b/CHANGELOG.md index 0152bed1..162a7f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/pgtype/array.go b/pgtype/array.go index d34a94e5..93f5aa9b 100644 --- a/pgtype/array.go +++ b/pgtype/array.go @@ -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) } diff --git a/pgtype/array_codec.go b/pgtype/array_codec.go index 8aab13bb..8ed45da5 100644 --- a/pgtype/array_codec.go +++ b/pgtype/array_codec.go @@ -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 } diff --git a/pgtype/array_test.go b/pgtype/array_test.go index 8043e12f..f246b346 100644 --- a/pgtype/array_test.go +++ b/pgtype/array_test.go @@ -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 diff --git a/pgtype/doc.go b/pgtype/doc.go index 1de29bd2..9764aabf 100644 --- a/pgtype/doc.go +++ b/pgtype/doc.go @@ -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