from . import pq
from . import proto
from .pq import Format as Format
-from .proto import AdaptContext, DumpersMap, DumperType
-from .proto import LoadersMap, LoaderType
+from .types import builtins
+from .proto import AdaptContext, DumpersMap, DumperType, LoadersMap, LoaderType
from .cursor import BaseCursor
from .connection import BaseConnection
+TEXT_OID = builtins["text"].oid
+
class Dumper:
globals: DumpersMap = {}
def dump(self, obj: Any) -> Union[bytes, Tuple[bytes, int]]:
raise NotImplementedError()
+ @property
+ def oid(self) -> int:
+ return TEXT_OID
+
@classmethod
def register(
cls,
def __init__(self, src: type, context: AdaptContext = None):
super().__init__(src, context)
self._tx = Transformer(context)
+ self._oid = 0
def _array_oid(self, base_oid: int) -> int:
"""
def dump(self, obj: List[Any]) -> Tuple[bytes, int]:
tokens: List[bytes] = []
- oid = 0
-
def dump_list(obj: List[Any]) -> None:
- nonlocal oid
-
if not obj:
tokens.append(b"{}")
return
else:
ad = self._tx.dump(item)
if isinstance(ad, tuple):
- if oid == 0:
- oid = ad[1]
+ if not self._oid:
+ self._oid = ad[1]
got_type = type(item)
- elif oid != ad[1]:
+ elif self._oid != ad[1]:
raise e.DataError(
f"array contains different types,"
f" at least {got_type} and {type(item)}"
dump_list(obj)
- return b"".join(tokens), self._array_oid(oid)
+ return b"".join(tokens), self._array_oid(self._oid)
+
+ @property
+ def oid(self) -> int:
+ return self._array_oid(self._oid) if self._oid else TEXT_ARRAY_OID
@Dumper.binary(list)
data: List[bytes] = [b"", b""] # placeholders to avoid a resize
dims: List[int] = []
hasnull = 0
- oid = 0
def calc_dims(L: List[Any]) -> None:
if isinstance(L, self.src):
calc_dims(obj)
def dump_list(L: List[Any], dim: int) -> None:
- nonlocal oid, hasnull
+ nonlocal hasnull
if len(L) != dims[dim]:
raise e.DataError("nested lists have inconsistent lengths")
for item in L:
ad = self._tx.dump(item, Format.BINARY)
if isinstance(ad, tuple):
- if oid == 0:
- oid = ad[1]
+ if not self._oid:
+ self._oid = ad[1]
got_type = type(item)
- elif oid != ad[1]:
+ elif self._oid != ad[1]:
raise e.DataError(
f"array contains different types,"
f" at least {got_type} and {type(item)}"
dump_list(obj, 0)
- if oid == 0:
- oid = TEXT_OID
+ if not self._oid:
+ self._oid = TEXT_OID
- data[0] = _struct_head.pack(len(dims), hasnull, oid or TEXT_OID)
+ data[0] = _struct_head.pack(len(dims), hasnull, self._oid)
data[1] = b"".join(_struct_dim.pack(dim, 1) for dim in dims)
- return b"".join(data), self._array_oid(oid)
+ return b"".join(data), self._array_oid(self._oid)
+
+ @property
+ def oid(self) -> int:
+ return self._array_oid(self._oid) if self._oid else TEXT_ARRAY_OID
class BaseArrayLoader(Loader):
def dump(self, obj: bytes) -> Tuple[bytes, int]:
return self.esc.escape_bytea(obj), BYTEA_OID
+ @property
+ def oid(self) -> int:
+ return BYTEA_OID
+
@Dumper.binary(bytes)
class BinaryBytesDumper(Dumper):
def dump(self, b: bytes) -> Tuple[bytes, int]:
return b, BYTEA_OID
+ @property
+ def oid(self) -> int:
+ return BYTEA_OID
+
@Loader.text(builtins["bytea"].oid)
def load_bytea_text(data: bytes) -> bytes: