pg_fld.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /*
  2. * Portions Copyright (C) 2001-2003 FhG FOKUS
  3. * Copyright (C) 2003 August.Net Services, LLC
  4. * Portions Copyright (C) 2005-2008 iptelorg GmbH
  5. *
  6. * This file is part of SER, a free SIP server.
  7. *
  8. * SER is free software; you can redistribute it and/or modify it under the
  9. * terms of the GNU General Public License as published by the Free Software
  10. * Foundation; either version 2 of the License, or (at your option) any later
  11. * version
  12. *
  13. * For a license to use the ser software under conditions other than those
  14. * described here, or to purchase support for this software, please contact
  15. * iptel.org by e-mail at the following addresses: [email protected]
  16. *
  17. * SER is distributed in the hope that it will be useful, but WITHOUT ANY
  18. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  19. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  20. * details.
  21. *
  22. * You should have received a copy of the GNU General Public License along
  23. * with this program; if not, write to the Free Software Foundation, Inc., 59
  24. * Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. */
  26. /*!
  27. * \file
  28. * \brief DB_POSTGRES :: Data field conversion and type checking functions.
  29. * \ingroup db_postgres
  30. * Module: \ref db_postgres
  31. */
  32. #include "pg_fld.h"
  33. #include "pg_con.h" /* flags */
  34. #include "pg_mod.h"
  35. #include "../../lib/srdb2/db_drv.h"
  36. #include "../../mem/mem.h"
  37. #include "../../dprint.h"
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40. #include <netinet/in.h>
  41. #include <stdint.h>
  42. #include <string.h>
  43. /**
  44. * This is the epoch time in time_t format, this value is used to convert
  45. * timestamp values to/from PostgreSQL format.
  46. * 2000-01-01 00:00:00 +0000 as the value of time_t in UTC
  47. */
  48. #define PG_EPOCH_TIME ((int64_t)946684800)
  49. /** Frees memory used by a pg_fld structure.
  50. * This function frees all memory used by a pg_fld structure
  51. * @param fld Generic db_fld_t* structure being freed.
  52. * @param payload The postgresql extension structure to be freed
  53. */
  54. static void pg_fld_free(db_fld_t* fld, struct pg_fld* payload)
  55. {
  56. db_drv_free(&payload->gen);
  57. if (payload->name) pkg_free(payload->name);
  58. pkg_free(payload);
  59. }
  60. int pg_fld(db_fld_t* fld, char* table)
  61. {
  62. struct pg_fld* res;
  63. res = (struct pg_fld*)pkg_malloc(sizeof(struct pg_fld));
  64. if (res == NULL) {
  65. ERR("postgres: No memory left\n");
  66. return -1;
  67. }
  68. memset(res, '\0', sizeof(struct pg_fld));
  69. if (db_drv_init(&res->gen, pg_fld_free) < 0) goto error;
  70. DB_SET_PAYLOAD(fld, res);
  71. return 0;
  72. error:
  73. if (res) pkg_free(res);
  74. return -1;
  75. }
  76. union ull {
  77. uint64_t ui64;
  78. uint32_t ui32[2];
  79. };
  80. static inline uint64_t htonll(uint64_t in)
  81. {
  82. union ull* p = (union ull*)&in;
  83. return ((uint64_t)htonl(p->ui32[0]) << 32) + (uint64_t)htonl(p->ui32[1]);
  84. }
  85. static inline uint64_t ntohll(uint64_t in)
  86. {
  87. union ull* p = (union ull*)&in;
  88. return ((uint64_t)ntohl(p->ui32[0]) << 32) + (uint64_t)ntohl(p->ui32[1]);
  89. }
  90. static inline void db_int2pg_int4(struct pg_params* dst, int i,
  91. db_fld_t* src)
  92. {
  93. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  94. pfld->v.int4[0] = htonl(src->v.int4);
  95. dst->fmt[i] = 1;
  96. dst->val[i] = pfld->v.byte;
  97. dst->len[i] = 4;
  98. }
  99. static inline void db_int2pg_int2(struct pg_params* dst, int i,
  100. db_fld_t* src)
  101. {
  102. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  103. pfld->v.int2[0] = htons(src->v.int4);
  104. dst->fmt[i] = 1;
  105. dst->val[i] = pfld->v.byte;
  106. dst->len[i] = 2;
  107. }
  108. static inline void db_int2pg_timestamp(struct pg_params* dst, int i,
  109. db_fld_t* src, unsigned int flags)
  110. {
  111. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  112. if (flags & PG_INT8_TIMESTAMP) {
  113. pfld->v.int8 = ((int64_t)src->v.int4 - PG_EPOCH_TIME) * 1000000;
  114. } else {
  115. pfld->v.dbl = (double)src->v.int4 - (double)PG_EPOCH_TIME;
  116. }
  117. pfld->v.int8 = htonll(pfld->v.int8);
  118. dst->fmt[i] = 1;
  119. dst->val[i] = pfld->v.byte;
  120. dst->len[i] = 8;
  121. }
  122. static inline void db_int2pg_int8(struct pg_params* dst, int i,
  123. db_fld_t* src)
  124. {
  125. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  126. pfld->v.int4[0] = 0;
  127. pfld->v.int4[1] = htonl(src->v.int4);
  128. dst->fmt[i] = 1;
  129. dst->val[i] = pfld->v.byte;
  130. dst->len[i] = 8;
  131. }
  132. static inline void db_int2pg_bool(struct pg_params* dst, int i, db_fld_t* src)
  133. {
  134. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  135. if (src->v.int4) pfld->v.byte[0] = 1;
  136. else pfld->v.byte[0] = 0;
  137. dst->fmt[i] = 1;
  138. dst->val[i] = pfld->v.byte;
  139. dst->len[i] = 1;
  140. }
  141. static inline void db_int2pg_inet(struct pg_params* dst, int i, db_fld_t* src)
  142. {
  143. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  144. pfld->v.byte[0] = AF_INET; /* Address family */
  145. pfld->v.byte[1] = 32; /* Netmask */
  146. pfld->v.byte[2] = 0; /* is CIDR */
  147. pfld->v.byte[3] = 4; /* Number of bytes */
  148. pfld->v.int4[1] = htonl(src->v.int4); /* Actuall IP address */
  149. dst->fmt[i] = 1;
  150. dst->val[i] = pfld->v.byte;
  151. dst->len[i] = 8;
  152. }
  153. static inline void db_float2pg_float4(struct pg_params* dst, int i, db_fld_t* src)
  154. {
  155. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  156. pfld->v.int4[0] = htonl(src->v.int4);
  157. dst->fmt[i] = 1;
  158. dst->val[i] = pfld->v.byte;
  159. dst->len[i] = 4;
  160. }
  161. static inline void db_float2pg_float8(struct pg_params* dst, int i, db_fld_t* src)
  162. {
  163. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  164. pfld->v.dbl = src->v.flt;
  165. pfld->v.int8 = htonll(pfld->v.int8);
  166. dst->fmt[i] = 1;
  167. dst->val[i] = pfld->v.byte;
  168. dst->len[i] = 8;
  169. }
  170. static inline void db_double2pg_float8(struct pg_params* dst, int i, db_fld_t* src)
  171. {
  172. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  173. pfld->v.int8 = htonll(src->v.int8);
  174. dst->fmt[i] = 1;
  175. dst->val[i] = pfld->v.byte;
  176. dst->len[i] = 8;
  177. }
  178. static inline void db_double2pg_float4(struct pg_params* dst, int i, db_fld_t* src)
  179. {
  180. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  181. pfld->v.flt = src->v.dbl;
  182. pfld->v.int4[0] = htonl(pfld->v.int4[0]);
  183. dst->fmt[i] = 1;
  184. dst->val[i] = pfld->v.byte;
  185. dst->len[i] = 4;
  186. }
  187. static inline void db_int2pg_bit(struct pg_params* dst, int i, db_fld_t* src)
  188. {
  189. struct pg_fld* pfld = DB_GET_PAYLOAD(src);
  190. pfld->v.int4[0] = htonl(32);
  191. pfld->v.int4[1] = htonl(src->v.int4);
  192. dst->fmt[i] = 1;
  193. dst->val[i] = pfld->v.byte;
  194. dst->len[i] = 8;
  195. }
  196. static inline void db_str2pg_string(struct pg_params* dst, int i,
  197. db_fld_t* src)
  198. {
  199. dst->fmt[i] = 1;
  200. dst->val[i] = src->v.lstr.s;
  201. dst->len[i] = src->v.lstr.len;
  202. }
  203. static inline void db_cstr2pg_string(struct pg_params* dst, int i,
  204. db_fld_t* src)
  205. {
  206. dst->fmt[i] = 0;
  207. dst->val[i] = src->v.cstr;
  208. }
  209. int pg_fld2pg(struct pg_params* dst, int off, pg_type_t* types,
  210. db_fld_t* src, unsigned int flags)
  211. {
  212. int i;
  213. struct pg_fld* pfld;
  214. if (src == NULL) return 0;
  215. for(i = 0; !DB_FLD_EMPTY(src) && !DB_FLD_LAST(src[i]); i++) {
  216. pfld = DB_GET_PAYLOAD(src + i);
  217. /* NULL value */
  218. if (src[i].flags & DB_NULL) {
  219. dst->val[off + i] = NULL;
  220. dst->len[off + i] = 0;
  221. continue;
  222. }
  223. switch(src[i].type) {
  224. case DB_INT:
  225. if (pfld->oid == types[PG_INT2].oid)
  226. db_int2pg_int2(dst, off + i, src + i);
  227. else if (pfld->oid == types[PG_INT4].oid)
  228. db_int2pg_int4(dst, off + i, src + i);
  229. else if ((pfld->oid == types[PG_TIMESTAMP].oid) ||
  230. (pfld->oid == types[PG_TIMESTAMPTZ].oid))
  231. db_int2pg_timestamp(dst, off + i, src + i, flags);
  232. else if (pfld->oid == types[PG_INT8].oid)
  233. db_int2pg_int8(dst, off + i, src + i);
  234. else if (pfld->oid == types[PG_INET].oid)
  235. db_int2pg_inet(dst, off + i, src + i);
  236. else if (pfld->oid == types[PG_BOOL].oid)
  237. db_int2pg_bool(dst, off + i, src + i);
  238. else if (pfld->oid == types[PG_BIT].oid)
  239. db_int2pg_bit(dst, off + i, src + i);
  240. else if (pfld->oid == types[PG_VARBIT].oid)
  241. db_int2pg_bit(dst, off + i, src + i);
  242. else goto bug;
  243. break;
  244. case DB_BITMAP:
  245. if (pfld->oid == types[PG_INT4].oid)
  246. db_int2pg_int4(dst, off + i, src + i);
  247. else if (pfld->oid == types[PG_INT8].oid)
  248. db_int2pg_int8(dst, off + i, src + i);
  249. else if (pfld->oid == types[PG_BIT].oid)
  250. db_int2pg_bit(dst, off + i, src + i);
  251. else if (pfld->oid == types[PG_VARBIT].oid)
  252. db_int2pg_bit(dst, off + i, src + i);
  253. else goto bug;
  254. break;
  255. case DB_DATETIME:
  256. if (pfld->oid == types[PG_INT4].oid)
  257. db_int2pg_int4(dst, off + i, src + i);
  258. else if ((pfld->oid == types[PG_TIMESTAMP].oid) ||
  259. (pfld->oid == types[PG_TIMESTAMPTZ].oid))
  260. db_int2pg_timestamp(dst, off + i, src + i, flags);
  261. else if (pfld->oid == types[PG_INT8].oid)
  262. db_int2pg_int8(dst, off + i, src + i);
  263. else goto bug;
  264. break;
  265. case DB_FLOAT:
  266. if (pfld->oid == types[PG_FLOAT4].oid)
  267. db_float2pg_float4(dst, off + i, src + i);
  268. else if (pfld->oid == types[PG_FLOAT8].oid)
  269. db_float2pg_float8(dst, off + i, src + i);
  270. else goto bug;
  271. break;
  272. case DB_DOUBLE:
  273. if (pfld->oid == types[PG_FLOAT4].oid)
  274. db_double2pg_float4(dst, off + i, src + i);
  275. else if (pfld->oid == types[PG_FLOAT8].oid)
  276. db_double2pg_float8(dst, off + i, src + i);
  277. else goto bug;
  278. break;
  279. case DB_STR:
  280. if (pfld->oid == types[PG_VARCHAR].oid ||
  281. pfld->oid == types[PG_BYTE].oid ||
  282. pfld->oid == types[PG_CHAR].oid ||
  283. pfld->oid == types[PG_TEXT].oid ||
  284. pfld->oid == types[PG_BPCHAR].oid)
  285. db_str2pg_string(dst, off + i, src + i);
  286. else goto bug;
  287. break;
  288. case DB_CSTR:
  289. if (pfld->oid == types[PG_VARCHAR].oid ||
  290. pfld->oid == types[PG_BYTE].oid ||
  291. pfld->oid == types[PG_CHAR].oid ||
  292. pfld->oid == types[PG_TEXT].oid ||
  293. pfld->oid == types[PG_BPCHAR].oid)
  294. db_cstr2pg_string(dst, off + i, src + i);
  295. else goto bug;
  296. break;
  297. case DB_BLOB:
  298. if (pfld->oid == types[PG_BYTE].oid)
  299. db_str2pg_string(dst, off + i, src + i);
  300. else goto bug;
  301. break;
  302. default:
  303. BUG("postgres: Unsupported field type %d in field %s\n",
  304. src[i].type, src[i].name);
  305. return -1;
  306. }
  307. }
  308. return 0;
  309. bug:
  310. BUG("postgres: Error while converting DB API type %d to Postgres Oid %d\n",
  311. src[i].type, pfld->oid);
  312. return -1;
  313. }
  314. int pg_check_fld2pg(db_fld_t* fld, pg_type_t* types)
  315. {
  316. int i;
  317. const char* name = "UNKNOWN";
  318. struct pg_fld* pfld;
  319. if (fld == NULL) return 0;
  320. for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
  321. pfld = DB_GET_PAYLOAD(fld + i);
  322. switch(fld[i].type) {
  323. case DB_INT:
  324. if (pfld->oid == types[PG_INT2].oid) continue;
  325. if (pfld->oid == types[PG_INT4].oid) continue;
  326. if (pfld->oid == types[PG_INT8].oid) continue;
  327. if (pfld->oid == types[PG_BOOL].oid) continue;
  328. if (pfld->oid == types[PG_INET].oid) continue;
  329. if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
  330. if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
  331. if (pfld->oid == types[PG_BIT].oid) continue;
  332. if (pfld->oid == types[PG_VARBIT].oid) continue;
  333. break;
  334. case DB_BITMAP:
  335. if (pfld->oid == types[PG_INT4].oid) continue;
  336. if (pfld->oid == types[PG_INT8].oid) continue;
  337. if (pfld->oid == types[PG_BIT].oid) continue;
  338. if (pfld->oid == types[PG_VARBIT].oid) continue;
  339. break;
  340. case DB_FLOAT:
  341. case DB_DOUBLE:
  342. if (pfld->oid == types[PG_FLOAT4].oid) continue;
  343. if (pfld->oid == types[PG_FLOAT8].oid) continue;
  344. break;
  345. case DB_CSTR:
  346. case DB_STR:
  347. if (pfld->oid == types[PG_BYTE].oid) continue;
  348. if (pfld->oid == types[PG_CHAR].oid) continue;
  349. if (pfld->oid == types[PG_TEXT].oid) continue;
  350. if (pfld->oid == types[PG_BPCHAR].oid) continue;
  351. if (pfld->oid == types[PG_VARCHAR].oid) continue;
  352. break;
  353. case DB_BLOB:
  354. if (pfld->oid == types[PG_BYTE].oid) continue;
  355. break;
  356. case DB_DATETIME:
  357. if (pfld->oid == types[PG_INT4].oid) continue;
  358. if (pfld->oid == types[PG_INT8].oid) continue;
  359. if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
  360. if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
  361. break;
  362. default:
  363. BUG("postgres: Unsupported field type %d, bug in postgres module\n",
  364. fld[i].type);
  365. return -1;
  366. }
  367. pg_oid2name(&name, types, pfld->oid);
  368. ERR("postgres: Cannot convert column '%s' of type %s "
  369. "to PostgreSQL column type '%s'\n",
  370. fld[i].name, db_fld_str[fld[i].type], name);
  371. return -1;
  372. }
  373. return 0;
  374. }
  375. int pg_resolve_param_oids(db_fld_t* vals, db_fld_t* match, int n1, int n2, PGresult* types)
  376. {
  377. struct pg_fld* pfld;
  378. int i;
  379. if (n1 + n2 != PQnparams(types)) {
  380. ERR("postgres: Number of command parameters do not match\n");
  381. return -1;
  382. }
  383. for(i = 0; i < n1; i++) {
  384. pfld = DB_GET_PAYLOAD(vals + i);
  385. pfld->oid = PQparamtype(types, i);
  386. }
  387. for(i = 0; i < n2; i++) {
  388. pfld = DB_GET_PAYLOAD(match + i);
  389. pfld->oid = PQparamtype(types, n1 + i);
  390. }
  391. return 0;
  392. }
  393. int pg_resolve_result_oids(db_fld_t* fld, int n, PGresult* types)
  394. {
  395. struct pg_fld* pfld;
  396. int i;
  397. if (fld == NULL) return 0;
  398. if (n != PQnfields(types)) {
  399. ERR("postgres: Result field numbers do not match\n");
  400. return -1;
  401. }
  402. for(i = 0; i < n; i++) {
  403. pfld = DB_GET_PAYLOAD(fld + i);
  404. pfld->oid = PQftype(types, i);
  405. }
  406. return 0;
  407. }
  408. int pg_check_pg2fld(db_fld_t* fld, pg_type_t* types)
  409. {
  410. int i;
  411. const char* name = "UNKNOWN";
  412. struct pg_fld* pfld;
  413. if (fld == NULL) return 0;
  414. for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
  415. pfld = DB_GET_PAYLOAD(fld + i);
  416. if (pfld->oid == 0) {
  417. ERR("postgres: Unknown type fields not supported\n");
  418. return -1;
  419. }
  420. switch(fld[i].type) {
  421. case DB_INT:
  422. if (pfld->oid == types[PG_INT2].oid) continue;
  423. if (pfld->oid == types[PG_INT4].oid) continue;
  424. if (pfld->oid == types[PG_INT8].oid) continue;
  425. if (pfld->oid == types[PG_BOOL].oid) continue;
  426. if (pfld->oid == types[PG_INET].oid) continue;
  427. if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
  428. if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
  429. if (pfld->oid == types[PG_BIT].oid) continue;
  430. if (pfld->oid == types[PG_VARBIT].oid) continue;
  431. break;
  432. case DB_BITMAP:
  433. if (pfld->oid == types[PG_INT2].oid) continue;
  434. if (pfld->oid == types[PG_INT4].oid) continue;
  435. if (pfld->oid == types[PG_INT8].oid) continue;
  436. if (pfld->oid == types[PG_BIT].oid) continue;
  437. if (pfld->oid == types[PG_VARBIT].oid) continue;
  438. break;
  439. case DB_FLOAT:
  440. if (pfld->oid == types[PG_FLOAT4].oid) continue;
  441. break;
  442. case DB_DOUBLE:
  443. if (pfld->oid == types[PG_FLOAT4].oid) continue;
  444. if (pfld->oid == types[PG_FLOAT8].oid) continue;
  445. break;
  446. case DB_CSTR:
  447. if (pfld->oid == types[PG_CHAR].oid) continue;
  448. if (pfld->oid == types[PG_TEXT].oid) continue;
  449. if (pfld->oid == types[PG_BPCHAR].oid) continue;
  450. if (pfld->oid == types[PG_VARCHAR].oid) continue;
  451. if (pfld->oid == types[PG_INT2].oid) continue;
  452. if (pfld->oid == types[PG_INT4].oid) continue;
  453. break;
  454. case DB_STR:
  455. case DB_BLOB:
  456. if (pfld->oid == types[PG_BYTE].oid) continue;
  457. if (pfld->oid == types[PG_CHAR].oid) continue;
  458. if (pfld->oid == types[PG_TEXT].oid) continue;
  459. if (pfld->oid == types[PG_BPCHAR].oid) continue;
  460. if (pfld->oid == types[PG_VARCHAR].oid) continue;
  461. if (pfld->oid == types[PG_INT2].oid) continue;
  462. if (pfld->oid == types[PG_INT4].oid) continue;
  463. break;
  464. case DB_DATETIME:
  465. if (pfld->oid == types[PG_INT2].oid) continue;
  466. if (pfld->oid == types[PG_INT4].oid) continue;
  467. if (pfld->oid == types[PG_TIMESTAMP].oid) continue;
  468. if (pfld->oid == types[PG_TIMESTAMPTZ].oid) continue;
  469. break;
  470. default:
  471. BUG("postgres: Unsupported field type %d, bug in postgres module\n",
  472. fld[i].type);
  473. return -1;
  474. }
  475. pg_oid2name(&name, types, pfld->oid);
  476. ERR("postgres: Cannot convert column '%s' of type %s "
  477. "to DB API field of type %s\n",
  478. fld[i].name, name, db_fld_str[fld[i].type]);
  479. return -1;
  480. }
  481. return 0;
  482. }
  483. static inline int pg_int2_2_db_cstr(db_fld_t* fld, char* val, int len)
  484. {
  485. struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
  486. int size, v;
  487. v = (int16_t)ntohs(*((int16_t*)val));
  488. size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
  489. if (size < 0 || size >= INT2STR_MAX_LEN) {
  490. BUG("postgres: Error while converting integer to string\n");
  491. return -1;
  492. }
  493. fld->v.cstr = pfld->buf;
  494. return 0;
  495. }
  496. static inline int pg_int4_2_db_cstr(db_fld_t* fld, char* val, int len)
  497. {
  498. struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
  499. int size, v;
  500. v = (int32_t)ntohl(*((int32_t*)val));
  501. size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
  502. if (len < 0 || size >= INT2STR_MAX_LEN) {
  503. BUG("postgres: Error while converting integer to string\n");
  504. return -1;
  505. }
  506. fld->v.cstr = pfld->buf;
  507. return 0;
  508. }
  509. static inline int pg_int2_2_db_str(db_fld_t* fld, char* val, int len)
  510. {
  511. struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
  512. int size, v;
  513. v = (int16_t)ntohs(*((int16_t*)val));
  514. size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
  515. if (size < 0 || size >= INT2STR_MAX_LEN) {
  516. BUG("postgres: Error while converting integer to string\n");
  517. return -1;
  518. }
  519. fld->v.lstr.s = pfld->buf;
  520. fld->v.lstr.len = size;
  521. return 0;
  522. }
  523. static inline int pg_int4_2_db_str(db_fld_t* fld, char* val, int len)
  524. {
  525. struct pg_fld* pfld = DB_GET_PAYLOAD(fld);
  526. int size, v;
  527. v = (int32_t)ntohl(*((int32_t*)val));
  528. size = snprintf(pfld->buf, INT2STR_MAX_LEN, "%-d", v);
  529. if (size < 0 || size >= INT2STR_MAX_LEN) {
  530. BUG("postgres: Error while converting integer to string\n");
  531. return -1;
  532. }
  533. fld->v.lstr.s = pfld->buf;
  534. fld->v.lstr.len = size;
  535. return 0;
  536. }
  537. static inline int pg_int2_2_db_int(db_fld_t* fld, char* val, int len)
  538. {
  539. fld->v.int4 = (int16_t)ntohs(*((int16_t*)val));
  540. return 0;
  541. }
  542. static inline int pg_int4_2_db_int(db_fld_t* fld, char* val, int len)
  543. {
  544. fld->v.int4 = (int32_t)ntohl(*((int32_t*)val));
  545. return 0;
  546. }
  547. static inline int pg_int8_2_db_int(db_fld_t* fld, char* val, int len)
  548. {
  549. fld->v.int8 = (int64_t)ntohll(*((int64_t*)val));
  550. return 0;
  551. }
  552. static inline int pg_bool2db_int(db_fld_t* fld, char* val, int len)
  553. {
  554. fld->v.int4 = val[0];
  555. return 0;
  556. }
  557. static inline int pg_inet2db_int(db_fld_t* fld, char* val, int len)
  558. {
  559. if (len != 8 || val[2] != 0) {
  560. ERR("postgres: Unsupported 'inet' format, column %s\n", fld->name);
  561. return -1;
  562. }
  563. if (val[0] != AF_INET) {
  564. ERR("postgres: Unsupported address family %d in field %s\n",
  565. val[0], fld->name);
  566. return -1;
  567. }
  568. if (val[1] != 32) {
  569. WARN("postgres: Netmasks shorter than 32-bits not supported, "
  570. "column %s\n", fld->name);
  571. }
  572. if (val[3] != 4) {
  573. ERR("postgres: Unsupported IP address size %d in column %s\n",
  574. val[3], fld->name);
  575. return -1;
  576. }
  577. fld->v.int4 = (int32_t)ntohl(((int32_t*)val)[1]);
  578. return 0;
  579. }
  580. static inline int pg_timestamp2db_int(db_fld_t* fld, char* val, int len,
  581. unsigned int flags)
  582. {
  583. if (flags & PG_INT8_TIMESTAMP) {
  584. /* int8 format */
  585. fld->v.int4 = (int64_t)ntohll(((int64_t*)val)[0]) / (int64_t)1000000 + PG_EPOCH_TIME;
  586. } else {
  587. /* double format */
  588. fld->v.int4 = PG_EPOCH_TIME + ntohll(((int64_t*)val)[0]);
  589. }
  590. return 0;
  591. }
  592. static inline int pg_bit2db_int(db_fld_t* fld, char* val, int len)
  593. {
  594. int size;
  595. size = ntohl(*(uint32_t*)val);
  596. if (size != 32) {
  597. ERR("postgres: Unsupported bit field size (%d), column %s\n",
  598. size, fld->name);
  599. return -1;
  600. }
  601. fld->v.int4 = ntohl(((uint32_t*)val)[1]);
  602. return 0;
  603. }
  604. static inline int pg_float42db_float(db_fld_t* fld, char* val, int len)
  605. {
  606. fld->v.int4 = (uint32_t)ntohl(*(uint32_t*)val);
  607. return 0;
  608. }
  609. static inline int pg_float42db_double(db_fld_t* fld, char* val, int len)
  610. {
  611. float tmp;
  612. tmp = ntohl(*(uint32_t*)val);
  613. fld->v.dbl = tmp;
  614. return 0;
  615. }
  616. static inline int pg_float82db_double(db_fld_t* fld, char* val, int len)
  617. {
  618. fld->v.int8 = ntohll(*(uint64_t*)val);
  619. return 0;
  620. }
  621. static inline int pg_string2db_cstr(db_fld_t* fld, char* val, int len)
  622. {
  623. fld->v.cstr = val;
  624. return 0;
  625. }
  626. static inline int pg_string2db_str(db_fld_t* fld, char* val, int len)
  627. {
  628. fld->v.lstr.s = val;
  629. fld->v.lstr.len = len;
  630. return 0;
  631. }
  632. int pg_pg2fld(db_fld_t* dst, PGresult* src, int row,
  633. pg_type_t* types, unsigned int flags)
  634. {
  635. char* val;
  636. int i, len, ret;
  637. Oid type;
  638. if (dst == NULL || src == NULL) return 0;
  639. ret = 0;
  640. for(i = 0; !DB_FLD_EMPTY(dst) && !DB_FLD_LAST(dst[i]); i++) {
  641. if (PQgetisnull(src, row, i)) {
  642. dst[i].flags |= DB_NULL;
  643. continue;
  644. } else {
  645. dst[i].flags &= ~DB_NULL;
  646. }
  647. type = PQftype(src, i);
  648. val = PQgetvalue(src, row, i);
  649. len = PQgetlength(src, row, i);
  650. switch(dst[i].type) {
  651. case DB_INT:
  652. if (type == types[PG_INT2].oid)
  653. ret |= pg_int2_2_db_int(dst + i, val, len);
  654. else if (type == types[PG_INT4].oid)
  655. ret |= pg_int4_2_db_int(dst + i, val, len);
  656. else if (type == types[PG_INT8].oid)
  657. ret |= pg_int8_2_db_int(dst + i, val, len);
  658. else if (type == types[PG_BOOL].oid)
  659. ret |= pg_bool2db_int(dst + i, val, len);
  660. else if (type == types[PG_INET].oid)
  661. ret |= pg_inet2db_int(dst + i, val, len);
  662. else if ((type == types[PG_TIMESTAMP].oid) ||
  663. (type == types[PG_TIMESTAMPTZ].oid))
  664. ret |= pg_timestamp2db_int(dst + i, val, len, flags);
  665. else if (type == types[PG_BIT].oid)
  666. ret |= pg_bit2db_int(dst + i, val, len);
  667. else if (type == types[PG_VARBIT].oid)
  668. ret |= pg_bit2db_int(dst + i, val, len);
  669. else goto bug;
  670. break;
  671. case DB_FLOAT:
  672. if (type == types[PG_FLOAT4].oid)
  673. ret |= pg_float42db_float(dst + i, val, len);
  674. else goto bug;
  675. break;
  676. case DB_DOUBLE:
  677. if (type == types[PG_FLOAT4].oid)
  678. ret |= pg_float42db_double(dst + i, val, len);
  679. else if (type == types[PG_FLOAT8].oid)
  680. ret |= pg_float82db_double(dst + i, val, len);
  681. else goto bug;
  682. break;
  683. case DB_DATETIME:
  684. if (type == types[PG_INT2].oid)
  685. ret |= pg_int2_2_db_int(dst + i, val, len);
  686. else if (type == types[PG_INT4].oid)
  687. ret |= pg_int4_2_db_int(dst + i, val, len);
  688. else if ((type == types[PG_TIMESTAMP].oid) ||
  689. (type == types[PG_TIMESTAMPTZ].oid))
  690. ret |= pg_timestamp2db_int(dst + i, val, len, flags);
  691. else goto bug;
  692. break;
  693. case DB_CSTR:
  694. if ((type == types[PG_CHAR].oid) ||
  695. (type == types[PG_TEXT].oid) ||
  696. (type == types[PG_BPCHAR].oid) ||
  697. (type == types[PG_VARCHAR].oid))
  698. ret |= pg_string2db_cstr(dst + i, val, len);
  699. else if (type == types[PG_INT2].oid)
  700. ret |= pg_int2_2_db_cstr(dst + i, val, len);
  701. else if (type == types[PG_INT4].oid)
  702. ret |= pg_int4_2_db_cstr(dst + i, val, len);
  703. else goto bug;
  704. break;
  705. case DB_STR:
  706. case DB_BLOB:
  707. if ((type == types[PG_BYTE].oid) ||
  708. (type == types[PG_CHAR].oid) ||
  709. (type == types[PG_TEXT].oid) ||
  710. (type == types[PG_BPCHAR].oid) ||
  711. (type == types[PG_VARCHAR].oid))
  712. ret |= pg_string2db_str(dst + i, val, len);
  713. else if (type == types[PG_INT2].oid)
  714. ret |= pg_int2_2_db_str(dst + i, val, len);
  715. else if (type == types[PG_INT4].oid)
  716. ret |= pg_int4_2_db_str(dst + i, val, len);
  717. else goto bug;
  718. break;
  719. case DB_BITMAP:
  720. if (type == types[PG_INT2].oid)
  721. ret |= pg_int2_2_db_int(dst + i, val, len);
  722. else if (type == types[PG_INT4].oid)
  723. ret |= pg_int4_2_db_int(dst + i, val, len);
  724. else if (type == types[PG_INT8].oid)
  725. ret |= pg_int8_2_db_int(dst + i, val, len);
  726. else if (type == types[PG_BIT].oid)
  727. ret |= pg_bit2db_int(dst + i, val, len);
  728. else if (type == types[PG_VARBIT].oid)
  729. ret |= pg_bit2db_int(dst + i, val, len);
  730. else goto bug;
  731. break;
  732. default:
  733. BUG("postgres: Unsupported field type %d in field %s\n",
  734. dst[i].type, dst[i].name);
  735. return -1;
  736. }
  737. }
  738. return ret;
  739. bug:
  740. BUG("postgres: Error while converting Postgres Oid %d to DB API type %d\n",
  741. type, dst[i].type);
  742. return -1;
  743. }