mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-15 18:48:14 +02:00
(experimental) upgraded to encoding/json/v2
This commit is contained in:
1 parent
4d4275c9aa
commit
97dd775455
125 files changed
+433
-364
No files matched your search
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
|
||||
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
||||
+13
-10
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -14,12 +14,9 @@ type jsonArrayAlias[T any] JSONArray[T]
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONArray[T]) MarshalJSON() ([]byte, error) {
|
||||
// initialize an empty map to ensure that `[]` is returned as json
|
||||
if m == nil {
|
||||
m = JSONArray[T]{}
|
||||
}
|
||||
|
||||
return json.Marshal(jsonArrayAlias[T](m))
|
||||
// note: forces the Deterministic option to ensure consistent output
|
||||
// in mixed json v1 and v2 configurations
|
||||
return json.Marshal(jsonArrayAlias[T](m), json.Deterministic(true))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json array.
|
||||
@@ -30,8 +27,7 @@ func (m JSONArray[T]) String() string {
|
||||
|
||||
// Value implements the [driver.Valuer] interface.
|
||||
func (m JSONArray[T]) Value() (driver.Value, error) {
|
||||
data, err := json.Marshal(m)
|
||||
|
||||
data, err := m.MarshalJSON()
|
||||
return string(data), err
|
||||
}
|
||||
|
||||
@@ -54,5 +50,12 @@ func (m *JSONArray[T]) Scan(value any) error {
|
||||
data = []byte("[]")
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, m)
|
||||
err := json.Unmarshal(data, m)
|
||||
if err != nil {
|
||||
// reset because jsonv2 performs streaming decoding and mutates the dst even on error
|
||||
*m = JSONArray[T]{}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package types_test
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestJSONArrayScan(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
result, _ := arr.MarshalJSON()
|
||||
result, _ := json.Marshal(arr, json.Deterministic(true))
|
||||
|
||||
if string(result) != s.expectJSON {
|
||||
t.Errorf("(%d) Expected %s, got %v", i, s.expectJSON, string(result))
|
||||
|
||||
+25
-22
@@ -2,31 +2,13 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// JSONMap defines a map that is safe for json and db read/write.
|
||||
type JSONMap[T any] map[string]T
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONMap[T]) MarshalJSON() ([]byte, error) {
|
||||
type alias JSONMap[T] // prevent recursion
|
||||
|
||||
// initialize an empty map to ensure that `{}` is returned as json
|
||||
if m == nil {
|
||||
m = JSONMap[T]{}
|
||||
}
|
||||
|
||||
return json.Marshal(alias(m))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json map.
|
||||
func (m JSONMap[T]) String() string {
|
||||
v, _ := m.MarshalJSON()
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// Get retrieves a single value from the current JSONMap[T].
|
||||
//
|
||||
// This helper was added primarily to assist the goja integration since custom map types
|
||||
@@ -43,10 +25,24 @@ func (m JSONMap[T]) Set(key string, value T) {
|
||||
m[key] = value
|
||||
}
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONMap[T]) MarshalJSON() ([]byte, error) {
|
||||
type alias JSONMap[T] // prevent recursion
|
||||
|
||||
// note: forces the Deterministic option to ensure consistent output
|
||||
// in mixed json v1 and v2 configurations
|
||||
return json.Marshal(alias(m), json.Deterministic(true))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json map.
|
||||
func (m JSONMap[T]) String() string {
|
||||
v, _ := m.MarshalJSON()
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// Value implements the [driver.Valuer] interface.
|
||||
func (m JSONMap[T]) Value() (driver.Value, error) {
|
||||
data, err := json.Marshal(m)
|
||||
|
||||
data, err := m.MarshalJSON()
|
||||
return string(data), err
|
||||
}
|
||||
|
||||
@@ -69,5 +65,12 @@ func (m *JSONMap[T]) Scan(value any) error {
|
||||
data = []byte("{}")
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, m)
|
||||
err := json.Unmarshal(data, m)
|
||||
if err != nil {
|
||||
// reset because jsonv2 performs streaming decoding and mutates the dst even on error
|
||||
*m = JSONMap[T]{}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package types_test
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -154,7 +155,7 @@ func TestJSONArrayMapScan(t *testing.T) {
|
||||
t.Fatalf("Expected %v, got %v (%v)", s.expectError, hasErr, scanErr)
|
||||
}
|
||||
|
||||
result, _ := arr.MarshalJSON()
|
||||
result, _ := json.Marshal(arr, json.Deterministic(true))
|
||||
|
||||
if string(result) != s.expectJSON {
|
||||
t.Fatalf("Expected %s, got %s", s.expectJSON, result)
|
||||
|
||||
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
||||
Reference in new issue
Block a user