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.

644 lines
15 KiB

21 years ago
20 years ago
21 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 6 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2009 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 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_01.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. | Author: Wez Furlong <wez@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #ifdef PHP_SQLITE2_HAVE_PDO
  24. #include "sqlite.h"
  25. #include "pdo/php_pdo.h"
  26. #include "pdo/php_pdo_driver.h"
  27. #include "zend_exceptions.h"
  28. #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
  29. #define php_sqlite_decode_binary(in, out) sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
  30. typedef struct {
  31. const char *file;
  32. int line;
  33. unsigned int errcode;
  34. char *errmsg;
  35. } pdo_sqlite2_error_info;
  36. typedef struct {
  37. sqlite *db;
  38. pdo_sqlite2_error_info einfo;
  39. } pdo_sqlite2_db_handle;
  40. typedef struct {
  41. pdo_sqlite2_db_handle *H;
  42. sqlite_vm *vm;
  43. const char **rowdata, **colnames;
  44. int ncols;
  45. unsigned pre_fetched:1;
  46. unsigned done:1;
  47. pdo_sqlite2_error_info einfo;
  48. } pdo_sqlite2_stmt;
  49. extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
  50. #define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
  51. #define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
  52. extern struct pdo_stmt_methods sqlite2_stmt_methods;
  53. static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
  54. {
  55. pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  56. if (S->vm) {
  57. char *errmsg = NULL;
  58. sqlite_finalize(S->vm, &errmsg);
  59. if (errmsg) {
  60. sqlite_freemem(errmsg);
  61. }
  62. S->vm = NULL;
  63. }
  64. if (S->einfo.errmsg) {
  65. pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
  66. }
  67. efree(S);
  68. return 1;
  69. }
  70. static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
  71. {
  72. pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  73. char *errmsg = NULL;
  74. const char *tail;
  75. if (stmt->executed && !S->done) {
  76. sqlite_finalize(S->vm, &errmsg);
  77. pdo_sqlite2_error_stmt(errmsg, stmt);
  78. errmsg = NULL;
  79. S->vm = NULL;
  80. }
  81. S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
  82. if (S->einfo.errcode != SQLITE_OK) {
  83. pdo_sqlite2_error_stmt(errmsg, stmt);
  84. return 0;
  85. }
  86. S->done = 0;
  87. S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
  88. switch (S->einfo.errcode) {
  89. case SQLITE_ROW:
  90. S->pre_fetched = 1;
  91. stmt->column_count = S->ncols;
  92. return 1;
  93. case SQLITE_DONE:
  94. stmt->column_count = S->ncols;
  95. stmt->row_count = sqlite_changes(S->H->db);
  96. S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
  97. if (S->einfo.errcode != SQLITE_OK) {
  98. pdo_sqlite2_error_stmt(errmsg, stmt);
  99. }
  100. S->done = 1;
  101. return 1;
  102. case SQLITE_ERROR:
  103. case SQLITE_MISUSE:
  104. case SQLITE_BUSY:
  105. default:
  106. pdo_sqlite2_error_stmt(errmsg, stmt);
  107. return 0;
  108. }
  109. }
  110. static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
  111. enum pdo_param_event event_type TSRMLS_DC)
  112. {
  113. return 1;
  114. }
  115. static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
  116. enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
  117. {
  118. pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  119. char *errmsg = NULL;
  120. if (!S->vm) {
  121. return 0;
  122. }
  123. if (S->pre_fetched) {
  124. S->pre_fetched = 0;
  125. return 1;
  126. }
  127. if (S->done) {
  128. return 0;
  129. }
  130. S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
  131. switch (S->einfo.errcode) {
  132. case SQLITE_ROW:
  133. return 1;
  134. case SQLITE_DONE:
  135. S->done = 1;
  136. S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
  137. if (S->einfo.errcode != SQLITE_OK) {
  138. pdo_sqlite2_error_stmt(errmsg, stmt);
  139. errmsg = NULL;
  140. }
  141. return 0;
  142. default:
  143. pdo_sqlite2_error_stmt(errmsg, stmt);
  144. return 0;
  145. }
  146. }
  147. static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
  148. {
  149. pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  150. if(colno >= S->ncols) {
  151. /* error invalid column */
  152. pdo_sqlite2_error_stmt(NULL, stmt);
  153. return 0;
  154. }
  155. stmt->columns[colno].name = estrdup(S->colnames[colno]);
  156. stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
  157. stmt->columns[colno].maxlen = 0xffffffff;
  158. stmt->columns[colno].precision = 0;
  159. stmt->columns[colno].param_type = PDO_PARAM_STR;
  160. return 1;
  161. }
  162. static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
  163. {
  164. pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  165. if (!S->vm) {
  166. return 0;
  167. }
  168. if(colno >= S->ncols) {
  169. /* error invalid column */
  170. pdo_sqlite2_error_stmt(NULL, stmt);
  171. return 0;
  172. }
  173. if (S->rowdata[colno]) {
  174. if (S->rowdata[colno][0] == '\x01') {
  175. /* encoded */
  176. *caller_frees = 1;
  177. *ptr = emalloc(strlen(S->rowdata[colno]));
  178. *len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
  179. (*(char**)ptr)[*len] = '\0';
  180. } else {
  181. *ptr = (char*)S->rowdata[colno];
  182. *len = strlen(*ptr);
  183. }
  184. } else {
  185. *ptr = NULL;
  186. *len = 0;
  187. }
  188. return 1;
  189. }
  190. struct pdo_stmt_methods sqlite2_stmt_methods = {
  191. pdo_sqlite2_stmt_dtor,
  192. pdo_sqlite2_stmt_execute,
  193. pdo_sqlite2_stmt_fetch,
  194. pdo_sqlite2_stmt_describe,
  195. pdo_sqlite2_stmt_get_col,
  196. pdo_sqlite2_stmt_param_hook,
  197. NULL, /* set_attr */
  198. NULL, /* get_attr */
  199. NULL
  200. };
  201. int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
  202. {
  203. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  204. pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
  205. pdo_sqlite2_error_info *einfo = &H->einfo;
  206. pdo_sqlite2_stmt *S;
  207. if (stmt) {
  208. S = stmt->driver_data;
  209. einfo = &S->einfo;
  210. }
  211. einfo->file = file;
  212. einfo->line = line;
  213. if (einfo->errmsg) {
  214. pefree(einfo->errmsg, dbh->is_persistent);
  215. einfo->errmsg = NULL;
  216. }
  217. if (einfo->errcode != SQLITE_OK) {
  218. if (errmsg) {
  219. einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
  220. sqlite_freemem(errmsg);
  221. } else {
  222. einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
  223. }
  224. } else { /* no error */
  225. strcpy(*pdo_err, PDO_ERR_NONE);
  226. return 0;
  227. }
  228. switch (einfo->errcode) {
  229. case SQLITE_NOTFOUND:
  230. strcpy(*pdo_err, "42S02");
  231. break;
  232. case SQLITE_INTERRUPT:
  233. strcpy(*pdo_err, "01002");
  234. break;
  235. case SQLITE_NOLFS:
  236. strcpy(*pdo_err, "HYC00");
  237. break;
  238. case SQLITE_TOOBIG:
  239. strcpy(*pdo_err, "22001");
  240. break;
  241. case SQLITE_CONSTRAINT:
  242. strcpy(*pdo_err, "23000");
  243. break;
  244. case SQLITE_ERROR:
  245. default:
  246. strcpy(*pdo_err, "HY000");
  247. break;
  248. }
  249. if (!dbh->methods) {
  250. #if PHP_VERSION_ID > 50200
  251. zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
  252. *pdo_err, einfo->errcode, einfo->errmsg);
  253. #else
  254. zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
  255. *pdo_err, einfo->errcode, einfo->errmsg);
  256. #endif
  257. }
  258. return einfo->errcode;
  259. }
  260. /* }}} */
  261. static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
  262. {
  263. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  264. pdo_sqlite2_error_info *einfo = &H->einfo;
  265. pdo_sqlite2_stmt *S;
  266. if (stmt) {
  267. S = stmt->driver_data;
  268. einfo = &S->einfo;
  269. }
  270. if (einfo->errcode) {
  271. add_next_index_long(info, einfo->errcode);
  272. if (einfo->errmsg) {
  273. add_next_index_string(info, einfo->errmsg, 1);
  274. }
  275. }
  276. return 1;
  277. }
  278. static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
  279. {
  280. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  281. if (H) {
  282. if (H->db) {
  283. sqlite_close(H->db);
  284. H->db = NULL;
  285. }
  286. if (H->einfo.errmsg) {
  287. pefree(H->einfo.errmsg, dbh->is_persistent);
  288. H->einfo.errmsg = NULL;
  289. }
  290. pefree(H, dbh->is_persistent);
  291. dbh->driver_data = NULL;
  292. }
  293. return 0;
  294. }
  295. /* }}} */
  296. static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
  297. {
  298. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  299. pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
  300. S->H = H;
  301. stmt->driver_data = S;
  302. stmt->methods = &sqlite2_stmt_methods;
  303. stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
  304. if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
  305. H->einfo.errcode = SQLITE_ERROR;
  306. pdo_sqlite2_error(NULL, dbh);
  307. return 0;
  308. }
  309. return 1;
  310. }
  311. static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
  312. {
  313. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  314. char *errmsg = NULL;
  315. if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
  316. pdo_sqlite2_error(errmsg, dbh);
  317. return -1;
  318. } else {
  319. return sqlite_changes(H->db);
  320. }
  321. }
  322. static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, int *len TSRMLS_DC)
  323. {
  324. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  325. char *id;
  326. id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
  327. *len = strlen(id);
  328. return id;
  329. }
  330. static int sqlite2_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
  331. {
  332. char *ret;
  333. if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
  334. /* binary string */
  335. int len;
  336. ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
  337. ret[0] = '\'';
  338. ret[1] = '\x01';
  339. len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
  340. ret[len + 2] = '\'';
  341. ret[len + 3] = '\0';
  342. *quoted = ret;
  343. *quotedlen = len + 3;
  344. /* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
  345. return 1;
  346. } else if (unquotedlen) {
  347. ret = sqlite_mprintf("'%q'", unquoted);
  348. if (ret) {
  349. *quoted = estrdup(ret);
  350. *quotedlen = strlen(ret);
  351. sqlite_freemem(ret);
  352. return 1;
  353. }
  354. return 0;
  355. } else {
  356. *quoted = estrdup("''");
  357. *quotedlen = 2;
  358. return 1;
  359. }
  360. }
  361. static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
  362. {
  363. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  364. char *errmsg = NULL;
  365. if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
  366. pdo_sqlite2_error(errmsg, dbh);
  367. return 0;
  368. }
  369. return 1;
  370. }
  371. static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
  372. {
  373. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  374. char *errmsg = NULL;
  375. if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
  376. pdo_sqlite2_error(errmsg, dbh);
  377. return 0;
  378. }
  379. return 1;
  380. }
  381. static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
  382. {
  383. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  384. char *errmsg = NULL;
  385. if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
  386. pdo_sqlite2_error(errmsg, dbh);
  387. return 0;
  388. }
  389. return 1;
  390. }
  391. static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
  392. {
  393. switch (attr) {
  394. case PDO_ATTR_CLIENT_VERSION:
  395. case PDO_ATTR_SERVER_VERSION:
  396. ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
  397. break;
  398. default:
  399. return 0;
  400. }
  401. return 1;
  402. }
  403. static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
  404. {
  405. pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
  406. switch (attr) {
  407. case PDO_ATTR_TIMEOUT:
  408. convert_to_long(val);
  409. sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
  410. return 1;
  411. }
  412. return 0;
  413. }
  414. static PHP_FUNCTION(sqlite2_create_function)
  415. {
  416. /* TODO: implement this stuff */
  417. }
  418. static const zend_function_entry dbh_methods[] = {
  419. PHP_FE(sqlite2_create_function, NULL)
  420. {NULL, NULL, NULL}
  421. };
  422. static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
  423. {
  424. switch (kind) {
  425. case PDO_DBH_DRIVER_METHOD_KIND_DBH:
  426. return dbh_methods;
  427. default:
  428. return NULL;
  429. }
  430. }
  431. static struct pdo_dbh_methods sqlite2_methods = {
  432. sqlite2_handle_closer,
  433. sqlite2_handle_preparer,
  434. sqlite2_handle_doer,
  435. sqlite2_handle_quoter,
  436. sqlite2_handle_begin,
  437. sqlite2_handle_commit,
  438. sqlite2_handle_rollback,
  439. pdo_sqlite2_set_attr,
  440. pdo_sqlite2_last_insert_id,
  441. pdo_sqlite2_fetch_error_func,
  442. pdo_sqlite2_get_attribute,
  443. NULL, /* check_liveness: not needed */
  444. get_driver_methods,
  445. NULL
  446. };
  447. static char *make_filename_safe(const char *filename TSRMLS_DC)
  448. {
  449. if (strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
  450. char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
  451. if (!fullpath) {
  452. return NULL;
  453. }
  454. if (php_check_open_basedir(fullpath TSRMLS_CC)) {
  455. efree(fullpath);
  456. return NULL;
  457. }
  458. return fullpath;
  459. }
  460. return estrdup(filename);
  461. }
  462. static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
  463. const char *arg5, const char *arg6)
  464. {
  465. char *filename;
  466. switch (access_type) {
  467. case SQLITE_COPY: {
  468. TSRMLS_FETCH();
  469. filename = make_filename_safe(arg4 TSRMLS_CC);
  470. if (!filename) {
  471. return SQLITE_DENY;
  472. }
  473. efree(filename);
  474. return SQLITE_OK;
  475. }
  476. case SQLITE_ATTACH: {
  477. TSRMLS_FETCH();
  478. filename = make_filename_safe(arg3 TSRMLS_CC);
  479. if (!filename) {
  480. return SQLITE_DENY;
  481. }
  482. efree(filename);
  483. return SQLITE_OK;
  484. }
  485. default:
  486. /* access allowed */
  487. return SQLITE_OK;
  488. }
  489. }
  490. static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
  491. {
  492. pdo_sqlite2_db_handle *H;
  493. int ret = 0;
  494. long timeout = 60;
  495. char *filename;
  496. char *errmsg = NULL;
  497. H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
  498. H->einfo.errcode = 0;
  499. H->einfo.errmsg = NULL;
  500. dbh->driver_data = H;
  501. filename = make_filename_safe(dbh->data_source TSRMLS_CC);
  502. if (!filename) {
  503. #if PHP_VERSION_ID > 50200
  504. zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
  505. "open_basedir prohibits opening %s",
  506. dbh->data_source);
  507. #else
  508. zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC,
  509. "open_basedir prohibits opening %s",
  510. dbh->data_source);
  511. #endif
  512. goto cleanup;
  513. }
  514. H->db = sqlite_open(filename, 0666, &errmsg);
  515. efree(filename);
  516. if (!H->db) {
  517. pdo_sqlite2_error(errmsg, dbh);
  518. goto cleanup;
  519. }
  520. sqlite_set_authorizer(H->db, authorizer, NULL);
  521. if (driver_options) {
  522. timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
  523. }
  524. sqlite_busy_timeout(H->db, timeout * 1000);
  525. dbh->alloc_own_columns = 1;
  526. dbh->max_escaped_char_length = 2;
  527. ret = 1;
  528. cleanup:
  529. dbh->methods = &sqlite2_methods;
  530. return ret;
  531. }
  532. /* }}} */
  533. pdo_driver_t pdo_sqlite2_driver = {
  534. PDO_DRIVER_HEADER(sqlite2),
  535. pdo_sqlite2_handle_factory
  536. };
  537. #endif
  538. /*
  539. * Local variables:
  540. * tab-width: 4
  541. * c-basic-offset: 4
  542. * End:
  543. * vim600: noet sw=4 ts=4 fdm=marker
  544. * vim<600: noet sw=4 ts=4
  545. */