You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2575 lines
67 KiB

23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 4 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2003 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.0 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_0.txt. |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Wez Furlong <wez@thebrainroom.com> |
  16. | Tal Peer <tal@php.net> |
  17. | Marcus Boerger <helly@php.net> |
  18. +----------------------------------------------------------------------+
  19. $Id$
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include "config.h"
  23. #endif
  24. #define PHP_SQLITE_MODULE_VERSION "1.1-dev"
  25. #include "php.h"
  26. #include "php_ini.h"
  27. #include "ext/standard/info.h"
  28. #include "ext/session/php_session.h"
  29. #include "php_sqlite.h"
  30. #if HAVE_TIME_H
  31. # include <time.h>
  32. #endif
  33. #if HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #include <sqlite.h>
  37. #include "zend_default_classes.h"
  38. #ifdef HAVE_SPL
  39. #include "ext/spl/php_spl.h"
  40. #include "ext/spl/spl_functions.h"
  41. #endif
  42. #ifndef safe_emalloc
  43. # define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
  44. #endif
  45. #ifndef ZEND_ENGINE_2
  46. # define OnUpdateLong OnUpdateInt
  47. #endif
  48. ZEND_DECLARE_MODULE_GLOBALS(sqlite)
  49. #if HAVE_PHP_SESSION
  50. extern ps_module ps_mod_sqlite;
  51. #define ps_sqlite_ptr &ps_mod_sqlite
  52. #endif
  53. extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
  54. extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
  55. static int le_sqlite_db, le_sqlite_result, le_sqlite_pdb;
  56. static inline void php_sqlite_strtoupper(char *s)
  57. {
  58. while (*s!='\0') {
  59. *s = toupper(*s);
  60. s++;
  61. }
  62. }
  63. static inline void php_sqlite_strtolower(char *s)
  64. {
  65. while (*s!='\0') {
  66. *s = tolower(*s);
  67. s++;
  68. }
  69. }
  70. /* {{{ PHP_INI
  71. */
  72. PHP_INI_BEGIN()
  73. STD_PHP_INI_ENTRY_EX("sqlite.assoc_case", "0", PHP_INI_ALL, OnUpdateLong, assoc_case, zend_sqlite_globals, sqlite_globals, display_link_numbers)
  74. PHP_INI_END()
  75. /* }}} */
  76. #define DB_FROM_ZVAL(db, zv) ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
  77. #define DB_FROM_OBJECT(db, object) \
  78. { \
  79. sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
  80. db = obj->u.db; \
  81. if (!db) { \
  82. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The database wasn't opened"); \
  83. RETURN_NULL(); \
  84. } \
  85. }
  86. #define RES_FROM_OBJECT(res, object) \
  87. { \
  88. sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
  89. res = obj->u.res; \
  90. if (!res) { \
  91. php_error_docref(NULL TSRMLS_CC, E_WARNING, "No result set available"); \
  92. RETURN_NULL(); \
  93. } \
  94. }
  95. #define SQLITE_THROW(message) \
  96. PG(suppress_errors) = 0; \
  97. EG(exception) = sqlite_instanciate(sqlite_ce_exception, NULL TSRMLS_CC); \
  98. { \
  99. zval *tmp; \
  100. MAKE_STD_ZVAL(tmp); \
  101. ZVAL_STRING(tmp, message, 1); \
  102. zend_hash_update(Z_OBJPROP_P(EG(exception)), "message", sizeof("message"), (void **) message, sizeof(zval *), NULL); \
  103. MAKE_STD_ZVAL(tmp); \
  104. ZVAL_STRING(tmp, zend_get_executed_filename(TSRMLS_C), 1); \
  105. zend_hash_update(Z_OBJPROP_P(EG(exception)), "file", sizeof("file"), (void **) &tmp, sizeof(zval *), NULL); \
  106. MAKE_STD_ZVAL(tmp); \
  107. ZVAL_LONG(tmp, zend_get_executed_lineno(TSRMLS_C)); \
  108. zend_hash_update(Z_OBJPROP_P(EG(exception)), "line", sizeof("line"), (void **) &tmp, sizeof(zval *), NULL); \
  109. }
  110. struct php_sqlite_result {
  111. struct php_sqlite_db *db;
  112. sqlite_vm *vm;
  113. int buffered;
  114. int ncolumns;
  115. int nrows;
  116. int curr_row;
  117. char **col_names;
  118. int alloc_rows;
  119. char **table;
  120. int mode;
  121. };
  122. struct php_sqlite_db {
  123. sqlite *db;
  124. int last_err_code;
  125. zend_bool is_persistent;
  126. int rsrc_id;
  127. HashTable callbacks;
  128. };
  129. struct php_sqlite_agg_functions {
  130. struct php_sqlite_db *db;
  131. int is_valid;
  132. zval *step;
  133. zval *fini;
  134. };
  135. enum { PHPSQLITE_ASSOC = 1, PHPSQLITE_NUM = 2, PHPSQLITE_BOTH = PHPSQLITE_ASSOC|PHPSQLITE_NUM };
  136. function_entry sqlite_functions[] = {
  137. PHP_FE(sqlite_open, third_arg_force_ref)
  138. PHP_FE(sqlite_popen, third_arg_force_ref)
  139. PHP_FE(sqlite_close, NULL)
  140. PHP_FE(sqlite_query, NULL)
  141. PHP_FE(sqlite_array_query, NULL)
  142. PHP_FE(sqlite_single_query, NULL)
  143. PHP_FE(sqlite_fetch_array, NULL)
  144. PHP_FE(sqlite_fetch_single, NULL)
  145. PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, NULL)
  146. PHP_FE(sqlite_fetch_all, NULL)
  147. PHP_FE(sqlite_current, NULL)
  148. PHP_FE(sqlite_column, NULL)
  149. PHP_FE(sqlite_libversion, NULL)
  150. PHP_FE(sqlite_libencoding, NULL)
  151. PHP_FE(sqlite_changes, NULL)
  152. PHP_FE(sqlite_last_insert_rowid, NULL)
  153. PHP_FE(sqlite_num_rows, NULL)
  154. PHP_FE(sqlite_num_fields, NULL)
  155. PHP_FE(sqlite_field_name, NULL)
  156. PHP_FE(sqlite_seek, NULL)
  157. PHP_FE(sqlite_rewind, NULL)
  158. PHP_FE(sqlite_next, NULL)
  159. PHP_FE(sqlite_prev, NULL)
  160. PHP_FE(sqlite_has_more, NULL)
  161. PHP_FE(sqlite_has_prev, NULL)
  162. PHP_FE(sqlite_escape_string, NULL)
  163. PHP_FE(sqlite_busy_timeout, NULL)
  164. PHP_FE(sqlite_last_error, NULL)
  165. PHP_FE(sqlite_error_string, NULL)
  166. PHP_FE(sqlite_unbuffered_query, NULL)
  167. PHP_FE(sqlite_create_aggregate, NULL)
  168. PHP_FE(sqlite_create_function, NULL)
  169. PHP_FE(sqlite_factory, third_arg_force_ref)
  170. PHP_FE(sqlite_udf_encode_binary, NULL)
  171. PHP_FE(sqlite_udf_decode_binary, NULL)
  172. {NULL, NULL, NULL}
  173. };
  174. #define PHP_ME_MAPPING(name, func_name, arg_types) \
  175. ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types)
  176. function_entry sqlite_funcs_db[] = {
  177. PHP_ME_MAPPING(sqlite_db, sqlite_open, NULL)
  178. /* PHP_ME_MAPPING(close, sqlite_close, NULL)*/
  179. PHP_ME_MAPPING(query, sqlite_query, NULL)
  180. PHP_ME_MAPPING(array_query, sqlite_array_query, NULL)
  181. PHP_ME_MAPPING(single_query, sqlite_single_query, NULL)
  182. PHP_ME_MAPPING(unbuffered_query, sqlite_unbuffered_query, NULL)
  183. PHP_ME_MAPPING(last_insert_rowid, sqlite_last_insert_rowid, NULL)
  184. PHP_ME_MAPPING(create_aggregate, sqlite_create_aggregate, NULL)
  185. PHP_ME_MAPPING(create_function, sqlite_create_function, NULL)
  186. PHP_ME_MAPPING(busy_timeout, sqlite_busy_timeout, NULL)
  187. PHP_ME_MAPPING(last_error, sqlite_last_error, NULL)
  188. /* PHP_ME_MAPPING(error_string, sqlite_error_string, NULL) static */
  189. /* PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL) static */
  190. {NULL, NULL, NULL}
  191. };
  192. function_entry sqlite_funcs_query[] = {
  193. PHP_ME_MAPPING(fetch_array, sqlite_fetch_array, NULL)
  194. PHP_ME_MAPPING(fetch_single, sqlite_fetch_single, NULL)
  195. PHP_ME_MAPPING(fetch_all, sqlite_fetch_all, NULL)
  196. PHP_ME_MAPPING(column, sqlite_column, NULL)
  197. PHP_ME_MAPPING(changes, sqlite_changes, NULL)
  198. PHP_ME_MAPPING(num_fields, sqlite_num_fields, NULL)
  199. PHP_ME_MAPPING(field_name, sqlite_field_name, NULL)
  200. /* spl_forward */
  201. PHP_ME_MAPPING(current, sqlite_current, NULL)
  202. PHP_ME_MAPPING(next, sqlite_next, NULL)
  203. PHP_ME_MAPPING(prev, sqlite_prev, NULL)
  204. PHP_ME_MAPPING(has_more, sqlite_has_more, NULL)
  205. PHP_ME_MAPPING(has_prev, sqlite_has_prev, NULL)
  206. /* spl_sequence */
  207. PHP_ME_MAPPING(rewind, sqlite_rewind, NULL)
  208. /* additional */
  209. PHP_ME_MAPPING(num_rows, sqlite_num_rows, NULL)
  210. PHP_ME_MAPPING(seek, sqlite_seek, NULL)
  211. {NULL, NULL, NULL}
  212. };
  213. function_entry sqlite_funcs_ub_query[] = {
  214. PHP_ME_MAPPING(fetch_array, sqlite_fetch_array, NULL)
  215. PHP_ME_MAPPING(fetch_single, sqlite_fetch_single, NULL)
  216. PHP_ME_MAPPING(fetch_all, sqlite_fetch_all, NULL)
  217. PHP_ME_MAPPING(column, sqlite_column, NULL)
  218. PHP_ME_MAPPING(changes, sqlite_changes, NULL)
  219. PHP_ME_MAPPING(num_fields, sqlite_num_fields, NULL)
  220. PHP_ME_MAPPING(field_name, sqlite_field_name, NULL)
  221. /* spl_forward */
  222. PHP_ME_MAPPING(current, sqlite_current, NULL)
  223. PHP_ME_MAPPING(next, sqlite_next, NULL)
  224. PHP_ME_MAPPING(has_more, sqlite_has_more, NULL)
  225. {NULL, NULL, NULL}
  226. };
  227. function_entry sqlite_funcs_exception[] = {
  228. {NULL, NULL, NULL}
  229. };
  230. zend_module_entry sqlite_module_entry = {
  231. #if ZEND_MODULE_API_NO >= 20010901
  232. STANDARD_MODULE_HEADER,
  233. #endif
  234. "sqlite",
  235. sqlite_functions,
  236. PHP_MINIT(sqlite),
  237. NULL,
  238. PHP_RINIT(sqlite),
  239. PHP_RSHUTDOWN(sqlite),
  240. PHP_MINFO(sqlite),
  241. #if ZEND_MODULE_API_NO >= 20010901
  242. PHP_SQLITE_MODULE_VERSION,
  243. #endif
  244. STANDARD_MODULE_PROPERTIES
  245. };
  246. #ifdef COMPILE_DL_SQLITE
  247. ZEND_GET_MODULE(sqlite)
  248. #endif
  249. static int php_sqlite_callback_invalidator(struct php_sqlite_agg_functions *funcs TSRMLS_DC)
  250. {
  251. if (!funcs->is_valid) {
  252. return 0;
  253. }
  254. if (funcs->step) {
  255. zval_ptr_dtor(&funcs->step);
  256. funcs->step = NULL;
  257. }
  258. if (funcs->fini) {
  259. zval_ptr_dtor(&funcs->fini);
  260. funcs->fini = NULL;
  261. }
  262. funcs->is_valid = 0;
  263. return 0;
  264. }
  265. static void php_sqlite_callback_dtor(void *pDest)
  266. {
  267. struct php_sqlite_agg_functions *funcs = (struct php_sqlite_agg_functions*)pDest;
  268. if (funcs->is_valid) {
  269. TSRMLS_FETCH();
  270. php_sqlite_callback_invalidator(funcs TSRMLS_CC);
  271. }
  272. }
  273. static ZEND_RSRC_DTOR_FUNC(php_sqlite_db_dtor)
  274. {
  275. if (rsrc->ptr) {
  276. struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
  277. sqlite_close(db->db);
  278. zend_hash_destroy(&db->callbacks);
  279. pefree(db, db->is_persistent);
  280. rsrc->ptr = NULL;
  281. }
  282. }
  283. static void real_result_dtor(struct php_sqlite_result *res TSRMLS_DC)
  284. {
  285. int i, j, base;
  286. if (res->vm) {
  287. sqlite_finalize(res->vm, NULL);
  288. }
  289. if (res->table) {
  290. if (!res->buffered && res->nrows) {
  291. res->nrows = 1; /* only one row is stored */
  292. }
  293. for (i = 0; i < res->nrows; i++) {
  294. base = i * res->ncolumns;
  295. for (j = 0; j < res->ncolumns; j++) {
  296. if (res->table[base + j] != NULL) {
  297. efree(res->table[base + j]);
  298. }
  299. }
  300. }
  301. efree(res->table);
  302. }
  303. if (res->col_names) {
  304. for (j = 0; j < res->ncolumns; j++) {
  305. efree(res->col_names[j]);
  306. }
  307. efree(res->col_names);
  308. }
  309. zend_list_delete(res->db->rsrc_id);
  310. efree(res);
  311. }
  312. static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor)
  313. {
  314. struct php_sqlite_result *res = (struct php_sqlite_result *)rsrc->ptr;
  315. real_result_dtor(res TSRMLS_CC);
  316. }
  317. static int php_sqlite_forget_persistent_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  318. {
  319. struct php_sqlite_db *db;
  320. if (Z_TYPE_P(rsrc) != le_sqlite_pdb) {
  321. return 0;
  322. }
  323. db = (struct php_sqlite_db*)rsrc->ptr;
  324. db->rsrc_id = FAILURE;
  325. /* don't leave pending commits hanging around */
  326. sqlite_exec(db->db, "ROLLBACK", NULL, NULL, NULL);
  327. /* prevent bad mojo if someone tries to use a previously registered function in the next request */
  328. zend_hash_apply(&db->callbacks, (apply_func_t)php_sqlite_callback_invalidator TSRMLS_CC);
  329. return 0;
  330. }
  331. PHP_RSHUTDOWN_FUNCTION(sqlite)
  332. {
  333. zend_hash_apply(&EG(persistent_list), (apply_func_t)php_sqlite_forget_persistent_id_numbers TSRMLS_CC);
  334. return SUCCESS;
  335. }
  336. /* {{{ PHP Function interface */
  337. static void php_sqlite_generic_function_callback(sqlite_func *func, int argc, const char **argv)
  338. {
  339. zval *retval = NULL;
  340. zval ***zargs = NULL;
  341. zval funcname;
  342. int i, res;
  343. char *callable = NULL, *errbuf=NULL;
  344. TSRMLS_FETCH();
  345. /* sanity check the args */
  346. if (argc == 0) {
  347. sqlite_set_result_error(func, "not enough parameters", -1);
  348. return;
  349. }
  350. ZVAL_STRING(&funcname, (char*)argv[0], 0);
  351. if (!zend_is_callable(&funcname, 0, &callable)) {
  352. spprintf(&errbuf, 0, "function `%s' is not callable", callable);
  353. sqlite_set_result_error(func, errbuf, -1);
  354. efree(errbuf);
  355. efree(callable);
  356. return;
  357. }
  358. efree(callable);
  359. if (argc > 1) {
  360. zargs = (zval ***)safe_emalloc((argc - 1), sizeof(zval **), 0);
  361. for (i = 0; i < argc-1; i++) {
  362. zargs[i] = emalloc(sizeof(zval *));
  363. MAKE_STD_ZVAL(*zargs[i]);
  364. ZVAL_STRING(*zargs[i], (char*)argv[i+1], 1);
  365. }
  366. }
  367. res = call_user_function_ex(EG(function_table),
  368. NULL,
  369. &funcname,
  370. &retval,
  371. argc-1,
  372. zargs,
  373. 0, NULL TSRMLS_CC);
  374. if (res == SUCCESS) {
  375. if (retval == NULL) {
  376. sqlite_set_result_string(func, NULL, 0);
  377. } else {
  378. switch (Z_TYPE_P(retval)) {
  379. case IS_STRING:
  380. sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
  381. break;
  382. case IS_LONG:
  383. case IS_BOOL:
  384. sqlite_set_result_int(func, Z_LVAL_P(retval));
  385. break;
  386. case IS_DOUBLE:
  387. sqlite_set_result_double(func, Z_DVAL_P(retval));
  388. break;
  389. case IS_NULL:
  390. default:
  391. sqlite_set_result_string(func, NULL, 0);
  392. }
  393. }
  394. } else {
  395. sqlite_set_result_error(func, "call_user_function_ex failed", -1);
  396. }
  397. if (retval) {
  398. zval_ptr_dtor(&retval);
  399. }
  400. if (zargs) {
  401. for (i = 0; i < argc-1; i++) {
  402. zval_ptr_dtor(zargs[i]);
  403. efree(zargs[i]);
  404. }
  405. efree(zargs);
  406. }
  407. }
  408. /* }}} */
  409. /* {{{ callback for sqlite_create_function */
  410. static void php_sqlite_function_callback(sqlite_func *func, int argc, const char **argv)
  411. {
  412. zval *retval = NULL;
  413. zval ***zargs = NULL;
  414. int i, res;
  415. struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
  416. TSRMLS_FETCH();
  417. if (!funcs->is_valid) {
  418. sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
  419. return;
  420. }
  421. if (argc > 0) {
  422. zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
  423. for (i = 0; i < argc; i++) {
  424. zargs[i] = emalloc(sizeof(zval *));
  425. MAKE_STD_ZVAL(*zargs[i]);
  426. if (argv[i] == NULL) {
  427. ZVAL_NULL(*zargs[i]);
  428. } else {
  429. ZVAL_STRING(*zargs[i], (char*)argv[i], 1);
  430. }
  431. }
  432. }
  433. res = call_user_function_ex(EG(function_table),
  434. NULL,
  435. funcs->step,
  436. &retval,
  437. argc,
  438. zargs,
  439. 0, NULL TSRMLS_CC);
  440. if (res == SUCCESS) {
  441. if (retval == NULL) {
  442. sqlite_set_result_string(func, NULL, 0);
  443. } else {
  444. switch (Z_TYPE_P(retval)) {
  445. case IS_STRING:
  446. /* TODO: for binary results, need to encode the string */
  447. sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
  448. break;
  449. case IS_LONG:
  450. case IS_BOOL:
  451. sqlite_set_result_int(func, Z_LVAL_P(retval));
  452. break;
  453. case IS_DOUBLE:
  454. sqlite_set_result_double(func, Z_DVAL_P(retval));
  455. break;
  456. case IS_NULL:
  457. default:
  458. sqlite_set_result_string(func, NULL, 0);
  459. }
  460. }
  461. } else {
  462. sqlite_set_result_error(func, "call_user_function_ex failed", -1);
  463. }
  464. if (retval) {
  465. zval_ptr_dtor(&retval);
  466. }
  467. if (zargs) {
  468. for (i = 0; i < argc; i++) {
  469. zval_ptr_dtor(zargs[i]);
  470. efree(zargs[i]);
  471. }
  472. efree(zargs);
  473. }
  474. }
  475. /* }}} */
  476. /* {{{ callback for sqlite_create_aggregate: step function */
  477. static void php_sqlite_agg_step_function_callback(sqlite_func *func, int argc, const char **argv)
  478. {
  479. zval *retval = NULL;
  480. zval ***zargs;
  481. zval **context_p;
  482. int i, res, zargc;
  483. struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
  484. TSRMLS_FETCH();
  485. if (!funcs->is_valid) {
  486. sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
  487. return;
  488. }
  489. /* sanity check the args */
  490. if (argc < 1) {
  491. return;
  492. }
  493. zargc = argc + 1;
  494. zargs = (zval ***)safe_emalloc(zargc, sizeof(zval **), 0);
  495. /* first arg is always the context zval */
  496. context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
  497. if (*context_p == NULL) {
  498. MAKE_STD_ZVAL(*context_p);
  499. (*context_p)->is_ref = 1;
  500. Z_TYPE_PP(context_p) = IS_NULL;
  501. }
  502. zargs[0] = context_p;
  503. /* copy the other args */
  504. for (i = 0; i < argc; i++) {
  505. zargs[i+1] = emalloc(sizeof(zval *));
  506. MAKE_STD_ZVAL(*zargs[i+1]);
  507. if (argv[i] == NULL) {
  508. ZVAL_NULL(*zargs[i+1]);
  509. } else {
  510. ZVAL_STRING(*zargs[i+1], (char*)argv[i], 1);
  511. }
  512. }
  513. res = call_user_function_ex(EG(function_table),
  514. NULL,
  515. funcs->step,
  516. &retval,
  517. zargc,
  518. zargs,
  519. 0, NULL TSRMLS_CC);
  520. if (res != SUCCESS) {
  521. php_error_docref(NULL TSRMLS_CC, E_WARNING, "call_user_function_ex failed");
  522. }
  523. if (retval) {
  524. zval_ptr_dtor(&retval);
  525. }
  526. if (zargs) {
  527. for (i = 1; i < zargc; i++) {
  528. zval_ptr_dtor(zargs[i]);
  529. efree(zargs[i]);
  530. }
  531. efree(zargs);
  532. }
  533. }
  534. /* }}} */
  535. /* {{{ callback for sqlite_create_aggregate: finalize function */
  536. static void php_sqlite_agg_fini_function_callback(sqlite_func *func)
  537. {
  538. zval *retval = NULL;
  539. int res;
  540. struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
  541. zval **context_p;
  542. TSRMLS_FETCH();
  543. if (!funcs->is_valid) {
  544. sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
  545. return;
  546. }
  547. context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
  548. res = call_user_function_ex(EG(function_table),
  549. NULL,
  550. funcs->fini,
  551. &retval,
  552. 1,
  553. &context_p,
  554. 0, NULL TSRMLS_CC);
  555. if (res == SUCCESS) {
  556. if (retval == NULL) {
  557. sqlite_set_result_string(func, NULL, 0);
  558. } else {
  559. switch (Z_TYPE_P(retval)) {
  560. case IS_STRING:
  561. /* TODO: for binary results, need to encode the string */
  562. sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
  563. break;
  564. case IS_LONG:
  565. case IS_BOOL:
  566. sqlite_set_result_int(func, Z_LVAL_P(retval));
  567. break;
  568. case IS_DOUBLE:
  569. sqlite_set_result_double(func, Z_DVAL_P(retval));
  570. break;
  571. case IS_NULL:
  572. default:
  573. sqlite_set_result_string(func, NULL, 0);
  574. }
  575. }
  576. } else {
  577. sqlite_set_result_error(func, "call_user_function_ex failed", -1);
  578. }
  579. if (retval) {
  580. zval_ptr_dtor(&retval);
  581. }
  582. zval_ptr_dtor(context_p);
  583. }
  584. /* }}} */
  585. /* {{{ Authorization Callback */
  586. static int php_sqlite_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
  587. const char *arg5, const char *arg6)
  588. {
  589. switch (access_type) {
  590. case SQLITE_COPY:
  591. {
  592. TSRMLS_FETCH();
  593. if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
  594. return SQLITE_DENY;
  595. }
  596. if (php_check_open_basedir(arg4 TSRMLS_CC)) {
  597. return SQLITE_DENY;
  598. }
  599. }
  600. return SQLITE_OK;
  601. #ifdef SQLITE_ATTACH
  602. case SQLITE_ATTACH:
  603. {
  604. TSRMLS_FETCH();
  605. if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
  606. return SQLITE_DENY;
  607. }
  608. if (php_check_open_basedir(arg3 TSRMLS_CC)) {
  609. return SQLITE_DENY;
  610. }
  611. }
  612. return SQLITE_OK;
  613. #endif
  614. default:
  615. /* access allowed */
  616. return SQLITE_OK;
  617. }
  618. }
  619. /* }}} */
  620. /* {{{ OO init/structure stuff */
  621. #define REGISTER_SQLITE_CLASS(name, parent) \
  622. { \
  623. zend_class_entry ce; \
  624. INIT_CLASS_ENTRY(ce, "sqlite_" # name, sqlite_funcs_ ## name); \
  625. ce.create_object = sqlite_object_new_ ## name; \
  626. sqlite_ce_ ## name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
  627. memcpy(&sqlite_object_handlers_ ## name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
  628. sqlite_object_handlers_ ## name.clone_obj = NULL; \
  629. }
  630. zend_class_entry *sqlite_ce_db, *sqlite_ce_exception;
  631. zend_class_entry *sqlite_ce_query, *sqlite_ce_ub_query;
  632. static zend_object_handlers sqlite_object_handlers_db;
  633. static zend_object_handlers sqlite_object_handlers_query;
  634. static zend_object_handlers sqlite_object_handlers_ub_query;
  635. static zend_object_handlers sqlite_object_handlers_exception;
  636. typedef enum {
  637. is_db,
  638. is_result
  639. } sqlite_obj_type;
  640. typedef struct _sqlite_object {
  641. zend_object std;
  642. sqlite_obj_type type;
  643. union {
  644. struct php_sqlite_db *db;
  645. struct php_sqlite_result *res;
  646. void *ptr;
  647. } u;
  648. } sqlite_object;
  649. static int sqlite_free_persistent(list_entry *le, void *ptr TSRMLS_DC)
  650. {
  651. return le->ptr == ptr;
  652. }
  653. static void sqlite_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
  654. {
  655. sqlite_object *intern = (sqlite_object *)object;
  656. zend_hash_destroy(intern->std.properties);
  657. FREE_HASHTABLE(intern->std.properties);
  658. if (intern->u.ptr) {
  659. if (intern->type == is_db) {
  660. if (intern->u.db->rsrc_id) {
  661. zend_list_delete(intern->u.db->rsrc_id);
  662. zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) sqlite_free_persistent, &intern->u.ptr TSRMLS_CC);
  663. }
  664. } else {
  665. real_result_dtor(intern->u.res TSRMLS_CC);
  666. }
  667. }
  668. efree(object);
  669. }
  670. static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
  671. {
  672. sqlite_object *intern;
  673. zval *tmp;
  674. intern = emalloc(sizeof(sqlite_object));
  675. memset(intern, 0, sizeof(sqlite_object));
  676. intern->std.ce = class_type;
  677. ALLOC_HASHTABLE(intern->std.properties);
  678. zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
  679. zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
  680. retval->handle = zend_objects_store_put(intern, sqlite_object_dtor, NULL TSRMLS_CC);
  681. retval->handlers = handlers;
  682. }
  683. static zend_object_value sqlite_object_new_db(zend_class_entry *class_type TSRMLS_DC)
  684. {
  685. zend_object_value retval;
  686. sqlite_object_new(class_type, &sqlite_object_handlers_db, &retval TSRMLS_CC);
  687. return retval;
  688. }
  689. static zend_object_value sqlite_object_new_query(zend_class_entry *class_type TSRMLS_DC)
  690. {
  691. zend_object_value retval;
  692. sqlite_object_new(class_type, &sqlite_object_handlers_query, &retval TSRMLS_CC);
  693. return retval;
  694. }
  695. static zend_object_value sqlite_object_new_ub_query(zend_class_entry *class_type TSRMLS_DC)
  696. {
  697. zend_object_value retval;
  698. sqlite_object_new(class_type, &sqlite_object_handlers_ub_query, &retval TSRMLS_CC);
  699. return retval;
  700. }
  701. static zend_object_value sqlite_object_new_exception(zend_class_entry *class_type TSRMLS_DC)
  702. {
  703. zend_object_value retval;
  704. sqlite_object_new(class_type, &sqlite_object_handlers_exception, &retval TSRMLS_CC);
  705. return retval;
  706. }
  707. #define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
  708. { \
  709. sqlite_object *obj; \
  710. obj = (sqlite_object*)zend_object_store_get_object(_object TSRMLS_CC); \
  711. obj->type = is_ ## _type; \
  712. obj->u._type = _ptr; \
  713. }
  714. static zend_class_entry *sqlite_get_ce_query(zval *object TSRMLS_DC)
  715. {
  716. return sqlite_ce_query;
  717. }
  718. static zend_class_entry *sqlite_get_ce_ub_query(zval *object TSRMLS_DC)
  719. {
  720. return sqlite_ce_ub_query;
  721. }
  722. static zval * sqlite_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
  723. {
  724. if (!object) {
  725. ALLOC_ZVAL(object);
  726. }
  727. Z_TYPE_P(object) = IS_OBJECT;
  728. object_init_ex(object, pce);
  729. object->refcount = 1;
  730. object->is_ref = 1;
  731. return object;
  732. }
  733. /* }}} */
  734. static int init_sqlite_globals(zend_sqlite_globals *g)
  735. {
  736. g->assoc_case = 0;
  737. return SUCCESS;
  738. }
  739. PHP_MINIT_FUNCTION(sqlite)
  740. {
  741. REGISTER_SQLITE_CLASS(db, NULL);
  742. REGISTER_SQLITE_CLASS(query, NULL);
  743. REGISTER_SQLITE_CLASS(ub_query, NULL);
  744. REGISTER_SQLITE_CLASS(exception, zend_exception_get_default());
  745. sqlite_object_handlers_query.get_class_entry = sqlite_get_ce_query;
  746. sqlite_object_handlers_ub_query.get_class_entry = sqlite_get_ce_ub_query;
  747. ZEND_INIT_MODULE_GLOBALS(sqlite, init_sqlite_globals, NULL);
  748. REGISTER_INI_ENTRIES();
  749. #if HAVE_PHP_SESSION
  750. php_session_register_module(ps_sqlite_ptr);
  751. #endif
  752. le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number);
  753. le_sqlite_pdb = zend_register_list_destructors_ex(NULL, php_sqlite_db_dtor, "sqlite database (persistent)", module_number);
  754. le_sqlite_result = zend_register_list_destructors_ex(php_sqlite_result_dtor, NULL, "sqlite result", module_number);
  755. REGISTER_LONG_CONSTANT("SQLITE_BOTH", PHPSQLITE_BOTH, CONST_CS|CONST_PERSISTENT);
  756. REGISTER_LONG_CONSTANT("SQLITE_NUM", PHPSQLITE_NUM, CONST_CS|CONST_PERSISTENT);
  757. REGISTER_LONG_CONSTANT("SQLITE_ASSOC", PHPSQLITE_ASSOC, CONST_CS|CONST_PERSISTENT);
  758. REGISTER_LONG_CONSTANT("SQLITE_OK", SQLITE_OK, CONST_CS|CONST_PERSISTENT);
  759. REGISTER_LONG_CONSTANT("SQLITE_ERROR", SQLITE_ERROR, CONST_CS|CONST_PERSISTENT);
  760. REGISTER_LONG_CONSTANT("SQLITE_INTERNAL", SQLITE_INTERNAL, CONST_CS|CONST_PERSISTENT);
  761. REGISTER_LONG_CONSTANT("SQLITE_PERM", SQLITE_PERM, CONST_CS|CONST_PERSISTENT);
  762. REGISTER_LONG_CONSTANT("SQLITE_ABORT", SQLITE_ABORT, CONST_CS|CONST_PERSISTENT);
  763. REGISTER_LONG_CONSTANT("SQLITE_BUSY", SQLITE_BUSY, CONST_CS|CONST_PERSISTENT);
  764. REGISTER_LONG_CONSTANT("SQLITE_LOCKED", SQLITE_LOCKED, CONST_CS|CONST_PERSISTENT);
  765. REGISTER_LONG_CONSTANT("SQLITE_NOMEM", SQLITE_NOMEM, CONST_CS|CONST_PERSISTENT);
  766. REGISTER_LONG_CONSTANT("SQLITE_READONLY", SQLITE_READONLY, CONST_CS|CONST_PERSISTENT);
  767. REGISTER_LONG_CONSTANT("SQLITE_INTERRUPT", SQLITE_INTERRUPT, CONST_CS|CONST_PERSISTENT);
  768. REGISTER_LONG_CONSTANT("SQLITE_IOERR", SQLITE_IOERR, CONST_CS|CONST_PERSISTENT);
  769. REGISTER_LONG_CONSTANT("SQLITE_CORRUPT", SQLITE_CORRUPT, CONST_CS|CONST_PERSISTENT);
  770. REGISTER_LONG_CONSTANT("SQLITE_NOTFOUND", SQLITE_NOTFOUND, CONST_CS|CONST_PERSISTENT);
  771. REGISTER_LONG_CONSTANT("SQLITE_FULL", SQLITE_FULL, CONST_CS|CONST_PERSISTENT);
  772. REGISTER_LONG_CONSTANT("SQLITE_CANTOPEN", SQLITE_CANTOPEN, CONST_CS|CONST_PERSISTENT);
  773. REGISTER_LONG_CONSTANT("SQLITE_PROTOCOL", SQLITE_PROTOCOL, CONST_CS|CONST_PERSISTENT);
  774. REGISTER_LONG_CONSTANT("SQLITE_EMPTY", SQLITE_EMPTY, CONST_CS|CONST_PERSISTENT);
  775. REGISTER_LONG_CONSTANT("SQLITE_SCHEMA", SQLITE_SCHEMA, CONST_CS|CONST_PERSISTENT);
  776. REGISTER_LONG_CONSTANT("SQLITE_TOOBIG", SQLITE_TOOBIG, CONST_CS|CONST_PERSISTENT);
  777. REGISTER_LONG_CONSTANT("SQLITE_CONSTRAINT", SQLITE_CONSTRAINT, CONST_CS|CONST_PERSISTENT);
  778. REGISTER_LONG_CONSTANT("SQLITE_MISMATCH", SQLITE_MISMATCH, CONST_CS|CONST_PERSISTENT);
  779. REGISTER_LONG_CONSTANT("SQLITE_MISUSE", SQLITE_MISUSE, CONST_CS|CONST_PERSISTENT);
  780. REGISTER_LONG_CONSTANT("SQLITE_NOLFS", SQLITE_NOLFS, CONST_CS|CONST_PERSISTENT);
  781. REGISTER_LONG_CONSTANT("SQLITE_AUTH", SQLITE_AUTH, CONST_CS|CONST_PERSISTENT);
  782. #ifdef SQLITE_FORMAT
  783. REGISTER_LONG_CONSTANT("SQLITE_FORMAT", SQLITE_FORMAT, CONST_CS|CONST_PERSISTENT);
  784. #endif
  785. REGISTER_LONG_CONSTANT("SQLITE_ROW", SQLITE_ROW, CONST_CS|CONST_PERSISTENT);
  786. REGISTER_LONG_CONSTANT("SQLITE_DONE", SQLITE_DONE, CONST_CS|CONST_PERSISTENT);
  787. return SUCCESS;
  788. }
  789. PHP_RINIT_FUNCTION(sqlite)
  790. {
  791. #ifdef HAVE_SPL
  792. if (!sqlite_ce_query->num_interfaces) {
  793. spl_register_implement(sqlite_ce_query, spl_ce_forward TSRMLS_CC);
  794. spl_register_implement(sqlite_ce_query, spl_ce_sequence TSRMLS_CC);
  795. }
  796. if (!sqlite_ce_ub_query->num_interfaces) {
  797. spl_register_implement(sqlite_ce_ub_query, spl_ce_forward TSRMLS_CC);
  798. }
  799. #endif
  800. return SUCCESS;
  801. }
  802. PHP_MINFO_FUNCTION(sqlite)
  803. {
  804. php_info_print_table_start();
  805. php_info_print_table_header(2, "SQLite support", "enabled");
  806. php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id$");
  807. php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
  808. php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
  809. php_info_print_table_end();
  810. DISPLAY_INI_ENTRIES();
  811. }
  812. static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg, zval *object TSRMLS_DC)
  813. {
  814. char *errtext = NULL;
  815. sqlite *sdb = NULL;
  816. struct php_sqlite_db *db = NULL;
  817. sdb = sqlite_open(filename, mode, &errtext);
  818. if (sdb == NULL) {
  819. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  820. if (errmsg) {
  821. ZVAL_STRING(errmsg, errtext, 1);
  822. }
  823. sqlite_freemem(errtext);
  824. /* if object is not an object then we're called from the factory() function */
  825. if (object && Z_TYPE_P(object) != IS_OBJECT) {
  826. RETVAL_NULL();
  827. } else {
  828. RETVAL_FALSE;
  829. }
  830. return NULL;
  831. }
  832. db = (struct php_sqlite_db *)pemalloc(sizeof(struct php_sqlite_db), persistent_id ? 1 : 0);
  833. db->is_persistent = persistent_id ? 1 : 0;
  834. db->last_err_code = SQLITE_OK;
  835. db->db = sdb;
  836. zend_hash_init(&db->callbacks, 0, NULL, php_sqlite_callback_dtor, db->is_persistent);
  837. /* register the PHP functions */
  838. sqlite_create_function(sdb, "php", -1, php_sqlite_generic_function_callback, 0);
  839. /* set default busy handler; keep retrying up until 1 minute has passed,
  840. * then fail with a busy status code */
  841. sqlite_busy_timeout(sdb, 60000);
  842. /* authorizer hook so we can enforce safe mode
  843. * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
  844. * and IS backwards binary compatible with earlier versions */
  845. sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
  846. db->rsrc_id = ZEND_REGISTER_RESOURCE(object ? NULL : return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
  847. if (object) {
  848. /* if object is not an object then we're called from the factory() function */
  849. if (Z_TYPE_P(object) != IS_OBJECT) {
  850. sqlite_instanciate(sqlite_ce_db, object TSRMLS_CC);
  851. }
  852. /* and now register the object */
  853. SQLITE_REGISTER_OBJECT(db, object, db)
  854. }
  855. if (persistent_id) {
  856. list_entry le;
  857. Z_TYPE(le) = le_sqlite_pdb;
  858. le.ptr = db;
  859. if (FAILURE == zend_hash_update(&EG(persistent_list), persistent_id,
  860. strlen(persistent_id)+1,
  861. (void *)&le, sizeof(le), NULL)) {
  862. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource");
  863. }
  864. }
  865. return db;
  866. }
  867. /* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
  868. Opens a persistent handle to a SQLite database. Will create the database if it does not exist. */
  869. PHP_FUNCTION(sqlite_popen)
  870. {
  871. int mode = 0666;
  872. char *filename, *fullpath, *hashkey;
  873. long filename_len, hashkeylen;
  874. zval *errmsg = NULL;
  875. struct php_sqlite_db *db = NULL;
  876. list_entry *le;
  877. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
  878. &filename, &filename_len, &mode, &errmsg)) {
  879. return;
  880. }
  881. if (errmsg) {
  882. zval_dtor(errmsg);
  883. }
  884. if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
  885. /* resolve the fully-qualified path name to use as the hash key */
  886. fullpath = expand_filepath(filename, NULL TSRMLS_CC);
  887. if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
  888. RETURN_FALSE;
  889. }
  890. if (php_check_open_basedir(fullpath TSRMLS_CC)) {
  891. RETURN_FALSE;
  892. }
  893. } else {
  894. fullpath = estrndup(filename, filename_len);
  895. }
  896. hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%d", fullpath, mode);
  897. /* do we have an existing persistent connection ? */
  898. if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkeylen+1, (void*)&le)) {
  899. if (Z_TYPE_P(le) == le_sqlite_pdb) {
  900. db = (struct php_sqlite_db*)le->ptr;
  901. if (db->rsrc_id == FAILURE) {
  902. /* give it a valid resource id for this request */
  903. db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
  904. } else {
  905. int type;
  906. /* sanity check to ensure that the resource is still a valid regular resource
  907. * number */
  908. if (zend_list_find(db->rsrc_id, &type) == db) {
  909. /* already accessed this request; map it */
  910. zend_list_addref(db->rsrc_id);
  911. ZVAL_RESOURCE(return_value, db->rsrc_id);
  912. } else {
  913. db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
  914. }
  915. }
  916. /* all set */
  917. efree(fullpath);
  918. efree(hashkey);
  919. return;
  920. }
  921. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Some other type of persistent resource is using this hash key!?");
  922. RETURN_FALSE;
  923. }
  924. /* now we need to open the database */
  925. php_sqlite_open(fullpath, mode, hashkey, return_value, errmsg, NULL TSRMLS_CC);
  926. efree(fullpath);
  927. efree(hashkey);
  928. }
  929. /* }}} */
  930. /* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
  931. Opens a SQLite database. Will create the database if it does not exist. */
  932. PHP_FUNCTION(sqlite_open)
  933. {
  934. int mode = 0666;
  935. char *filename;
  936. long filename_len;
  937. zval *errmsg = NULL;
  938. zval *object = getThis();
  939. php_set_error_handling(object ? EH_THROW : EH_NORMAL, zend_exception_get_default() TSRMLS_CC);
  940. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
  941. &filename, &filename_len, &mode, &errmsg)) {
  942. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  943. return;
  944. }
  945. if (errmsg) {
  946. zval_dtor(errmsg);
  947. }
  948. if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
  949. if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
  950. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  951. if (object) {
  952. RETURN_NULL();
  953. } else {
  954. RETURN_FALSE;
  955. }
  956. }
  957. if (php_check_open_basedir(filename TSRMLS_CC)) {
  958. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  959. if (object) {
  960. RETURN_NULL();
  961. } else {
  962. RETURN_FALSE;
  963. }
  964. }
  965. }
  966. php_sqlite_open(filename, mode, NULL, return_value, errmsg, object TSRMLS_CC);
  967. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  968. }
  969. /* }}} */
  970. /* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
  971. Opens a SQLite database and creates an object for it. Will create the database if it does not exist. */
  972. PHP_FUNCTION(sqlite_factory)
  973. {
  974. int mode = 0666;
  975. char *filename;
  976. long filename_len;
  977. zval *errmsg = NULL;
  978. php_set_error_handling(EH_THROW, sqlite_ce_exception TSRMLS_CC);
  979. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
  980. &filename, &filename_len, &mode, &errmsg)) {
  981. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  982. RETURN_NULL();
  983. }
  984. if (errmsg) {
  985. zval_dtor(errmsg);
  986. }
  987. if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
  988. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  989. RETURN_NULL();
  990. }
  991. if (php_check_open_basedir(filename TSRMLS_CC)) {
  992. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  993. RETURN_NULL();
  994. }
  995. php_sqlite_open(filename, mode, NULL, return_value, errmsg, return_value TSRMLS_CC);
  996. php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
  997. }
  998. /* }}} */
  999. /* {{{ proto void sqlite_busy_timeout(resource db, int ms)
  1000. Set busy timeout duration. If ms <= 0, all busy handlers are disabled. */
  1001. PHP_FUNCTION(sqlite_busy_timeout)
  1002. {
  1003. zval *zdb;
  1004. struct php_sqlite_db *db;
  1005. long ms;
  1006. zval *object = getThis();
  1007. if (object) {
  1008. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) {
  1009. return;
  1010. }
  1011. DB_FROM_OBJECT(db, object);
  1012. } else {
  1013. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
  1014. return;
  1015. }
  1016. DB_FROM_ZVAL(db, &zdb);
  1017. }
  1018. sqlite_busy_timeout(db->db, ms);
  1019. }
  1020. /* }}} */
  1021. /* {{{ proto void sqlite_close(resource db)
  1022. Closes an open sqlite database. */
  1023. PHP_FUNCTION(sqlite_close)
  1024. {
  1025. zval *zdb;
  1026. struct php_sqlite_db *db;
  1027. zval *object = getThis();
  1028. if (object) {
  1029. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Ignored, you must destruct the object instead");
  1030. } else {
  1031. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
  1032. return;
  1033. }
  1034. DB_FROM_ZVAL(db, &zdb);
  1035. }
  1036. zend_list_delete(Z_RESVAL_P(zdb));
  1037. }
  1038. /* }}} */
  1039. /* {{{ php_sqlite_fetch */
  1040. int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
  1041. {
  1042. const char **rowdata, **colnames;
  1043. int ret, i, base;
  1044. char *errtext = NULL, *colname;
  1045. next_row:
  1046. ret = sqlite_step(rres->vm, &rres->ncolumns, &rowdata, &colnames);
  1047. if (!rres->nrows) {
  1048. /* first row - lets copy the column names */
  1049. rres->col_names = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
  1050. for (i = 0; i < rres->ncolumns; i++) {
  1051. colname = strchr(colnames[i], '.');
  1052. if (!colname++) {
  1053. colname = (char*)colnames[i];
  1054. }
  1055. if (SQLITE_G(assoc_case) == 1) {
  1056. php_sqlite_strtoupper(colname);
  1057. } else if (SQLITE_G(assoc_case) == 2) {
  1058. php_sqlite_strtolower(colname);
  1059. }
  1060. rres->col_names[i] = estrdup(colname);
  1061. }
  1062. if (!rres->buffered) {
  1063. /* non buffered mode - also fetch memory for on single row */
  1064. rres->table = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
  1065. }
  1066. }
  1067. switch (ret) {
  1068. case SQLITE_ROW:
  1069. if (rres->buffered) {
  1070. /* add the row to our collection */
  1071. if (rres->nrows + 1 >= rres->alloc_rows) {
  1072. rres->alloc_rows = rres->alloc_rows ? rres->alloc_rows * 2 : 16;
  1073. rres->table = erealloc(rres->table, rres->alloc_rows * rres->ncolumns * sizeof(char *));
  1074. }
  1075. base = rres->nrows * rres->ncolumns;
  1076. for (i = 0; i < rres->ncolumns; i++) {
  1077. if (rowdata[i]) {
  1078. rres->table[base + i] = estrdup(rowdata[i]);
  1079. } else {
  1080. rres->table[base + i] = NULL;
  1081. }
  1082. }
  1083. rres->nrows++;
  1084. goto next_row;
  1085. } else {
  1086. /* non buffered: only fetch one row but first free data if not first row */
  1087. if (rres->nrows++) {
  1088. for (i = 0; i < rres->ncolumns; i++) {
  1089. if (rres->table[i]) {
  1090. efree(rres->table[i]);
  1091. }
  1092. }
  1093. }
  1094. for (i = 0; i < rres->ncolumns; i++) {
  1095. if (rowdata[i]) {
  1096. rres->table[i] = estrdup(rowdata[i]);
  1097. } else {
  1098. rres->table[i] = NULL;
  1099. }
  1100. }
  1101. }
  1102. ret = SQLITE_OK;
  1103. break;
  1104. case SQLITE_BUSY:
  1105. case SQLITE_ERROR:
  1106. case SQLITE_MISUSE:
  1107. case SQLITE_DONE:
  1108. default:
  1109. if (rres->vm) {
  1110. ret = sqlite_finalize(rres->vm, &errtext);
  1111. }
  1112. rres->vm = NULL;
  1113. if (ret != SQLITE_OK) {
  1114. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1115. sqlite_freemem(errtext);
  1116. }
  1117. break;
  1118. }
  1119. rres->db->last_err_code = ret;
  1120. return ret;
  1121. }
  1122. /* }}} */
  1123. /* {{{ sqlite_query */
  1124. void sqlite_query(zval *object, struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result *rres TSRMLS_DC)
  1125. {
  1126. struct php_sqlite_result res;
  1127. int ret;
  1128. char *errtext = NULL;
  1129. const char *tail;
  1130. memset(&res, 0, sizeof(res));
  1131. res.buffered = buffered;
  1132. res.mode = mode;
  1133. ret = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
  1134. db->last_err_code = ret;
  1135. if (ret != SQLITE_OK) {
  1136. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1137. sqlite_freemem(errtext);
  1138. if (return_value) {
  1139. RETURN_FALSE;
  1140. } else {
  1141. return;
  1142. }
  1143. }
  1144. if (!rres) {
  1145. rres = (struct php_sqlite_result*)emalloc(sizeof(*rres));
  1146. }
  1147. memcpy(rres, &res, sizeof(*rres));
  1148. rres->db = db;
  1149. zend_list_addref(db->rsrc_id);
  1150. /* now the result set is ready for stepping: get first row */
  1151. if (php_sqlite_fetch(rres TSRMLS_CC) != SQLITE_OK) {
  1152. real_result_dtor(rres TSRMLS_CC);
  1153. if (return_value) {
  1154. RETURN_FALSE;
  1155. } else {
  1156. return;
  1157. }
  1158. }
  1159. rres->curr_row = 0;
  1160. if (object) {
  1161. sqlite_object *obj;
  1162. if (buffered) {
  1163. sqlite_instanciate(sqlite_ce_query, return_value TSRMLS_CC);
  1164. } else {
  1165. sqlite_instanciate(sqlite_ce_ub_query, return_value TSRMLS_CC);
  1166. }
  1167. obj = (sqlite_object *) zend_object_store_get_object(return_value TSRMLS_CC);
  1168. obj->type = is_result;
  1169. obj->u.res = rres;
  1170. } else if (return_value) {
  1171. ZEND_REGISTER_RESOURCE(object ? NULL : return_value, rres, le_sqlite_result);
  1172. }
  1173. }
  1174. /* }}} */
  1175. /* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type ])
  1176. Executes a query that does not prefetch and buffer all data. */
  1177. PHP_FUNCTION(sqlite_unbuffered_query)
  1178. {
  1179. zval *zdb;
  1180. struct php_sqlite_db *db;
  1181. char *sql;
  1182. long sql_len;
  1183. int mode = PHPSQLITE_BOTH;
  1184. char *errtext = NULL;
  1185. zval *object = getThis();
  1186. if (object) {
  1187. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &sql, &sql_len, &mode)) {
  1188. return;
  1189. }
  1190. DB_FROM_OBJECT(db, object);
  1191. } else {
  1192. if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
  1193. ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &sql, &sql_len, &zdb, &mode) &&
  1194. FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &sql, &sql_len, &mode)) {
  1195. return;
  1196. }
  1197. DB_FROM_ZVAL(db, &zdb);
  1198. }
  1199. /* avoid doing work if we can */
  1200. if (!return_value_used) {
  1201. db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
  1202. if (db->last_err_code != SQLITE_OK) {
  1203. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1204. sqlite_freemem(errtext);
  1205. }
  1206. return;
  1207. }
  1208. sqlite_query(object, db, sql, sql_len, mode, 0, return_value, NULL TSRMLS_CC);
  1209. }
  1210. /* }}} */
  1211. /* {{{ proto resource sqlite_query(string query, resource db [, int result_type ])
  1212. Executes a query against a given database and returns a result handle. */
  1213. PHP_FUNCTION(sqlite_query)
  1214. {
  1215. zval *zdb;
  1216. struct php_sqlite_db *db;
  1217. char *sql;
  1218. long sql_len;
  1219. int mode = PHPSQLITE_BOTH;
  1220. char *errtext = NULL;
  1221. zval *object = getThis();
  1222. if (object) {
  1223. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &sql, &sql_len, &mode)) {
  1224. return;
  1225. }
  1226. DB_FROM_OBJECT(db, object);
  1227. } else {
  1228. if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
  1229. ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &sql, &sql_len, &zdb, &mode) &&
  1230. FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &sql, &sql_len, &mode)) {
  1231. return;
  1232. }
  1233. DB_FROM_ZVAL(db, &zdb);
  1234. }
  1235. /* avoid doing work if we can */
  1236. if (!return_value_used) {
  1237. db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
  1238. if (db->last_err_code != SQLITE_OK) {
  1239. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1240. sqlite_freemem(errtext);
  1241. }
  1242. return;
  1243. }
  1244. sqlite_query(object, db, sql, sql_len, mode, 1, return_value, NULL TSRMLS_CC);
  1245. }
  1246. /* }}} */
  1247. /* {{{ php_sqlite_fetch_array */
  1248. static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
  1249. {
  1250. int j, n = res->ncolumns, buffered = res->buffered;
  1251. const char **rowdata, **colnames;
  1252. /* check range of the row */
  1253. if (res->curr_row >= res->nrows) {
  1254. /* no more */
  1255. RETURN_FALSE;
  1256. }
  1257. colnames = (const char**)res->col_names;
  1258. if (res->buffered) {
  1259. rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
  1260. } else {
  1261. rowdata = (const char**)res->table;
  1262. }
  1263. /* now populate the result */
  1264. array_init(return_value);
  1265. for (j = 0; j < n; j++) {
  1266. zval *decoded;
  1267. MAKE_STD_ZVAL(decoded);
  1268. if (rowdata[j] == NULL) {
  1269. ZVAL_NULL(decoded);
  1270. } else if (decode_binary && rowdata[j][0] == '\x01') {
  1271. Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
  1272. Z_STRLEN_P(decoded) = sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
  1273. Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
  1274. Z_TYPE_P(decoded) = IS_STRING;
  1275. if (!buffered) {
  1276. efree((char*)rowdata[j]);
  1277. rowdata[j] = NULL;
  1278. }
  1279. } else {
  1280. ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
  1281. if (!buffered) {
  1282. rowdata[j] = NULL;
  1283. }
  1284. }
  1285. if (mode & PHPSQLITE_NUM) {
  1286. if (mode & PHPSQLITE_ASSOC) {
  1287. add_index_zval(return_value, j, decoded);
  1288. ZVAL_ADDREF(decoded);
  1289. add_assoc_zval(return_value, (char*)colnames[j], decoded);
  1290. } else {
  1291. add_next_index_zval(return_value, decoded);
  1292. }
  1293. } else {
  1294. add_assoc_zval(return_value, (char*)colnames[j], decoded);
  1295. }
  1296. }
  1297. if (move_next) {
  1298. if (!res->buffered) {
  1299. /* non buffered: fetch next row */
  1300. php_sqlite_fetch(res TSRMLS_CC);
  1301. }
  1302. /* advance the row pointer */
  1303. res->curr_row++;
  1304. }
  1305. }
  1306. /* }}} */
  1307. /* {{{ php_sqlite_fetch_column */
  1308. static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which, zend_bool decode_binary, zval *return_value TSRMLS_DC)
  1309. {
  1310. int j;
  1311. const char **rowdata, **colnames;
  1312. /* check range of the row */
  1313. if (res->curr_row >= res->nrows) {
  1314. /* no more */
  1315. RETURN_FALSE;
  1316. }
  1317. colnames = (const char**)res->col_names;
  1318. if (Z_TYPE_P(which) == IS_LONG) {
  1319. j = Z_LVAL_P(which);
  1320. } else {
  1321. convert_to_string_ex(&which);
  1322. for (j = 0; j < res->ncolumns; j++) {
  1323. if (!strcasecmp((char*)colnames[j], Z_STRVAL_P(which))) {
  1324. break;
  1325. }
  1326. }
  1327. }
  1328. if (j < 0 || j >= res->ncolumns) {
  1329. php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such column %d", j);
  1330. RETURN_FALSE;
  1331. }
  1332. if (res->buffered) {
  1333. rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
  1334. } else {
  1335. rowdata = (const char**)res->table;
  1336. }
  1337. if (rowdata[j] == NULL) {
  1338. RETURN_NULL();
  1339. } else if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
  1340. int l = strlen(rowdata[j]);
  1341. char *decoded = emalloc(l);
  1342. l = sqlite_decode_binary(rowdata[j]+1, decoded);
  1343. decoded[l] = '\0';
  1344. RETVAL_STRINGL(decoded, l, 0);
  1345. if (!res->buffered) {
  1346. efree((char*)rowdata[j]);
  1347. rowdata[j] = NULL;
  1348. }
  1349. } else {
  1350. RETVAL_STRING((char*)rowdata[j], res->buffered);
  1351. if (!res->buffered) {
  1352. rowdata[j] = NULL;
  1353. }
  1354. }
  1355. }
  1356. /* }}} */
  1357. /* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
  1358. Fetches all rows from a result set as an array of arrays. */
  1359. PHP_FUNCTION(sqlite_fetch_all)
  1360. {
  1361. zval *zres, *ent;
  1362. int mode = PHPSQLITE_BOTH;
  1363. zend_bool decode_binary = 1;
  1364. struct php_sqlite_result *res;
  1365. zval *object = getThis();
  1366. if (object) {
  1367. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
  1368. return;
  1369. }
  1370. RES_FROM_OBJECT(res, object);
  1371. if (!ZEND_NUM_ARGS()) {
  1372. mode = res->mode;
  1373. }
  1374. } else {
  1375. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
  1376. return;
  1377. }
  1378. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1379. if (ZEND_NUM_ARGS() < 2) {
  1380. mode = res->mode;
  1381. }
  1382. }
  1383. if (res->curr_row >= res->nrows && res->nrows) {
  1384. if (!res->buffered) {
  1385. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "One or more rowsets were already returned");
  1386. } else {
  1387. res->curr_row = 0;
  1388. }
  1389. }
  1390. array_init(return_value);
  1391. while (res->curr_row < res->nrows) {
  1392. MAKE_STD_ZVAL(ent);
  1393. php_sqlite_fetch_array(res, mode, decode_binary, 1, ent TSRMLS_CC);
  1394. add_next_index_zval(return_value, ent);
  1395. }
  1396. }
  1397. /* }}} */
  1398. /* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
  1399. Fetches the next row from a result set as an array. */
  1400. PHP_FUNCTION(sqlite_fetch_array)
  1401. {
  1402. zval *zres;
  1403. int mode = PHPSQLITE_BOTH;
  1404. zend_bool decode_binary = 1;
  1405. struct php_sqlite_result *res;
  1406. zval *object = getThis();
  1407. if (object) {
  1408. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
  1409. return;
  1410. }
  1411. RES_FROM_OBJECT(res, object);
  1412. if (!ZEND_NUM_ARGS()) {
  1413. mode = res->mode;
  1414. }
  1415. } else {
  1416. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
  1417. return;
  1418. }
  1419. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1420. if (ZEND_NUM_ARGS() < 2) {
  1421. mode = res->mode;
  1422. }
  1423. }
  1424. php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
  1425. }
  1426. /* }}} */
  1427. /* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
  1428. Executes a query against a given database and returns an array of arrays. */
  1429. PHP_FUNCTION(sqlite_array_query)
  1430. {
  1431. zval *zdb, *ent;
  1432. struct php_sqlite_db *db;
  1433. struct php_sqlite_result *rres;
  1434. char *sql;
  1435. long sql_len;
  1436. int mode = PHPSQLITE_BOTH;
  1437. char *errtext = NULL;
  1438. zend_bool decode_binary = 1;
  1439. zval *object = getThis();
  1440. if (object) {
  1441. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &sql, &sql_len, &mode, &decode_binary)) {
  1442. return;
  1443. }
  1444. DB_FROM_OBJECT(db, object);
  1445. } else {
  1446. if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
  1447. ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
  1448. FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
  1449. return;
  1450. }
  1451. DB_FROM_ZVAL(db, &zdb);
  1452. }
  1453. /* avoid doing work if we can */
  1454. if (!return_value_used) {
  1455. db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
  1456. if (db->last_err_code != SQLITE_OK) {
  1457. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1458. sqlite_freemem(errtext);
  1459. }
  1460. return;
  1461. }
  1462. rres = (struct php_sqlite_result *)emalloc(sizeof(*rres));
  1463. sqlite_query(NULL, db, sql, sql_len, mode, 0, NULL, rres TSRMLS_CC);
  1464. if (db->last_err_code != SQLITE_OK) {
  1465. efree(rres);
  1466. RETURN_FALSE;
  1467. }
  1468. array_init(return_value);
  1469. while (rres->curr_row < rres->nrows) {
  1470. MAKE_STD_ZVAL(ent);
  1471. php_sqlite_fetch_array(rres, mode, decode_binary, 1, ent TSRMLS_CC);
  1472. add_next_index_zval(return_value, ent);
  1473. }
  1474. real_result_dtor(rres TSRMLS_CC);
  1475. }
  1476. /* }}} */
  1477. /* {{{ php_sqlite_fetch_single */
  1478. static void php_sqlite_fetch_single(struct php_sqlite_result *res, zend_bool decode_binary, zval *return_value TSRMLS_DC)
  1479. {
  1480. const char **rowdata;
  1481. char *decoded;
  1482. int decoded_len;
  1483. /* check range of the row */
  1484. if (res->curr_row >= res->nrows) {
  1485. /* no more */
  1486. RETURN_FALSE;
  1487. }
  1488. if (res->buffered) {
  1489. rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
  1490. } else {
  1491. rowdata = (const char**)res->table;
  1492. }
  1493. if (decode_binary && rowdata[0] != NULL && rowdata[0][0] == '\x01') {
  1494. decoded = emalloc(strlen(rowdata[0]));
  1495. decoded_len = sqlite_decode_binary(rowdata[0]+1, decoded);
  1496. if (!res->buffered) {
  1497. efree((char*)rowdata[0]);
  1498. rowdata[0] = NULL;
  1499. }
  1500. } else if (rowdata[0]) {
  1501. decoded_len = strlen((char*)rowdata[0]);
  1502. if (res->buffered) {
  1503. decoded = estrndup((char*)rowdata[0], decoded_len);
  1504. } else {
  1505. decoded = (char*)rowdata[0];
  1506. rowdata[0] = NULL;
  1507. }
  1508. } else {
  1509. decoded = NULL;
  1510. decoded_len = 0;
  1511. }
  1512. if (!res->buffered) {
  1513. /* non buffered: fetch next row */
  1514. php_sqlite_fetch(res TSRMLS_CC);
  1515. }
  1516. /* advance the row pointer */
  1517. res->curr_row++;
  1518. if (decoded == NULL) {
  1519. RETURN_NULL();
  1520. } else {
  1521. RETURN_STRINGL(decoded, decoded_len, 0);
  1522. }
  1523. }
  1524. /* }}} */
  1525. /* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
  1526. Executes a query and returns either an array for one single column or the value of the first row. */
  1527. PHP_FUNCTION(sqlite_single_query)
  1528. {
  1529. zval *zdb, *ent;
  1530. struct php_sqlite_db *db;
  1531. struct php_sqlite_result *rres;
  1532. char *sql;
  1533. long sql_len;
  1534. char *errtext = NULL;
  1535. zend_bool decode_binary = 1;
  1536. zend_bool srow = 1;
  1537. zval *object = getThis();
  1538. if (object) {
  1539. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb", &sql, &sql_len, &srow, &decode_binary)) {
  1540. return;
  1541. }
  1542. RES_FROM_OBJECT(db, object);
  1543. } else {
  1544. if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
  1545. ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) &&
  1546. FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
  1547. return;
  1548. }
  1549. DB_FROM_ZVAL(db, &zdb);
  1550. }
  1551. /* avoid doing work if we can */
  1552. if (!return_value_used) {
  1553. db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
  1554. if (db->last_err_code != SQLITE_OK) {
  1555. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
  1556. sqlite_freemem(errtext);
  1557. }
  1558. return;
  1559. }
  1560. rres = (struct php_sqlite_result *)emalloc(sizeof(*rres));
  1561. sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, rres TSRMLS_CC);
  1562. if (db->last_err_code != SQLITE_OK) {
  1563. efree(rres);
  1564. RETURN_FALSE;
  1565. }
  1566. if (!srow) {
  1567. array_init(return_value);
  1568. }
  1569. while (rres->curr_row < rres->nrows) {
  1570. MAKE_STD_ZVAL(ent);
  1571. php_sqlite_fetch_single(rres, decode_binary, ent TSRMLS_CC);
  1572. /* if set and we only have 1 row in the result set, return the result as a string. */
  1573. if (srow) {
  1574. if (rres->curr_row == 1 && rres->curr_row >= rres->nrows) {
  1575. *return_value = *ent;
  1576. zval_copy_ctor(return_value);
  1577. zval_dtor(ent);
  1578. FREE_ZVAL(ent);
  1579. break;
  1580. } else {
  1581. srow = 0;
  1582. array_init(return_value);
  1583. }
  1584. }
  1585. add_next_index_zval(return_value, ent);
  1586. }
  1587. real_result_dtor(rres TSRMLS_CC);
  1588. }
  1589. /* }}} */
  1590. /* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
  1591. Fetches the first column of a result set as a string. */
  1592. PHP_FUNCTION(sqlite_fetch_single)
  1593. {
  1594. zval *zres;
  1595. zend_bool decode_binary = 1;
  1596. struct php_sqlite_result *res;
  1597. zval *object = getThis();
  1598. if (object) {
  1599. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &decode_binary)) {
  1600. return;
  1601. }
  1602. RES_FROM_OBJECT(res, object);
  1603. } else {
  1604. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
  1605. return;
  1606. }
  1607. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1608. }
  1609. php_sqlite_fetch_single(res, decode_binary, return_value TSRMLS_CC);
  1610. }
  1611. /* }}} */
  1612. /* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
  1613. Fetches the current row from a result set as an array. */
  1614. PHP_FUNCTION(sqlite_current)
  1615. {
  1616. zval *zres;
  1617. int mode = PHPSQLITE_BOTH;
  1618. zend_bool decode_binary = 1;
  1619. struct php_sqlite_result *res;
  1620. zval *object = getThis();
  1621. if (object) {
  1622. if (ZEND_NUM_ARGS() && FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
  1623. return;
  1624. }
  1625. RES_FROM_OBJECT(res, object);
  1626. if (!ZEND_NUM_ARGS()) {
  1627. mode = res->mode;
  1628. }
  1629. } else {
  1630. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
  1631. return;
  1632. }
  1633. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1634. if (ZEND_NUM_ARGS() < 2) {
  1635. mode = res->mode;
  1636. }
  1637. }
  1638. php_sqlite_fetch_array(res, mode, decode_binary, 0, return_value TSRMLS_CC);
  1639. }
  1640. /* }}} */
  1641. /* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
  1642. Fetches a column from the current row of a result set. */
  1643. PHP_FUNCTION(sqlite_column)
  1644. {
  1645. zval *zres;
  1646. zval *which;
  1647. zend_bool decode_binary = 1;
  1648. struct php_sqlite_result *res;
  1649. zval *object = getThis();
  1650. if (object) {
  1651. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &which, &decode_binary)) {
  1652. return;
  1653. }
  1654. RES_FROM_OBJECT(res, object);
  1655. } else {
  1656. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
  1657. return;
  1658. }
  1659. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1660. }
  1661. php_sqlite_fetch_column(res, which, decode_binary, return_value TSRMLS_CC);
  1662. }
  1663. /* }}} */
  1664. /* {{{ proto string sqlite_libversion()
  1665. Returns the version of the linked SQLite library. */
  1666. PHP_FUNCTION(sqlite_libversion)
  1667. {
  1668. if (ZEND_NUM_ARGS() != 0) {
  1669. WRONG_PARAM_COUNT;
  1670. }
  1671. RETURN_STRING((char*)sqlite_libversion(), 1);
  1672. }
  1673. /* }}} */
  1674. /* {{{ proto string sqlite_libencoding()
  1675. Returns the encoding (iso8859 or UTF-8) of the linked SQLite library. */
  1676. PHP_FUNCTION(sqlite_libencoding)
  1677. {
  1678. if (ZEND_NUM_ARGS() != 0) {
  1679. WRONG_PARAM_COUNT;
  1680. }
  1681. RETURN_STRING((char*)sqlite_libencoding(), 1);
  1682. }
  1683. /* }}} */
  1684. /* {{{ proto int sqlite_changes(resource db)
  1685. Returns the number of rows that were changed by the most recent SQL statement. */
  1686. PHP_FUNCTION(sqlite_changes)
  1687. {
  1688. zval *zdb;
  1689. struct php_sqlite_db *db;
  1690. zval *object = getThis();
  1691. if (object) {
  1692. if (ZEND_NUM_ARGS() != 0) {
  1693. WRONG_PARAM_COUNT
  1694. }
  1695. DB_FROM_OBJECT(db, object);
  1696. } else {
  1697. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
  1698. return;
  1699. }
  1700. DB_FROM_ZVAL(db, &zdb);
  1701. }
  1702. RETURN_LONG(sqlite_changes(db->db));
  1703. }
  1704. /* }}} */
  1705. /* {{{ proto int sqlite_last_insert_rowid(resource db)
  1706. Returns the rowid of the most recently inserted row. */
  1707. PHP_FUNCTION(sqlite_last_insert_rowid)
  1708. {
  1709. zval *zdb;
  1710. struct php_sqlite_db *db;
  1711. zval *object = getThis();
  1712. if (object) {
  1713. if (ZEND_NUM_ARGS() != 0) {
  1714. WRONG_PARAM_COUNT
  1715. }
  1716. DB_FROM_OBJECT(db, object);
  1717. } else {
  1718. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
  1719. return;
  1720. }
  1721. DB_FROM_ZVAL(db, &zdb);
  1722. }
  1723. RETURN_LONG(sqlite_last_insert_rowid(db->db));
  1724. }
  1725. /* }}} */
  1726. /* {{{ proto int sqlite_num_rows(resource result)
  1727. Returns the number of rows in a buffered result set. */
  1728. PHP_FUNCTION(sqlite_num_rows)
  1729. {
  1730. zval *zres;
  1731. struct php_sqlite_result *res;
  1732. zval *object = getThis();
  1733. if (object) {
  1734. if (ZEND_NUM_ARGS() != 0) {
  1735. WRONG_PARAM_COUNT
  1736. }
  1737. RES_FROM_OBJECT(res, object);
  1738. } else {
  1739. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1740. return;
  1741. }
  1742. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1743. }
  1744. if (res->buffered) {
  1745. RETURN_LONG(res->nrows);
  1746. } else {
  1747. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Row count is not available for unbuffered queries");
  1748. RETURN_FALSE;
  1749. }
  1750. }
  1751. /* }}} */
  1752. /* {{{ proto bool sqlite_has_more(resource result)
  1753. Returns whether more rows are available. */
  1754. PHP_FUNCTION(sqlite_has_more)
  1755. {
  1756. zval *zres;
  1757. struct php_sqlite_result *res;
  1758. zval *object = getThis();
  1759. if (object) {
  1760. if (ZEND_NUM_ARGS() != 0) {
  1761. WRONG_PARAM_COUNT
  1762. }
  1763. RES_FROM_OBJECT(res, object);
  1764. } else {
  1765. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1766. return;
  1767. }
  1768. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1769. }
  1770. RETURN_BOOL(res->curr_row < res->nrows && res->nrows); /* curr_row may be -1 */
  1771. }
  1772. /* }}} */
  1773. /* {{{ proto bool sqlite_has_prev(resource result)
  1774. * Returns whether a previous row is available. */
  1775. PHP_FUNCTION(sqlite_has_prev)
  1776. {
  1777. zval *zres;
  1778. struct php_sqlite_result *res;
  1779. zval *object = getThis();
  1780. if (object) {
  1781. if (ZEND_NUM_ARGS() != 0) {
  1782. WRONG_PARAM_COUNT
  1783. }
  1784. RES_FROM_OBJECT(res, object);
  1785. } else {
  1786. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1787. return;
  1788. }
  1789. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1790. }
  1791. if(!res->buffered) {
  1792. php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_has_prev on unbuffered querys");
  1793. RETURN_FALSE;
  1794. }
  1795. RETURN_BOOL(res->curr_row);
  1796. }
  1797. /* }}} */
  1798. /* {{{ proto int sqlite_num_fields(resource result)
  1799. Returns the number of fields in a result set. */
  1800. PHP_FUNCTION(sqlite_num_fields)
  1801. {
  1802. zval *zres;
  1803. struct php_sqlite_result *res;
  1804. zval *object = getThis();
  1805. if (object) {
  1806. if (ZEND_NUM_ARGS() != 0) {
  1807. WRONG_PARAM_COUNT
  1808. }
  1809. RES_FROM_OBJECT(res, object);
  1810. } else {
  1811. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1812. return;
  1813. }
  1814. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1815. }
  1816. RETURN_LONG(res->ncolumns);
  1817. }
  1818. /* }}} */
  1819. /* {{{ proto string sqlite_field_name(resource result, int field_index)
  1820. Returns the name of a particular field of a result set. */
  1821. PHP_FUNCTION(sqlite_field_name)
  1822. {
  1823. zval *zres;
  1824. struct php_sqlite_result *res;
  1825. int field;
  1826. zval *object = getThis();
  1827. if (object) {
  1828. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &field)) {
  1829. return;
  1830. }
  1831. RES_FROM_OBJECT(res, object);
  1832. } else {
  1833. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
  1834. return;
  1835. }
  1836. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1837. }
  1838. if (field < 0 || field >= res->ncolumns) {
  1839. php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %d out of range", field);
  1840. RETURN_FALSE;
  1841. }
  1842. RETURN_STRING(res->col_names[field], 1);
  1843. }
  1844. /* }}} */
  1845. /* {{{ proto bool sqlite_seek(resource result, int row)
  1846. Seek to a particular row number of a buffered result set. */
  1847. PHP_FUNCTION(sqlite_seek)
  1848. {
  1849. zval *zres;
  1850. struct php_sqlite_result *res;
  1851. int row;
  1852. zval *object = getThis();
  1853. if (object) {
  1854. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &row)) {
  1855. return;
  1856. }
  1857. RES_FROM_OBJECT(res, object);
  1858. } else {
  1859. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
  1860. return;
  1861. }
  1862. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1863. }
  1864. if (!res->buffered) {
  1865. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
  1866. RETURN_FALSE;
  1867. }
  1868. if (row < 0 || row >= res->nrows) {
  1869. php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %d out of range", row);
  1870. RETURN_FALSE;
  1871. }
  1872. res->curr_row = row;
  1873. RETURN_TRUE;
  1874. }
  1875. /* }}} */
  1876. /* {{{ proto bool sqlite_rewind(resource result)
  1877. Seek to the first row number of a buffered result set. */
  1878. PHP_FUNCTION(sqlite_rewind)
  1879. {
  1880. zval *zres;
  1881. struct php_sqlite_result *res;
  1882. zval *object = getThis();
  1883. if (object) {
  1884. if (ZEND_NUM_ARGS() != 0) {
  1885. WRONG_PARAM_COUNT
  1886. }
  1887. RES_FROM_OBJECT(res, object);
  1888. } else {
  1889. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1890. return;
  1891. }
  1892. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1893. }
  1894. if (!res->buffered) {
  1895. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rewind an unbuffered result set");
  1896. RETURN_FALSE;
  1897. }
  1898. if (!res->nrows) {
  1899. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "no rows received");
  1900. RETURN_FALSE;
  1901. }
  1902. res->curr_row = 0;
  1903. RETURN_TRUE;
  1904. }
  1905. /* }}} */
  1906. /* {{{ proto bool sqlite_next(resource result)
  1907. Seek to the next row number of a result set. */
  1908. PHP_FUNCTION(sqlite_next)
  1909. {
  1910. zval *zres;
  1911. struct php_sqlite_result *res;
  1912. zval *object = getThis();
  1913. if (object) {
  1914. if (ZEND_NUM_ARGS() != 0) {
  1915. WRONG_PARAM_COUNT
  1916. }
  1917. RES_FROM_OBJECT(res, object);
  1918. } else {
  1919. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1920. return;
  1921. }
  1922. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1923. }
  1924. if (!res->buffered && res->vm) {
  1925. php_sqlite_fetch(res TSRMLS_CC);
  1926. }
  1927. if (res->curr_row >= res->nrows) {
  1928. php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available");
  1929. RETURN_FALSE;
  1930. }
  1931. res->curr_row++;
  1932. RETURN_TRUE;
  1933. }
  1934. /* }}} */
  1935. /* {{{ proto bool sqlite_prev(resource result)
  1936. * Seek to the previous row number of a result set. */
  1937. PHP_FUNCTION(sqlite_prev)
  1938. {
  1939. zval *zres;
  1940. struct php_sqlite_result *res;
  1941. zval *object = getThis();
  1942. if (object) {
  1943. if (ZEND_NUM_ARGS() != 0) {
  1944. WRONG_PARAM_COUNT
  1945. }
  1946. RES_FROM_OBJECT(res, object);
  1947. } else {
  1948. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
  1949. return;
  1950. }
  1951. ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
  1952. }
  1953. if (!res->buffered) {
  1954. php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_prev on unbuffered querys");
  1955. RETURN_FALSE;
  1956. }
  1957. if (res->curr_row <= 0) {
  1958. php_error_docref(NULL TSRMLS_CC, E_WARNING, "no previous row available");
  1959. RETURN_FALSE;
  1960. }
  1961. res->curr_row--;
  1962. RETURN_TRUE;
  1963. }
  1964. /* }}} */
  1965. /* {{{ proto string sqlite_escape_string(string item)
  1966. Escapes a string for use as a query parameter. */
  1967. PHP_FUNCTION(sqlite_escape_string)
  1968. {
  1969. char *string = NULL;
  1970. long stringlen;
  1971. char *ret;
  1972. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &stringlen)) {
  1973. return;
  1974. }
  1975. if (stringlen && (string[0] == '\x01' || memchr(string, '\0', stringlen) != NULL)) {
  1976. /* binary string */
  1977. int enclen;
  1978. ret = emalloc( 1 + ((256 * stringlen + 1262) / 253) );
  1979. ret[0] = '\x01';
  1980. enclen = sqlite_encode_binary((const unsigned char*)string, stringlen, ret+1);
  1981. RETVAL_STRINGL(ret, enclen+1, 0);
  1982. } else {
  1983. ret = sqlite_mprintf("%q", string);
  1984. if (ret) {
  1985. RETVAL_STRING(ret, 1);
  1986. sqlite_freemem(ret);
  1987. }
  1988. }
  1989. }
  1990. /* }}} */
  1991. /* {{{ proto int sqlite_last_error(resource db)
  1992. Returns the error code of the last error for a database. */
  1993. PHP_FUNCTION(sqlite_last_error)
  1994. {
  1995. zval *zdb;
  1996. struct php_sqlite_db *db;
  1997. zval *object = getThis();
  1998. if (object) {
  1999. if (ZEND_NUM_ARGS() != 0) {
  2000. WRONG_PARAM_COUNT
  2001. }
  2002. DB_FROM_OBJECT(db, object);
  2003. } else {
  2004. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
  2005. return;
  2006. }
  2007. DB_FROM_ZVAL(db, &zdb);
  2008. }
  2009. RETURN_LONG(db->last_err_code);
  2010. }
  2011. /* }}} */
  2012. /* {{{ proto string sqlite_error_string(int error_code)
  2013. Returns the textual description of an error code. */
  2014. PHP_FUNCTION(sqlite_error_string)
  2015. {
  2016. long code;
  2017. const char *msg;
  2018. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
  2019. return;
  2020. }
  2021. msg = sqlite_error_string(code);
  2022. if (msg) {
  2023. RETURN_STRING((char*)msg, 1);
  2024. } else {
  2025. RETURN_NULL();
  2026. }
  2027. }
  2028. /* }}} */
  2029. /* manages duplicate registrations of a particular function, and
  2030. * also handles the case where the db is using a persistent connection */
  2031. enum callback_prep_t { DO_REG, SKIP_REG, ERR };
  2032. static enum callback_prep_t prep_callback_struct(struct php_sqlite_db *db, int is_agg,
  2033. char *funcname,
  2034. zval *step, zval *fini, struct php_sqlite_agg_functions **funcs)
  2035. {
  2036. struct php_sqlite_agg_functions *alloc_funcs, func_tmp;
  2037. char *hashkey;
  2038. int hashkeylen;
  2039. enum callback_prep_t ret;
  2040. hashkeylen = spprintf(&hashkey, 0, "%s-%s", is_agg ? "agg" : "reg", funcname);
  2041. /* is it already registered ? */
  2042. if (SUCCESS == zend_hash_find(&db->callbacks, hashkey, hashkeylen+1, (void*)&alloc_funcs)) {
  2043. /* override the previous definition */
  2044. if (alloc_funcs->is_valid) {
  2045. /* release these */
  2046. if (alloc_funcs->step) {
  2047. zval_ptr_dtor(&alloc_funcs->step);
  2048. alloc_funcs->step = NULL;
  2049. }
  2050. if (alloc_funcs->fini) {
  2051. zval_ptr_dtor(&alloc_funcs->fini);
  2052. alloc_funcs->fini = NULL;
  2053. }
  2054. }
  2055. ret = SKIP_REG;
  2056. } else {
  2057. /* add a new one */
  2058. func_tmp.db = db;
  2059. ret = SUCCESS == zend_hash_update(&db->callbacks, hashkey, hashkeylen+1,
  2060. (void*)&func_tmp, sizeof(func_tmp), (void**)&alloc_funcs) ? DO_REG : ERR;
  2061. }
  2062. efree(hashkey);
  2063. MAKE_STD_ZVAL(alloc_funcs->step);
  2064. *(alloc_funcs->step) = *step;
  2065. zval_copy_ctor(alloc_funcs->step);
  2066. if (is_agg) {
  2067. MAKE_STD_ZVAL(alloc_funcs->fini);
  2068. *(alloc_funcs->fini) = *fini;
  2069. zval_copy_ctor(alloc_funcs->fini);
  2070. } else {
  2071. alloc_funcs->fini = NULL;
  2072. }
  2073. alloc_funcs->is_valid = 1;
  2074. *funcs = alloc_funcs;
  2075. return ret;
  2076. }
  2077. /* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
  2078. Registers an aggregate function for queries. */
  2079. PHP_FUNCTION(sqlite_create_aggregate)
  2080. {
  2081. char *funcname = NULL;
  2082. long funcname_len;
  2083. zval *zstep, *zfinal, *zdb;
  2084. struct php_sqlite_db *db;
  2085. struct php_sqlite_agg_functions *funcs;
  2086. char *callable = NULL;
  2087. long num_args = -1;
  2088. zval *object = getThis();
  2089. if (object) {
  2090. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
  2091. return;
  2092. }
  2093. DB_FROM_OBJECT(db, object);
  2094. } else {
  2095. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
  2096. return;
  2097. }
  2098. DB_FROM_ZVAL(db, &zdb);
  2099. }
  2100. if (!zend_is_callable(zstep, 0, &callable)) {
  2101. php_error_docref(NULL TSRMLS_CC, E_WARNING, "step function `%s' is not callable", callable);
  2102. efree(callable);
  2103. return;
  2104. }
  2105. efree(callable);
  2106. if (!zend_is_callable(zfinal, 0, &callable)) {
  2107. php_error_docref(NULL TSRMLS_CC, E_WARNING, "finalize function `%s' is not callable", callable);
  2108. efree(callable);
  2109. return;
  2110. }
  2111. efree(callable);
  2112. if (prep_callback_struct(db, 1, funcname, zstep, zfinal, &funcs) == DO_REG) {
  2113. sqlite_create_aggregate(db->db, funcname, num_args,
  2114. php_sqlite_agg_step_function_callback,
  2115. php_sqlite_agg_fini_function_callback, funcs);
  2116. }
  2117. }
  2118. /* }}} */
  2119. /* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
  2120. Registers a "regular" function for queries. */
  2121. PHP_FUNCTION(sqlite_create_function)
  2122. {
  2123. char *funcname = NULL;
  2124. long funcname_len;
  2125. zval *zcall, *zdb;
  2126. struct php_sqlite_db *db;
  2127. struct php_sqlite_agg_functions *funcs;
  2128. char *callable = NULL;
  2129. long num_args = -1;
  2130. zval *object = getThis();
  2131. if (object) {
  2132. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &funcname, &funcname_len, &zcall, &num_args)) {
  2133. return;
  2134. }
  2135. DB_FROM_OBJECT(db, object);
  2136. } else {
  2137. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
  2138. return;
  2139. }
  2140. DB_FROM_ZVAL(db, &zdb);
  2141. }
  2142. if (!zend_is_callable(zcall, 0, &callable)) {
  2143. php_error_docref(NULL TSRMLS_CC, E_WARNING, "function `%s' is not callable", callable);
  2144. efree(callable);
  2145. return;
  2146. }
  2147. efree(callable);
  2148. if (prep_callback_struct(db, 0, funcname, zcall, NULL, &funcs) == DO_REG) {
  2149. sqlite_create_function(db->db, funcname, num_args, php_sqlite_function_callback, funcs);
  2150. }
  2151. }
  2152. /* }}} */
  2153. /* {{{ proto string sqlite_udf_encode_binary(string data)
  2154. Apply binary encoding (if required) to a string to return from an UDF. */
  2155. PHP_FUNCTION(sqlite_udf_encode_binary)
  2156. {
  2157. char *data = NULL;
  2158. long datalen;
  2159. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
  2160. return;
  2161. }
  2162. if (data == NULL) {
  2163. RETURN_NULL();
  2164. }
  2165. if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) {
  2166. /* binary string */
  2167. int enclen;
  2168. char *ret;
  2169. ret = emalloc( 1 + ((256 * datalen + 1262) / 253) );
  2170. ret[0] = '\x01';
  2171. enclen = sqlite_encode_binary((const unsigned char*)data, datalen, ret+1);
  2172. RETVAL_STRINGL(ret, enclen+1, 0);
  2173. } else {
  2174. RETVAL_STRINGL(data, datalen, 1);
  2175. }
  2176. }
  2177. /* }}} */
  2178. /* {{{ proto string sqlite_udf_decode_binary(string data)
  2179. Decode binary encoding on a string parameter passed to an UDF. */
  2180. PHP_FUNCTION(sqlite_udf_decode_binary)
  2181. {
  2182. char *data = NULL;
  2183. long datalen;
  2184. if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
  2185. return;
  2186. }
  2187. if (data == NULL) {
  2188. RETURN_NULL();
  2189. }
  2190. if (datalen && data[0] == '\x01') {
  2191. /* encoded string */
  2192. int enclen;
  2193. char *ret;
  2194. ret = emalloc(datalen);
  2195. enclen = sqlite_decode_binary((const unsigned char*)data+1, ret);
  2196. ret[enclen] = '\0';
  2197. RETVAL_STRINGL(ret, enclen, 0);
  2198. } else {
  2199. RETVAL_STRINGL(data, datalen, 1);
  2200. }
  2201. }
  2202. /* }}} */
  2203. /*
  2204. * Local variables:
  2205. * tab-width: 4
  2206. * c-basic-offset: 4
  2207. * End:
  2208. * vim600: sw=4 ts=4 fdm=marker
  2209. * vim<600: sw=4 ts=4
  2210. */