#include #include #include /* struct timespec & clock_gettime() */ #include /* strerror() */ #include /* inet_ntop(), inet_ntoa() */ #include /* fd passing */ #include /* fd passing */ #include /* dlopen() etc */ #undef PERL_IMPLICIT_SYS #define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifndef av_push_simple #define av_push_simple av_push #endif #ifndef BOOL_INTERNALS_sv_isbool_true #define BOOL_INTERNALS_sv_isbool_true(x) SvTRUEx(x) #endif #ifndef newSV_true #define newSV_true() newSVsv(&PL_sv_yes) #endif #ifndef newSV_false #define newSV_false() newSVsv(&PL_sv_no) #endif /* Disable key/value struct packing in khashl, so we can safely take a pointer * to values inside the hash table. */ #define kh_packed #include "c/khashl.h" #include "c/common.c" #include "c/compress.c" #include "c/fcgi.c" #include "c/fdpass.c" #include "c/jsonfmt.c" #include "c/jsonparse.c" #include "c/xmlwr.c" #include "c/libpq.h" #include "c/pgtypes.c" #include "c/pgconn.c" #include "c/pgst.c" #define FUPG_CONN_COOKIE \ if (c->cookie) fu_confess("Invalid operation on the top-level connection while a transaction object exists") #define FUPG_TXN_COOKIE \ if (!t->cookie) fu_confess("Invalid operation on a transaction that has already been marked as done"); \ if (t->cookie != t->conn->cookie) fu_confess("Invalid operation on transaction while a subtransaction object exists") #define FUPG_ST_COOKIE \ if (st->cookie != st->conn->cookie) fu_confess("Invalid cross-transaction operation on statement object") #define FUPG_STFLAGS do {\ if (!ix) ix = FUPG_CACHE;\ if (items == 1 || SvTRUE(ST(1))) x->stflags |= ix; \ else x->stflags &= ~ix; \ } while(0) MODULE = FU PROTOTYPES: DISABLE TYPEMAP: <fd = fd; ctx->maxproc = maxproc; ctx->reqid = ctx->keepconn = ctx->len = ctx->off = 0; ST(0) = fu_selfobj(ctx, "FU::fcgi"); void read_req(fufcgi *ctx, SV *headers, SV *params) CODE: ST(0) = sv_2mortal(newSViv(fufcgi_read_req(aTHX_ ctx, headers, params))); ctx->off = ctx->len = 0; void keepalive(fufcgi *ctx) CODE: ST(0) = ctx->keepconn ? &PL_sv_yes : &PL_sv_no; void print(fufcgi *ctx, SV *sv) CODE: STRLEN len; const char *buf = SvPVbyte(sv, len); fufcgi_print(ctx, buf, len); void flush(fufcgi *ctx) CODE: fufcgi_done(ctx); void DESTROY(fufcgi *ctx) CODE: safefree(ctx); MODULE = FU PACKAGE = FU::Pg void _load_libpq() CODE: if (!PQconnectdb) fupg_load(); void lib_version() CODE: XSRETURN_IV(PQlibVersion()); void connect(const char *pkg, const char *conninfo) CODE: (void)pkg; ST(0) = fupg_connect(aTHX_ conninfo); MODULE = FU PACKAGE = FU::Pg::conn void server_version(fupg_conn *c) CODE: XSRETURN_IV(PQserverVersion(c->conn)); void _debug_trace(fupg_conn *c, bool on) CODE: if (on) PQtrace(c->conn, stderr); else PQuntrace(c->conn); ST(0) = c->self; void query_trace(fupg_conn *c, SV *cb) CODE: if (c->trace) SvREFCNT_dec(c->trace); SvGETMAGIC(cb); c->trace = SvOK(cb) ? SvREFCNT_inc(cb) : NULL; void status(fupg_conn *c) CODE: ST(0) = sv_2mortal(newSVpv(fupg_conn_status(c), 0)); void escape_literal(fupg_conn *c, SV *v) CODE: STRLEN len; const char *str = SvPVutf8(v, len); char *r = PQescapeLiteral(c->conn, str, len); if (!r) fupg_conn_croak(c, "escapeLiteral"); ST(0) = newSVpvn_flags(r, strlen(r), SVf_UTF8|SVs_TEMP); PQfreemem(r); void escape_identifier(fupg_conn *c, SV *v) CODE: STRLEN len; const char *str = SvPVutf8(v, len); char *r = PQescapeIdentifier(c->conn, str, len); if (!r) fupg_conn_croak(c, "escapeIdentifier"); ST(0) = newSVpvn_flags(r, strlen(r), SVf_UTF8|SVs_TEMP); PQfreemem(r); void cache(fupg_conn *x, ...) ALIAS: FU::Pg::conn::text_params = FUPG_TEXT_PARAMS FU::Pg::conn::text_results = FUPG_TEXT_RESULTS FU::Pg::conn::text = FUPG_TEXT CODE: FUPG_STFLAGS; void cache_size(fupg_conn *c, unsigned int n) CODE: c->prep_max = n; fupg_prepared_prune(c); XSRETURN(1); void disconnect(fupg_conn *c) CODE: fupg_conn_disconnect(c); void DESTROY(fupg_conn *c) CODE: fupg_conn_destroy(aTHX_ c); void txn(fupg_conn *c) CODE: FUPG_CONN_COOKIE; ST(0) = fupg_conn_txn(aTHX_ c); void exec(fupg_conn *c, SV *sv) CODE: FUPG_CONN_COOKIE; ST(0) = fupg_exec(aTHX_ c, SvPVutf8_nolen(sv)); void q(fupg_conn *c, SV *sv, ...) CODE: FUPG_CONN_COOKIE; ST(0) = fupg_q(aTHX_ c, c->stflags, SvPVutf8_nolen(sv), ax, items); void copy(fupg_conn *c, SV *sv) CODE: FUPG_CONN_COOKIE; ST(0) = fupg_copy_exec(aTHX_ c, SvPVutf8_nolen(sv)); void _set_type(fupg_conn *c, SV *name, SV *sendsv, SV *recvsv) CODE: fupg_set_type(aTHX_ c, name, sendsv, recvsv); XSRETURN(1); void perl2bin(fupg_conn *c, int oid, SV *sv) CODE: ST(0) = fupg_perl2bin(aTHX_ c, oid, sv); void bin2perl(fupg_conn *c, int oid, SV *sv) CODE: ST(0) = fupg_bin2perl(aTHX_ c, oid, sv); MODULE = FU PACKAGE = FU::Pg::txn void DESTROY(fupg_txn *t) CODE: fupg_txn_destroy(aTHX_ t); void cache(fupg_txn *x, ...) ALIAS: FU::Pg::txn::text_params = FUPG_TEXT_PARAMS FU::Pg::txn::text_results = FUPG_TEXT_RESULTS FU::Pg::txn::text = FUPG_TEXT CODE: FUPG_STFLAGS; void status(fupg_txn *t) CODE: ST(0) = sv_2mortal(newSVpv(fupg_txn_status(t), 0)); void txn(fupg_txn *t) CODE: FUPG_TXN_COOKIE; ST(0) = fupg_txn_txn(aTHX_ t); void commit(fupg_txn *t) CODE: FUPG_TXN_COOKIE; fupg_txn_commit(t); void rollback(fupg_txn *t) CODE: FUPG_TXN_COOKIE; fupg_txn_rollback(t); void exec(fupg_txn *t, SV *sv) CODE: FUPG_TXN_COOKIE; ST(0) = fupg_exec(aTHX_ t->conn, SvPVutf8_nolen(sv)); void q(fupg_txn *t, SV *sv, ...) CODE: FUPG_TXN_COOKIE; ST(0) = fupg_q(aTHX_ t->conn, t->stflags, SvPVutf8_nolen(sv), ax, items); # XXX: The copy object should probably keep a ref on the transaction void copy(fupg_txn *t, SV *sv) CODE: FUPG_TXN_COOKIE; ST(0) = fupg_copy_exec(aTHX_ t->conn, SvPVutf8_nolen(sv)); MODULE = FU PACKAGE = FU::Pg::st void cache(fupg_st *x, ...) ALIAS: FU::Pg::st::text_params = FUPG_TEXT_PARAMS FU::Pg::st::text_results = FUPG_TEXT_RESULTS FU::Pg::st::text = FUPG_TEXT CODE: if (ix == 0 && x->prepared) fu_confess("Invalid attempt to change statement configuration after it has already been prepared or executed"); FUPG_STFLAGS; XSRETURN(1); void exec(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_exec(aTHX_ st); void val(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_val(aTHX_ st); void rowl(fupg_st *st) CODE: FUPG_ST_COOKIE; XSRETURN(fupg_st_rowl(aTHX_ st, ax)); void rowa(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_rowa(aTHX_ st); void rowh(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_rowh(aTHX_ st); void alla(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_alla(aTHX_ st); void allh(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_allh(aTHX_ st); void flat(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_flat(aTHX_ st); void kvv(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_kvv(aTHX_ st); void kva(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_kva(aTHX_ st); void kvh(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_kvh(aTHX_ st); void param_types(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_param_types(aTHX_ st); void param_values(fupg_st *st); CODE: ST(0) = fupg_st_param_values(aTHX_ st); void columns(fupg_st *st) CODE: FUPG_ST_COOKIE; ST(0) = fupg_st_columns(aTHX_ st); void nrows(fupg_st *st) CODE: ST(0) = st->result ? sv_2mortal(newSViv(PQntuples(st->result))) : &PL_sv_undef; void query(fupg_st *st) CODE: ST(0) = newSVpvn_flags(st->query, strlen(st->query), SVs_TEMP|SVf_UTF8); void exec_time(fupg_st *st) CODE: ST(0) = st->exectime <= 0 ? &PL_sv_undef : sv_2mortal(newSVnv(st->exectime)); void prepare_time(fupg_st *st) CODE: ST(0) = !st->prepared ? &PL_sv_undef : sv_2mortal(newSVnv(st->preptime)); void get_cache(fupg_st *st) ALIAS: FU::Pg::st::get_text_params = FUPG_TEXT_PARAMS FU::Pg::st::get_text_results = FUPG_TEXT_RESULTS CODE: if (!ix) ix = FUPG_CACHE; ST(0) = st->stflags & ix ? &PL_sv_yes : &PL_sv_no; void DESTROY(fupg_st *st) CODE: fupg_st_destroy(aTHX_ st); MODULE = FU PACKAGE = FU::Pg::copy void write(fupg_copy *c, SV *sv) CODE: fupg_copy_write(aTHX_ c, sv); void read(fupg_copy *c) CODE: ST(0) = fupg_copy_read(aTHX_ c, 0); void is_binary(fupg_copy *c) CODE: ST(0) = c->bin ? &PL_sv_yes : &PL_sv_no; void close(fupg_copy *c) CODE: fupg_copy_close(aTHX_ c, 0); void DESTROY(fupg_copy *c) CODE: fupg_copy_destroy(aTHX_ c); MODULE = FU PACKAGE = FU::XMLWriter void _new() CODE: ST(0) = fuxmlwr_new(aTHX); void _done(fuxmlwr *wr) CODE: ST(0) = sv_2mortal(fustr_done(&wr->out)); fustr_init(&wr->out, NULL, SIZE_MAX); void lit_(SV *sv) CODE: if (!fuxmlwr_tail) fu_confess("No active FU::XMLWriter instance"); STRLEN len; const char *buf = SvPVutf8(sv, len); fustr_write(&fuxmlwr_tail->out, buf, len); void txt_(SV *sv) CODE: if (!fuxmlwr_tail) fu_confess("No active FU::XMLWriter instance"); fuxmlwr_escape(aTHX_ fuxmlwr_tail, sv); void tag_(SV *sv, ...) CODE: if (!fuxmlwr_tail) fu_confess("No active FU::XMLWriter instance"); STRLEN len; const char *tagname = SvPV(sv, len); fuxmlwr_isname(tagname); fuxmlwr_tag(aTHX_ fuxmlwr_tail, ax, 1, items, 0, tagname, len); INCLUDE_COMMAND: $^X -e '$FU::XMLWriter::XSPRINT=1; require "./FU/XMLWriter.pm"' void DESTROY(fuxmlwr *wr) CODE: fuxmlwr_destroy(aTHX_ wr);