fix
[libdbw.git] / include / pg / pg.h
blob8174f0c82b05c740644d89dc5dae3a840843c5ec
1 #ifndef __PGWRAPPER_H__
2 #define __PGWRAPPER_H__
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdint.h>
7 #include <stdarg.h>
8 #include <time.h>
9 #include <endian.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <pthread.h>
14 #include <gmp.h>
15 #include <libpq-fe.h>
16 #include <pgtypes_date.h>
17 #include <pgtypes_numeric.h>
18 #include <pgtypes_timestamp.h>
19 #include <libex/str.h>
20 #include <libex/list.h>
21 #include <libex/tree.h>
22 #include "pgconsts.h"
23 #include "pgerrcodes.h"
25 #define NUMERIC_POS 0x0000
26 #define NUMERIC_NEG 0x4000
27 #define NUMERIC_SHORT 0x8000
28 #define NUMERIC_DSCALE_MASK 0x3FFF
30 #define UUID_LEN 16
32 typedef int64_t money_t;
33 typedef int64_t chatl_t;
35 typedef struct pgpool pgpool_t;
36 typedef struct {
37 time_t lastm;
38 list_item_t *node;
39 int status;
40 const char *msg;
41 char *cmd;
42 PGconn *db;
43 rbtree_t *pres;
44 // pgpool
45 pgpool_t *pool;
46 time_t tm_released;
47 list_item_t *li;
48 } pgconn_t;
49 pgconn_t *pg_connect (const char *conn_info);
50 void pg_disconnect (pgconn_t *conn);
52 typedef struct {
53 int status;
54 char *msg;
55 PGresult *stmt;
56 const char *stmtName;
57 PGresult *stmt_prep;
58 int pg_status;
59 int nrecs;
60 int nflds;
61 int nrows;
62 int nparams;
63 char *sqlstate;
64 } pgres_t;
65 void pg_close (pgres_t *res);
67 typedef struct {
68 int32_t len;
69 uint32_t bit;
70 } bit32_t;
72 typedef struct {
73 int64_t time;
74 int32_t day;
75 int32_t month;
76 } interval_t;
78 typedef union {
79 int32_t i4;
80 int64_t i8;
81 float f4;
82 double f8;
83 char *s;
84 int8_t b;
85 int32_t d;
86 timestamp tm;
87 interval_t intv;
88 mpq_t q;
89 bit32_t bit32;
90 struct in_addr sin_addr;
91 unsigned char uuid [UUID_LEN];
92 #ifdef PG_USER_DEFINED_DATA
93 PG_USER_DEFINED_DATA
94 #endif
95 } pgval_t;
96 int timestamp_to_tm (timestamp dt, struct tm *tm);
97 struct tm *date_to_tm (date dt, struct tm *tm);
98 struct tm *interval_to_tm(interval_t *span, struct tm *tm);
100 typedef struct pgfld pgfld_t;
101 typedef void (*setfld_h) (pgfld_t*, int, Oid*, const char**, int*, int*);
102 struct pgfld {
103 int is_null;
104 int type;
105 int16_t dscale;
106 pgval_t data;
107 size_t len;
108 setfld_h setfld;
111 #ifndef NAMEDATALEN
112 #define NAMEDATALEN 64
113 #endif
114 typedef struct {
115 float order;
116 char label [NAMEDATALEN];
117 } pgenumval_t;
119 typedef struct {
120 uint32_t oid;
121 int len;
122 pgenumval_t vals [0];
123 } pgenum_t;
124 pgenum_t *pg_enum (pgconn_t *conn, const char *typname);
126 void pg_get_int (pgres_t *res, int row ,int col, pgfld_t *fld);
127 void pg_get_bigint (pgres_t *res, int row ,int col, pgfld_t *fld);
128 void pg_get_float (pgres_t *res, int rpw, int col, pgfld_t *fld);
129 void pg_get_double (pgres_t *res, int row, int col, pgfld_t *fld);
130 void pg_get_varchar (pgres_t *res, int row, int col, pgfld_t *fld);
131 #define pg_get_text(res,row,col,fld) pg_get_varchar(res,row,col,fld)
132 void pg_get_bool (pgres_t *res, int row ,int col, pgfld_t *fld);
133 void pg_get_date (pgres_t *res, int row, int col, pgfld_t *fld);
134 void pg_get_timestamp (pgres_t *res, int row, int col, pgfld_t *fld);
135 void pg_get_interval (pgres_t *res, int row, int col, pgfld_t *fld);
136 void pg_get_numeric (pgres_t *res, int row, int col, pgfld_t *fld);
137 void pg_get_uuid (pgres_t *res, int row, int col, pgfld_t *fld);
138 void pg_get_bytea (pgres_t *res, int row, int col, pgfld_t *fld);
139 void pg_get_inet (pgres_t *res, int row, int col, pgfld_t *fld);
140 void pg_get_bit32 (pgres_t *res, int row, int col, pgfld_t *fld);
142 void pg_set (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
143 void pg_set_int (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
144 void pg_set_bigint (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
145 void pg_set_float (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
146 void pg_set_double (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
147 void pg_set_varchar (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
148 static inline void pg_set_char(pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts) { pg_set_varchar(fld,col,types,vals,lens,fmts); };
149 void pg_set_bool (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
150 void pg_set_date (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
151 void pg_set_timestamp (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
152 void pg_set_uuid (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
153 void pg_set_bytea (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
154 void pg_set_bit32 (pgfld_t *fld, int col, Oid *types, const char **vals, int *lens, int *fmts);
156 void pg_clear_numeric (pgfld_t *fld);
158 str_t *pg_str_double (pgfld_t *fld, int base, int digits);
159 str_t *pg_str_float (pgfld_t *fld, int base, int digits);
160 str_t *pg_str_int (pgfld_t *fld, int base);
161 str_t *pg_str_bigint (pgfld_t *fld, int base);
162 str_t *pg_str_numeric_f (pgfld_t *fld, int base, int float_prec);
163 str_t *pg_str_numeric_q (pgfld_t *fld, int base);
164 static inline char *pg_str_timestamp (pgfld_t *fld) {
165 return PGTYPEStimestamp_to_asc(fld->data.tm);
167 static inline char *pg_str_date (pgfld_t *fld) {
168 return PGTYPESdate_to_asc(fld->data.d);
171 #define PG_DEF_MPZ { ._mp_alloc = 0, ._mp_size = 0, ._mp_d = NULL }
172 #define PG_DEF_MPQ { ._mp_num = PG_DEF_MPZ, ._mp_den = PG_DEF_MPZ }
173 #define PG_DEF_NUMERIC_DATA { .q = {PG_DEF_MPQ} }
175 #define PG_DEF { .is_null = 1, .type = 0, .setfld = pg_set }
176 #define PG_DEF_INT { .is_null = 1, .type = OID_INT4, .setfld = pg_set_int }
177 #define PG_DEF_BIGINT { .is_null = 1, .type = OID_INT8, .setfld = pg_set_bigint }
178 #define PG_DEF_FLOAT { .is_null = 1, .type = OID_FLOAT4, .setfld = pg_set_float }
179 #define PG_DEF_DOUBLE { .is_null = 1, .type = OID_FLOAT8, .setfld = pg_set_double }
180 #define PG_DEF_VARCHAR { .is_null = 1, .type = OID_VARCHAR, .setfld = pg_set_varchar }
181 #define PG_DEF_CHAR { .is_null = 1, .type = OID_CHAR, .setfld = pg_set_char }
182 #define PG_DEF_BOOL { .is_null = 1, .type = OID_BOOL, .setfld = pg_set_bool }
183 #define PG_DEF_DATE { .is_null = 1, .type = OID_DATE, .setfld = pg_set_date }
184 #define PG_DEF_TIMESTAMP { .is_null = 1, .type = OID_TIMESTAMP, .setfld = pg_set_timestamp }
185 #define PG_DEF_UUID { .is_null = 1, .type = OID_UUID, .setfld = pg_set_uuid }
186 #define PG_DEF_BYTEA { .is_null = 1, .type = OID_BYTEA, .setfld = pg_set_bytea }
187 #define PG_DEF_BIT32 { .is_null = 1, .type = OID_BIT, .setfld = pg_set_bit32 }
188 #define PG_DEF_MONEY { .is_null = 1, .type = OID_MONEY, .setfld = pg_set_bigint }
189 #define PG_DEF_TEXT { .is_null = 1, .type = OID_TEXT, .setfld = pg_set_varchar }
191 #define PG_INIT(X) (X)->is_null = 0; (X)->type = 0, (X)->setfld = pg_set
192 #define PG_INIT_INT(X) (X)->is_null = 0; (X)->type = OID_INT4; (X)->setfld = pg_set_int
193 #define PG_INIT_BIGINT(X) (X)->is_null = 0; (X)->type = OID_INT8; (X)->setfld = pg_set_bigint
194 #define PG_INIT_FLOAT(X) (X)->is_null = 0; (X)->type = OID_FLOAT4; (X)->setfld = pg_set_float
195 #define PG_INIT_DOUBLE(X) (X)->is_null = 0; (X)->type = OID_FLOAT8; (X)->setfld = pg_set_double
196 #define PG_INIT_VARCHAR(X) (X)->is_null = 0; (X)->type = OID_VARCHAR; (X)->setfld = pg_set_varchar
197 #define PG_INIT_CHAR(X) (X)->is_null = 0; (X)->type = OID_CHAR; (X)->setfld = pg_set_char
198 #define PG_INIT_BOOL(X) (X)->is_null = 0; (X)->type = OID_BOOL; (X)->setfld = pg_set_bool
199 #define PG_INIT_DATE(X) (X)->is_null = 0; (X)->type = OID_DATE; (X)->setfld = pg_set_date
200 #define PG_INIT_TIMESTAMP(X) (X)->is_null = 0; (X)->type = OID_TIMESTAMP; (X)->setfld = pg_set_timestamp
201 #define PG_INIT_UUID(X) (X)->is_null = 0; (X)->type = OID_UUID; (X)->setfld = pg_set_uuid
202 #define PG_INIT_BYTEA(X) (X)->is_null = 0; (X)->type = OID_BYTEA; (X)->setfld = pg_set_bytea
203 #define PG_INIT_BIT32(X) (X)->is_null = 0; (X)->type = OID_BIT; (X)->setfld = pg_set_bit32
204 #define PG_INIT_MONEY(X) (X)->is_null = 0; (X)->type = OID_MONEY; (X)->setfld = pg_set_bigint
205 #define PG_INIT_TEXT(X) (X)->is_null = 0; (X)->type = OID_TEXT; (X)->setfld = pg_set_bigint
207 #define PG_SET(X,V) (X)->is_null = 0; (X)->data.s = V
208 #define PG_SET_NULL(X) (X)->is_null = 1
209 #define PG_SET_INT(X,V) (X)->is_null = 0; (X)->data.i4 = V
210 #define PG_SET_BIGINT(X,V) (X)->is_null = 0; (X)->data.i8 = V
211 #define PG_SET_FLOAT(X,V) (X)->is_null = 0; (X)->data.f4 = V
212 #define PG_SET_DOUBLE(X,V) (X)->is_null = 0; (X)->data.f8 = V
213 #define PG_SET_VARCHAR(X,V) (X)->is_null = 0; (X)->data.s = V
214 #define PG_SET_CHAR(X,V) (X)->is_null = 0; (X)->data.s = V
215 #define PG_SET_BOOL(X,V) (X)->is_null = 0; (X)->data.b = V ? 1 : 0
216 #define PG_SET_DATE(X,V) (X)->is_null = 0; (X)->data.d = V
217 #define PG_SET_TIMESTAMP(X,V) (X)->is_null = 0; (X)->data.tm = V
218 #define PG_SET_BYTEA(X,V,L) (X)->is_null = 0; (X)->data.s = V; (X)->len = L
219 #define PG_SET_UUID(X,V) (X)->is_null = 0; memcpy((X)->data.uuid, V, UUID_LEN)
220 #define PG_SET_BIT32(X,V) (X)->is_null = 0, (X)->data.bit32.bit = V, (X)->data.bit32.len = 32
221 #define PG_SET_TEXT(X,V) (X)->is_null = 0; (X)->data.s = V
222 #define PG_SET_MONEY(X,V) PG_SET_BIGINT(X,V)
224 #define PG_CLR_NUMERIC(X) mpq_clear((X)->data.q)
226 #define PG_DEFAULT 0
227 typedef enum { PG_ISOLATION_DEFAULT=PG_DEFAULT, PG_SERIALIZABLE, PG_REPEATABLE_READ, PG_READ_COMMITTED, PG_READ_UNCOMMITTED } pg_level_t;
228 typedef enum { PG_RW_DEFAULT=PG_DEFAULT, PG_READ_WRITE, PG_READ_ONLY } pg_rw_t;
230 #define PG_READ_WRITE 1
231 #define PG_READ_ONLY 2
233 int pg_rows (pgres_t *res);
235 void pg_execva (pgconn_t *conn, pgres_t *res, pgfld_t *first, va_list ap);
236 pgres_t *pg_exec (pgconn_t *conn, const char *sql, pgfld_t *arg, ...);
237 pgres_t *pg_execv (pgconn_t *conn, const char *sql, int argc, pgfld_t **args);
238 pgres_t *pg_execl (pgconn_t *conn, const char *sql, list_t *args);
239 int pg_prepare (pgconn_t *conn, const char *name, const char *sql, int arg, ...);
240 pgres_t *pg_pnexec (pgconn_t *conn, const char *name, pgfld_t *arg, ...);
241 void pg_release (pgconn_t *conn, const char *name);
242 void pg_pexec (pgconn_t *conn, pgres_t *res, pgfld_t *arg, ...);
243 int pg_exec_sql (pgconn_t *conn, const char *sql);
244 static inline int pg_start(pgconn_t *conn) { return pg_exec_sql(conn, "start transaction"); }
245 int pg_start2 (pgconn_t *conn, pg_level_t level, pg_rw_t rw);
246 static inline int pg_commit(pgconn_t *conn) { return pg_exec_sql(conn, "commit"); }
247 static inline int pg_rollback(pgconn_t *conn) { return pg_exec_sql(conn, "rollback"); }
249 typedef enum {
250 PGPOOL_ERROR_HANDLER,
251 PGPOOL_CONNINFO,
252 PGPOOL_LIVINGTIME,
253 PGPOOL_MAXLEN
254 } pgpool_opt_t;
256 typedef void (*pgpool_error_h) (pgconn_t*);
257 struct pgpool {
258 char *conn_info;
259 time_t livingtime;
260 list_t *pg_free;
261 list_t *pg_busy;
262 pgpool_error_h on_error;
263 pthread_mutex_t locker;
264 pthread_cond_t cond;
265 pthread_condattr_t cond_attr;
266 pthread_t th;
267 int is_alive;
268 int maxlen;
271 void pgpool_setopt_err (pgpool_t *pool, pgpool_opt_t opt, pgpool_error_h arg);
272 void pgpool_setopt_str (pgpool_t *pool, pgpool_opt_t opt, char *arg);
273 void pgpool_setopt_int (pgpool_t *pool, pgpool_opt_t opt, long long int arg);
274 #define pgpool_setopt(pool,opt,arg) \
275 _Generic((arg), \
276 pgpool_error_h: pgpool_setopt_err, \
277 char*: pgpool_setopt_str, \
278 default: pgpool_setopt_int \
279 )(pool,opt,arg)
281 pgpool_t *pgpool_create ();
282 int pgpool_start (pgpool_t *pool);
283 pgconn_t *pgpool_get (pgpool_t *pool);
284 void pgpool_release (pgconn_t *conn);
285 void pgpool_free (pgpool_t *pool);
287 #endif // __PGWRAPPER_H__