from typing import Any, Callable, Optional
from .oids import builtins
-from ..adapt import Dumper
+from ..adapt import Dumper, Loader
from ..proto import EncodeFunc
+from ..errors import DataError
_encode_utf8 = codecs.lookup("utf8").encode
self, obj: _JsonWrapper, __encode: EncodeFunc = _encode_utf8
) -> bytes:
return b"\x01" + __encode(obj.dumps())[0]
+
+
+@Loader.text(builtins["json"].oid)
+@Loader.text(builtins["jsonb"].oid)
+@Loader.binary(builtins["json"].oid)
+class JsonLoader(Loader):
+ def load(self, data: bytes) -> Any:
+ return json.loads(data)
+
+
+@Loader.binary(builtins["jsonb"].oid)
+class BinaryJsonBLoader(Loader):
+ def load(self, data: bytes) -> Any:
+ if data and data[0] != 1:
+ raise DataError("unknown jsonb binary format: {data[0]}")
+ return json.loads(data[1:])
assert cur.fetchone()[0] is True
-def my_dumps(obj):
- obj["baz"] = "qux"
- return json.dumps(obj)
+@pytest.mark.parametrize("val", samples)
+@pytest.mark.parametrize("jtype", ["json", "jsonb"])
+@pytest.mark.parametrize("fmt_out", [Format.TEXT, Format.BINARY])
+def test_json_load(conn, val, jtype, fmt_out):
+ cur = conn.cursor(format=fmt_out)
+ cur.execute(f"select %s::{jtype}", (val,))
+ assert cur.fetchone()[0] == json.loads(val)
@pytest.mark.parametrize("fmt_in", [Format.TEXT, Format.BINARY])
cur = conn.cursor()
cur.execute(f"select {ph}->>'baz' = 'qux'", (MyWrapper(obj),))
assert cur.fetchone()[0] is True
+
+
+def my_dumps(obj):
+ obj["baz"] = "qux"
+ return json.dumps(obj)