apr_dbd_sqlite2.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
  2. * applicable.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "apu.h"
  17. #if APU_HAVE_SQLITE2
  18. #include <ctype.h>
  19. #include <stdlib.h>
  20. #include <sqlite.h>
  21. #include "apr_strings.h"
  22. #include "apr_time.h"
  23. #include "apr_dbd_internal.h"
  24. struct apr_dbd_transaction_t {
  25. int errnum;
  26. apr_dbd_t *handle;
  27. };
  28. struct apr_dbd_t {
  29. sqlite *conn;
  30. char *errmsg;
  31. apr_dbd_transaction_t *trans;
  32. };
  33. struct apr_dbd_results_t {
  34. int random;
  35. sqlite *handle;
  36. char **res;
  37. size_t ntuples;
  38. size_t sz;
  39. size_t index;
  40. };
  41. struct apr_dbd_row_t {
  42. int n;
  43. char **data;
  44. apr_dbd_results_t *res;
  45. };
  46. struct apr_dbd_prepared_t {
  47. const char *name;
  48. int prepared;
  49. };
  50. #define FREE_ERROR_MSG(dbd) \
  51. do { \
  52. if(dbd && dbd->errmsg) { \
  53. free(dbd->errmsg); \
  54. dbd->errmsg = NULL; \
  55. } \
  56. } while(0);
  57. static apr_status_t free_table(void *data)
  58. {
  59. sqlite_free_table(data);
  60. return APR_SUCCESS;
  61. }
  62. static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql,
  63. apr_dbd_results_t ** results, const char *query,
  64. int seek)
  65. {
  66. char **result;
  67. int ret = 0;
  68. int tuples = 0;
  69. int fields = 0;
  70. if (sql->trans && sql->trans->errnum) {
  71. return sql->trans->errnum;
  72. }
  73. FREE_ERROR_MSG(sql);
  74. ret = sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
  75. &sql->errmsg);
  76. if (ret == SQLITE_OK) {
  77. if (!*results) {
  78. *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
  79. }
  80. (*results)->res = result;
  81. (*results)->ntuples = tuples;
  82. (*results)->sz = fields;
  83. (*results)->random = seek;
  84. if (tuples > 0)
  85. apr_pool_cleanup_register(pool, result, free_table,
  86. apr_pool_cleanup_null);
  87. ret = 0;
  88. }
  89. else {
  90. sql->trans->errnum = ret;
  91. }
  92. return ret;
  93. }
  94. static int dbd_sqlite_get_row(apr_pool_t * pool, apr_dbd_results_t * res,
  95. apr_dbd_row_t ** rowp, int rownum)
  96. {
  97. apr_dbd_row_t *row = *rowp;
  98. int sequential = ((rownum >= 0) && res->random) ? 0 : 1;
  99. if (row == NULL) {
  100. row = apr_palloc(pool, sizeof(apr_dbd_row_t));
  101. *rowp = row;
  102. row->res = res;
  103. row->n = sequential ? 0 : rownum - 1;
  104. }
  105. else {
  106. if (sequential) {
  107. ++row->n;
  108. }
  109. else {
  110. row->n = rownum - 1;
  111. }
  112. }
  113. if (row->n >= res->ntuples) {
  114. *rowp = NULL;
  115. apr_pool_cleanup_run(pool, res->res, free_table);
  116. res->res = NULL;
  117. return -1;
  118. }
  119. /* Pointer magic explanation:
  120. * The sqlite result is an array such that the first res->sz elements are
  121. * the column names and each tuple follows afterwards
  122. * ex: (from the sqlite2 documentation)
  123. SELECT employee_name, login, host FROM users WHERE login LIKE * 'd%';
  124. nrow = 2
  125. ncolumn = 3
  126. result[0] = "employee_name"
  127. result[1] = "login"
  128. result[2] = "host"
  129. result[3] = "dummy"
  130. result[4] = "No such user"
  131. result[5] = 0
  132. result[6] = "D. Richard Hipp"
  133. result[7] = "drh"
  134. result[8] = "zadok"
  135. */
  136. row->data = res->res + res->sz + (res->sz * row->n);
  137. return 0;
  138. }
  139. static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n)
  140. {
  141. if ((n < 0) || (n >= row->res->sz)) {
  142. return NULL;
  143. }
  144. return row->data[n];
  145. }
  146. static const char *dbd_sqlite_error(apr_dbd_t * sql, int n)
  147. {
  148. return sql->errmsg;
  149. }
  150. static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query)
  151. {
  152. char **result;
  153. int ret;
  154. int tuples = 0;
  155. int fields = 0;
  156. if (sql->trans && sql->trans->errnum) {
  157. return sql->trans->errnum;
  158. }
  159. FREE_ERROR_MSG(sql);
  160. ret =
  161. sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
  162. &sql->errmsg);
  163. if (ret == SQLITE_OK) {
  164. *nrows = sqlite_changes(sql->conn);
  165. if (tuples > 0)
  166. free(result);
  167. ret = 0;
  168. }
  169. if (sql->trans) {
  170. sql->trans->errnum = ret;
  171. }
  172. return ret;
  173. }
  174. static apr_status_t free_mem(void *data)
  175. {
  176. sqlite_freemem(data);
  177. return APR_SUCCESS;
  178. }
  179. static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg,
  180. apr_dbd_t * sql)
  181. {
  182. char *ret = sqlite_mprintf("%q", arg);
  183. apr_pool_cleanup_register(pool, ret, free_mem, apr_pool_cleanup_null);
  184. return ret;
  185. }
  186. static int dbd_sqlite_prepare(apr_pool_t * pool, apr_dbd_t * sql,
  187. const char *query, const char *label,
  188. apr_dbd_prepared_t ** statement)
  189. {
  190. return APR_ENOTIMPL;
  191. }
  192. static int dbd_sqlite_pquery(apr_pool_t * pool, apr_dbd_t * sql,
  193. int *nrows, apr_dbd_prepared_t * statement,
  194. int nargs, const char **values)
  195. {
  196. return APR_ENOTIMPL;
  197. }
  198. static int dbd_sqlite_pvquery(apr_pool_t * pool, apr_dbd_t * sql,
  199. int *nrows, apr_dbd_prepared_t * statement,
  200. va_list args)
  201. {
  202. return APR_ENOTIMPL;
  203. }
  204. static int dbd_sqlite_pselect(apr_pool_t * pool, apr_dbd_t * sql,
  205. apr_dbd_results_t ** results,
  206. apr_dbd_prepared_t * statement,
  207. int seek, int nargs, const char **values)
  208. {
  209. return APR_ENOTIMPL;
  210. }
  211. static int dbd_sqlite_pvselect(apr_pool_t * pool, apr_dbd_t * sql,
  212. apr_dbd_results_t ** results,
  213. apr_dbd_prepared_t * statement, int seek,
  214. va_list args)
  215. {
  216. return APR_ENOTIMPL;
  217. }
  218. static int dbd_sqlite_start_transaction(apr_pool_t * pool, apr_dbd_t * handle,
  219. apr_dbd_transaction_t ** trans)
  220. {
  221. int ret, rows;
  222. ret = dbd_sqlite_query(handle, &rows, "BEGIN TRANSACTION");
  223. if (ret == 0) {
  224. if (!*trans) {
  225. *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
  226. }
  227. (*trans)->handle = handle;
  228. handle->trans = *trans;
  229. }
  230. else {
  231. ret = -1;
  232. }
  233. return ret;
  234. }
  235. static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans)
  236. {
  237. int rows;
  238. int ret = -1; /* no transaction is an error cond */
  239. if (trans) {
  240. if (trans->errnum) {
  241. trans->errnum = 0;
  242. ret =
  243. dbd_sqlite_query(trans->handle, &rows,
  244. "ROLLBACK TRANSACTION");
  245. }
  246. else {
  247. ret =
  248. dbd_sqlite_query(trans->handle, &rows, "COMMIT TRANSACTION");
  249. }
  250. trans->handle->trans = NULL;
  251. }
  252. return ret;
  253. }
  254. static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_)
  255. {
  256. apr_dbd_t *sql;
  257. sqlite *conn = NULL;
  258. char *perm;
  259. int iperms = 600;
  260. char* params = apr_pstrdup(pool, params_);
  261. /* params = "[filename]:[permissions]"
  262. * example: "shopping.db:600"
  263. */
  264. perm = strstr(params, ":");
  265. if (perm) {
  266. *(perm++) = '\x00'; /* split the filename and permissions */
  267. if (strlen(perm) > 0)
  268. iperms = atoi(perm);
  269. }
  270. conn = sqlite_open(params, iperms, NULL);
  271. sql = apr_pcalloc(pool, sizeof(*sql));
  272. sql->conn = conn;
  273. return sql;
  274. }
  275. static apr_status_t dbd_sqlite_close(apr_dbd_t * handle)
  276. {
  277. if (handle->conn) {
  278. sqlite_close(handle->conn);
  279. handle->conn = NULL;
  280. }
  281. return APR_SUCCESS;
  282. }
  283. static apr_status_t dbd_sqlite_check_conn(apr_pool_t * pool,
  284. apr_dbd_t * handle)
  285. {
  286. if (handle->conn == NULL)
  287. return -1;
  288. return APR_SUCCESS;
  289. }
  290. static int dbd_sqlite_select_db(apr_pool_t * pool, apr_dbd_t * handle,
  291. const char *name)
  292. {
  293. return APR_ENOTIMPL;
  294. }
  295. static void *dbd_sqlite_native(apr_dbd_t * handle)
  296. {
  297. return handle->conn;
  298. }
  299. static int dbd_sqlite_num_cols(apr_dbd_results_t * res)
  300. {
  301. return res->sz;
  302. }
  303. static int dbd_sqlite_num_tuples(apr_dbd_results_t * res)
  304. {
  305. return res->ntuples;
  306. }
  307. APU_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = {
  308. "sqlite2",
  309. NULL,
  310. dbd_sqlite_native,
  311. dbd_sqlite_open,
  312. dbd_sqlite_check_conn,
  313. dbd_sqlite_close,
  314. dbd_sqlite_select_db,
  315. dbd_sqlite_start_transaction,
  316. dbd_sqlite_end_transaction,
  317. dbd_sqlite_query,
  318. dbd_sqlite_select,
  319. dbd_sqlite_num_cols,
  320. dbd_sqlite_num_tuples,
  321. dbd_sqlite_get_row,
  322. dbd_sqlite_get_entry,
  323. dbd_sqlite_error,
  324. dbd_sqlite_escape,
  325. dbd_sqlite_prepare,
  326. dbd_sqlite_pvquery,
  327. dbd_sqlite_pvselect,
  328. dbd_sqlite_pquery,
  329. dbd_sqlite_pselect,
  330. };
  331. #endif