changed types.JsonArray to support generics
This commit is contained in:
parent
a79f3a7c56
commit
923fc26a31
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
- (@todo docs) Added support for advanced unique constraints and indexes management ([#345](https://github.com/pocketbase/pocketbase/issues/345), [#544](https://github.com/pocketbase/pocketbase/issues/544))
|
- (@todo docs) Added support for advanced unique constraints and indexes management ([#345](https://github.com/pocketbase/pocketbase/issues/345), [#544](https://github.com/pocketbase/pocketbase/issues/544))
|
||||||
|
|
||||||
|
- Deprecated `SchemaField.Unique`. Unique constraints are now managed via indexes.
|
||||||
|
The `Unique` field is a no-op and will be removed in future version.
|
||||||
|
|
||||||
- Optimized single relation lookups.
|
- Optimized single relation lookups.
|
||||||
|
|
||||||
- Normalized record values on `maxSelect` field option change (`select`, `file`, `relation`).
|
- Normalized record values on `maxSelect` field option change (`select`, `file`, `relation`).
|
||||||
|
@ -17,6 +20,9 @@
|
||||||
|
|
||||||
- Added option to explicitly set the record id from the Admin UI ([#2118](https://github.com/pocketbase/pocketbase/issues/2118)).
|
- Added option to explicitly set the record id from the Admin UI ([#2118](https://github.com/pocketbase/pocketbase/issues/2118)).
|
||||||
|
|
||||||
|
- **!** Changed `types.JsonArray` to support specifying a generic type, aka. `types.JsonArray[T]`.
|
||||||
|
If you have previously used `types.JsonArray`, you'll have to update it to `types.JsonArray[any]`.
|
||||||
|
|
||||||
- **!** Registered the `RemoveTrailingSlash` middleware only for the `/api/*` routes since it is causing issues with subpath file serving endpoints ([#2072](https://github.com/pocketbase/pocketbase/issues/2072)).
|
- **!** Registered the `RemoveTrailingSlash` middleware only for the `/api/*` routes since it is causing issues with subpath file serving endpoints ([#2072](https://github.com/pocketbase/pocketbase/issues/2072)).
|
||||||
|
|
||||||
- **!** Changed the request logs `method` value to UPPERCASE, eg. "get" => "GET" ([#1956](https://github.com/pocketbase/pocketbase/discussions/1956)).
|
- **!** Changed the request logs `method` value to UPPERCASE, eg. "get" => "GET" ([#1956](https://github.com/pocketbase/pocketbase/discussions/1956)).
|
||||||
|
|
|
@ -247,9 +247,9 @@ func (dao *Dao) IsRecordValueUnique(
|
||||||
var normalizedVal any
|
var normalizedVal any
|
||||||
switch val := value.(type) {
|
switch val := value.(type) {
|
||||||
case []string:
|
case []string:
|
||||||
normalizedVal = append(types.JsonArray{}, list.ToInterfaceSlice(val)...)
|
normalizedVal = append(types.JsonArray[string]{}, val...)
|
||||||
case []any:
|
case []any:
|
||||||
normalizedVal = append(types.JsonArray{}, val...)
|
normalizedVal = append(types.JsonArray[any]{}, val...)
|
||||||
default:
|
default:
|
||||||
normalizedVal = val
|
normalizedVal = val
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ func normalizeExpands(paths []string) []string {
|
||||||
|
|
||||||
func isRelFieldUnique(collection *models.Collection, fieldName string) bool {
|
func isRelFieldUnique(collection *models.Collection, fieldName string) bool {
|
||||||
for _, idx := range collection.Indexes {
|
for _, idx := range collection.Indexes {
|
||||||
parsed := dbutils.ParseIndex(idx.(string))
|
parsed := dbutils.ParseIndex(idx)
|
||||||
if parsed.Unique && len(parsed.Columns) == 1 && strings.EqualFold(parsed.Columns[0].Name, fieldName) {
|
if parsed.Unique && len(parsed.Columns) == 1 && strings.EqualFold(parsed.Columns[0].Name, fieldName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/pocketbase/pocketbase/tools/dbutils"
|
"github.com/pocketbase/pocketbase/tools/dbutils"
|
||||||
"github.com/pocketbase/pocketbase/tools/list"
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
"github.com/pocketbase/pocketbase/tools/security"
|
"github.com/pocketbase/pocketbase/tools/security"
|
||||||
"github.com/spf13/cast"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SyncRecordTableSchema compares the two provided collections
|
// SyncRecordTableSchema compares the two provided collections
|
||||||
|
@ -309,7 +308,7 @@ func (dao *Dao) dropCollectionIndex(collection *models.Collection) error {
|
||||||
|
|
||||||
return dao.RunInTransaction(func(txDao *Dao) error {
|
return dao.RunInTransaction(func(txDao *Dao) error {
|
||||||
for _, raw := range collection.Indexes {
|
for _, raw := range collection.Indexes {
|
||||||
parsed := dbutils.ParseIndex(cast.ToString(raw))
|
parsed := dbutils.ParseIndex(raw)
|
||||||
|
|
||||||
if !parsed.IsValid() {
|
if !parsed.IsValid() {
|
||||||
continue
|
continue
|
||||||
|
@ -342,8 +341,7 @@ func (dao *Dao) createCollectionIndexes(collection *models.Collection) error {
|
||||||
// record table changes
|
// record table changes
|
||||||
errs := validation.Errors{}
|
errs := validation.Errors{}
|
||||||
for i, idx := range collection.Indexes {
|
for i, idx := range collection.Indexes {
|
||||||
idxString := cast.ToString(idx)
|
parsed := dbutils.ParseIndex(idx)
|
||||||
parsed := dbutils.ParseIndex(idxString)
|
|
||||||
|
|
||||||
// ensure that the index is always for the current collection
|
// ensure that the index is always for the current collection
|
||||||
parsed.TableName = collection.Name
|
parsed.TableName = collection.Name
|
||||||
|
|
|
@ -40,7 +40,7 @@ func TestSyncRecordTableSchema(t *testing.T) {
|
||||||
Type: schema.FieldTypeEmail,
|
Type: schema.FieldTypeEmail,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
updatedCollection.Indexes = types.JsonArray{"create index idx_title_renamed on anything (title_renamed)"}
|
updatedCollection.Indexes = types.JsonArray[string]{"create index idx_title_renamed on anything (title_renamed)"}
|
||||||
|
|
||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -75,7 +75,7 @@ func TestSyncRecordTableSchema(t *testing.T) {
|
||||||
Type: schema.FieldTypeText,
|
Type: schema.FieldTypeText,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Indexes: types.JsonArray{"create index idx_auth_test on anything (email, username)"},
|
Indexes: types.JsonArray[string]{"create index idx_auth_test on anything (email, username)"},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
[]string{
|
[]string{
|
||||||
|
|
|
@ -27,18 +27,18 @@ type CollectionUpsert struct {
|
||||||
dao *daos.Dao
|
dao *daos.Dao
|
||||||
collection *models.Collection
|
collection *models.Collection
|
||||||
|
|
||||||
Id string `form:"id" json:"id"`
|
Id string `form:"id" json:"id"`
|
||||||
Type string `form:"type" json:"type"`
|
Type string `form:"type" json:"type"`
|
||||||
Name string `form:"name" json:"name"`
|
Name string `form:"name" json:"name"`
|
||||||
System bool `form:"system" json:"system"`
|
System bool `form:"system" json:"system"`
|
||||||
Schema schema.Schema `form:"schema" json:"schema"`
|
Schema schema.Schema `form:"schema" json:"schema"`
|
||||||
Indexes []string `form:"indexes" json:"indexes"`
|
Indexes types.JsonArray[string] `form:"indexes" json:"indexes"`
|
||||||
ListRule *string `form:"listRule" json:"listRule"`
|
ListRule *string `form:"listRule" json:"listRule"`
|
||||||
ViewRule *string `form:"viewRule" json:"viewRule"`
|
ViewRule *string `form:"viewRule" json:"viewRule"`
|
||||||
CreateRule *string `form:"createRule" json:"createRule"`
|
CreateRule *string `form:"createRule" json:"createRule"`
|
||||||
UpdateRule *string `form:"updateRule" json:"updateRule"`
|
UpdateRule *string `form:"updateRule" json:"updateRule"`
|
||||||
DeleteRule *string `form:"deleteRule" json:"deleteRule"`
|
DeleteRule *string `form:"deleteRule" json:"deleteRule"`
|
||||||
Options types.JsonMap `form:"options" json:"options"`
|
Options types.JsonMap `form:"options" json:"options"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCollectionUpsert creates a new [CollectionUpsert] form with initializer
|
// NewCollectionUpsert creates a new [CollectionUpsert] form with initializer
|
||||||
|
@ -59,7 +59,7 @@ func NewCollectionUpsert(app core.App, collection *models.Collection) *Collectio
|
||||||
form.Type = form.collection.Type
|
form.Type = form.collection.Type
|
||||||
form.Name = form.collection.Name
|
form.Name = form.collection.Name
|
||||||
form.System = form.collection.System
|
form.System = form.collection.System
|
||||||
form.Indexes = list.ToUniqueStringSlice(form.collection.Indexes)
|
form.Indexes = form.collection.Indexes
|
||||||
form.ListRule = form.collection.ListRule
|
form.ListRule = form.collection.ListRule
|
||||||
form.ViewRule = form.collection.ViewRule
|
form.ViewRule = form.collection.ViewRule
|
||||||
form.CreateRule = form.collection.CreateRule
|
form.CreateRule = form.collection.CreateRule
|
||||||
|
@ -388,7 +388,7 @@ func (form *CollectionUpsert) checkRule(value any) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (form *CollectionUpsert) checkIndexes(value any) error {
|
func (form *CollectionUpsert) checkIndexes(value any) error {
|
||||||
v, _ := value.([]string)
|
v, _ := value.(types.JsonArray[string])
|
||||||
|
|
||||||
for i, rawIndex := range v {
|
for i, rawIndex := range v {
|
||||||
parsed := dbutils.ParseIndex(rawIndex)
|
parsed := dbutils.ParseIndex(rawIndex)
|
||||||
|
@ -510,12 +510,9 @@ func (form *CollectionUpsert) Submit(interceptors ...InterceptorFunc[*models.Col
|
||||||
form.collection.Schema = form.Schema
|
form.collection.Schema = form.Schema
|
||||||
|
|
||||||
// normalize indexes format
|
// normalize indexes format
|
||||||
form.collection.Indexes = types.JsonArray{}
|
form.collection.Indexes = make(types.JsonArray[string], len(form.Indexes))
|
||||||
for _, rawIdx := range form.Indexes {
|
for i, rawIdx := range form.Indexes {
|
||||||
form.collection.Indexes = append(
|
form.collection.Indexes[i] = dbutils.ParseIndex(rawIdx).Build()
|
||||||
form.collection.Indexes,
|
|
||||||
dbutils.ParseIndex(rawIdx).Build(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ const (
|
||||||
type Collection struct {
|
type Collection struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
Name string `db:"name" json:"name"`
|
Name string `db:"name" json:"name"`
|
||||||
Type string `db:"type" json:"type"`
|
Type string `db:"type" json:"type"`
|
||||||
System bool `db:"system" json:"system"`
|
System bool `db:"system" json:"system"`
|
||||||
Schema schema.Schema `db:"schema" json:"schema"`
|
Schema schema.Schema `db:"schema" json:"schema"`
|
||||||
Indexes types.JsonArray `db:"indexes" json:"indexes"`
|
Indexes types.JsonArray[string] `db:"indexes" json:"indexes"`
|
||||||
|
|
||||||
// rules
|
// rules
|
||||||
ListRule *string `db:"listRule" json:"listRule"`
|
ListRule *string `db:"listRule" json:"listRule"`
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestCollectionMarshalJSON(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unknown type + non empty options",
|
"unknown type + non empty options",
|
||||||
models.Collection{Name: "test", Type: "unknown", ListRule: types.Pointer("test_list"), Options: types.JsonMap{"test": 123}, Indexes: types.JsonArray{"idx_test"}},
|
models.Collection{Name: "test", Type: "unknown", ListRule: types.Pointer("test_list"), Options: types.JsonMap{"test": 123}, Indexes: types.JsonArray[string]{"idx_test"}},
|
||||||
`{"id":"","created":"","updated":"","name":"test","type":"unknown","system":false,"schema":[],"indexes":["idx_test"],"listRule":"test_list","viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{}}`,
|
`{"id":"","created":"","updated":"","name":"test","type":"unknown","system":false,"schema":[],"indexes":["idx_test"],"listRule":"test_list","viewRule":null,"createRule":null,"updateRule":null,"deleteRule":null,"options":{}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -630,16 +630,16 @@ func (m *Record) getNormalizeDataValueForDB(key string) any {
|
||||||
switch ids := val.(type) {
|
switch ids := val.(type) {
|
||||||
case []string:
|
case []string:
|
||||||
// encode string slice
|
// encode string slice
|
||||||
return append(types.JsonArray{}, list.ToInterfaceSlice(ids)...)
|
return append(types.JsonArray[string]{}, ids...)
|
||||||
case []int:
|
case []int:
|
||||||
// encode int slice
|
// encode int slice
|
||||||
return append(types.JsonArray{}, list.ToInterfaceSlice(ids)...)
|
return append(types.JsonArray[int]{}, ids...)
|
||||||
case []float64:
|
case []float64:
|
||||||
// encode float64 slice
|
// encode float64 slice
|
||||||
return append(types.JsonArray{}, list.ToInterfaceSlice(ids)...)
|
return append(types.JsonArray[float64]{}, ids...)
|
||||||
case []any:
|
case []any:
|
||||||
// encode interface slice
|
// encode interface slice
|
||||||
return append(types.JsonArray{}, ids...)
|
return append(types.JsonArray[any]{}, ids...)
|
||||||
default:
|
default:
|
||||||
// no changes
|
// no changes
|
||||||
return val
|
return val
|
||||||
|
|
|
@ -149,7 +149,7 @@ func init() {
|
||||||
collection.Updated = collection.Created
|
collection.Updated = collection.Created
|
||||||
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0 || 'backtick`test' = 0")
|
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0 || 'backtick`test' = 0")
|
||||||
collection.ViewRule = types.Pointer(`id = "1"`)
|
collection.ViewRule = types.Pointer(`id = "1"`)
|
||||||
collection.Indexes = types.JsonArray{"create index test on new_name (id)"}
|
collection.Indexes = types.JsonArray[string]{"create index test on new_name (id)"}
|
||||||
collection.SetOptions(models.CollectionAuthOptions{
|
collection.SetOptions(models.CollectionAuthOptions{
|
||||||
ManageRule: types.Pointer("created > 0"),
|
ManageRule: types.Pointer("created > 0"),
|
||||||
MinPasswordLength: 20,
|
MinPasswordLength: 20,
|
||||||
|
@ -318,7 +318,7 @@ func init() {
|
||||||
collection.Updated = collection.Created
|
collection.Updated = collection.Created
|
||||||
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0 || 'backtick`test' = 0")
|
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0 || 'backtick`test' = 0")
|
||||||
collection.ViewRule = types.Pointer(`id = "1"`)
|
collection.ViewRule = types.Pointer(`id = "1"`)
|
||||||
collection.Indexes = types.JsonArray{"create index test on test456 (id)"}
|
collection.Indexes = types.JsonArray[string]{"create index test on test456 (id)"}
|
||||||
collection.SetOptions(models.CollectionAuthOptions{
|
collection.SetOptions(models.CollectionAuthOptions{
|
||||||
ManageRule: types.Pointer("created > 0"),
|
ManageRule: types.Pointer("created > 0"),
|
||||||
MinPasswordLength: 20,
|
MinPasswordLength: 20,
|
||||||
|
@ -642,7 +642,7 @@ func init() {
|
||||||
collection.Updated = collection.Created
|
collection.Updated = collection.Created
|
||||||
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0")
|
collection.ListRule = types.Pointer("@request.auth.id != '' && created > 0")
|
||||||
collection.ViewRule = types.Pointer(`id = "1"`)
|
collection.ViewRule = types.Pointer(`id = "1"`)
|
||||||
collection.Indexes = types.JsonArray{"create index test1 on test456 (f1_name)"}
|
collection.Indexes = types.JsonArray[string]{"create index test1 on test456 (f1_name)"}
|
||||||
collection.SetOptions(models.CollectionAuthOptions{
|
collection.SetOptions(models.CollectionAuthOptions{
|
||||||
ManageRule: types.Pointer("created > 0"),
|
ManageRule: types.Pointer("created > 0"),
|
||||||
MinPasswordLength: 20,
|
MinPasswordLength: 20,
|
||||||
|
@ -681,7 +681,7 @@ func init() {
|
||||||
collection.Type = models.CollectionTypeBase
|
collection.Type = models.CollectionTypeBase
|
||||||
collection.DeleteRule = types.Pointer(`updated > 0 && @request.auth.id != ''`)
|
collection.DeleteRule = types.Pointer(`updated > 0 && @request.auth.id != ''`)
|
||||||
collection.ListRule = nil
|
collection.ListRule = nil
|
||||||
collection.Indexes = types.JsonArray{
|
collection.Indexes = types.JsonArray[string]{
|
||||||
"create index test1 on test456_update (f1_name)",
|
"create index test1 on test456_update (f1_name)",
|
||||||
}
|
}
|
||||||
collection.NormalizeOptions()
|
collection.NormalizeOptions()
|
||||||
|
|
|
@ -254,7 +254,7 @@ func TestToUniqueStringSlice(t *testing.T) {
|
||||||
{[]any{0, 1, "test", ""}, []string{"0", "1", "test"}},
|
{[]any{0, 1, "test", ""}, []string{"0", "1", "test"}},
|
||||||
{[]string{"test1", "test2", "test1"}, []string{"test1", "test2"}},
|
{[]string{"test1", "test2", "test1"}, []string{"test1", "test2"}},
|
||||||
{`["test1", "test2", "test2"]`, []string{"test1", "test2"}},
|
{`["test1", "test2", "test2"]`, []string{"test1", "test2"}},
|
||||||
{types.JsonArray{"test1", "test2", "test1"}, []string{"test1", "test2"}},
|
{types.JsonArray[string]{"test1", "test2", "test1"}, []string{"test1", "test2"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, scenario := range scenarios {
|
for i, scenario := range scenarios {
|
||||||
|
|
|
@ -7,30 +7,32 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// JsonArray defines a slice that is safe for json and db read/write.
|
// JsonArray defines a slice that is safe for json and db read/write.
|
||||||
type JsonArray []any
|
type JsonArray[T any] []T
|
||||||
|
|
||||||
|
// internal alias to prevent recursion during marshalization.
|
||||||
|
type jsonArrayAlias[T any] JsonArray[T]
|
||||||
|
|
||||||
// MarshalJSON implements the [json.Marshaler] interface.
|
// MarshalJSON implements the [json.Marshaler] interface.
|
||||||
func (m JsonArray) MarshalJSON() ([]byte, error) {
|
func (m JsonArray[T]) MarshalJSON() ([]byte, error) {
|
||||||
type alias JsonArray // prevent recursion
|
|
||||||
|
|
||||||
// initialize an empty map to ensure that `[]` is returned as json
|
// initialize an empty map to ensure that `[]` is returned as json
|
||||||
if m == nil {
|
if m == nil {
|
||||||
m = JsonArray{}
|
m = JsonArray[T]{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Marshal(alias(m))
|
return json.Marshal(jsonArrayAlias[T](m))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value implements the [driver.Valuer] interface.
|
// Value implements the [driver.Valuer] interface.
|
||||||
func (m JsonArray) Value() (driver.Value, error) {
|
func (m JsonArray[T]) Value() (driver.Value, error) {
|
||||||
data, err := json.Marshal(m)
|
data, err := json.Marshal(m)
|
||||||
|
|
||||||
return string(data), err
|
return string(data), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan implements [sql.Scanner] interface to scan the provided value
|
// Scan implements [sql.Scanner] interface to scan the provided value
|
||||||
// into the current `JsonArray` instance.
|
// into the current JsonArray[T] instance.
|
||||||
func (m *JsonArray) Scan(value any) error {
|
func (m *JsonArray[T]) Scan(value any) error {
|
||||||
var data []byte
|
var data []byte
|
||||||
switch v := value.(type) {
|
switch v := value.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
|
|
|
@ -2,6 +2,7 @@ package types_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
|
@ -9,14 +10,14 @@ import (
|
||||||
|
|
||||||
func TestJsonArrayMarshalJSON(t *testing.T) {
|
func TestJsonArrayMarshalJSON(t *testing.T) {
|
||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
json types.JsonArray
|
json json.Marshaler
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{nil, "[]"},
|
{new(types.JsonArray[any]), "[]"},
|
||||||
{types.JsonArray{}, `[]`},
|
{types.JsonArray[any]{}, `[]`},
|
||||||
{types.JsonArray{1, 2, 3}, `[1,2,3]`},
|
{types.JsonArray[int]{1, 2, 3}, `[1,2,3]`},
|
||||||
{types.JsonArray{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
|
{types.JsonArray[string]{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
|
||||||
{types.JsonArray{1, "test"}, `[1,"test"]`},
|
{types.JsonArray[any]{1, "test"}, `[1,"test"]`},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range scenarios {
|
for i, s := range scenarios {
|
||||||
|
@ -33,14 +34,14 @@ func TestJsonArrayMarshalJSON(t *testing.T) {
|
||||||
|
|
||||||
func TestJsonArrayValue(t *testing.T) {
|
func TestJsonArrayValue(t *testing.T) {
|
||||||
scenarios := []struct {
|
scenarios := []struct {
|
||||||
json types.JsonArray
|
json driver.Valuer
|
||||||
expected driver.Value
|
expected driver.Value
|
||||||
}{
|
}{
|
||||||
{nil, `[]`},
|
{new(types.JsonArray[any]), `[]`},
|
||||||
{types.JsonArray{}, `[]`},
|
{types.JsonArray[any]{}, `[]`},
|
||||||
{types.JsonArray{1, 2, 3}, `[1,2,3]`},
|
{types.JsonArray[int]{1, 2, 3}, `[1,2,3]`},
|
||||||
{types.JsonArray{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
|
{types.JsonArray[string]{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
|
||||||
{types.JsonArray{1, "test"}, `[1,"test"]`},
|
{types.JsonArray[any]{1, "test"}, `[1,"test"]`},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range scenarios {
|
for i, s := range scenarios {
|
||||||
|
@ -77,7 +78,7 @@ func TestJsonArrayScan(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range scenarios {
|
for i, s := range scenarios {
|
||||||
arr := types.JsonArray{}
|
arr := types.JsonArray[any]{}
|
||||||
scanErr := arr.Scan(s.value)
|
scanErr := arr.Scan(s.value)
|
||||||
|
|
||||||
hasErr := scanErr != nil
|
hasErr := scanErr != nil
|
||||||
|
|
Loading…
Reference in New Issue