Pg-PQ
view release on metacpan or search on metacpan
static SV *
make_constant(char *name, STRLEN l, U32 value, char *tag) {
SV *sv = newSV(0);
SvUPGRADE(sv, SVt_PVIV);
sv_setpvn(sv, name, l);
SvIOK_on(sv);
SvIsUV_on(sv);
SvUV_set(sv, value);
SvREADONLY_on(sv);
newCONSTSUB(gv_stashpv("Pg::PQ", 1), name, sv);
if (tag) {
HV *hv = get_hv("Pg::PQ::EXPORT_TAGS", TRUE);
SV **svp = hv_fetch(hv, tag, strlen(tag), 1);
if (!svp || !*svp)
Perl_croak(aTHX_ "internal error populating EXPORT_TAGS");
if (!SvOK(*svp) || !SvROK(*svp) || (SvTYPE(SvRV(*svp)) != SVt_PVAV))
sv_setsv(*svp, sv_2mortal(newRV_noinc((SV*)newAV())));
av_push((AV*)SvRV(*svp), my_newSVpv_utf8(aTHX_ name));
}
return sv;
}
static void
sv_chomp(SV *sv) {
while (SvOK(sv) && SvPOK(sv) && SvCUR(sv) && SvPVX(sv)[SvCUR(sv) - 1] == '\n')
SvCUR_set(sv, SvCUR(sv) - 1);
}
#include "enums.h"
MODULE = Pg::PQ PACKAGE = Pg::PQ PREFIX=PQ
PROTOTYPES: DISABLE
BOOT:
init_constants();
char *
PQlibVersion()
CODE:
#if (0 && (PQMAJOR >= 9))
RETVAL = PQlibVersion(); /* this returns an integer, use the
* value obtained from pg_config at
* compilation instead */
#else
RETVAL = PQVERSION;
#endif
OUTPUT:
RETVAL
MODULE = Pg::PQ PACKAGE = Pg::PQ::Conn PREFIX=PQ
void
PQdefaults(...)
PREINIT:
PQconninfoOption *opts;
int n = 0;
PPCODE:
opts = PQconndefaults();
if (opts) {
for (; opts[n].keyword; n++) {
HV *hv = newHV();
XPUSHs(newRV_noinc((SV*)hv));
hv_stores(hv, "keyword" , newSVpv(opts[n].keyword , 0));
hv_stores(hv, "envvar" , newSVpv(opts[n].envvar , 0));
hv_stores(hv, "compiled", newSVpv(opts[n].compiled, 0));
hv_stores(hv, "value" , newSVpv(opts[n].val , 0));
hv_stores(hv, "label" , newSVpv(opts[n].label , 0));
hv_stores(hv, "dispchar", newSVpv(opts[n].dispchar, 0));
hv_stores(hv, "dispsize", newSViv(opts[n].dispsize));
}
PQconninfoFree(opts);
}
XSRETURN(n);
PGconn *PQconnectdb(const char *conninfo);
PGconn *PQconnectStart(char *conninfo)
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
char *PQdb(PGconn *conn)
char *PQuser(PGconn *conn)
char *PQpass(PGconn *conn)
char *PQhost(PGconn *conn)
char *PQport(PGconn *conn)
char *PQoptions( PGconn *conn)
ConnStatusType PQstatus(PGconn *conn)
PGTransactionStatusType PQtransactionStatus(PGconn *conn)
const char *PQparameterStatus(PGconn *conn, char *paramName)
int PQprotocolVersion(PGconn *conn)
int PQserverVersion(PGconn *conn)
char *PQerrorMessage(PGconn *conn)
CLEANUP:
sv_chomp(ST(0));
int PQsocket(PGconn *conn)
int PQbackendPID(PGconn *conn)
int PQconnectionNeedsPassword(PGconn *conn)
int PQconnectionUsedPassword(PGconn *conn)
# SSL *PQgetssl(PGconn *conn)
void PQfinish(PGconn *conn)
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
void PQtrace(PGconn *conn, FILE *stream);
void PQuntrace(PGconn *conn);
# PGresult *PQexec(PGconn *conn, const char *command);
# PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
PGresult *PQexec(PGconn *conn, const char *command, ...)
ALIAS:
execQuery = 0
CODE:
if (items <= 2) {
RETVAL = PQexec(conn, command);
}
else {
int n = items - 2, i;
char **values;
Newx(values, n, char *);
for (i = 0; i < n; i++) values[i] = SvPVutf8_nolen(ST(i + 2));
RETVAL = PQexecParams(conn, command, n, NULL, (const char **)values, NULL, NULL, 0);
Safefree(values);
}
OUTPUT:
RETVAL
# PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);
PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query)
C_ARGS: conn, stmtName, query, 0, NULL
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
# PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, ...)
ALIAS:
execQueryPrepared = 0
PREINIT:
int n = items - 2, i;
char **values;
CODE:
Newx(values, n, char *);
for (i = 0; i < n; i++) values[i] = SvPVutf8_nolen(ST(i + 2));
RETVAL = PQexecPrepared(conn, stmtName, n, (const char **)values, NULL, NULL, 0);
Safefree(values);
OUTPUT:
RETVAL
# PGcancel *PQgetCancel(PGconn *conn);
# ALIAS:
# makeCancel = 0
void PQnotifies(PGconn *conn)
PREINIT:
PGnotify *notice;
PPCODE:
notice = PQnotifies(conn);
if (notice) {
int pid = notice->be_pid;
SV *name = sv_2mortal(my_newSVpv_utf8(aTHX_ notice->relname));
SV *extra = sv_2mortal(my_newSVpv_utf8(aTHX_ notice->extra));
PQfreemem(notice);
EXTEND(sp, 3);
PUSHs(name);
if (GIMME_V == G_ARRAY) {
PUSHs(sv_2mortal(newSViv(pid)));
PUSHs(extra);
XSRETURN(3);
}
else
XSRETURN(1);
}
else
XSRETURN(0);
PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
ALIAS:
PQmakeEmptyResult = 0
SV *PQescapeString(PGconn *conn, SV *from)
PREINIT:
STRLEN len;
char *pv;
int error;
CODE:
pv = SvPVutf8(from, len);
RETVAL = newSV(len * 2 + 1);
SvPOK_on(RETVAL);
SvCUR_set(RETVAL, PQescapeStringConn(conn, SvPVX(RETVAL), pv, len, &error));
if (error) {
SvREFCNT_dec(RETVAL);
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
#if PQMAJOR >= 9
char *PQescapeLiteral(PGconn *conn, const char *str, size_t length(str))
CLEANUP:
if (RETVAL) PQfreemem(RETVAL);
char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length(str))
CLEANUP:
if (RETVAL) PQfreemem(RETVAL);
#endif
# unsigned char *PQescapeByteaConn(PGconn *conn, unsigned char *from, size_t from_length, size_t *to_length);
# int PQsendQuery(PGconn *conn, const char *command);
# int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
int PQsendQuery(PGconn *conn, const char *command, ...)
CODE:
PQsetnonblocking(conn, SvIV(nb));
RETVAL = PQisnonblocking(conn);
OUTPUT:
RETVAL
int PQflush(PGconn *conn);
# PGresult *PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs);
MODULE = Pg::PQ PACKAGE = Pg::PQ::Result PREFIX=PQ
ExecStatusType PQresultStatus(PGresult *res)
ALIAS:
status = 0
char *PQresStatus(ExecStatusType status)
char *statusMessage(PGresult *res)
CODE:
RETVAL = PQresStatus(PQresultStatus(res));
OUTPUT:
RETVAL
char *PQresultErrorMessage(PGresult *res)
ALIAS:
errorMessage = 0
CLEANUP:
sv_chomp(ST(0));
char *PQresultErrorField(PGresult *res, char field);
ALIAS:
_errorField = 0
CLEANUP:
sv_chomp(ST(0));
void PQclear(PGresult *res)
POSTCALL:
sv_setsv(ST(0), &PL_sv_undef);
int PQntuples(PGresult *res)
ALIAS:
nTuples = 0
nRows = 1
int PQnfields(PGresult *res)
ALIAS:
nFields = 0
nColumns = 1
char *PQfname(PGresult *res, int column_number)
ALIAS:
columnName = 0
void
PQfnames(PGresult *res)
ALIAS:
columnNames = 0
PREINIT:
int cols;
PPCODE:
cols = PQnfields(res);
if (cols) {
int j;
if (GIMME_V != G_ARRAY) cols = 1;
EXTEND(sp, cols);
for (j = 0; j < cols; j++) {
char *pv = PQfname(res, j);
SV *sv = newSVpvn_utf8(pv, strlen(pv), 1);
mPUSHs(sv);
}
}
XSRETURN(cols);
int PQfnumber(PGresult *res, const char *column_name)
ALIAS:
columnNumber = 0
Oid PQftable(PGresult *res, int column_number)
ALIAS:
columnTable = 0
SV *PQftablecol(PGresult *res, int column_number);
ALIAS:
columnTableColumn = 0
PREINIT:
int col;
CODE:
col = PQftablecol(res, column_number);
RETVAL = (col ? newSViv(col) : &PL_sv_undef);
OUTPUT:
RETVAL
int PQfformat(PGresult *res, int column_number);
Oid PQftype(PGresult *res, int column_number);
int PQfmod(PGresult *res, int column_number);
int PQfsize(PGresult *res, int column_number);
ALIAS:
fSize = 0
int PQbinaryTuples(PGresult *res);
int PQgetisnull(PGresult *res, int row_number, int column_number);
ALIAS:
null = 0
# TODO: handle data in binary format
SV *PQgetvalue(PGresult *res, int row_number, int column_number);
ALIAS:
value = 0
PREINIT:
char *pv;
CODE:
if (PQgetisnull(res, row_number, column_number))
RETVAL = &PL_sv_undef;
else {
pv = PQgetvalue(res, row_number, column_number);
if (pv)
RETVAL = newSVpvn_utf8(pv, PQgetlength(res, row_number, column_number), 1);
else
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
void
PQgettuple(PGresult *res, UV i = 0)
ALIAS:
row = 0
PREINIT:
int rows, cols, j;
PPCODE:
rows = PQntuples(res);
cols = PQnfields(res);
if ((i > rows) || !cols)
XSRETURN(0);
else {
if (GIMME_V != G_ARRAY) cols = 1;
EXTEND(SP, cols);
for (j = 0; j < cols; j++) {
if (!PQgetisnull(res, i, j)) {
char *pv = PQgetvalue(res, i, j);
if (pv) {
PUSHs(newSVpvn_utf8(pv, PQgetlength(res, i, j), 1));
continue;
}
}
PUSHs(&PL_sv_undef);
}
XSRETURN(cols);
}
void
PQgettuple_as_hash(PGresult *res, ...)
ALIAS:
rowAsHash = 0
PREINIT:
int i, rows, cols;
PPCODE:
i = (items > 1 ? SvIV(ST(1)) : 0);
rows = PQntuples(res);
cols = PQnfields(res);
if ((i > rows) || !cols)
XSRETURN(0);
else {
int j;
HV *hv = newHV();
SV *rv = newRV_noinc((SV*)hv);
SV *tmp = NULL;
for (j = 0; j < cols; j++) {
SV *key;
SV *val = ( PQgetisnull(res, i, j)
? newSV(0)
: newSVpvn_utf8(PQgetvalue(res, i, j), PQgetlength(res, i, j), 1));
if ((items > j + 2) && SvOK(ST(j + 2))) {
key = ST(j + 2);
}
else {
if (!tmp) tmp = sv_newmortal();
key = tmp;
sv_setpv(key, PQfname(res, j));
SvUTF8_on(key);
}
/*fprintf(stderr, "*>> hv_store_ent(0x%p, %s, %s)\n", hv, SvPV_nolen(key), SvPV_nolen(val));*/
hv_store_ent(hv, key, val, 0);
}
mPUSHs(rv);
XSRETURN(1);
}
void
PQgetcolumn(PGresult *res, int j = 0)
ALIAS:
column = 0
PREINIT:
int rows, cols, i;
PPCODE:
rows = PQntuples(res);
cols = PQnfields(res);
if ((j > cols) || !rows)
XSRETURN(0);
else {
if (GIMME_V != G_ARRAY) rows = 1;
EXTEND(SP, rows);
for (i = 0; i < rows; i++) {
if (!PQgetisnull(res, i, j)) {
char *pv = PQgetvalue(res, i, j);
if (pv) {
PUSHs(newSVpvn_utf8(pv, PQgetlength(res, i, j), 1));
continue;
}
}
PUSHs(&PL_sv_undef);
}
XSRETURN(rows);
}
void
PQgettuples(PGresult *res)
ALIAS:
rows = 0
PREINIT:
int rows, cols, i, j;
PPCODE:
rows = PQntuples(res);
cols = PQnfields(res);
if (GIMME_V != G_ARRAY) {
mPUSHi(rows);
XSRETURN(1);
}
else {
EXTEND(SP, rows);
for (i = 0; i < rows; i++) {
AV *av = newAV();
mPUSHs(newRV_noinc((SV*)av));
if (cols) av_extend(av, cols - 1);
for (j = 0; j < cols; j++) {
SV *val = ( PQgetisnull(res, i, j)
? &PL_sv_undef
: newSVpvn_utf8(PQgetvalue(res, i, j), PQgetlength(res, i, j), 1) );
av_store(av, j, val);
}
}
XSRETURN(rows);
}
void
PQgettuples_as_hashes(PGresult *res)
ALIAS:
rowsAsHashes = 0
PREINIT:
int rows, cols, i, j;
PPCODE:
rows = PQntuples(res);
cols = PQnfields(res);
if (GIMME_V != G_ARRAY) {
mPUSHi(cols);
XSRETURN(1);
}
else {
SV **names;
Newx(names, cols, SV *);
EXTEND(SP, rows);
for (j = 0; j < cols; j++) {
if (items - 1 > j) {
names[j] = ST(j - 1);
}
else {
names[j] = sv_2mortal(newSVpv(PQfname(res, j), 0));
SvUTF8_on(names[j]);
}
}
for (i = 0; i < rows; i++) {
HV *hv = newHV();
for (j = 0; j < cols; j++) {
SV *val = ( PQgetisnull(res, i, j)
? newSV(0)
: newSVpvn_utf8(PQgetvalue(res, i, j), PQgetlength(res, i, j), 1) );
hv_store_ent(hv, names[j], val, 0);
}
mPUSHs(newRV_noinc((SV*)hv));
}
Safefree(names);
XSRETURN(rows);
}
void
PQgetcolumns(PGresult *res)
ALIAS:
columns = 0
PREINIT:
int rows, cols, i, j;
PPCODE:
rows = PQntuples(res);
cols = PQnfields(res);
if (GIMME_V != G_ARRAY) {
mPUSHi(cols);
XSRETURN(1);
}
else {
EXTEND(SP, rows);
for (j = 0; j < cols; j++) {
AV *av = newAV();
mPUSHs(newRV_noinc((SV*)av));
if (rows) av_extend(av, rows - 1);
for (i = 0; i < rows; i++) {
if (!PQgetisnull(res, i, j)) {
char *pv = PQgetvalue(res, i, j);
if (pv) {
av_store(av, i, newSVpvn_utf8(pv, PQgetlength(res, i, j), 1));
continue;
}
}
av_store(av, i, &PL_sv_undef);
}
}
XSRETURN(cols);
}
int PQgetlength(PGresult *res, int row_number, int column_number);
ALIAS:
valueLength = 0
int PQnparams(PGresult *res)
ALIAS:
nParams = 0
Oid PQparamtype(PGresult *res, int param_number)
ALIAS:
paramType = 0
# void PQprint(FILE *fout, PGresult *res, PQprintOpt *po);
char *PQcmdStatus(PGresult *res)
SV *PQcmdTuples(PGresult *res)
ALIAS:
cmdRows = 0
PREINIT:
char *pv;
CODE:
pv = PQcmdTuples(res);
if (!pv || !pv[0])
RETVAL = &PL_sv_undef;
else
RETVAL = my_newSVpv_utf8(aTHX_ pv);
OUTPUT:
RETVAL
Oid PQoidValue(PGresult *res)
( run in 1.136 second using v1.01-cache-2.11-cpan-5511b514fd6 )