dbase.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
  1. /*
  2. * Core functions.
  3. * See db/db.h for description.
  4. *
  5. * @todo add paranoid checks for sql statement buffer overflow, and protect
  6. * the checks with macro which is switched off by default.
  7. *
  8. * Copyright (C) 2005 RingCentral Inc.
  9. * Created by Dmitry Semyonov <[email protected]>
  10. *
  11. *
  12. * This file is part of ser, a free SIP server.
  13. *
  14. * ser is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version
  18. *
  19. * For a license to use the ser software under conditions
  20. * other than those described here, or to purchase support for this
  21. * software, please contact iptel.org by e-mail at the following addresses:
  22. * [email protected]
  23. *
  24. * ser is distributed in the hope that it will be useful,
  25. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. * GNU General Public License for more details.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * along with this program; if not, write to the Free Software
  31. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  32. */
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include "../../mem/mem.h"
  36. #include "../../dprint.h"
  37. #include "../../ut.h"
  38. #include "common.h"
  39. #include "dbase.h"
  40. #include "utils.h"
  41. #include "prepare.h"
  42. static ora_param_t ora_params[ORA_PARAMS_MAX];
  43. static sb2 ora_bind_inds[ORA_BINDS_MAX];
  44. static int bind_values(db_con_t* _h, db_val_t* _v, int _n, int bound_count);
  45. static int define_params(db_con_t* _h, int _nc);
  46. static void free_params(void);
  47. static int map_int_param_type_and_size_to_ext(db_con_t* _h, dvoid* p_param,
  48. int ora_param_num);
  49. static int init_db_res(db_res_t** _r, int params_num);
  50. static int convert_row(int params_num, db_res_t* _r);
  51. static db_type_t sqlt_to_db_type(ub2 sqlt);
  52. static int oci_prepare(db_con_t *_h);
  53. static int oci_execute(db_con_t *_h, ub4 iters);
  54. #if !DB_PREALLOC_SQLT_HANDLE
  55. static int oci_cleanup(db_con_t *_h);
  56. #endif
  57. int db_use_table(db_con_t* _h, const char* _t)
  58. {
  59. if (_h == NULL || _t == NULL)
  60. {
  61. ERR("%s: invalid (NULL) argument(s)\n", __FUNCTION__);
  62. return -1;
  63. }
  64. DBG("%s(%s)\n", __FUNCTION__, _t);
  65. CON_TABLE(_h) = _t; /* XXX: shouldn't we copy the string here instead? */
  66. return 0;
  67. }
  68. db_con_t* db_init(const char* _sqlurl)
  69. {
  70. db_con_t *p_db_con = NULL;
  71. ora_con_t *p_ora_con = NULL;
  72. sword rc = OCI_ERROR;
  73. int res = -1;
  74. char sz_user[32];
  75. char sz_passwd[32];
  76. char sz_db[32];
  77. LOG(L_ALERT, "WARNING! This module is experimental and may crash SER "
  78. "or create unexpected results. You use the module at your own "
  79. "risk. Please submit bugs at http://bugs.sip-router.org/\n");
  80. if (_sqlurl == NULL)
  81. {
  82. ERR("%s: invalid (NULL) argument\n", __FUNCTION__);
  83. goto db_init_err;
  84. }
  85. DBG("%s(%s)\n", __FUNCTION__, _sqlurl);
  86. if ((res = parse_sql_url(_sqlurl, sz_user, sz_passwd, sz_db)) < 0)
  87. {
  88. ERR("%s: Error %d while parsing %s\n", __FUNCTION__, res, _sqlurl);
  89. goto db_init_err;
  90. }
  91. p_db_con = pkg_malloc(sizeof(db_con_t));
  92. p_ora_con = pkg_malloc(sizeof(ora_con_t));
  93. if (p_db_con == NULL || p_ora_con == NULL)
  94. {
  95. ERR("%s: no memory\n", __FUNCTION__);
  96. goto db_init_err;
  97. }
  98. memset(p_db_con, 0, sizeof(db_con_t));
  99. memset(p_ora_con, 0, sizeof(ora_con_t));
  100. CON_TABLE(p_db_con) = NULL;
  101. /* CON_ORA() could not be used as lvalue due to deprecated lvalue casts. */
  102. CON_TAIL(p_db_con) = (unsigned long)p_ora_con;
  103. rc = OCIEnvCreate(&(p_ora_con->env.ptr), OCI_DEFAULT,
  104. NULL, NULL, NULL, NULL, 0, NULL);
  105. if (rc != OCI_SUCCESS)
  106. {
  107. OCICHECK(p_ora_con->env.ptr, rc);
  108. goto db_init_err;
  109. }
  110. rc = OCIHandleAlloc(p_ora_con->env.ptr, &(p_ora_con->err.dvoid_ptr),
  111. OCI_HTYPE_ERROR, 0, NULL);
  112. if (rc != OCI_SUCCESS)
  113. {
  114. OCICHECK(p_ora_con->err.ptr, rc);
  115. goto db_init_err;
  116. }
  117. rc = OCIHandleAlloc(p_ora_con->env.ptr, &(p_ora_con->svc.dvoid_ptr),
  118. OCI_HTYPE_SVCCTX, 0, NULL);
  119. if (rc != OCI_SUCCESS)
  120. {
  121. OCICHECK(p_ora_con->env.ptr, rc);
  122. goto db_init_err;
  123. }
  124. rc = OCILogon(p_ora_con->env.ptr, p_ora_con->err.ptr, &(p_ora_con->svc.ptr),
  125. (OraText *)sz_user, strlen(sz_user),
  126. (OraText *)sz_passwd, strlen(sz_passwd),
  127. (OraText *)sz_db, strlen(sz_db));
  128. if (rc != OCI_SUCCESS)
  129. {
  130. OCICHECK(p_ora_con->err.ptr, rc);
  131. goto db_init_err;
  132. }
  133. #if DB_PREALLOC_SQLT_HANDLE
  134. rc = OCIHandleAlloc(p_ora_con->env.ptr, &(p_ora_con->stmt.dvoid_ptr),
  135. OCI_HTYPE_STMT, 0, NULL);
  136. if (rc != OCI_SUCCESS)
  137. {
  138. OCICHECK(p_ora_con->env.ptr, rc);
  139. goto db_init_err;
  140. }
  141. #endif
  142. return p_db_con;
  143. db_init_err:
  144. #if DB_PREALLOC_SQLT_HANDLE
  145. if (p_ora_con->stmt.ptr != NULL)
  146. OCICHECK(p_ora_con->env.ptr, OCIHandleFree(p_ora_con->stmt.ptr, OCI_HTYPE_STMT));
  147. #endif
  148. if (p_ora_con->svc.ptr != NULL)
  149. OCICHECK(p_ora_con->env.ptr, OCIHandleFree(p_ora_con->svc.ptr, OCI_HTYPE_SVCCTX));
  150. if (p_ora_con->err.ptr != NULL)
  151. OCICHECK(p_ora_con->env.ptr, OCIHandleFree(p_ora_con->err.ptr, OCI_HTYPE_ERROR));
  152. if (p_ora_con)
  153. {
  154. pkg_free(p_ora_con);
  155. p_ora_con = NULL;
  156. }
  157. if (p_db_con)
  158. {
  159. pkg_free(p_db_con);
  160. p_db_con = NULL;
  161. }
  162. ERR("%s failed\n", __FUNCTION__);
  163. return NULL;
  164. }
  165. void db_close(db_con_t* _h)
  166. {
  167. sword rc = OCI_ERROR;
  168. if (_h == NULL)
  169. {
  170. ERR("%s: invalid (NULL) argument\n", __FUNCTION__);
  171. return;
  172. }
  173. DBG("%s\n", __FUNCTION__);
  174. #if DB_PREALLOC_SQLT_HANDLE
  175. rc = OCIHandleFree(CON_ORA(_h)->stmt.ptr, OCI_HTYPE_STMT);
  176. if (rc != OCI_SUCCESS)
  177. {
  178. OCICHECK(CON_ORA(_h)->env.ptr, rc);
  179. }
  180. #endif
  181. rc = OCILogoff(CON_ORA(_h)->svc.ptr, CON_ORA(_h)->err.ptr);
  182. if (rc != OCI_SUCCESS)
  183. {
  184. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  185. }
  186. /* Note: svc.ptr handle was released by OCILogoff() function. */
  187. rc = OCIHandleFree(CON_ORA(_h)->err.ptr, OCI_HTYPE_ERROR);
  188. if (rc != OCI_SUCCESS)
  189. {
  190. OCICHECK(CON_ORA(_h)->env.ptr, rc);
  191. }
  192. rc = OCITerminate(OCI_DEFAULT);
  193. if (rc != OCI_SUCCESS)
  194. {
  195. OCICHECK(CON_ORA(_h)->env.ptr, rc);
  196. }
  197. if (CON_ORA(_h) != NULL)
  198. {
  199. pkg_free(CON_ORA(_h));
  200. CON_TAIL(_h) = (unsigned long)NULL;
  201. }
  202. if (_h != NULL)
  203. {
  204. pkg_free(_h);
  205. _h = NULL;
  206. }
  207. }
  208. int db_query(db_con_t* _h, db_key_t* _k,
  209. db_op_t* _op, db_val_t* _v,
  210. db_key_t* _c, int _n, int _nc,
  211. db_key_t _o, db_res_t** _r)
  212. {
  213. sword rc = OCI_ERROR;
  214. int params_num;
  215. *_r = NULL; /* Required for processing under err_cleanup label,
  216. and simply to be on the safe side. */
  217. if (_h == NULL)
  218. {
  219. ERR("%s: invalid (NULL) argument(s)\n", __FUNCTION__);
  220. return -1;
  221. }
  222. if (ora_params[0].p_data != NULL)
  223. {
  224. ERR("%s: Nested calls to db_query() are not allowed!\n", __FUNCTION__);
  225. return -1;
  226. }
  227. DBG("%s\n", __FUNCTION__);
  228. prepare_select(_c, _nc);
  229. prepare_from(CON_TABLE(_h));
  230. prepare_where(_k, _op, _v, _n);
  231. prepare_order_by(_o);
  232. DBG("%.*s\n", prepared_sql_len(), prepared_sql());
  233. rc = oci_prepare(_h);
  234. if (rc != 0) return -1;
  235. rc = bind_values(_h, _v, _n, 0);
  236. if (rc < 0) goto err_cleanup;
  237. rc = oci_execute(_h, 0);
  238. if (rc != 0) goto err_cleanup;
  239. params_num = define_params(_h, _nc);
  240. if (params_num <= 0) { rc = -1; goto err_cleanup; }
  241. rc = init_db_res(_r, params_num);
  242. if (rc != 0) goto err_cleanup;
  243. while ((rc = OCIStmtFetch(CON_ORA(_h)->stmt.ptr, CON_ORA(_h)->err.ptr, 1, 0, 0))
  244. == OCI_SUCCESS)
  245. {
  246. rc = convert_row(params_num, *_r);
  247. if (rc != 0) goto err_cleanup;
  248. }
  249. if (rc != OCI_SUCCESS && rc != OCI_NO_DATA)
  250. {
  251. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  252. rc = -1;
  253. goto err_cleanup;
  254. }
  255. else
  256. {
  257. rc = 0;
  258. }
  259. if (RES_ROW_N(*_r) == 0)
  260. {
  261. DBG("%s: no data\n", __FUNCTION__);
  262. }
  263. err_cleanup:
  264. #if !DB_PREALLOC_SQLT_HANDLE
  265. (void)oci_cleanup(_h);
  266. #endif
  267. if (rc != 0)
  268. {
  269. (void)db_free_result(_h, *_r);
  270. return -1;
  271. }
  272. else
  273. {
  274. return 0;
  275. }
  276. }
  277. int db_raw_query(db_con_t* _h, char* _s, db_res_t** _r)
  278. {
  279. ERR("%s: unimplemented\n", __FUNCTION__);
  280. *_r = NULL; /* Just in case */
  281. return -1;
  282. }
  283. int db_free_result(db_con_t* _h, db_res_t* _r)
  284. {
  285. db_row_t *p_row;
  286. db_val_t *p_val;
  287. if (_h == NULL)
  288. {
  289. ERR("%s: invalid (NULL) argument(s)\n", __FUNCTION__);
  290. return -1;
  291. }
  292. DBG("%s\n", __FUNCTION__);
  293. free_params();
  294. if (_r == NULL)
  295. return 0; /* Nothing else to free. */
  296. if (RES_ROW_N(_r) < 0)
  297. {
  298. ERR("%s: invalid RES_ROW_N(_r) value!\n", __FUNCTION__);
  299. }
  300. p_row = RES_ROWS(_r);
  301. while (RES_ROW_N(_r)-- > 0)
  302. {
  303. p_val = ROW_VALUES(p_row);
  304. while (ROW_N(p_row)--)
  305. {
  306. if (VAL_NULL(p_val) == 0)
  307. {
  308. if (VAL_TYPE(p_val) == DB_STRING && VAL_STRING(p_val) != NULL)
  309. {
  310. pkg_free((void *)VAL_STRING(p_val)); /* XXX Get rid of cast */
  311. VAL_STRING(p_val) = NULL;
  312. DBG("%s: DB_STRING memory released\n", __FUNCTION__);
  313. }
  314. else if (VAL_TYPE(p_val) == DB_BLOB && VAL_BLOB(p_val).s != NULL)
  315. {
  316. pkg_free(VAL_BLOB(p_val).s);
  317. VAL_BLOB(p_val).s = NULL;
  318. DBG("%s: DB_BLOB memory released\n", __FUNCTION__);
  319. }
  320. else if (VAL_TYPE(p_val) == DB_STR && VAL_STR(p_val).s != NULL)
  321. {
  322. pkg_free(VAL_STR(p_val).s);
  323. VAL_STR(p_val).s = NULL;
  324. DBG("%s: DB_STR memory released\n", __FUNCTION__);
  325. }
  326. }
  327. else
  328. {
  329. DBG("%s: NULL value skipped\n", __FUNCTION__);
  330. }
  331. ++p_val;
  332. }
  333. pkg_free(ROW_VALUES(p_row));
  334. ROW_VALUES(p_row) = NULL;
  335. DBG("%s: row memory released\n", __FUNCTION__);
  336. ++p_row;
  337. }
  338. if (RES_ROWS(_r) != NULL)
  339. {
  340. pkg_free(RES_ROWS(_r));
  341. RES_ROWS(_r) = NULL;
  342. DBG("%s: rows memory released\n", __FUNCTION__);
  343. }
  344. if (RES_TYPES(_r) != NULL)
  345. {
  346. pkg_free(RES_TYPES(_r));
  347. RES_TYPES(_r) = NULL;
  348. DBG("%s: types memory released\n", __FUNCTION__);
  349. }
  350. if (RES_NAMES(_r) != NULL)
  351. {
  352. pkg_free(RES_NAMES(_r));
  353. RES_NAMES(_r) = NULL;
  354. DBG("%s: names memory released\n", __FUNCTION__);
  355. }
  356. return 0;
  357. }
  358. int db_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n)
  359. {
  360. sword rc;
  361. if (_h == NULL || _k == NULL || _v == NULL || _n <= 0)
  362. {
  363. ERR("%s: invalid (NULL) argument(s)\n", __FUNCTION__);
  364. return -1;
  365. }
  366. DBG("%s\n", __FUNCTION__);
  367. prepare_insert(CON_TABLE(_h));
  368. prepare_insert_columns(_k, _n);
  369. prepare_insert_values(_v, _n);
  370. DBG("%.*s\n", prepared_sql_len(), prepared_sql());
  371. rc = oci_prepare(_h);
  372. if (rc != 0) goto err_cleanup;
  373. rc = bind_values(_h, _v, _n, 0);
  374. if (rc < 0) goto err_cleanup;
  375. rc = oci_execute(_h, 1);
  376. if (rc != 0) goto err_cleanup;
  377. err_cleanup:
  378. #if !DB_PREALLOC_SQLT_HANDLE
  379. (void)oci_cleanup(_h);
  380. #endif
  381. return rc != 0 ? -1 : 0;
  382. }
  383. int db_delete(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v, int _n)
  384. {
  385. sword rc;
  386. if (_h == NULL)
  387. {
  388. ERR("%s: invalid (NULL) argument\n", __FUNCTION__);
  389. return -1;
  390. }
  391. DBG("%s\n", __FUNCTION__);
  392. prepare_delete(CON_TABLE(_h));
  393. prepare_where(_k, _op, _v, _n);
  394. DBG("%.*s\n", prepared_sql_len(), prepared_sql());
  395. rc = oci_prepare(_h);
  396. if (rc != 0) goto err_cleanup;
  397. rc = bind_values(_h, _v, _n, 0);
  398. if (rc < 0) goto err_cleanup;
  399. rc = oci_execute(_h, 1);
  400. if (rc != 0) goto err_cleanup;
  401. err_cleanup:
  402. #if !DB_PREALLOC_SQLT_HANDLE
  403. (void)oci_cleanup(_h);
  404. #endif
  405. return rc != 0 ? -1 : 0;
  406. }
  407. int db_update(db_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v,
  408. db_key_t* _uk, db_val_t* _uv, int _n, int _un)
  409. {
  410. sword rc;
  411. if (_h == NULL || _uk == NULL || _uv == NULL || _un <= 0)
  412. {
  413. ERR("%s: invalid argument(s)\n", __FUNCTION__);
  414. return -1;
  415. }
  416. DBG("%s\n", __FUNCTION__);
  417. prepare_update(CON_TABLE(_h));
  418. prepare_update_set(_uk, _uv, _un);
  419. prepare_where(_k, _op, _v, _n);
  420. DBG("%.*s\n", prepared_sql_len(), prepared_sql());
  421. rc = oci_prepare(_h);
  422. if (rc != 0) goto err_cleanup;
  423. rc = bind_values(_h, _uv, _un, 0);
  424. if (rc < 0) goto err_cleanup;
  425. rc = bind_values(_h, _v, _n, rc);
  426. if (rc < 0) goto err_cleanup;
  427. rc = oci_execute(_h, 1);
  428. if (rc != 0) goto err_cleanup;
  429. err_cleanup:
  430. #if !DB_PREALLOC_SQLT_HANDLE
  431. (void)oci_cleanup(_h);
  432. #endif
  433. return rc != 0 ? -1 : 0;
  434. }
  435. /* Return: number of bound values (it could be different from _n parameter
  436. * due to null values), or -1 in case of failure. */
  437. static int bind_values(db_con_t* _h, db_val_t* _v, int _n, int bound_count)
  438. {
  439. sword rc;
  440. int i;
  441. OCIBind *p_bnd;
  442. dvoid *p_bind_val;
  443. sb4 bind_val_sz;
  444. ub2 bind_val_type;
  445. /* XXX Will fail if more than single date is inserted!
  446. * It is necessary to allocate them dynamically! */
  447. static unsigned char ora_date[7] =
  448. { '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; /* Oracle date format */
  449. for (i = 0; i < _n; ++i, ++_v)
  450. {
  451. if (VAL_NULL(_v))
  452. {
  453. DBG("%s: (null)\n", __FUNCTION__);
  454. /* 'null' is used in queries. So, nothing to bind.
  455. But we should keep correct index and 'for' condition. */
  456. --i;
  457. --_n;
  458. continue;
  459. }
  460. else
  461. {
  462. ora_bind_inds[i] = OCI_IND_NOTNULL;
  463. switch (VAL_TYPE(_v))
  464. {
  465. case DB_INT:
  466. p_bind_val = &VAL_INT(_v);
  467. bind_val_sz = sizeof(VAL_INT(_v));
  468. bind_val_type = SQLT_INT;
  469. DBG("%s: DB_INT - %d\n", __FUNCTION__, VAL_INT(_v));
  470. break;
  471. case DB_DOUBLE:
  472. p_bind_val = &VAL_DOUBLE(_v);
  473. bind_val_sz = sizeof(VAL_DOUBLE(_v));
  474. bind_val_type = SQLT_FLT;
  475. DBG("%s: DB_DOUBLE - %e\n", __FUNCTION__, VAL_DOUBLE(_v));
  476. break;
  477. case DB_STRING:
  478. p_bind_val = &VAL_STRING(_v);
  479. bind_val_sz = strlen(VAL_STRING(_v));
  480. /* XXX length should not exceed 4000 bytes here */
  481. bind_val_type = SQLT_CHR;
  482. DBG("%s: DB_STRING - %s\n", __FUNCTION__, VAL_STRING(_v));
  483. break;
  484. case DB_STR:
  485. p_bind_val = VAL_STR(_v).s;
  486. bind_val_sz = VAL_STR(_v).len;
  487. /* XXX length should not exceed 4000 bytes here */
  488. bind_val_type = SQLT_CHR;
  489. DBG("%s: DB_STR - %.*s\n", __FUNCTION__,
  490. VAL_STR(_v).len, ZSW(VAL_STR(_v).s) );
  491. break;
  492. case DB_DATETIME:
  493. {
  494. struct tm *p_tm = localtime(&VAL_TIME(_v));
  495. if (p_tm == NULL)
  496. {
  497. ERR("%s: time_t -> struct tm conversion failure %ld\n",
  498. __FUNCTION__, VAL_TIME(_v));
  499. return -1;
  500. }
  501. p_tm->tm_year += 1900; /* tm_year is stored as (Year - 1900) value. */
  502. ora_date[0] = p_tm->tm_year / 100 + 100;
  503. ora_date[1] = p_tm->tm_year % 100 + 100;
  504. ora_date[2] = p_tm->tm_mon + 1; /* tm_mon is from [0-11] interval */
  505. ora_date[3] = p_tm->tm_mday;
  506. ora_date[4] = p_tm->tm_hour + 1;
  507. ora_date[5] = p_tm->tm_min + 1;
  508. ora_date[6] = p_tm->tm_sec + 1;
  509. /* XXX: Should tm_isdst, etc. be processed? */
  510. p_bind_val = ora_date;
  511. bind_val_sz = sizeof(ora_date);
  512. bind_val_type = SQLT_DAT;
  513. DBG("%s: DB_DATETIME - %s\n", __FUNCTION__,
  514. ctime(&VAL_TIME(_v)));
  515. break;
  516. }
  517. case DB_BLOB:
  518. p_bind_val = VAL_BLOB(_v).s;
  519. bind_val_sz = VAL_BLOB(_v).len;
  520. /* XXX length should not exceed 4000 bytes here (?) */
  521. bind_val_type = SQLT_VCS; /* XXX review */
  522. DBG("%s: DB_BLOB, length %d\n", __FUNCTION__, VAL_BLOB(_v).len);
  523. break;
  524. case DB_BITMAP:
  525. p_bind_val = &VAL_BITMAP(_v);
  526. bind_val_sz = sizeof(VAL_BITMAP(_v));
  527. bind_val_type = SQLT_UIN;
  528. DBG("%s: DB_BITMAP - %#x\n", __FUNCTION__, VAL_BITMAP(_v));
  529. break;
  530. default:
  531. ERR("%s: Unsupported DB value type - %d\n",
  532. __FUNCTION__, VAL_TYPE(_v));
  533. return -1;
  534. }
  535. }
  536. p_bnd = NULL; /* XXX Not used so far */
  537. rc = OCIBindByPos(CON_ORA(_h)->stmt.ptr, &p_bnd, CON_ORA(_h)->err.ptr,
  538. bound_count + i + 1, p_bind_val, bind_val_sz,
  539. bind_val_type, &ora_bind_inds[i], 0, 0, 0, 0,
  540. OCI_DEFAULT);
  541. if (rc != OCI_SUCCESS)
  542. {
  543. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  544. return -1;
  545. }
  546. }
  547. return _n;
  548. }
  549. /* Used by db_query().
  550. * free_params() must be called after the query is finished.
  551. * Return: number of parameters or -1 in case of failure;
  552. * (free_params() must be called in both cases).
  553. * @sa free_params()
  554. */
  555. static int define_params(db_con_t* _h, int _nc)
  556. {
  557. OCIDefine *p_dfn = NULL;
  558. dvoid *p_param = NULL;
  559. int ora_params_num = 0;
  560. sword rc;
  561. #if DB_DEBUG
  562. int i = 0;
  563. for (; i < sizeof(ora_params) / sizeof(ora_params[0]); ++i)
  564. {
  565. if (ora_params[i].p_data != NULL)
  566. {
  567. ERR("%s: Internal logic is broken!\n", __FUNCTION__);
  568. return -1;
  569. }
  570. }
  571. #endif
  572. /* XXX handle case when _nc is defined separately to avoid extra call
  573. * to OCIParamGet() */
  574. while ((rc = OCIParamGet(CON_ORA(_h)->stmt.ptr, OCI_HTYPE_STMT,
  575. CON_ORA(_h)->err.ptr,
  576. &p_param, ora_params_num + 1)) == OCI_SUCCESS)
  577. {
  578. if (ora_params_num == ORA_PARAMS_MAX)
  579. {
  580. /* XXX log more info */
  581. ERR("%s: Too many table columns!\n", __FUNCTION__);
  582. return -1;
  583. }
  584. rc = map_int_param_type_and_size_to_ext(_h, p_param, ora_params_num);
  585. if (rc != 0) return -1;
  586. ora_params[ora_params_num].p_data =
  587. pkg_malloc(ora_params[ora_params_num].size);
  588. p_dfn = NULL; /* XXX currently unused */
  589. rc = OCIDefineByPos(CON_ORA(_h)->stmt.ptr, &p_dfn, CON_ORA(_h)->err.ptr,
  590. ora_params_num + 1,
  591. ora_params[ora_params_num].p_data,
  592. ora_params[ora_params_num].size,
  593. ora_params[ora_params_num].type,
  594. &ora_params[ora_params_num].ind, 0, 0, OCI_DEFAULT);
  595. if (rc != OCI_SUCCESS)
  596. {
  597. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  598. return -1;
  599. }
  600. ++ora_params_num;
  601. }
  602. if (rc != OCI_SUCCESS)
  603. {
  604. /*
  605. * OCI_ERROR + ORA-24334 are returned in case of invalid pos parameter of
  606. * OCIParamGet(). This is the only(?) way to handle 'select *'
  607. * statement while using non-scrollable cursor.
  608. */
  609. if (OCICHECK(CON_ORA(_h)->err.ptr, rc) != 24334 || rc != OCI_ERROR)
  610. {
  611. return -1;
  612. }
  613. }
  614. DBG("%s: ora_params_num = %d\n", __FUNCTION__, ora_params_num);
  615. return ora_params_num;
  616. }
  617. /* A companion for define_params() function
  618. * @sa define_params()
  619. */
  620. static void free_params(void)
  621. {
  622. int i = 0;
  623. int freed_count = 0;
  624. DBG("%s\n", __FUNCTION__);
  625. for (; i < sizeof(ora_params) / sizeof(ora_params[0]); ++i)
  626. {
  627. if (ora_params[i].p_data != NULL)
  628. {
  629. pkg_free(ora_params[i].p_data);
  630. ora_params[i].p_data = NULL;
  631. freed_count++;
  632. }
  633. }
  634. DBG("%s: %d parameter(s) freed\n", __FUNCTION__, freed_count);
  635. }
  636. /*
  637. * Called by define_params().
  638. * Uses and updates global ora_params[ora_params_num].
  639. * Defines the conversion rules that will be applied during fetching.
  640. * Don't forget to update sqlt_to_db_type() if output types are changed.
  641. */
  642. static int map_int_param_type_and_size_to_ext(db_con_t* _h, dvoid* p_param,
  643. int ora_params_num)
  644. {
  645. sword rc;
  646. rc = OCIAttrGet(p_param, OCI_DTYPE_PARAM, &ora_params[ora_params_num].type,
  647. 0, OCI_ATTR_DATA_TYPE, CON_ORA(_h)->err.ptr);
  648. if (rc != OCI_SUCCESS)
  649. {
  650. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  651. return -1;
  652. }
  653. DBG1("%s: Oracle type %s\n", __FUNCTION__,
  654. sqlt_to_str(ora_params[ora_params_num].type));
  655. switch (ora_params[ora_params_num].type)
  656. {
  657. case SQLT_STR:
  658. case SQLT_VCS:
  659. case SQLT_CHR:
  660. {
  661. rc = OCIAttrGet(p_param, OCI_DTYPE_PARAM,
  662. &ora_params[ora_params_num].size,
  663. 0, OCI_ATTR_DATA_SIZE, CON_ORA(_h)->err.ptr);
  664. if (rc != OCI_SUCCESS)
  665. {
  666. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  667. return -1;
  668. }
  669. DBG1("%s: SQLT_CHR/VCS/STR size %d\n", __FUNCTION__,
  670. ora_params[ora_params_num].size);
  671. ora_params[ora_params_num].type = SQLT_STR;
  672. break;
  673. }
  674. case SQLT_INT:
  675. ora_params[ora_params_num].size = sizeof(int);
  676. break;
  677. case SQLT_UIN:
  678. ora_params[ora_params_num].size = sizeof(unsigned int);
  679. break;
  680. case SQLT_FLT:
  681. ora_params[ora_params_num].size = sizeof(double);
  682. break;
  683. case SQLT_DATE:
  684. case SQLT_TIMESTAMP:
  685. case SQLT_TIMESTAMP_TZ:
  686. case SQLT_TIMESTAMP_LTZ:
  687. /*
  688. * Let OCI make a conversion of date types
  689. * to the one that we understand.
  690. */
  691. ora_params[ora_params_num].type = SQLT_DAT;
  692. ora_params[ora_params_num].size = 7;
  693. break;
  694. case SQLT_DAT:
  695. ora_params[ora_params_num].size = 7;
  696. break;
  697. case SQLT_NUM:
  698. {
  699. sb2 precision;
  700. sb1 scale;
  701. rc = OCIAttrGet(p_param, OCI_DTYPE_PARAM,
  702. &precision,
  703. 0, OCI_ATTR_PRECISION, CON_ORA(_h)->err.ptr);
  704. if (rc != OCI_SUCCESS)
  705. {
  706. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  707. return -1;
  708. }
  709. rc = OCIAttrGet(p_param, OCI_DTYPE_PARAM,
  710. &scale,
  711. 0, OCI_ATTR_SCALE, CON_ORA(_h)->err.ptr);
  712. if (rc != OCI_SUCCESS)
  713. {
  714. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  715. return -1;
  716. }
  717. /*
  718. * Depending on precision and scale attributes we should decide
  719. * what external number type to use.
  720. */
  721. DBG1("%s: SQLT_NUM precision %d, scale %d\n", __FUNCTION__,
  722. precision, scale);
  723. if (precision < 9 && scale == 0)
  724. {
  725. /*
  726. * MAX_INT (= 134217727) occupies 9 digits. So, maximum integer
  727. * number supported is 99 999 999 (8 digits).
  728. */
  729. ora_params[ora_params_num].type = SQLT_INT;
  730. ora_params[ora_params_num].size = sizeof(int);
  731. }
  732. else
  733. {
  734. ora_params[ora_params_num].type = SQLT_FLT;
  735. ora_params[ora_params_num].size = sizeof(double);
  736. }
  737. break;
  738. }
  739. default:
  740. ERR("%s: Unsupported data type: %d!\n",
  741. __FUNCTION__, ora_params[ora_params_num].type);
  742. return -1;
  743. }
  744. DBG1("%s: External type %s, size %d\n", __FUNCTION__,
  745. sqlt_to_str(ora_params[ora_params_num].type),
  746. ora_params[ora_params_num].size);
  747. return 0;
  748. }
  749. /* @sa db_free_result() */
  750. static int init_db_res(db_res_t** _r, int params_num)
  751. {
  752. static db_res_t res;
  753. int i;
  754. *_r = &res;
  755. RES_NAMES(*_r) = (db_key_t *)pkg_malloc(sizeof(db_key_t) * params_num);
  756. RES_TYPES(*_r) = (db_type_t *)pkg_malloc(sizeof(db_type_t) * params_num);
  757. if (RES_NAMES(*_r) == NULL || RES_TYPES(*_r) == NULL)
  758. {
  759. ERR("%s: No memory for %d bytes!\n", __FUNCTION__,
  760. (sizeof(db_key_t) + sizeof(db_type_t)) * params_num);
  761. if ( RES_NAMES(*_r) != NULL )
  762. {
  763. pkg_free(RES_NAMES(*_r));
  764. RES_NAMES(*_r) = NULL;
  765. }
  766. if ( RES_TYPES(*_r) != NULL )
  767. {
  768. pkg_free(RES_TYPES(*_r));
  769. RES_TYPES(*_r) = NULL;
  770. }
  771. return -1;
  772. }
  773. RES_COL_N(*_r) = params_num;
  774. RES_ROWS(*_r) = NULL;
  775. RES_ROW_N(*_r) = 0;
  776. for (i = 0; i < params_num; i++)
  777. {
  778. RES_NAMES(*_r)[i] = NULL; /* XXX unimplemented */
  779. RES_TYPES(*_r)[i] = sqlt_to_db_type(ora_params[i].type);
  780. }
  781. return 0;
  782. }
  783. /*
  784. * Only limited subset of SQLT_* types is allowed! The subset comes from
  785. * map_int_param_type_and_size_to_ext() function
  786. */
  787. static db_type_t sqlt_to_db_type(ub2 sqlt)
  788. {
  789. switch (sqlt)
  790. {
  791. case SQLT_STR: return DB_STR;
  792. case SQLT_INT: return DB_INT;
  793. case SQLT_UIN: return DB_BITMAP;
  794. case SQLT_FLT: return DB_DOUBLE;
  795. case SQLT_DAT: return DB_DATETIME;
  796. default:
  797. ERR("%s: Internal logic is broken!\n", __FUNCTION__);
  798. return -1;
  799. }
  800. }
  801. /* @sa db_free_result() */
  802. static int convert_row(int params_num, db_res_t* _r)
  803. {
  804. static int allocated_rows;
  805. int i;
  806. db_val_t *p_val;
  807. ora_param_t *p_param;
  808. DBG("%s: params_num = %d, _r = %p\n", __FUNCTION__, params_num, _r);
  809. /* Detect initial invocation. */
  810. if (RES_ROWS(_r) == NULL)
  811. {
  812. allocated_rows = 0;
  813. }
  814. /*
  815. * Since we don't know number of rows aforetime, we aggressively
  816. * pre-allocate them to avoid multiple memory re-allocations.
  817. * The exact pre-allocation algorithm should be adjusted according
  818. * to actual queries. Let's use factor 10 for the beginning.
  819. */
  820. if (RES_ROW_N(_r) == allocated_rows)
  821. {
  822. void *tmp_ptr;
  823. allocated_rows *= 10;
  824. ++allocated_rows; /* Handling initial 0 value. */
  825. /*
  826. * We can't assign directly to RES_ROWS(_r) here, since we don't want
  827. * to loose original pointer in case of realloc failure.
  828. */
  829. tmp_ptr = pkg_realloc(RES_ROWS(_r), sizeof(db_row_t) * allocated_rows);
  830. if (tmp_ptr == NULL)
  831. {
  832. ERR("%s: No memory for %d bytes!\n", __FUNCTION__,
  833. sizeof(db_row_t) * allocated_rows);
  834. return -1;
  835. }
  836. else
  837. {
  838. RES_ROWS(_r) = tmp_ptr;
  839. }
  840. }
  841. ROW_N(RES_ROWS(_r) + RES_ROW_N(_r)) = params_num;
  842. ROW_VALUES(RES_ROWS(_r) + RES_ROW_N(_r)) =
  843. p_val = pkg_malloc(sizeof(db_val_t) * params_num);
  844. ++RES_ROW_N(_r);
  845. p_param = ora_params;
  846. for (i = 0; i < params_num; i++, p_val++, p_param++)
  847. {
  848. VAL_TYPE(p_val) = sqlt_to_db_type(p_param->type);
  849. if (p_param->ind == OCI_IND_NULL)
  850. {
  851. VAL_NULL(p_val) = 1;
  852. DBG("OCI_IND_NULL, type %s\n", sqlt_to_str(p_param->type));
  853. continue;
  854. }
  855. else if (p_param->ind != OCI_IND_NOTNULL)
  856. {
  857. ERR("ind = %d, type %s\n", p_param->ind, sqlt_to_str(p_param->type));
  858. }
  859. VAL_NULL(p_val) = 0;
  860. switch (p_param->type)
  861. {
  862. case SQLT_STR:
  863. {
  864. /* We construct correct value of type DB_STR and at the same time
  865. of type DB_STRING (as long as _union_ is used inside db_val_t
  866. structure and string pointer is the _first_ variable of _str
  867. structure). This is necessary since the callers tend to ignore
  868. returned value types. Reported type is DB_STR. */
  869. size_t buflen = strlen(p_param->p_data) + 1;
  870. VAL_STR(p_val).s = pkg_malloc(buflen);
  871. if (VAL_STR(p_val).s == NULL)
  872. {
  873. /*
  874. * Set number of coulumns to actually processed value.
  875. * db_free_result() must honor this number during cleanup.
  876. */
  877. ROW_N(RES_ROWS(_r) + RES_ROW_N(_r) - 1) = i;
  878. return -1;
  879. }
  880. memcpy(VAL_STR(p_val).s, p_param->p_data, buflen);
  881. VAL_STR(p_val).len = buflen - 1;
  882. DBG("SQLT_STR: %.*s\n", VAL_STR(p_val).len, ZSW(VAL_STR(p_val).s));
  883. break;
  884. }
  885. case SQLT_INT:
  886. VAL_INT(p_val) = *(int *)(p_param->p_data);
  887. DBG("SQLT_INT: %d\n", *(int *)(p_param->p_data));
  888. break;
  889. case SQLT_UIN:
  890. VAL_BITMAP(p_val) = *(unsigned int *)(p_param->p_data);
  891. DBG("SQLT_UIN: %#x\n", *(unsigned int *)(p_param->p_data));
  892. break;
  893. case SQLT_FLT:
  894. VAL_DOUBLE(p_val) = *(double *)(p_param->p_data);
  895. DBG("SQLT_FLT: %e\n", *(double *)(p_param->p_data));
  896. break;
  897. case SQLT_DAT:
  898. {
  899. struct tm tm;
  900. time_t time;
  901. char *p_ora_date = p_param->p_data;
  902. tm.tm_year = (*p_ora_date++ - 100) * 100;
  903. /*
  904. * Second step is necessary here, since single step operation
  905. * could result in wrong value due to double pointer++ operation.
  906. *
  907. * 1900 is substracted since tm_year is stored as (Year - 1900) value.
  908. */
  909. tm.tm_year += *p_ora_date++ - 100 - 1900;
  910. tm.tm_mon = *p_ora_date++ - 1; /* tm_mon is from [0-11] interval */
  911. tm.tm_mday = *p_ora_date++;
  912. tm.tm_hour = *p_ora_date++ - 1;
  913. tm.tm_min = *p_ora_date++ - 1;
  914. tm.tm_sec = *p_ora_date++ - 1;
  915. tm.tm_isdst = -1; /* XXX: unknown DST. Is it correct? */
  916. /* XXX Is it necessary to preset tm_gmtoff, tm_zone? */
  917. tm.tm_gmtoff = 0;
  918. tm.tm_zone = 0;
  919. time = mktime(&tm);
  920. if (time == -1)
  921. {
  922. ERR("%s: SQLT_DAT -> time_t conversion failed\n", __FUNCTION__);
  923. return -1;
  924. }
  925. VAL_TIME(p_val) = time;
  926. DBG("SQLT_DAT: %s\n", ctime(&time));
  927. break;
  928. }
  929. default:
  930. /* All unsupported types must had been catched before. */
  931. ERR("%s: Internal logic is broken: %d!\n",
  932. __FUNCTION__, p_param->type);
  933. return -1;
  934. }
  935. }
  936. return 0;
  937. }
  938. /* Allocate and prepare SQL statement */
  939. static int oci_prepare(db_con_t *_h)
  940. {
  941. DBG("%s\n", __FUNCTION__);
  942. #if !DB_PREALLOC_SQLT_HANDLE
  943. sword rc = OCIHandleAlloc(CON_ORA(_h)->env.ptr,
  944. (dvoid **)&(CON_ORA(_h)->stmt.ptr),
  945. OCI_HTYPE_STMT, 0, NULL);
  946. if (rc != OCI_SUCCESS)
  947. {
  948. OCICHECK(CON_ORA(_h)->env.ptr, rc);
  949. return -1;
  950. }
  951. #else
  952. sword
  953. #endif
  954. rc = OCIStmtPrepare(CON_ORA(_h)->stmt.ptr, CON_ORA(_h)->err.ptr,
  955. (OraText *)prepared_sql(), prepared_sql_len(),
  956. OCI_NTV_SYNTAX, OCI_DEFAULT);
  957. if (rc != OCI_SUCCESS)
  958. {
  959. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  960. #if !DB_PREALLOC_SQLT_HANDLE
  961. if (CON_ORA(_h)->stmt.ptr != NULL)
  962. {
  963. OCICHECK(CON_ORA(_h)->env.ptr,
  964. OCIHandleFree(CON_ORA(_h)->stmt.ptr, OCI_HTYPE_STMT));
  965. }
  966. #endif
  967. return -2;
  968. }
  969. return 0;
  970. }
  971. /* 'iters' must be set to 0 for 'select' statement, and to 1 for others. */
  972. static int oci_execute(db_con_t *_h, ub4 iters)
  973. {
  974. DBG("%s\n", __FUNCTION__);
  975. sword rc = OCIStmtExecute(CON_ORA(_h)->svc.ptr, CON_ORA(_h)->stmt.ptr,
  976. CON_ORA(_h)->err.ptr, iters, 0, NULL, NULL,
  977. OCI_COMMIT_ON_SUCCESS);
  978. if (rc != OCI_SUCCESS)
  979. {
  980. OCICHECK(CON_ORA(_h)->err.ptr, rc);
  981. return -1;
  982. }
  983. return 0;
  984. }
  985. #if !DB_PREALLOC_SQLT_HANDLE
  986. static int oci_cleanup(db_con_t *_h)
  987. {
  988. DBG("%s\n", __FUNCTION__);
  989. sword rc = OCIHandleFree(CON_ORA(_h)->stmt.ptr, OCI_HTYPE_STMT);
  990. if (rc != OCI_SUCCESS)
  991. {
  992. OCICHECK(CON_ORA(_h)->env.ptr, rc);
  993. return -1;
  994. }
  995. return 0;
  996. }
  997. #endif