// Built-in codecs for primitive MoonBit values.
///|
// `Bool` maps directly to PostgreSQL `bool`.
pub impl ToSql for Bool with fn accepts(_, type_) {
type_.oid == BOOL_OID
}
///|
pub impl ToSql for Bool with fn moonbit_type_name(_) {
"Bool"
}
///|
pub impl ToSql for Bool with fn to_sql(self, _, buf) {
@types.bool_to_sql(self, buf)
No
}
///|
pub impl FromSql for Bool with fn accepts(type_) {
type_.oid == BOOL_OID
}
///|
pub impl FromSql for Bool with fn moonbit_type_name() {
"Bool"
}
///|
pub impl FromSql for Bool with fn from_sql(_, format, raw) {
match format {
Text => decode_utf8(raw) == "t" || decode_utf8(raw) == "true"
Binary => @types.bool_from_sql(raw)
}
}
///|
// `Int` is intentionally limited to PostgreSQL `int2` and `int4`.
pub impl ToSql for Int with fn to_sql(self, type_, buf) {
match type_.oid {
INT2_OID => @types.int2_to_sql(self, buf)
INT4_OID => @types.int4_to_sql(self, buf)
_ => raise ClientError::Encode("cannot encode Int for type \{type_.name}")
}
No
}
///|
pub impl ToSql for Int with fn accepts(_, type_) {
match type_.oid {
INT2_OID | INT4_OID => true
_ => false
}
}
///|
pub impl ToSql for Int with fn moonbit_type_name(_) {
"Int"
}
///|
pub impl FromSql for Int with fn from_sql(type_, format, raw) {
match format {
Text => @string.parse_int(decode_utf8(raw))
Binary =>
match type_.oid {
INT2_OID => @types.int2_from_sql(raw)
INT4_OID => @types.int4_from_sql(raw)
_ => raise ClientError::Decode("cannot decode Int from \{type_.name}")
}
}
}
///|
pub impl FromSql for Int with fn accepts(type_) {
match type_.oid {
INT2_OID | INT4_OID => true
_ => false
}
}
///|
pub impl FromSql for Int with fn moonbit_type_name() {
"Int"
}
///|
// `Int64` maps to PostgreSQL `int8`.
pub impl ToSql for Int64 with fn accepts(_, type_) {
type_.oid == INT8_OID
}
///|
pub impl ToSql for Int64 with fn moonbit_type_name(_) {
"Int64"
}
///|
pub impl ToSql for Int64 with fn to_sql(self, _, buf) {
@types.int8_to_sql(self, buf)
No
}
///|
pub impl FromSql for Int64 with fn accepts(type_) {
type_.oid == INT8_OID
}
///|
pub impl FromSql for Int64 with fn moonbit_type_name() {
"Int64"
}
///|
pub impl FromSql for Int64 with fn from_sql(_, format, raw) {
match format {
Text => @string.parse_int64(decode_utf8(raw))
Binary => @types.int8_from_sql(raw)
}
}
///|
// `Float` maps to PostgreSQL single precision `float4`.
pub impl ToSql for Float with fn accepts(_, type_) {
type_.oid == FLOAT4_OID
}
///|
pub impl ToSql for Float with fn moonbit_type_name(_) {
"Float"
}
///|
pub impl ToSql for Float with fn to_sql(self, _, buf) {
@types.float4_to_sql(self, buf)
No
}
///|
pub impl FromSql for Float with fn accepts(type_) {
type_.oid == FLOAT4_OID
}
///|
pub impl FromSql for Float with fn moonbit_type_name() {
"Float"
}
///|
pub impl FromSql for Float with fn from_sql(_, format, raw) {
match format {
Text => Float::from_double(@string.parse_double(decode_utf8(raw)))
Binary => @types.float4_from_sql(raw)
}
}
///|
// `Double` maps to PostgreSQL double precision `float8`.
pub impl ToSql for Double with fn accepts(_, type_) {
type_.oid == FLOAT8_OID
}
///|
pub impl ToSql for Double with fn moonbit_type_name(_) {
"Double"
}
///|
pub impl ToSql for Double with fn to_sql(self, _, buf) {
@types.float8_to_sql(self, buf)
No
}
///|
pub impl FromSql for Double with fn accepts(type_) {
type_.oid == FLOAT8_OID
}
///|
pub impl FromSql for Double with fn moonbit_type_name() {
"Double"
}
///|
pub impl FromSql for Double with fn from_sql(_, format, raw) {
match format {
Text => @string.parse_double(decode_utf8(raw))
Binary => @types.float8_from_sql(raw)
}
}
///|
// `UInt` is reserved for PostgreSQL `oid`.
pub impl ToSql for UInt with fn accepts(_, type_) {
type_.oid == OID_TYPE_OID
}
///|
pub impl ToSql for UInt with fn moonbit_type_name(_) {
"UInt"
}
///|
pub impl ToSql for UInt with fn to_sql(self, _, buf) {
@types.oid_to_sql(self, buf)
No
}
///|
pub impl FromSql for UInt with fn accepts(type_) {
type_.oid == OID_TYPE_OID
}
///|
pub impl FromSql for UInt with fn moonbit_type_name() {
"UInt"
}
///|
pub impl FromSql for UInt with fn from_sql(_, format, raw) {
match format {
Text => @string.parse_uint(decode_utf8(raw))
Binary => @types.oid_from_sql(raw)
}
}
///|
// `String` prefers text format because PostgreSQL text types are naturally textual.
pub impl ToSql for String with fn accepts(_, type_) {
is_text_type(type_)
}
///|
pub impl ToSql for String with fn moonbit_type_name(_) {
"String"
}
///|
pub impl ToSql for String with fn format(_, _) {
Text
}
///|
pub impl ToSql for String with fn to_sql(self, _, buf) {
buf.write_bytes(@proto.utf8_encode(self))
No
}
///|
pub impl FromSql for String with fn accepts(type_) {
is_text_type(type_)
}
///|
pub impl FromSql for String with fn moonbit_type_name() {
"String"
}
///|
pub impl FromSql for String with fn from_sql(_, _, raw) {
decode_utf8(raw)
}
///|
// `Bytes` currently covers PostgreSQL `bytea` and raw `uuid` storage.
pub impl ToSql for Bytes with fn accepts(_, type_) {
is_bytes_type(type_)
}
///|
pub impl ToSql for Bytes with fn moonbit_type_name(_) {
"Bytes"
}
///|
pub impl ToSql for Bytes with fn to_sql(self, type_, buf) {
match type_.oid {
BYTEA_OID => @types.bytea_to_sql(self[:], buf)
UUID_OID => @types.uuid_to_sql(self[:], buf)
_ => raise ClientError::Encode("cannot encode bytes for type \{type_.name}")
}
No
}
///|
pub impl FromSql for Bytes with fn accepts(type_) {
is_bytes_type(type_)
}
///|
pub impl FromSql for Bytes with fn moonbit_type_name() {
"Bytes"
}
///|
pub impl FromSql for Bytes with fn from_sql(type_, format, raw) {
match format {
Text =>
if type_.oid == BYTEA_OID {
raw.to_owned()
} else {
@proto.utf8_encode(decode_utf8(raw))
}
Binary =>
match type_.oid {
BYTEA_OID => @types.bytea_from_sql(raw).to_owned()
UUID_OID => @types.uuid_from_sql(raw)
_ => raw.to_owned()
}
}
}
///|
// `Json` is sent as text so the same codec covers PostgreSQL `json` and `jsonb`.
pub impl ToSql for Json with fn accepts(_, type_) {
is_json_type(type_)
}
///|
pub impl ToSql for Json with fn moonbit_type_name(_) {
"Json"
}
///|
pub impl ToSql for Json with fn format(_, _) {
Text
}
///|
pub impl ToSql for Json with fn to_sql(self, _, buf) {
buf.write_bytes(@proto.utf8_encode(self.stringify()))
No
}
///|
pub impl FromSql for Json with fn accepts(type_) {
is_json_type(type_)
}
///|
pub impl FromSql for Json with fn moonbit_type_name() {
"Json"
}
///|
pub impl FromSql for Json with fn from_sql(type_, format, raw) {
match format {
Text => @json.parse(decode_utf8(raw)[:])
Binary =>
match type_.oid {
JSONB_OID => decode_jsonb_binary(raw)
_ => @json.parse(decode_utf8(raw)[:])
}
}
}
///|
fn decode_jsonb_binary(raw : BytesView) -> Json raise Error {
match raw {
[b'\x01', .. payload] => @json.parse(decode_utf8(payload)[:])
_ => raise ClientError::Decode("jsonb version 1 only supported")
}
}