pg: Add json, jsonb, jsonpath support
NOW we're really getting to the part where this module is more awesome than DBD::Pg. (When I started working on this module I was expecting that the Postgres binary protocol would send jsonb in a binary format as well and that I'd be duplicating parts of the JSON parser/formatter to make that work, but it turns out that Postgres just uses plain json for exchange. Saves me some trouble, I guess)
This commit is contained in:
parent
7f1c48e0cf
commit
2aaec6a218
4 changed files with 98 additions and 49 deletions
48
c/pgtypes.c
48
c/pgtypes.c
|
|
@ -57,10 +57,6 @@ typedef struct {
|
|||
if (iv < min || iv > max) fu_confess("Integer %"IVdf" out of range for type '%s' (oid %u)", iv, ctx->name, ctx->oid)
|
||||
|
||||
|
||||
RECVFN(textfmt) {
|
||||
return newSVpvn_utf8(buf, len, 1);
|
||||
}
|
||||
|
||||
RECVFN(bool) {
|
||||
RLEN(1);
|
||||
return *buf ? &PL_sv_yes : &PL_sv_no;
|
||||
|
|
@ -182,6 +178,44 @@ SENDFN(float8) {
|
|||
fustr_write(out, (const char *)&uv, 8);
|
||||
}
|
||||
|
||||
RECVFN(json) {
|
||||
fujson_parse_ctx json = {
|
||||
.buf = (const unsigned char *)buf,
|
||||
.end = (const unsigned char *)buf + len,
|
||||
.depth = 512
|
||||
};
|
||||
SV *sv = fujson_parse(aTHX_ &json);
|
||||
if (sv == NULL) fu_confess("Received invalid JSON for type '%s' (oid %u)", ctx->name, ctx->oid);
|
||||
if (json.buf != json.end) fu_confess("Received invalid JSON for type '%s' (oid %u)", ctx->name, ctx->oid);
|
||||
return sv;
|
||||
}
|
||||
|
||||
SENDFN(json) {
|
||||
fujson_fmt_ctx json = { .out = out, .depth = 512, .canon = 1, .pretty = 0 };
|
||||
fujson_fmt(aTHX_ &json, val);
|
||||
}
|
||||
|
||||
RECVFN(jsonb) {
|
||||
if (len <= 1 || *buf != 1) fu_confess("Unexpected format for type '%s' (oid %u)", ctx->name, ctx->oid);
|
||||
return fupg_recv_json(aTHX_ ctx, buf+1, len-1);
|
||||
}
|
||||
|
||||
SENDFN(jsonb) {
|
||||
fustr_write_ch(out, 1);
|
||||
fupg_send_json(aTHX_ ctx, val, out);
|
||||
}
|
||||
|
||||
RECVFN(jsonpath) {
|
||||
if (len <= 1 || *buf != 1) fu_confess("Unexpected format for type '%s' (oid %u)", ctx->name, ctx->oid);
|
||||
return fupg_recv_text(aTHX_ ctx, buf+1, len-1);
|
||||
}
|
||||
|
||||
SENDFN(jsonpath) {
|
||||
fustr_write_ch(out, 1);
|
||||
fupg_send_text(aTHX_ ctx, val, out);
|
||||
}
|
||||
|
||||
#undef SIV
|
||||
#undef RLEN
|
||||
#undef RECVFN
|
||||
#undef SENDFN
|
||||
|
|
@ -230,7 +264,7 @@ SENDFN(float8) {
|
|||
B( 28, "xid", uint4 )\
|
||||
B( 29, "cid", uint4 )\
|
||||
/* 30 oidvector */ \
|
||||
/* 114 json */ \
|
||||
B( 114, "json", json )\
|
||||
B( 142, "xml", text )\
|
||||
B( 194, "pg_node_tree", text ) /* can't be used as a bind param */\
|
||||
/* 600 point */\
|
||||
|
|
@ -275,8 +309,8 @@ SENDFN(float8) {
|
|||
/* 3642 gtsvector, does not support binary send/recv */\
|
||||
B( 3734, "regconfig", uint4 )\
|
||||
B( 3769, "regdictionary", uint4 )\
|
||||
/* 3802 jsonb */\
|
||||
/* 4072 jsonpath */\
|
||||
B( 3802, "jsonb", jsonb )\
|
||||
B( 4072, "jsonpath", jsonpath)\
|
||||
B( 4089, "regnamespace", uint4 )\
|
||||
B( 4096, "regrole", uint4 )\
|
||||
B( 4191, "regcollation", uint4 )\
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue