1 /*Copyright (c) Brian B.
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 3 of the License, or (at your option) any later version.
7 See the file LICENSE included with this distribution for more
14 #include <sys/types.h>
15 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
21 #include <libex/list.h>
22 #include <libex/net.h>
23 #include <libex/endian.h>
24 #include "pgerrcodes.h"
27 #define EPG_PORT 0x80000000
28 #define EPG_ERRNO 0x40000000
29 #define EPG_PROTO 0x20000000
30 #define EPG_HOST 0x0fffffff
32 #define PG_NRECS(C) C->row_list->len
33 #define PG_NFLDS(C) C->rowdesc->nflds
34 #define PG_FLDLEN(C,R,F) C->rows[R]->fields[F].len
35 #define PG_DATA(C,R,F) C->rows[R]->fields[F].data
36 #define PG_ISNULL(C,R,F) C->rows[R]->fields[F].len >= 0 ? 0 : 1
37 #define PG_TYPE(C,F) C->rowdesc->fields[F].oid_field
39 #define CHECK_BOUNDS(C,R,F) (R >= 0 && R < PG_NRECS(C) && F >= 0 && F < PG_NFLDS(C))
48 typedef struct pgpool pgpool_t
;
56 pgmsg_datarow_t
**rows
;
59 pgmsg_rowdesc_t
*rowdesc
;
60 pgmsg_cmd_complete_t
*complete
;
64 char *client_encoding
;
65 char *server_encoding
;
85 void pgconn_init (const char *pg_srv_addr
, const char *pg_srv_service
);
86 pgconn_t
*pg_connect (const char *url
);
88 const int pg_error (pgconn_t
*conn
, pgerror_t
*e
);
90 int pg_error (pgconn_t
*conn
, pgerror_t
*e
);
92 static inline char pg_ready (pgconn_t
*conn
) {
93 return conn
->ready
? conn
->ready
->tr
: 0;
95 int pg_execsql (pgconn_t
*conn
, const char *sql
, size_t sql_len
);
96 int pg_copyin (pgconn_t
*conn
, const char *table_name
);
97 int pg_copyin_sendln (pgconn_t
*conn
, pgfld_t
**flds
);
98 int pg_copyin_end (pgconn_t
*conn
);
99 static inline int pg_start (pgconn_t
* conn
) {
100 return pg_execsql(conn
, CONST_STR_LEN("start transaction"));
102 static inline int pg_commit (pgconn_t
*conn
) {
103 return pg_execsql(conn
, CONST_STR_LEN("commit"));
105 static inline int pg_rollback (pgconn_t
*conn
) {
106 return pg_execsql(conn
, CONST_STR_LEN("rollback"));
108 int pg_prepareln (pgconn_t
*conn
, const char *name
, size_t name_len
,
109 const char *sql
, size_t sql_len
, int fld_len
, pgfld_t
**flds
);
110 static inline int pg_preparel (pgconn_t
*conn
, const char *sql
, size_t sql_len
, int fld_len
, pgfld_t
**flds
) {
111 return pg_prepareln(conn
, CONST_STR_NULL
, sql
, sql_len
, fld_len
, flds
);
113 int pg_preparen (pgconn_t
*conn
, const char *name
, size_t name_len
,
114 const char *sql
, size_t sql_len
, pgfld_t
*fld
, ...);
115 int pg_prepare (pgconn_t
*conn
, const char *sql
, size_t sql_len
, pgfld_t
*fld
, ...);
116 int pg_execln (pgconn_t
*conn
, const char *portal
, size_t portal_len
,
117 const char *stmt
, size_t stmt_len
,
118 int fld_len
, pgfld_t
**flds
, int res_fmt_len
, int *res_fmt
, int max_data
);
119 static inline int pg_execl (pgconn_t
*conn
, int fld_len
, pgfld_t
**flds
, int res_fmt_len
, int *res_fmt
, int max_data
) {
120 return pg_execln(conn
, CONST_STR_NULL
, CONST_STR_NULL
, fld_len
, flds
, res_fmt_len
, res_fmt
, max_data
);
122 int pg_execvn (pgconn_t
*conn
, const char *portal
, size_t portal_len
, const char *stmt
, size_t stmt_len
, int max_data
, int fmt_out
, pgfld_t
*fld
, va_list ap
);
123 static inline int pg_execv (pgconn_t
*conn
, int max_data
, int out_fmt
, pgfld_t
*fld
, va_list ap
) {
124 return pg_execvn(conn
, CONST_STR_NULL
, CONST_STR_NULL
, max_data
, out_fmt
, fld
, ap
);
126 int pg_execn (pgconn_t
*conn
, const char *portal
, size_t portal_len
, const char *stmt
, size_t stmt_len
, int max_data
, int out_fmt
, pgfld_t
*fld
, ...);
127 int pg_exec (pgconn_t
*conn
, int max_data
, int out_fmt
, pgfld_t
*fld
, ...);
128 int pg_nextn (pgconn_t
*conn
, const char *portal
, size_t portal_len
, int max_data
);
129 static inline int pg_next (pgconn_t
*conn
, int max_data
) {
130 return pg_nextn(conn
, CONST_STR_NULL
, max_data
);
132 static inline char pg_getready (pgconn_t
*conn
) {
133 return conn
->ready
? conn
->ready
->tr
: 0;
135 int pg_release (pgconn_t
*conn
, const char *name
, size_t name_len
);
136 void pg_close (pgconn_t
*conn
);
137 void pg_disconnect(pgconn_t
*conn
);
139 static inline int pg_nrecs (pgconn_t
*conn
) { return PG_NRECS(conn
); };
140 static inline int pg_nflds (pgconn_t
*conn
) { return conn
->rowdesc
? PG_NFLDS(conn
) : 0; };
141 static inline int pg_isnull (pgconn_t
*conn
, int row
, int col
) { return PG_ISNULL(conn
, row
, col
); };
143 #define pg_getdate(C,R,F) pg_geti32(C,R,F)
144 #define pg_gettm(C,R,F) pg_geti64(C,R,F)
146 const strptr_t
pg_get (pgconn_t
*conn
, int row
, int col
);
148 strptr_t
pg_get (pgconn_t
*conn
, int row
, int col
);
150 static inline int pg_fldlen (pgconn_t
*conn
, int row
, int col
) {
151 assert(CHECK_BOUNDS(conn
, row
, col
));
152 return PG_FLDLEN(conn
, row
, col
);
154 cstr_t
*pg_getstr (pgconn_t
*conn
, int row
, int col
);
155 static inline int16_t pg_geti16 (pgconn_t
*conn
, int row
, int col
) {
156 assert(CHECK_BOUNDS(conn
, row
, col
));
157 return be16toh(*(int16_t*)PG_DATA(conn
, row
, col
));
160 static inline int32_t pg_geti32 (pgconn_t
*conn
, int row
, int col
) {
161 assert(CHECK_BOUNDS(conn
, row
, col
));
162 return be32toh(*(int32_t*)PG_DATA(conn
, row
, col
));
164 static inline int64_t pg_geti64 (pgconn_t
*conn
, int row
, int col
) {
165 assert(CHECK_BOUNDS(conn
, row
, col
));
166 return be64toh(*(int64_t*)PG_DATA(conn
, row
, col
));
168 static inline double pg_getd (pgconn_t
*conn
, int row
, int col
) {
169 assert(CHECK_BOUNDS(conn
, row
, col
));
170 return pg_conv_double(*(double*)PG_DATA(conn
, row
, col
));
172 static inline float pg_getf (pgconn_t
*conn
, int row
, int col
) {
173 assert(CHECK_BOUNDS(conn
, row
, col
));
174 return pg_conv_float(*(float*)PG_DATA(conn
, row
, col
));
176 static inline int8_t pg_getbool (pgconn_t
*conn
, int row
, int col
) {
177 assert(CHECK_BOUNDS(conn
, row
, col
));
178 return *PG_DATA(conn
, row
, col
);
180 uint32_t pg_getx32 (pgconn_t
*conn
, int row
, int col
);
181 pg_intv_t
pg_getintv (pgconn_t
*conn
, int row
, int col
);
182 int32_t pg_getinet4 (pgconn_t
*conn
, int row
, int col
);
184 static inline void pg_getnum (pgconn_t
*conn
, int row
, int col
, mpq_t res
, uint16_t *dscale
) {
185 assert(CHECK_BOUNDS(conn
, row
, col
));
186 pg_get_numeric(PG_DATA(conn
, row
, col
), res
, dscale
);
189 static inline unsigned char *pg_getuuid (pgconn_t
*conn
, int row
, int col
) {
190 assert(CHECK_BOUNDS(conn
, row
, col
));
191 return PG_DATA(conn
, row
, col
);