prepare.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. * It is assumed throughout this file that sqlbuf size is large enough.
  3. * Any paranoid checks should be performed outside.
  4. *
  5. * The code looks a bit ugly. This is for speed.
  6. * Please, don't add calls to sprintf(), etc.
  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 <stdio.h>
  34. #include <string.h>
  35. #include "common.h"
  36. #include "prepare.h"
  37. #if SQL_STMT_BUFF_SZ < 1024
  38. #warning It is not recommended to set SQL_STMT_BUFF_SZ to less than 1K
  39. #endif
  40. static char sqlbuf[SQL_STMT_BUFF_SZ];
  41. static char *sqlbuf_pos = NULL;
  42. static const char sql_eq_char = '=';
  43. /*
  44. * ' is null ' or
  45. * ' is not null '
  46. * depending on _op.
  47. */
  48. void prepare_null(db_op_t *_op)
  49. {
  50. static const char sql_str_eq[] = " is null";
  51. static const size_t sql_str_eq_len = sizeof(sql_str_eq) - 1;
  52. static const char sql_str_ne[] = " is not null";
  53. static const size_t sql_str_ne_len = sizeof(sql_str_ne) - 1;
  54. if (_op == NULL || strcmp(*_op, OP_EQ) == 0)
  55. {
  56. memcpy(sqlbuf_pos, sql_str_eq, sql_str_eq_len);
  57. sqlbuf_pos += sql_str_eq_len;
  58. }
  59. else
  60. {
  61. memcpy(sqlbuf_pos, sql_str_ne, sql_str_ne_len);
  62. sqlbuf_pos += sql_str_ne_len;
  63. }
  64. }
  65. /*
  66. * where <name> <op> :a and <name> <op> :b and ... <name> <op> :n
  67. * or none.
  68. */
  69. void prepare_where(db_key_t* _k, db_op_t* _op, db_val_t* _v, int _n)
  70. {
  71. static const char sql_str[] = "where ";
  72. static const size_t sql_str_len = sizeof(sql_str) - 1;
  73. char sql_bind_char = 'a';
  74. /* XXX: assert(_n < 'z' - 'a' + 1) */
  75. if (_n > 0)
  76. {
  77. size_t cur_len;
  78. memcpy(sqlbuf_pos, sql_str, sql_str_len);
  79. sqlbuf_pos += sql_str_len;
  80. cur_len = strlen(*_k);
  81. memcpy(sqlbuf_pos, *_k++, cur_len);
  82. sqlbuf_pos += cur_len;
  83. if (VAL_NULL(_v++))
  84. {
  85. prepare_null(_op);
  86. }
  87. else
  88. {
  89. /* Default operation is '=' */
  90. if (_op == NULL)
  91. {
  92. *sqlbuf_pos++ = sql_eq_char;
  93. }
  94. else
  95. {
  96. cur_len = strlen(*_op);
  97. memcpy(sqlbuf_pos, *_op, cur_len);
  98. sqlbuf_pos += cur_len;
  99. }
  100. *sqlbuf_pos++ = ':';
  101. *sqlbuf_pos++ = sql_bind_char++;
  102. }
  103. if (_op != NULL)
  104. ++_op;
  105. while (--_n)
  106. {
  107. *sqlbuf_pos++ = ' ';
  108. *sqlbuf_pos++ = 'a';
  109. *sqlbuf_pos++ = 'n';
  110. *sqlbuf_pos++ = 'd';
  111. *sqlbuf_pos++ = ' ';
  112. cur_len = strlen(*_k);
  113. memcpy(sqlbuf_pos, *_k++, cur_len);
  114. sqlbuf_pos += cur_len;
  115. if (VAL_NULL(_v++))
  116. {
  117. prepare_null(_op);
  118. }
  119. else
  120. {
  121. /* Default operation is '=' */
  122. if (_op == NULL)
  123. {
  124. *sqlbuf_pos++ = sql_eq_char;
  125. }
  126. else
  127. {
  128. cur_len = strlen(*_op);
  129. memcpy(sqlbuf_pos, *_op, cur_len);
  130. sqlbuf_pos += cur_len;
  131. }
  132. *sqlbuf_pos++ = ':';
  133. *sqlbuf_pos++ = sql_bind_char++;
  134. }
  135. if (_op != NULL)
  136. ++_op;
  137. }
  138. *sqlbuf_pos++ = ' ';
  139. }
  140. }
  141. /*
  142. * ^select <col1>,<col2>,...,<colN>
  143. * or
  144. * ^select *
  145. */
  146. void prepare_select(db_key_t* _c, int _nc)
  147. {
  148. static const char sql_str[] = "select ";
  149. static const size_t sql_str_len = sizeof(sql_str) - 1;
  150. memcpy(sqlbuf, sql_str, sql_str_len);
  151. sqlbuf_pos = sqlbuf + sql_str_len;
  152. if (_nc <= 0)
  153. {
  154. *sqlbuf_pos++ = '*';
  155. }
  156. else
  157. {
  158. size_t cur_len;
  159. cur_len = strlen(*_c);
  160. memcpy(sqlbuf_pos, *_c++, cur_len);
  161. sqlbuf_pos += cur_len;
  162. while (--_nc)
  163. {
  164. *sqlbuf_pos++ = ',';
  165. cur_len = strlen(*_c);
  166. memcpy(sqlbuf_pos, *_c++, cur_len);
  167. sqlbuf_pos += cur_len;
  168. }
  169. }
  170. *sqlbuf_pos++ = ' ';
  171. }
  172. /* from <table> */
  173. void prepare_from(const char* _t)
  174. {
  175. static const char sql_str[] = "from ";
  176. static const size_t sql_str_len = sizeof(sql_str) - 1;
  177. size_t cur_len;
  178. memcpy(sqlbuf_pos, sql_str, sql_str_len);
  179. sqlbuf_pos += sql_str_len;
  180. cur_len = strlen(_t);
  181. memcpy(sqlbuf_pos, _t, cur_len);
  182. sqlbuf_pos += cur_len;
  183. *sqlbuf_pos++ = ' ';
  184. }
  185. /*
  186. * order by <name>
  187. * or none
  188. */
  189. void prepare_order_by(db_key_t _o)
  190. {
  191. if (_o != NULL)
  192. {
  193. static const char sql_str[] = "order by ";
  194. static const size_t sql_str_len = sizeof(sql_str) - 1;
  195. size_t cur_len;
  196. memcpy(sqlbuf_pos, sql_str, sql_str_len);
  197. sqlbuf_pos += sql_str_len;
  198. cur_len = strlen(_o);
  199. memcpy(sqlbuf_pos, _o, cur_len);
  200. sqlbuf_pos += cur_len;
  201. *sqlbuf_pos++ = ' ';
  202. }
  203. }
  204. /* ^insert into <table> */
  205. void prepare_insert(const char* _t)
  206. {
  207. static const char sql_str[] = "insert into ";
  208. static const size_t sql_str_len = sizeof(sql_str) - 1;
  209. size_t cur_len;
  210. memcpy(sqlbuf, sql_str, sql_str_len);
  211. sqlbuf_pos = sqlbuf + sql_str_len;
  212. cur_len = strlen(_t);
  213. memcpy(sqlbuf_pos, _t, cur_len);
  214. sqlbuf_pos += cur_len;
  215. *sqlbuf_pos++ = ' ';
  216. }
  217. /* (<col1>, <col2>, ..., <colN>) */
  218. void prepare_insert_columns(db_key_t* _k, int _n)
  219. {
  220. size_t cur_len;
  221. *sqlbuf_pos++ = '(';
  222. cur_len = strlen(*_k);
  223. memcpy(sqlbuf_pos, *_k++, cur_len);
  224. sqlbuf_pos += cur_len;
  225. while (--_n)
  226. {
  227. *sqlbuf_pos++ = ',';
  228. cur_len = strlen(*_k);
  229. memcpy(sqlbuf_pos, *_k++, cur_len);
  230. sqlbuf_pos += cur_len;
  231. }
  232. *sqlbuf_pos++ = ')';
  233. *sqlbuf_pos++ = ' ';
  234. }
  235. /* values (:a, :b, ..., :n) */
  236. void prepare_insert_values(db_val_t* _v, int _n)
  237. {
  238. static const char sql_str[] = "values (";
  239. static const size_t sql_str_len = sizeof(sql_str) - 1;
  240. char sql_bind_char = 'a';
  241. memcpy(sqlbuf_pos, sql_str, sql_str_len);
  242. sqlbuf_pos += sql_str_len;
  243. if (VAL_NULL(_v++))
  244. {
  245. *sqlbuf_pos++ = 'n';
  246. *sqlbuf_pos++ = 'u';
  247. *sqlbuf_pos++ = 'l';
  248. *sqlbuf_pos++ = 'l';
  249. }
  250. else
  251. {
  252. *sqlbuf_pos++ = ':';
  253. *sqlbuf_pos++ = sql_bind_char++;
  254. }
  255. while (--_n)
  256. {
  257. *sqlbuf_pos++ = ',';
  258. if (VAL_NULL(_v++))
  259. {
  260. *sqlbuf_pos++ = 'n';
  261. *sqlbuf_pos++ = 'u';
  262. *sqlbuf_pos++ = 'l';
  263. *sqlbuf_pos++ = 'l';
  264. }
  265. else
  266. {
  267. *sqlbuf_pos++ = ':';
  268. *sqlbuf_pos++ = sql_bind_char++;
  269. }
  270. }
  271. *sqlbuf_pos++ = ')';
  272. *sqlbuf_pos++ = ' ';
  273. }
  274. /* ^delete from <table> */
  275. void prepare_delete(const char* _t)
  276. {
  277. static const char sql_str[] = "delete from ";
  278. static const size_t sql_str_len = sizeof(sql_str) - 1;
  279. size_t cur_len;
  280. memcpy(sqlbuf, sql_str, sql_str_len);
  281. sqlbuf_pos = sqlbuf + sql_str_len;
  282. cur_len = strlen(_t);
  283. memcpy(sqlbuf_pos, _t, cur_len);
  284. sqlbuf_pos += cur_len;
  285. *sqlbuf_pos++ = ' ';
  286. }
  287. /* ^update <table> */
  288. void prepare_update(const char* _t)
  289. {
  290. static const char sql_str[] = "update ";
  291. static const size_t sql_str_len = sizeof(sql_str) - 1;
  292. size_t cur_len;
  293. memcpy(sqlbuf, sql_str, sql_str_len);
  294. sqlbuf_pos = sqlbuf + sql_str_len;
  295. cur_len = strlen(_t);
  296. memcpy(sqlbuf_pos, _t, cur_len);
  297. sqlbuf_pos += cur_len;
  298. *sqlbuf_pos++ = ' ';
  299. }
  300. /* set <name1>=:a,<name2>=:b,...,<nameN>=:n */
  301. void prepare_update_set(db_key_t* _k, db_val_t* _v, int _n)
  302. {
  303. size_t cur_len;
  304. char sql_bind_char = 'a';
  305. *sqlbuf_pos++ = 's';
  306. *sqlbuf_pos++ = 'e';
  307. *sqlbuf_pos++ = 't';
  308. *sqlbuf_pos++ = ' ';
  309. cur_len = strlen(*_k);
  310. memcpy(sqlbuf_pos, *_k++, cur_len);
  311. sqlbuf_pos += cur_len;
  312. *sqlbuf_pos++ = sql_eq_char;
  313. if (VAL_NULL(_v++))
  314. {
  315. *sqlbuf_pos++ = 'n';
  316. *sqlbuf_pos++ = 'u';
  317. *sqlbuf_pos++ = 'l';
  318. *sqlbuf_pos++ = 'l';
  319. }
  320. else
  321. {
  322. *sqlbuf_pos++ = ':';
  323. *sqlbuf_pos++ = sql_bind_char++;
  324. }
  325. while (--_n)
  326. {
  327. *sqlbuf_pos++ = ',';
  328. cur_len = strlen(*_k);
  329. memcpy(sqlbuf_pos, *_k++, cur_len);
  330. sqlbuf_pos += cur_len;
  331. *sqlbuf_pos++ = sql_eq_char;
  332. if (VAL_NULL(_v++))
  333. {
  334. *sqlbuf_pos++ = 'n';
  335. *sqlbuf_pos++ = 'u';
  336. *sqlbuf_pos++ = 'l';
  337. *sqlbuf_pos++ = 'l';
  338. }
  339. else
  340. {
  341. *sqlbuf_pos++ = ':';
  342. *sqlbuf_pos++ = sql_bind_char++;
  343. }
  344. }
  345. *sqlbuf_pos++ = ' ';
  346. }
  347. const char *prepared_sql(void)
  348. {
  349. /* OCI statements should be null terminated according to OCI docs. */
  350. *sqlbuf_pos = '\0';
  351. return sqlbuf;
  352. }
  353. /* without trailing null character */
  354. size_t prepared_sql_len(void)
  355. {
  356. return sqlbuf_pos - sqlbuf;
  357. }