Return to sqlite3.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / sqlite3 |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 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: | Authors: Scott MacVicar <scottmac@php.net> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: sqlite3.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: #ifdef HAVE_CONFIG_H ! 22: #include "config.h" ! 23: #endif ! 24: ! 25: #include "php.h" ! 26: #include "php_ini.h" ! 27: #include "ext/standard/info.h" ! 28: #include "php_sqlite3.h" ! 29: #include "php_sqlite3_structs.h" ! 30: #include "main/SAPI.h" ! 31: ! 32: #include <sqlite3.h> ! 33: ! 34: #include "zend_exceptions.h" ! 35: #include "zend_interfaces.h" ! 36: #include "SAPI.h" ! 37: ! 38: ZEND_DECLARE_MODULE_GLOBALS(sqlite3) ! 39: ! 40: static PHP_GINIT_FUNCTION(sqlite3); ! 41: static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6); ! 42: static void sqlite3_param_dtor(void *data); ! 43: static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement); ! 44: ! 45: /* {{{ Error Handler ! 46: */ ! 47: static void php_sqlite3_error(php_sqlite3_db_object *db_obj, char *format, ...) ! 48: { ! 49: va_list arg; ! 50: char *message; ! 51: TSRMLS_FETCH(); ! 52: ! 53: va_start(arg, format); ! 54: vspprintf(&message, 0, format, arg); ! 55: va_end(arg); ! 56: ! 57: if (db_obj->exception) { ! 58: zend_throw_exception(zend_exception_get_default(TSRMLS_C), message, 0 TSRMLS_CC); ! 59: } else { ! 60: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message); ! 61: } ! 62: ! 63: if (message) { ! 64: efree(message); ! 65: } ! 66: } ! 67: /* }}} */ ! 68: ! 69: #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \ ! 70: if (!(member)) { \ ! 71: php_sqlite3_error(db_obj, "The " #class_name " object has not been correctly initialised"); \ ! 72: RETURN_FALSE; \ ! 73: } ! 74: ! 75: /* {{{ PHP_INI ! 76: */ ! 77: PHP_INI_BEGIN() ! 78: STD_PHP_INI_ENTRY("sqlite3.extension_dir", NULL, PHP_INI_SYSTEM, OnUpdateString, extension_dir, zend_sqlite3_globals, sqlite3_globals) ! 79: PHP_INI_END() ! 80: /* }}} */ ! 81: ! 82: /* Handlers */ ! 83: static zend_object_handlers sqlite3_object_handlers; ! 84: static zend_object_handlers sqlite3_stmt_object_handlers; ! 85: static zend_object_handlers sqlite3_result_object_handlers; ! 86: ! 87: /* Class entries */ ! 88: zend_class_entry *php_sqlite3_sc_entry; ! 89: zend_class_entry *php_sqlite3_stmt_entry; ! 90: zend_class_entry *php_sqlite3_result_entry; ! 91: ! 92: /* {{{ proto void SQLite3::open(String filename [, int Flags [, string Encryption Key]]) ! 93: Opens a SQLite 3 Database, if the build includes encryption then it will attempt to use the key. */ ! 94: PHP_METHOD(sqlite3, open) ! 95: { ! 96: php_sqlite3_db_object *db_obj; ! 97: zval *object = getThis(); ! 98: char *filename, *encryption_key, *fullpath; ! 99: int filename_len, encryption_key_len = 0; ! 100: long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; ! 101: zend_error_handling error_handling; ! 102: ! 103: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 104: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); ! 105: ! 106: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &filename, &filename_len, &flags, &encryption_key, &encryption_key_len)) { ! 107: zend_restore_error_handling(&error_handling TSRMLS_CC); ! 108: return; ! 109: } ! 110: ! 111: zend_restore_error_handling(&error_handling TSRMLS_CC); ! 112: ! 113: if (db_obj->initialised) { ! 114: zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Already initialised DB Object", 0 TSRMLS_CC); ! 115: } ! 116: ! 117: if (strlen(filename) != filename_len) { ! 118: return; ! 119: } ! 120: if (strncmp(filename, ":memory:", 8) != 0) { ! 121: if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) { ! 122: zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Unable to expand filepath", 0 TSRMLS_CC); ! 123: return; ! 124: } ! 125: ! 126: #if PHP_API_VERSION < 20100412 ! 127: if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ! 128: zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "safe_mode prohibits opening %s", fullpath); ! 129: efree(fullpath); ! 130: return; ! 131: } ! 132: #endif ! 133: ! 134: if (php_check_open_basedir(fullpath TSRMLS_CC)) { ! 135: zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "open_basedir prohibits opening %s", fullpath); ! 136: efree(fullpath); ! 137: return; ! 138: } ! 139: } else { ! 140: fullpath = estrdup(filename); ! 141: } ! 142: ! 143: #if SQLITE_VERSION_NUMBER >= 3005000 ! 144: if (sqlite3_open_v2(fullpath, &(db_obj->db), flags, NULL) != SQLITE_OK) { ! 145: #else ! 146: if (sqlite3_open(fullpath, &(db_obj->db)) != SQLITE_OK) { ! 147: #endif ! 148: zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Unable to open database: %s", sqlite3_errmsg(db_obj->db)); ! 149: if (fullpath) { ! 150: efree(fullpath); ! 151: } ! 152: return; ! 153: } ! 154: ! 155: #if SQLITE_HAS_CODEC ! 156: if (encryption_key_len > 0) { ! 157: if (sqlite3_key(db_obj->db, encryption_key, encryption_key_len) != SQLITE_OK) { ! 158: zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Unable to open database: %s", sqlite3_errmsg(db_obj->db)); ! 159: return; ! 160: } ! 161: } ! 162: #endif ! 163: ! 164: db_obj->initialised = 1; ! 165: ! 166: #if PHP_API_VERSION < 20100412 ! 167: if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ! 168: #else ! 169: if (PG(open_basedir) && *PG(open_basedir)) { ! 170: #endif ! 171: sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, NULL); ! 172: } ! 173: ! 174: if (fullpath) { ! 175: efree(fullpath); ! 176: } ! 177: } ! 178: /* }}} */ ! 179: ! 180: /* {{{ proto bool SQLite3::close() ! 181: Close a SQLite 3 Database. */ ! 182: PHP_METHOD(sqlite3, close) ! 183: { ! 184: php_sqlite3_db_object *db_obj; ! 185: zval *object = getThis(); ! 186: int errcode; ! 187: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 188: ! 189: if (zend_parse_parameters_none() == FAILURE) { ! 190: return; ! 191: } ! 192: ! 193: if (db_obj->initialised) { ! 194: zend_llist_clean(&(db_obj->free_list)); ! 195: errcode = sqlite3_close(db_obj->db); ! 196: if (errcode != SQLITE_OK) { ! 197: php_sqlite3_error(db_obj, "Unable to close database: %d, %s", errcode, sqlite3_errmsg(db_obj->db)); ! 198: RETURN_FALSE; ! 199: } ! 200: db_obj->initialised = 0; ! 201: } ! 202: ! 203: RETURN_TRUE; ! 204: } ! 205: /* }}} */ ! 206: ! 207: /* {{{ proto bool SQLite3::exec(String Query) ! 208: Executes a result-less query against a given database. */ ! 209: PHP_METHOD(sqlite3, exec) ! 210: { ! 211: php_sqlite3_db_object *db_obj; ! 212: zval *object = getThis(); ! 213: char *sql, *errtext = NULL; ! 214: int sql_len; ! 215: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 216: ! 217: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 218: ! 219: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &sql, &sql_len)) { ! 220: return; ! 221: } ! 222: ! 223: if (sqlite3_exec(db_obj->db, sql, NULL, NULL, &errtext) != SQLITE_OK) { ! 224: php_sqlite3_error(db_obj, "%s", errtext); ! 225: sqlite3_free(errtext); ! 226: RETURN_FALSE; ! 227: } ! 228: ! 229: RETURN_TRUE; ! 230: } ! 231: /* }}} */ ! 232: ! 233: /* {{{ proto Array SQLite3::version() ! 234: Returns the SQLite3 Library version as a string constant and as a number. */ ! 235: PHP_METHOD(sqlite3, version) ! 236: { ! 237: if (zend_parse_parameters_none() == FAILURE) { ! 238: return; ! 239: } ! 240: ! 241: array_init(return_value); ! 242: ! 243: add_assoc_string(return_value, "versionString", (char*)sqlite3_libversion(), 1); ! 244: add_assoc_long(return_value, "versionNumber", sqlite3_libversion_number()); ! 245: ! 246: return; ! 247: } ! 248: /* }}} */ ! 249: ! 250: /* {{{ proto int SQLite3::lastInsertRowID() ! 251: Returns the rowid of the most recent INSERT into the database from the database connection. */ ! 252: PHP_METHOD(sqlite3, lastInsertRowID) ! 253: { ! 254: php_sqlite3_db_object *db_obj; ! 255: zval *object = getThis(); ! 256: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 257: ! 258: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 259: ! 260: if (zend_parse_parameters_none() == FAILURE) { ! 261: return; ! 262: } ! 263: ! 264: RETURN_LONG(sqlite3_last_insert_rowid(db_obj->db)); ! 265: } ! 266: /* }}} */ ! 267: ! 268: /* {{{ proto int SQLite3::lastErrorCode() ! 269: Returns the numeric result code of the most recent failed sqlite API call for the database connection. */ ! 270: PHP_METHOD(sqlite3, lastErrorCode) ! 271: { ! 272: php_sqlite3_db_object *db_obj; ! 273: zval *object = getThis(); ! 274: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 275: ! 276: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3) ! 277: ! 278: if (zend_parse_parameters_none() == FAILURE) { ! 279: return; ! 280: } ! 281: ! 282: RETURN_LONG(sqlite3_errcode(db_obj->db)); ! 283: } ! 284: /* }}} */ ! 285: ! 286: /* {{{ proto string SQLite3::lastErrorMsg() ! 287: Returns english text describing the most recent failed sqlite API call for the database connection. */ ! 288: PHP_METHOD(sqlite3, lastErrorMsg) ! 289: { ! 290: php_sqlite3_db_object *db_obj; ! 291: zval *object = getThis(); ! 292: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 293: ! 294: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3) ! 295: ! 296: if (zend_parse_parameters_none() == FAILURE) { ! 297: return; ! 298: } ! 299: ! 300: RETVAL_STRING((char *)sqlite3_errmsg(db_obj->db), 1); ! 301: } ! 302: /* }}} */ ! 303: ! 304: /* {{{ proto bool SQLite3::busyTimeout(int msecs) ! 305: Sets a busy handler that will sleep until database is not locked or timeout is reached. Passing a value less than or equal to zero turns off all busy handlers. */ ! 306: PHP_METHOD(sqlite3, busyTimeout) ! 307: { ! 308: php_sqlite3_db_object *db_obj; ! 309: zval *object = getThis(); ! 310: long ms; ! 311: int return_code; ! 312: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 313: ! 314: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 315: ! 316: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) { ! 317: return; ! 318: } ! 319: ! 320: return_code = sqlite3_busy_timeout(db_obj->db, ms); ! 321: if (return_code != SQLITE_OK) { ! 322: php_sqlite3_error(db_obj, "Unable to set busy timeout: %d, %s", return_code, sqlite3_errmsg(db_obj->db)); ! 323: RETURN_FALSE; ! 324: } ! 325: ! 326: RETURN_TRUE; ! 327: } ! 328: /* }}} */ ! 329: ! 330: ! 331: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 332: /* {{{ proto bool SQLite3::loadExtension(String Shared Library) ! 333: Attempts to load an SQLite extension library. */ ! 334: PHP_METHOD(sqlite3, loadExtension) ! 335: { ! 336: php_sqlite3_db_object *db_obj; ! 337: zval *object = getThis(); ! 338: char *extension, *lib_path, *extension_dir, *errtext = NULL; ! 339: char fullpath[MAXPATHLEN]; ! 340: int extension_len, extension_dir_len; ! 341: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 342: ! 343: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 344: ! 345: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension, &extension_len)) { ! 346: return; ! 347: } ! 348: ! 349: #ifdef ZTS ! 350: if ((strncmp(sapi_module.name, "cgi", 3) != 0) && ! 351: (strcmp(sapi_module.name, "cli") != 0) && ! 352: (strncmp(sapi_module.name, "embed", 5) != 0) ! 353: ) { php_sqlite3_error(db_obj, "Not supported in multithreaded Web servers"); ! 354: RETURN_FALSE; ! 355: } ! 356: #endif ! 357: ! 358: if (!SQLITE3G(extension_dir)) { ! 359: php_sqlite3_error(db_obj, "SQLite Extension are disabled"); ! 360: RETURN_FALSE; ! 361: } ! 362: ! 363: if (extension_len == 0) { ! 364: php_sqlite3_error(db_obj, "Empty string as an extension"); ! 365: RETURN_FALSE; ! 366: } ! 367: ! 368: extension_dir = SQLITE3G(extension_dir); ! 369: extension_dir_len = strlen(SQLITE3G(extension_dir)); ! 370: ! 371: if (IS_SLASH(extension_dir[extension_dir_len-1])) { ! 372: spprintf(&lib_path, 0, "%s%s", extension_dir, extension); ! 373: } else { ! 374: spprintf(&lib_path, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, extension); ! 375: } ! 376: ! 377: if (!VCWD_REALPATH(lib_path, fullpath)) { ! 378: php_sqlite3_error(db_obj, "Unable to load extension at '%s'", lib_path); ! 379: efree(lib_path); ! 380: RETURN_FALSE; ! 381: } ! 382: ! 383: efree(lib_path); ! 384: ! 385: if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) { ! 386: php_sqlite3_error(db_obj, "Unable to open extensions outside the defined directory"); ! 387: RETURN_FALSE; ! 388: } ! 389: ! 390: /* Extension loading should only be enabled for when we attempt to load */ ! 391: sqlite3_enable_load_extension(db_obj->db, 1); ! 392: if (sqlite3_load_extension(db_obj->db, fullpath, 0, &errtext) != SQLITE_OK) { ! 393: php_sqlite3_error(db_obj, "%s", errtext); ! 394: sqlite3_free(errtext); ! 395: sqlite3_enable_load_extension(db_obj->db, 0); ! 396: RETURN_FALSE; ! 397: } ! 398: sqlite3_enable_load_extension(db_obj->db, 0); ! 399: ! 400: RETURN_TRUE; ! 401: } ! 402: /* }}} */ ! 403: #endif ! 404: ! 405: /* {{{ proto int SQLite3::changes() ! 406: Returns the number of database rows that were changed (or inserted or deleted) by the most recent SQL statement. */ ! 407: PHP_METHOD(sqlite3, changes) ! 408: { ! 409: php_sqlite3_db_object *db_obj; ! 410: zval *object = getThis(); ! 411: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 412: ! 413: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 414: ! 415: if (zend_parse_parameters_none() == FAILURE) { ! 416: return; ! 417: } ! 418: ! 419: RETURN_LONG(sqlite3_changes(db_obj->db)); ! 420: } ! 421: /* }}} */ ! 422: ! 423: /* {{{ proto String SQLite3::escapeString(String value) ! 424: Returns a string that has been properly escaped. */ ! 425: PHP_METHOD(sqlite3, escapeString) ! 426: { ! 427: char *sql, *ret; ! 428: int sql_len; ! 429: ! 430: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &sql, &sql_len)) { ! 431: return; ! 432: } ! 433: ! 434: if (sql_len) { ! 435: ret = sqlite3_mprintf("%q", sql); ! 436: if (ret) { ! 437: RETVAL_STRING(ret, 1); ! 438: sqlite3_free(ret); ! 439: } ! 440: } else { ! 441: RETURN_EMPTY_STRING(); ! 442: } ! 443: } ! 444: /* }}} */ ! 445: ! 446: /* {{{ proto SQLite3Stmt SQLite3::prepare(String Query) ! 447: Returns a prepared SQL statement for execution. */ ! 448: PHP_METHOD(sqlite3, prepare) ! 449: { ! 450: php_sqlite3_db_object *db_obj; ! 451: php_sqlite3_stmt *stmt_obj; ! 452: zval *object = getThis(); ! 453: char *sql; ! 454: int sql_len, errcode; ! 455: php_sqlite3_free_list *free_item; ! 456: ! 457: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 458: ! 459: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 460: ! 461: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &sql, &sql_len)) { ! 462: return; ! 463: } ! 464: ! 465: if (!sql_len) { ! 466: RETURN_FALSE; ! 467: } ! 468: ! 469: object_init_ex(return_value, php_sqlite3_stmt_entry); ! 470: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(return_value TSRMLS_CC); ! 471: stmt_obj->db_obj = db_obj; ! 472: stmt_obj->db_obj_zval = getThis(); ! 473: ! 474: Z_ADDREF_P(object); ! 475: ! 476: errcode = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL); ! 477: if (errcode != SQLITE_OK) { ! 478: php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db)); ! 479: zval_dtor(return_value); ! 480: RETURN_FALSE; ! 481: } ! 482: ! 483: stmt_obj->initialised = 1; ! 484: ! 485: free_item = emalloc(sizeof(php_sqlite3_free_list)); ! 486: free_item->stmt_obj = stmt_obj; ! 487: free_item->stmt_obj_zval = return_value; ! 488: ! 489: zend_llist_add_element(&(db_obj->free_list), &free_item); ! 490: } ! 491: /* }}} */ ! 492: ! 493: /* {{{ proto SQLite3Result SQLite3::query(String Query) ! 494: Returns true or false, for queries that return data it will return a SQLite3Result object. */ ! 495: PHP_METHOD(sqlite3, query) ! 496: { ! 497: php_sqlite3_db_object *db_obj; ! 498: php_sqlite3_result *result; ! 499: php_sqlite3_stmt *stmt_obj; ! 500: zval *object = getThis(); ! 501: zval *stmt = NULL; ! 502: char *sql, *errtext = NULL; ! 503: int sql_len, return_code; ! 504: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 505: ! 506: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 507: ! 508: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &sql, &sql_len)) { ! 509: return; ! 510: } ! 511: ! 512: if (!sql_len) { ! 513: RETURN_FALSE; ! 514: } ! 515: ! 516: /* If there was no return value then just execute the query */ ! 517: if (!return_value_used) { ! 518: if (sqlite3_exec(db_obj->db, sql, NULL, NULL, &errtext) != SQLITE_OK) { ! 519: php_sqlite3_error(db_obj, "%s", errtext); ! 520: sqlite3_free(errtext); ! 521: } ! 522: return; ! 523: } ! 524: ! 525: MAKE_STD_ZVAL(stmt); ! 526: ! 527: object_init_ex(stmt, php_sqlite3_stmt_entry); ! 528: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(stmt TSRMLS_CC); ! 529: stmt_obj->db_obj = db_obj; ! 530: stmt_obj->db_obj_zval = getThis(); ! 531: ! 532: Z_ADDREF_P(object); ! 533: ! 534: return_code = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL); ! 535: if (return_code != SQLITE_OK) { ! 536: php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db)); ! 537: zval_ptr_dtor(&stmt); ! 538: RETURN_FALSE; ! 539: } ! 540: ! 541: stmt_obj->initialised = 1; ! 542: ! 543: object_init_ex(return_value, php_sqlite3_result_entry); ! 544: result = (php_sqlite3_result *)zend_object_store_get_object(return_value TSRMLS_CC); ! 545: result->db_obj = db_obj; ! 546: result->stmt_obj = stmt_obj; ! 547: result->stmt_obj_zval = stmt; ! 548: ! 549: return_code = sqlite3_step(result->stmt_obj->stmt); ! 550: ! 551: switch (return_code) { ! 552: case SQLITE_ROW: /* Valid Row */ ! 553: case SQLITE_DONE: /* Valid but no results */ ! 554: { ! 555: php_sqlite3_free_list *free_item; ! 556: free_item = emalloc(sizeof(php_sqlite3_free_list)); ! 557: free_item->stmt_obj = stmt_obj; ! 558: free_item->stmt_obj_zval = stmt; ! 559: zend_llist_add_element(&(db_obj->free_list), &free_item); ! 560: sqlite3_reset(result->stmt_obj->stmt); ! 561: break; ! 562: } ! 563: default: ! 564: php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db)); ! 565: sqlite3_finalize(stmt_obj->stmt); ! 566: stmt_obj->initialised = 0; ! 567: zval_dtor(return_value); ! 568: RETURN_FALSE; ! 569: } ! 570: } ! 571: /* }}} */ ! 572: ! 573: static zval* sqlite_value_to_zval(sqlite3_stmt *stmt, int column) /* {{{ */ ! 574: { ! 575: zval *data; ! 576: MAKE_STD_ZVAL(data); ! 577: switch (sqlite3_column_type(stmt, column)) { ! 578: case SQLITE_INTEGER: ! 579: if ((sqlite3_column_int64(stmt, column)) >= INT_MAX || sqlite3_column_int64(stmt, column) <= INT_MIN) { ! 580: ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column), 1); ! 581: } else { ! 582: ZVAL_LONG(data, sqlite3_column_int64(stmt, column)); ! 583: } ! 584: break; ! 585: ! 586: case SQLITE_FLOAT: ! 587: ZVAL_DOUBLE(data, sqlite3_column_double(stmt, column)); ! 588: break; ! 589: ! 590: case SQLITE_NULL: ! 591: ZVAL_NULL(data); ! 592: break; ! 593: ! 594: case SQLITE3_TEXT: ! 595: ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column), 1); ! 596: break; ! 597: ! 598: case SQLITE_BLOB: ! 599: default: ! 600: ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column), 1); ! 601: } ! 602: return data; ! 603: } ! 604: /* }}} */ ! 605: ! 606: /* {{{ proto SQLite3Result SQLite3::querySingle(String Query [, bool entire_row = false]) ! 607: Returns a string of the first column, or an array of the entire row. */ ! 608: PHP_METHOD(sqlite3, querySingle) ! 609: { ! 610: php_sqlite3_db_object *db_obj; ! 611: zval *object = getThis(); ! 612: char *sql, *errtext = NULL; ! 613: int sql_len, return_code; ! 614: zend_bool entire_row = 0; ! 615: sqlite3_stmt *stmt; ! 616: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 617: ! 618: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 619: ! 620: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &sql, &sql_len, &entire_row)) { ! 621: return; ! 622: } ! 623: ! 624: if (!sql_len) { ! 625: RETURN_FALSE; ! 626: } ! 627: ! 628: /* If there was no return value then just execute the query */ ! 629: if (!return_value_used) { ! 630: if (sqlite3_exec(db_obj->db, sql, NULL, NULL, &errtext) != SQLITE_OK) { ! 631: php_sqlite3_error(db_obj, "%s", errtext); ! 632: sqlite3_free(errtext); ! 633: } ! 634: return; ! 635: } ! 636: ! 637: return_code = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &stmt, NULL); ! 638: if (return_code != SQLITE_OK) { ! 639: php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", return_code, sqlite3_errmsg(db_obj->db)); ! 640: RETURN_FALSE; ! 641: } ! 642: ! 643: return_code = sqlite3_step(stmt); ! 644: ! 645: switch (return_code) { ! 646: case SQLITE_ROW: /* Valid Row */ ! 647: { ! 648: if (!entire_row) { ! 649: zval *data; ! 650: data = sqlite_value_to_zval(stmt, 0); ! 651: *return_value = *data; ! 652: zval_copy_ctor(return_value); ! 653: zval_dtor(data); ! 654: FREE_ZVAL(data); ! 655: } else { ! 656: int i = 0; ! 657: array_init(return_value); ! 658: for (i = 0; i < sqlite3_data_count(stmt); i++) { ! 659: zval *data; ! 660: data = sqlite_value_to_zval(stmt, i); ! 661: add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), data); ! 662: } ! 663: } ! 664: break; ! 665: } ! 666: case SQLITE_DONE: /* Valid but no results */ ! 667: { ! 668: if (!entire_row) { ! 669: RETVAL_NULL(); ! 670: } else { ! 671: array_init(return_value); ! 672: } ! 673: break; ! 674: } ! 675: default: ! 676: php_sqlite3_error(db_obj, "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db)); ! 677: RETVAL_FALSE; ! 678: } ! 679: sqlite3_finalize(stmt); ! 680: } ! 681: /* }}} */ ! 682: ! 683: static int sqlite3_do_callback(struct php_sqlite3_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg TSRMLS_DC) /* {{{ */ ! 684: { ! 685: zval ***zargs = NULL; ! 686: zval *retval = NULL; ! 687: int i; ! 688: int ret; ! 689: int fake_argc; ! 690: php_sqlite3_agg_context *agg_context = NULL; ! 691: ! 692: if (is_agg) { ! 693: is_agg = 2; ! 694: } ! 695: ! 696: fake_argc = argc + is_agg; ! 697: ! 698: fc->fci.size = sizeof(fc->fci); ! 699: fc->fci.function_table = EG(function_table); ! 700: fc->fci.function_name = cb; ! 701: fc->fci.symbol_table = NULL; ! 702: fc->fci.object_ptr = NULL; ! 703: fc->fci.retval_ptr_ptr = &retval; ! 704: fc->fci.param_count = fake_argc; ! 705: ! 706: /* build up the params */ ! 707: ! 708: if (fake_argc) { ! 709: zargs = (zval ***)safe_emalloc(fake_argc, sizeof(zval **), 0); ! 710: } ! 711: ! 712: if (is_agg) { ! 713: /* summon the aggregation context */ ! 714: agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context)); ! 715: ! 716: if (!agg_context->zval_context) { ! 717: MAKE_STD_ZVAL(agg_context->zval_context); ! 718: ZVAL_NULL(agg_context->zval_context); ! 719: } ! 720: zargs[0] = &agg_context->zval_context; ! 721: ! 722: zargs[1] = emalloc(sizeof(zval*)); ! 723: MAKE_STD_ZVAL(*zargs[1]); ! 724: ZVAL_LONG(*zargs[1], agg_context->row_count); ! 725: } ! 726: ! 727: for (i = 0; i < argc; i++) { ! 728: zargs[i + is_agg] = emalloc(sizeof(zval *)); ! 729: MAKE_STD_ZVAL(*zargs[i + is_agg]); ! 730: ! 731: switch (sqlite3_value_type(argv[i])) { ! 732: case SQLITE_INTEGER: ! 733: ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int(argv[i])); ! 734: break; ! 735: ! 736: case SQLITE_FLOAT: ! 737: ZVAL_DOUBLE(*zargs[i + is_agg], sqlite3_value_double(argv[i])); ! 738: break; ! 739: ! 740: case SQLITE_NULL: ! 741: ZVAL_NULL(*zargs[i + is_agg]); ! 742: break; ! 743: ! 744: case SQLITE_BLOB: ! 745: case SQLITE3_TEXT: ! 746: default: ! 747: ZVAL_STRINGL(*zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]), 1); ! 748: break; ! 749: } ! 750: } ! 751: ! 752: fc->fci.params = zargs; ! 753: ! 754: if ((ret = zend_call_function(&fc->fci, &fc->fcc TSRMLS_CC)) == FAILURE) { ! 755: php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the callback"); ! 756: } ! 757: ! 758: /* clean up the params */ ! 759: if (fake_argc) { ! 760: for (i = is_agg; i < argc + is_agg; i++) { ! 761: zval_ptr_dtor(zargs[i]); ! 762: efree(zargs[i]); ! 763: } ! 764: if (is_agg) { ! 765: zval_ptr_dtor(zargs[1]); ! 766: efree(zargs[1]); ! 767: } ! 768: efree(zargs); ! 769: } ! 770: ! 771: if (!is_agg || !argv) { ! 772: /* only set the sqlite return value if we are a scalar function, ! 773: * or if we are finalizing an aggregate */ ! 774: if (retval) { ! 775: switch (Z_TYPE_P(retval)) { ! 776: case IS_LONG: ! 777: sqlite3_result_int(context, Z_LVAL_P(retval)); ! 778: break; ! 779: ! 780: case IS_NULL: ! 781: sqlite3_result_null(context); ! 782: break; ! 783: ! 784: case IS_DOUBLE: ! 785: sqlite3_result_double(context, Z_DVAL_P(retval)); ! 786: break; ! 787: ! 788: default: ! 789: convert_to_string_ex(&retval); ! 790: sqlite3_result_text(context, Z_STRVAL_P(retval), Z_STRLEN_P(retval), SQLITE_TRANSIENT); ! 791: break; ! 792: } ! 793: } else { ! 794: sqlite3_result_error(context, "failed to invoke callback", 0); ! 795: } ! 796: ! 797: if (agg_context && agg_context->zval_context) { ! 798: zval_ptr_dtor(&agg_context->zval_context); ! 799: } ! 800: } else { ! 801: /* we're stepping in an aggregate; the return value goes into ! 802: * the context */ ! 803: if (agg_context && agg_context->zval_context) { ! 804: zval_ptr_dtor(&agg_context->zval_context); ! 805: } ! 806: if (retval) { ! 807: agg_context->zval_context = retval; ! 808: retval = NULL; ! 809: } else { ! 810: agg_context->zval_context = NULL; ! 811: } ! 812: } ! 813: ! 814: if (retval) { ! 815: zval_ptr_dtor(&retval); ! 816: } ! 817: return ret; ! 818: } ! 819: /* }}}*/ ! 820: ! 821: static void php_sqlite3_callback_func(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */ ! 822: { ! 823: php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context); ! 824: TSRMLS_FETCH(); ! 825: ! 826: sqlite3_do_callback(&func->afunc, func->func, argc, argv, context, 0 TSRMLS_CC); ! 827: } ! 828: /* }}}*/ ! 829: ! 830: static void php_sqlite3_callback_step(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */ ! 831: { ! 832: php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context); ! 833: php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context)); ! 834: ! 835: TSRMLS_FETCH(); ! 836: agg_context->row_count++; ! 837: ! 838: sqlite3_do_callback(&func->astep, func->step, argc, argv, context, 1 TSRMLS_CC); ! 839: } ! 840: /* }}} */ ! 841: ! 842: static void php_sqlite3_callback_final(sqlite3_context *context) /* {{{ */ ! 843: { ! 844: php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context); ! 845: php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context)); ! 846: ! 847: TSRMLS_FETCH(); ! 848: agg_context->row_count = 0; ! 849: ! 850: sqlite3_do_callback(&func->afini, func->fini, 0, NULL, context, 1 TSRMLS_CC); ! 851: } ! 852: /* }}} */ ! 853: ! 854: /* {{{ proto bool SQLite3::createFunction(string name, mixed callback [, int argcount]) ! 855: Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements. */ ! 856: PHP_METHOD(sqlite3, createFunction) ! 857: { ! 858: php_sqlite3_db_object *db_obj; ! 859: zval *object = getThis(); ! 860: php_sqlite3_func *func; ! 861: char *sql_func, *callback_name; ! 862: int sql_func_len; ! 863: zval *callback_func; ! 864: long sql_func_num_args = -1; ! 865: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 866: ! 867: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 868: ! 869: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &sql_func, &sql_func_len, &callback_func, &sql_func_num_args) == FAILURE) { ! 870: return; ! 871: } ! 872: ! 873: if (!sql_func_len) { ! 874: RETURN_FALSE; ! 875: } ! 876: ! 877: if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) { ! 878: php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name); ! 879: efree(callback_name); ! 880: RETURN_FALSE; ! 881: } ! 882: efree(callback_name); ! 883: ! 884: func = (php_sqlite3_func *)ecalloc(1, sizeof(*func)); ! 885: ! 886: if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) { ! 887: func->func_name = estrdup(sql_func); ! 888: ! 889: MAKE_STD_ZVAL(func->func); ! 890: MAKE_COPY_ZVAL(&callback_func, func->func); ! 891: ! 892: func->argc = sql_func_num_args; ! 893: func->next = db_obj->funcs; ! 894: db_obj->funcs = func; ! 895: ! 896: RETURN_TRUE; ! 897: } ! 898: efree(func); ! 899: ! 900: RETURN_FALSE; ! 901: } ! 902: /* }}} */ ! 903: ! 904: /* {{{ proto bool SQLite3::createAggregate(string name, mixed step, mixed final [, int argcount]) ! 905: Allows registration of a PHP function for use as an aggregate. */ ! 906: PHP_METHOD(sqlite3, createAggregate) ! 907: { ! 908: php_sqlite3_db_object *db_obj; ! 909: zval *object = getThis(); ! 910: php_sqlite3_func *func; ! 911: char *sql_func, *callback_name; ! 912: int sql_func_len; ! 913: zval *step_callback, *fini_callback; ! 914: long sql_func_num_args = -1; ! 915: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 916: ! 917: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 918: ! 919: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &sql_func, &sql_func_len, &step_callback, &fini_callback, &sql_func_num_args) == FAILURE) { ! 920: return; ! 921: } ! 922: ! 923: if (!sql_func_len) { ! 924: RETURN_FALSE; ! 925: } ! 926: ! 927: if (!zend_is_callable(step_callback, 0, &callback_name TSRMLS_CC)) { ! 928: php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name); ! 929: efree(callback_name); ! 930: RETURN_FALSE; ! 931: } ! 932: efree(callback_name); ! 933: ! 934: if (!zend_is_callable(fini_callback, 0, &callback_name TSRMLS_CC)) { ! 935: php_sqlite3_error(db_obj, "Not a valid callback function %s", callback_name); ! 936: efree(callback_name); ! 937: RETURN_FALSE; ! 938: } ! 939: efree(callback_name); ! 940: ! 941: func = (php_sqlite3_func *)ecalloc(1, sizeof(*func)); ! 942: ! 943: if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) { ! 944: func->func_name = estrdup(sql_func); ! 945: ! 946: MAKE_STD_ZVAL(func->step); ! 947: MAKE_COPY_ZVAL(&step_callback, func->step); ! 948: ! 949: MAKE_STD_ZVAL(func->fini); ! 950: MAKE_COPY_ZVAL(&fini_callback, func->fini); ! 951: ! 952: func->argc = sql_func_num_args; ! 953: func->next = db_obj->funcs; ! 954: db_obj->funcs = func; ! 955: ! 956: RETURN_TRUE; ! 957: } ! 958: efree(func); ! 959: ! 960: RETURN_FALSE; ! 961: } ! 962: /* }}} */ ! 963: ! 964: typedef struct { ! 965: sqlite3_blob *blob; ! 966: size_t position; ! 967: size_t size; ! 968: } php_stream_sqlite3_data; ! 969: ! 970: static size_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) ! 971: { ! 972: /* php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; */ ! 973: ! 974: return 0; ! 975: } ! 976: ! 977: static size_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) ! 978: { ! 979: php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; ! 980: ! 981: if (sqlite3_stream->position + count >= sqlite3_stream->size) { ! 982: count = sqlite3_stream->size - sqlite3_stream->position; ! 983: stream->eof = 1; ! 984: } ! 985: if (count) { ! 986: if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) { ! 987: return 0; ! 988: } ! 989: sqlite3_stream->position += count; ! 990: } ! 991: return count; ! 992: } ! 993: ! 994: static int php_sqlite3_stream_close(php_stream *stream, int close_handle TSRMLS_DC) ! 995: { ! 996: php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; ! 997: ! 998: if (sqlite3_blob_close(sqlite3_stream->blob) != SQLITE_OK) { ! 999: /* Error occured, but it still closed */ ! 1000: } ! 1001: ! 1002: efree(sqlite3_stream); ! 1003: ! 1004: return 0; ! 1005: } ! 1006: ! 1007: static int php_sqlite3_stream_flush(php_stream *stream TSRMLS_DC) ! 1008: { ! 1009: /* do nothing */ ! 1010: return 0; ! 1011: } ! 1012: ! 1013: /* {{{ */ ! 1014: static int php_sqlite3_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) ! 1015: { ! 1016: php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; ! 1017: ! 1018: switch(whence) { ! 1019: case SEEK_CUR: ! 1020: if (offset < 0) { ! 1021: if (sqlite3_stream->position < (size_t)(-offset)) { ! 1022: sqlite3_stream->position = 0; ! 1023: *newoffs = -1; ! 1024: return -1; ! 1025: } else { ! 1026: sqlite3_stream->position = sqlite3_stream->position + offset; ! 1027: *newoffs = sqlite3_stream->position; ! 1028: stream->eof = 0; ! 1029: return 0; ! 1030: } ! 1031: } else { ! 1032: if (sqlite3_stream->position + (size_t)(offset) > sqlite3_stream->size) { ! 1033: sqlite3_stream->position = sqlite3_stream->size; ! 1034: *newoffs = -1; ! 1035: return -1; ! 1036: } else { ! 1037: sqlite3_stream->position = sqlite3_stream->position + offset; ! 1038: *newoffs = sqlite3_stream->position; ! 1039: stream->eof = 0; ! 1040: return 0; ! 1041: } ! 1042: } ! 1043: case SEEK_SET: ! 1044: if (sqlite3_stream->size < (size_t)(offset)) { ! 1045: sqlite3_stream->position = sqlite3_stream->size; ! 1046: *newoffs = -1; ! 1047: return -1; ! 1048: } else { ! 1049: sqlite3_stream->position = offset; ! 1050: *newoffs = sqlite3_stream->position; ! 1051: stream->eof = 0; ! 1052: return 0; ! 1053: } ! 1054: case SEEK_END: ! 1055: if (offset > 0) { ! 1056: sqlite3_stream->position = sqlite3_stream->size; ! 1057: *newoffs = -1; ! 1058: return -1; ! 1059: } else if (sqlite3_stream->size < (size_t)(-offset)) { ! 1060: sqlite3_stream->position = 0; ! 1061: *newoffs = -1; ! 1062: return -1; ! 1063: } else { ! 1064: sqlite3_stream->position = sqlite3_stream->size + offset; ! 1065: *newoffs = sqlite3_stream->position; ! 1066: stream->eof = 0; ! 1067: return 0; ! 1068: } ! 1069: default: ! 1070: *newoffs = sqlite3_stream->position; ! 1071: return -1; ! 1072: } ! 1073: } ! 1074: /* }}} */ ! 1075: ! 1076: ! 1077: static int php_sqlite3_stream_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) ! 1078: { ! 1079: return FAILURE; ! 1080: } ! 1081: ! 1082: static int php_sqlite3_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) ! 1083: { ! 1084: php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract; ! 1085: ssb->sb.st_size = sqlite3_stream->size; ! 1086: return 0; ! 1087: } ! 1088: ! 1089: static php_stream_ops php_stream_sqlite3_ops = { ! 1090: php_sqlite3_stream_write, ! 1091: php_sqlite3_stream_read, ! 1092: php_sqlite3_stream_close, ! 1093: php_sqlite3_stream_flush, ! 1094: "SQLite3", ! 1095: php_sqlite3_stream_seek, ! 1096: php_sqlite3_stream_cast, ! 1097: php_sqlite3_stream_stat ! 1098: }; ! 1099: ! 1100: /* {{{ proto resource SQLite3::openBlob(string table, string column, int rowid [, string dbname]) ! 1101: Open a blob as a stream which we can read / write to. */ ! 1102: PHP_METHOD(sqlite3, openBlob) ! 1103: { ! 1104: php_sqlite3_db_object *db_obj; ! 1105: zval *object = getThis(); ! 1106: char *table, *column, *dbname = "main"; ! 1107: int table_len, column_len, dbname_len; ! 1108: long rowid, flags = 0; ! 1109: sqlite3_blob *blob = NULL; ! 1110: php_stream_sqlite3_data *sqlite3_stream; ! 1111: php_stream *stream; ! 1112: ! 1113: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 1114: ! 1115: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 1116: ! 1117: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl|s", &table, &table_len, &column, &column_len, &rowid, &dbname, &dbname_len) == FAILURE) { ! 1118: return; ! 1119: } ! 1120: ! 1121: if (sqlite3_blob_open(db_obj->db, dbname, table, column, rowid, flags, &blob) != SQLITE_OK) { ! 1122: php_sqlite3_error(db_obj, "Unable to open blob: %s", sqlite3_errmsg(db_obj->db)); ! 1123: RETURN_FALSE; ! 1124: } ! 1125: ! 1126: sqlite3_stream = emalloc(sizeof(php_stream_sqlite3_data)); ! 1127: sqlite3_stream->blob = blob; ! 1128: sqlite3_stream->position = 0; ! 1129: sqlite3_stream->size = sqlite3_blob_bytes(blob); ! 1130: ! 1131: stream = php_stream_alloc(&php_stream_sqlite3_ops, sqlite3_stream, 0, "rb"); ! 1132: ! 1133: if (stream) { ! 1134: php_stream_to_zval(stream, return_value); ! 1135: } else { ! 1136: RETURN_FALSE; ! 1137: } ! 1138: } ! 1139: /* }}} */ ! 1140: ! 1141: /* {{{ proto bool SQLite3::enableExceptions([bool enableExceptions = false]) ! 1142: Enables an exception error mode. */ ! 1143: PHP_METHOD(sqlite3, enableExceptions) ! 1144: { ! 1145: php_sqlite3_db_object *db_obj; ! 1146: zval *object = getThis(); ! 1147: zend_bool enableExceptions = 0; ! 1148: ! 1149: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(object TSRMLS_CC); ! 1150: ! 1151: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enableExceptions) == FAILURE) { ! 1152: return; ! 1153: } ! 1154: ! 1155: RETVAL_BOOL(db_obj->exception); ! 1156: ! 1157: db_obj->exception = enableExceptions; ! 1158: } ! 1159: /* }}} */ ! 1160: ! 1161: /* {{{ proto int SQLite3Stmt::paramCount() ! 1162: Returns the number of parameters within the prepared statement. */ ! 1163: PHP_METHOD(sqlite3stmt, paramCount) ! 1164: { ! 1165: php_sqlite3_stmt *stmt_obj; ! 1166: zval *object = getThis(); ! 1167: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1168: ! 1169: if (zend_parse_parameters_none() == FAILURE) { ! 1170: return; ! 1171: } ! 1172: ! 1173: RETURN_LONG(sqlite3_bind_parameter_count(stmt_obj->stmt)); ! 1174: } ! 1175: /* }}} */ ! 1176: ! 1177: /* {{{ proto bool SQLite3Stmt::close() ! 1178: Closes the prepared statement. */ ! 1179: PHP_METHOD(sqlite3stmt, close) ! 1180: { ! 1181: php_sqlite3_stmt *stmt_obj; ! 1182: zval *object = getThis(); ! 1183: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1184: ! 1185: if (zend_parse_parameters_none() == FAILURE) { ! 1186: return; ! 1187: } ! 1188: ! 1189: zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free); ! 1190: ! 1191: RETURN_TRUE; ! 1192: } ! 1193: /* }}} */ ! 1194: ! 1195: /* {{{ proto bool SQLite3Stmt::reset() ! 1196: Reset the prepared statement to the state before it was executed, bindings still remain. */ ! 1197: PHP_METHOD(sqlite3stmt, reset) ! 1198: { ! 1199: php_sqlite3_stmt *stmt_obj; ! 1200: zval *object = getThis(); ! 1201: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1202: ! 1203: if (zend_parse_parameters_none() == FAILURE) { ! 1204: return; ! 1205: } ! 1206: ! 1207: if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) { ! 1208: php_sqlite3_error(stmt_obj->db_obj, "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt))); ! 1209: RETURN_FALSE; ! 1210: } ! 1211: RETURN_TRUE; ! 1212: } ! 1213: /* }}} */ ! 1214: ! 1215: /* {{{ proto bool SQLite3Stmt::clear() ! 1216: Clear all current bound parameters. */ ! 1217: PHP_METHOD(sqlite3stmt, clear) ! 1218: { ! 1219: php_sqlite3_stmt *stmt_obj; ! 1220: zval *object = getThis(); ! 1221: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1222: ! 1223: if (zend_parse_parameters_none() == FAILURE) { ! 1224: return; ! 1225: } ! 1226: ! 1227: if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) { ! 1228: php_sqlite3_error(stmt_obj->db_obj, "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt))); ! 1229: RETURN_FALSE; ! 1230: } ! 1231: ! 1232: RETURN_TRUE; ! 1233: } ! 1234: /* }}} */ ! 1235: ! 1236: /* {{{ proto bool SQLite3Stmt::readOnly() ! 1237: Returns true if a statement is definitely read only */ ! 1238: PHP_METHOD(sqlite3stmt, readOnly) ! 1239: { ! 1240: php_sqlite3_stmt *stmt_obj; ! 1241: zval *object = getThis(); ! 1242: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1243: ! 1244: if (zend_parse_parameters_none() == FAILURE) { ! 1245: return; ! 1246: } ! 1247: ! 1248: #if SQLITE_VERSION_NUMBER >= 3007004 ! 1249: if (sqlite3_stmt_readonly(stmt_obj->stmt)) { ! 1250: RETURN_TRUE; ! 1251: } ! 1252: #endif ! 1253: RETURN_FALSE; ! 1254: } ! 1255: /* }}} */ ! 1256: ! 1257: static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt TSRMLS_DC) /* {{{ */ ! 1258: { ! 1259: HashTable *hash; ! 1260: hash = stmt->bound_params; ! 1261: ! 1262: if (!hash) { ! 1263: ALLOC_HASHTABLE(hash); ! 1264: zend_hash_init(hash, 13, NULL, sqlite3_param_dtor, 0); ! 1265: stmt->bound_params = hash; ! 1266: } ! 1267: ! 1268: /* We need a : prefix to resolve a name to a parameter number */ ! 1269: if (param->name) { ! 1270: if (param->name[0] != ':') { ! 1271: /* pre-increment for character + 1 for null */ ! 1272: char *temp = emalloc(++param->name_len + 1); ! 1273: temp[0] = ':'; ! 1274: memmove(temp+1, param->name, param->name_len); ! 1275: param->name = temp; ! 1276: } else { ! 1277: param->name = estrndup(param->name, param->name_len); ! 1278: } ! 1279: /* do lookup*/ ! 1280: param->param_number = sqlite3_bind_parameter_index(stmt->stmt, param->name); ! 1281: } ! 1282: ! 1283: if (param->param_number < 1) { ! 1284: efree(param->name); ! 1285: return 0; ! 1286: } ! 1287: ! 1288: if (param->param_number >= 1) { ! 1289: zend_hash_index_del(hash, param->param_number); ! 1290: } ! 1291: ! 1292: if (param->name) { ! 1293: zend_hash_update(hash, param->name, param->name_len, param, sizeof(*param), NULL); ! 1294: } else { ! 1295: zend_hash_index_update(hash, param->param_number, param, sizeof(*param), NULL); ! 1296: } ! 1297: ! 1298: return 1; ! 1299: } ! 1300: /* }}} */ ! 1301: ! 1302: /* {{{ proto bool SQLite3Stmt::bindParam(int parameter_number, mixed parameter [, int type]) ! 1303: Bind Paramater to a stmt variable. */ ! 1304: PHP_METHOD(sqlite3stmt, bindParam) ! 1305: { ! 1306: php_sqlite3_stmt *stmt_obj; ! 1307: zval *object = getThis(); ! 1308: struct php_sqlite3_bound_param param = {0}; ! 1309: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1310: ! 1311: param.param_number = -1; ! 1312: param.type = SQLITE3_TEXT; ! 1313: ! 1314: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz|l", ¶m.param_number, ¶m.parameter, ¶m.type) == FAILURE) { ! 1315: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", ¶m.name, ¶m.name_len, ¶m.parameter, ¶m.type) == FAILURE) { ! 1316: return; ! 1317: } ! 1318: } ! 1319: ! 1320: Z_ADDREF_P(param.parameter); ! 1321: ! 1322: if (!register_bound_parameter_to_sqlite(¶m, stmt_obj TSRMLS_CC)) { ! 1323: if (param.parameter) { ! 1324: zval_ptr_dtor(&(param.parameter)); ! 1325: param.parameter = NULL; ! 1326: } ! 1327: RETURN_FALSE; ! 1328: } ! 1329: RETURN_TRUE; ! 1330: } ! 1331: /* }}} */ ! 1332: ! 1333: /* {{{ proto bool SQLite3Stmt::bindValue(int parameter_number, mixed parameter [, int type]) ! 1334: Bind Value of a parameter to a stmt variable. */ ! 1335: PHP_METHOD(sqlite3stmt, bindValue) ! 1336: { ! 1337: php_sqlite3_stmt *stmt_obj; ! 1338: zval *object = getThis(); ! 1339: struct php_sqlite3_bound_param param = {0}; ! 1340: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1341: ! 1342: param.param_number = -1; ! 1343: param.type = SQLITE3_TEXT; ! 1344: ! 1345: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lz/|l", ¶m.param_number, ¶m.parameter, ¶m.type) == FAILURE) { ! 1346: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", ¶m.name, ¶m.name_len, ¶m.parameter, ¶m.type) == FAILURE) { ! 1347: return; ! 1348: } ! 1349: } ! 1350: ! 1351: Z_ADDREF_P(param.parameter); ! 1352: ! 1353: if (!register_bound_parameter_to_sqlite(¶m, stmt_obj TSRMLS_CC)) { ! 1354: if (param.parameter) { ! 1355: zval_ptr_dtor(&(param.parameter)); ! 1356: param.parameter = NULL; ! 1357: } ! 1358: RETURN_FALSE; ! 1359: } ! 1360: RETURN_TRUE; ! 1361: } ! 1362: /* }}} */ ! 1363: ! 1364: /* {{{ proto SQLite3Result SQLite3Stmt::execute() ! 1365: Executes a prepared statement and returns a result set object. */ ! 1366: PHP_METHOD(sqlite3stmt, execute) ! 1367: { ! 1368: php_sqlite3_stmt *stmt_obj; ! 1369: php_sqlite3_result *result; ! 1370: zval *object = getThis(); ! 1371: int return_code = 0; ! 1372: struct php_sqlite3_bound_param *param; ! 1373: ! 1374: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1375: ! 1376: if (zend_parse_parameters_none() == FAILURE) { ! 1377: return; ! 1378: } ! 1379: ! 1380: SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3) ! 1381: ! 1382: if (stmt_obj->bound_params) { ! 1383: zend_hash_internal_pointer_reset(stmt_obj->bound_params); ! 1384: while (zend_hash_get_current_data(stmt_obj->bound_params, (void **)¶m) == SUCCESS) { ! 1385: /* If the ZVAL is null then it should be bound as that */ ! 1386: if (Z_TYPE_P(param->parameter) == IS_NULL) { ! 1387: sqlite3_bind_null(stmt_obj->stmt, param->param_number); ! 1388: zend_hash_move_forward(stmt_obj->bound_params); ! 1389: continue; ! 1390: } ! 1391: ! 1392: switch (param->type) { ! 1393: case SQLITE_INTEGER: ! 1394: convert_to_long(param->parameter); ! 1395: sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(param->parameter)); ! 1396: break; ! 1397: ! 1398: case SQLITE_FLOAT: ! 1399: /* convert_to_double(param->parameter);*/ ! 1400: sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(param->parameter)); ! 1401: break; ! 1402: ! 1403: case SQLITE_BLOB: ! 1404: { ! 1405: php_stream *stream = NULL; ! 1406: int blength; ! 1407: char *buffer = NULL; ! 1408: if (Z_TYPE_P(param->parameter) == IS_RESOURCE) { ! 1409: php_stream_from_zval_no_verify(stream, ¶m->parameter); ! 1410: if (stream == NULL) { ! 1411: php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number); ! 1412: RETURN_FALSE; ! 1413: } ! 1414: blength = php_stream_copy_to_mem(stream, (void *)&buffer, PHP_STREAM_COPY_ALL, 0); ! 1415: } else { ! 1416: convert_to_string(param->parameter); ! 1417: blength = Z_STRLEN_P(param->parameter); ! 1418: buffer = Z_STRVAL_P(param->parameter); ! 1419: } ! 1420: ! 1421: sqlite3_bind_blob(stmt_obj->stmt, param->param_number, buffer, blength, SQLITE_TRANSIENT); ! 1422: ! 1423: if (stream) { ! 1424: pefree(buffer, 0); ! 1425: } ! 1426: break; ! 1427: } ! 1428: ! 1429: case SQLITE3_TEXT: ! 1430: convert_to_string(param->parameter); ! 1431: sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter), SQLITE_STATIC); ! 1432: break; ! 1433: ! 1434: case SQLITE_NULL: ! 1435: sqlite3_bind_null(stmt_obj->stmt, param->param_number); ! 1436: break; ! 1437: ! 1438: default: ! 1439: php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %ld for parameter %ld", param->type, param->param_number); ! 1440: RETURN_FALSE; ! 1441: } ! 1442: zend_hash_move_forward(stmt_obj->bound_params); ! 1443: } ! 1444: } ! 1445: ! 1446: return_code = sqlite3_step(stmt_obj->stmt); ! 1447: ! 1448: switch (return_code) { ! 1449: case SQLITE_ROW: /* Valid Row */ ! 1450: case SQLITE_DONE: /* Valid but no results */ ! 1451: { ! 1452: sqlite3_reset(stmt_obj->stmt); ! 1453: object_init_ex(return_value, php_sqlite3_result_entry); ! 1454: result = (php_sqlite3_result *)zend_object_store_get_object(return_value TSRMLS_CC); ! 1455: ! 1456: Z_ADDREF_P(object); ! 1457: ! 1458: result->is_prepared_statement = 1; ! 1459: result->db_obj = stmt_obj->db_obj; ! 1460: result->stmt_obj = stmt_obj; ! 1461: result->stmt_obj_zval = getThis(); ! 1462: ! 1463: break; ! 1464: } ! 1465: case SQLITE_ERROR: ! 1466: sqlite3_reset(stmt_obj->stmt); ! 1467: ! 1468: default: ! 1469: php_sqlite3_error(stmt_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt))); ! 1470: zval_dtor(return_value); ! 1471: RETURN_FALSE; ! 1472: } ! 1473: ! 1474: return; ! 1475: } ! 1476: /* }}} */ ! 1477: ! 1478: /* {{{ proto int SQLite3Stmt::__construct(SQLite3 dbobject, String Statement) ! 1479: __constructor for SQLite3Stmt. */ ! 1480: PHP_METHOD(sqlite3stmt, __construct) ! 1481: { ! 1482: php_sqlite3_stmt *stmt_obj; ! 1483: php_sqlite3_db_object *db_obj; ! 1484: zval *object = getThis(); ! 1485: zval *db_zval; ! 1486: char *sql; ! 1487: int sql_len, errcode; ! 1488: zend_error_handling error_handling; ! 1489: php_sqlite3_free_list *free_item; ! 1490: ! 1491: stmt_obj = (php_sqlite3_stmt *)zend_object_store_get_object(object TSRMLS_CC); ! 1492: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); ! 1493: ! 1494: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &db_zval, php_sqlite3_sc_entry, &sql, &sql_len) == FAILURE) { ! 1495: zend_restore_error_handling(&error_handling TSRMLS_CC); ! 1496: return; ! 1497: } ! 1498: ! 1499: db_obj = (php_sqlite3_db_object *)zend_object_store_get_object(db_zval TSRMLS_CC); ! 1500: ! 1501: SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) ! 1502: ! 1503: zend_restore_error_handling(&error_handling TSRMLS_CC); ! 1504: ! 1505: if (!sql_len) { ! 1506: RETURN_FALSE; ! 1507: } ! 1508: ! 1509: stmt_obj->db_obj = db_obj; ! 1510: stmt_obj->db_obj_zval = db_zval; ! 1511: ! 1512: Z_ADDREF_P(db_zval); ! 1513: ! 1514: errcode = sqlite3_prepare_v2(db_obj->db, sql, sql_len, &(stmt_obj->stmt), NULL); ! 1515: if (errcode != SQLITE_OK) { ! 1516: php_sqlite3_error(db_obj, "Unable to prepare statement: %d, %s", errcode, sqlite3_errmsg(db_obj->db)); ! 1517: zval_dtor(return_value); ! 1518: RETURN_FALSE; ! 1519: } ! 1520: stmt_obj->initialised = 1; ! 1521: ! 1522: free_item = emalloc(sizeof(php_sqlite3_free_list)); ! 1523: free_item->stmt_obj = stmt_obj; ! 1524: free_item->stmt_obj_zval = getThis(); ! 1525: ! 1526: zend_llist_add_element(&(db_obj->free_list), &free_item); ! 1527: } ! 1528: /* }}} */ ! 1529: ! 1530: /* {{{ proto int SQLite3Result::numColumns() ! 1531: Number of columns in the result set. */ ! 1532: PHP_METHOD(sqlite3result, numColumns) ! 1533: { ! 1534: php_sqlite3_result *result_obj; ! 1535: zval *object = getThis(); ! 1536: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1537: ! 1538: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1539: ! 1540: if (zend_parse_parameters_none() == FAILURE) { ! 1541: return; ! 1542: } ! 1543: ! 1544: RETURN_LONG(sqlite3_column_count(result_obj->stmt_obj->stmt)); ! 1545: } ! 1546: /* }}} */ ! 1547: ! 1548: /* {{{ proto string SQLite3Result::columnName(int column) ! 1549: Returns the name of the nth column. */ ! 1550: PHP_METHOD(sqlite3result, columnName) ! 1551: { ! 1552: php_sqlite3_result *result_obj; ! 1553: zval *object = getThis(); ! 1554: long column = 0; ! 1555: char *column_name; ! 1556: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1557: ! 1558: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1559: ! 1560: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &column) == FAILURE) { ! 1561: return; ! 1562: } ! 1563: column_name = (char*) sqlite3_column_name(result_obj->stmt_obj->stmt, column); ! 1564: ! 1565: if (column_name == NULL) { ! 1566: RETURN_FALSE; ! 1567: } ! 1568: ! 1569: RETVAL_STRING(column_name, 1); ! 1570: } ! 1571: /* }}} */ ! 1572: ! 1573: /* {{{ proto int SQLite3Result::columnType(int column) ! 1574: Returns the type of the nth column. */ ! 1575: PHP_METHOD(sqlite3result, columnType) ! 1576: { ! 1577: php_sqlite3_result *result_obj; ! 1578: zval *object = getThis(); ! 1579: long column = 0; ! 1580: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1581: ! 1582: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1583: ! 1584: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &column) == FAILURE) { ! 1585: return; ! 1586: } ! 1587: ! 1588: if (result_obj->complete) { ! 1589: RETURN_FALSE; ! 1590: } ! 1591: ! 1592: RETURN_LONG(sqlite3_column_type(result_obj->stmt_obj->stmt, column)); ! 1593: } ! 1594: /* }}} */ ! 1595: ! 1596: /* {{{ proto array SQLite3Result::fetchArray([int mode]) ! 1597: Fetch a result row as both an associative or numerically indexed array or both. */ ! 1598: PHP_METHOD(sqlite3result, fetchArray) ! 1599: { ! 1600: php_sqlite3_result *result_obj; ! 1601: zval *object = getThis(); ! 1602: int i, ret; ! 1603: long mode = PHP_SQLITE3_BOTH; ! 1604: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1605: ! 1606: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1607: ! 1608: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) { ! 1609: return; ! 1610: } ! 1611: ! 1612: ret = sqlite3_step(result_obj->stmt_obj->stmt); ! 1613: switch (ret) { ! 1614: case SQLITE_ROW: ! 1615: /* If there was no return value then just skip fetching */ ! 1616: if (!return_value_used) { ! 1617: return; ! 1618: } ! 1619: ! 1620: array_init(return_value); ! 1621: ! 1622: for (i = 0; i < sqlite3_data_count(result_obj->stmt_obj->stmt); i++) { ! 1623: zval *data; ! 1624: ! 1625: data = sqlite_value_to_zval(result_obj->stmt_obj->stmt, i); ! 1626: ! 1627: if (mode & PHP_SQLITE3_NUM) { ! 1628: add_index_zval(return_value, i, data); ! 1629: } ! 1630: ! 1631: if (mode & PHP_SQLITE3_ASSOC) { ! 1632: if (mode & PHP_SQLITE3_NUM) { ! 1633: Z_ADDREF_P(data); ! 1634: } ! 1635: add_assoc_zval(return_value, (char*)sqlite3_column_name(result_obj->stmt_obj->stmt, i), data); ! 1636: } ! 1637: } ! 1638: break; ! 1639: ! 1640: case SQLITE_DONE: ! 1641: result_obj->complete = 1; ! 1642: RETURN_FALSE; ! 1643: break; ! 1644: ! 1645: default: ! 1646: php_sqlite3_error(result_obj->db_obj, "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); ! 1647: } ! 1648: } ! 1649: /* }}} */ ! 1650: ! 1651: /* {{{ proto bool SQLite3Result::reset() ! 1652: Resets the result set back to the first row. */ ! 1653: PHP_METHOD(sqlite3result, reset) ! 1654: { ! 1655: php_sqlite3_result *result_obj; ! 1656: zval *object = getThis(); ! 1657: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1658: ! 1659: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1660: ! 1661: if (zend_parse_parameters_none() == FAILURE) { ! 1662: return; ! 1663: } ! 1664: ! 1665: if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) { ! 1666: RETURN_FALSE; ! 1667: } ! 1668: ! 1669: result_obj->complete = 0; ! 1670: ! 1671: RETURN_TRUE; ! 1672: } ! 1673: /* }}} */ ! 1674: ! 1675: /* {{{ proto bool SQLite3Result::finalize() ! 1676: Closes the result set. */ ! 1677: PHP_METHOD(sqlite3result, finalize) ! 1678: { ! 1679: php_sqlite3_result *result_obj; ! 1680: zval *object = getThis(); ! 1681: result_obj = (php_sqlite3_result *)zend_object_store_get_object(object TSRMLS_CC); ! 1682: ! 1683: SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) ! 1684: ! 1685: if (zend_parse_parameters_none() == FAILURE) { ! 1686: return; ! 1687: } ! 1688: ! 1689: /* We need to finalize an internal statement */ ! 1690: if (result_obj->is_prepared_statement == 0) { ! 1691: zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj_zval, ! 1692: (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free); ! 1693: } else { ! 1694: sqlite3_reset(result_obj->stmt_obj->stmt); ! 1695: } ! 1696: ! 1697: RETURN_TRUE; ! 1698: } ! 1699: /* }}} */ ! 1700: ! 1701: /* {{{ proto int SQLite3Result::__construct() ! 1702: __constructor for SQLite3Result. */ ! 1703: PHP_METHOD(sqlite3result, __construct) ! 1704: { ! 1705: zend_throw_exception(zend_exception_get_default(TSRMLS_C), "SQLite3Result cannot be directly instantiated", 0 TSRMLS_CC); ! 1706: } ! 1707: /* }}} */ ! 1708: ! 1709: /* {{{ arginfo */ ! 1710: ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_open, 0) ! 1711: ZEND_ARG_INFO(0, filename) ! 1712: ZEND_ARG_INFO(0, flags) ! 1713: ZEND_ARG_INFO(0, encryption_key) ! 1714: ZEND_END_ARG_INFO() ! 1715: ! 1716: ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_busytimeout, 0) ! 1717: ZEND_ARG_INFO(0, ms) ! 1718: ZEND_END_ARG_INFO() ! 1719: ! 1720: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 1721: ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_loadextension, 0) ! 1722: ZEND_ARG_INFO(0, shared_library) ! 1723: ZEND_END_ARG_INFO() ! 1724: #endif ! 1725: ! 1726: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_escapestring, 0, 0, 1) ! 1727: ZEND_ARG_INFO(0, value) ! 1728: ZEND_END_ARG_INFO() ! 1729: ! 1730: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_query, 0, 0, 1) ! 1731: ZEND_ARG_INFO(0, query) ! 1732: ZEND_END_ARG_INFO() ! 1733: ! 1734: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_querysingle, 0, 0, 1) ! 1735: ZEND_ARG_INFO(0, query) ! 1736: ZEND_ARG_INFO(0, entire_row) ! 1737: ZEND_END_ARG_INFO() ! 1738: ! 1739: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createfunction, 0, 0, 2) ! 1740: ZEND_ARG_INFO(0, name) ! 1741: ZEND_ARG_INFO(0, callback) ! 1742: ZEND_ARG_INFO(0, argument_count) ! 1743: ZEND_END_ARG_INFO() ! 1744: ! 1745: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createaggregate, 0, 0, 3) ! 1746: ZEND_ARG_INFO(0, name) ! 1747: ZEND_ARG_INFO(0, step_callback) ! 1748: ZEND_ARG_INFO(0, final_callback) ! 1749: ZEND_ARG_INFO(0, argument_count) ! 1750: ZEND_END_ARG_INFO() ! 1751: ! 1752: ZEND_BEGIN_ARG_INFO_EX(argingo_sqlite3_openblob, 0, 0, 3) ! 1753: ZEND_ARG_INFO(0, table) ! 1754: ZEND_ARG_INFO(0, column) ! 1755: ZEND_ARG_INFO(0, rowid) ! 1756: ZEND_ARG_INFO(0, dbname) ! 1757: ZEND_END_ARG_INFO() ! 1758: ! 1759: ZEND_BEGIN_ARG_INFO_EX(argingo_sqlite3_enableexceptions, 0, 0, 1) ! 1760: ZEND_ARG_INFO(0, enableExceptions) ! 1761: ZEND_END_ARG_INFO() ! 1762: ! 1763: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_bindparam, 0, 0, 2) ! 1764: ZEND_ARG_INFO(0, param_number) ! 1765: ZEND_ARG_INFO(1, param) ! 1766: ZEND_ARG_INFO(0, type) ! 1767: ZEND_END_ARG_INFO() ! 1768: ! 1769: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_bindvalue, 0, 0, 2) ! 1770: ZEND_ARG_INFO(0, param_number) ! 1771: ZEND_ARG_INFO(0, param) ! 1772: ZEND_ARG_INFO(0, type) ! 1773: ZEND_END_ARG_INFO() ! 1774: ! 1775: ZEND_BEGIN_ARG_INFO(arginfo_sqlite3stmt_construct, 1) ! 1776: ZEND_ARG_INFO(0, sqlite3) ! 1777: ZEND_END_ARG_INFO() ! 1778: ! 1779: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columnname, 0, 0, 1) ! 1780: ZEND_ARG_INFO(0, column_number) ! 1781: ZEND_END_ARG_INFO() ! 1782: ! 1783: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columntype, 0, 0, 1) ! 1784: ZEND_ARG_INFO(0, column_number) ! 1785: ZEND_END_ARG_INFO() ! 1786: ! 1787: ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_fetcharray, 0, 0, 1) ! 1788: ZEND_ARG_INFO(0, mode) ! 1789: ZEND_END_ARG_INFO() ! 1790: ! 1791: ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_void, 0) ! 1792: ZEND_END_ARG_INFO() ! 1793: /* }}} */ ! 1794: ! 1795: /* {{{ php_sqlite3_class_methods */ ! 1796: static zend_function_entry php_sqlite3_class_methods[] = { ! 1797: PHP_ME(sqlite3, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC) ! 1798: PHP_ME(sqlite3, close, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1799: PHP_ME(sqlite3, exec, arginfo_sqlite3_query, ZEND_ACC_PUBLIC) ! 1800: PHP_ME(sqlite3, version, arginfo_sqlite3_void, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ! 1801: PHP_ME(sqlite3, lastInsertRowID, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1802: PHP_ME(sqlite3, lastErrorCode, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1803: PHP_ME(sqlite3, lastErrorMsg, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1804: PHP_ME(sqlite3, busyTimeout, arginfo_sqlite3_busytimeout, ZEND_ACC_PUBLIC) ! 1805: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 1806: PHP_ME(sqlite3, loadExtension, arginfo_sqlite3_loadextension, ZEND_ACC_PUBLIC) ! 1807: #endif ! 1808: PHP_ME(sqlite3, changes, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1809: PHP_ME(sqlite3, escapeString, arginfo_sqlite3_escapestring, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ! 1810: PHP_ME(sqlite3, prepare, arginfo_sqlite3_query, ZEND_ACC_PUBLIC) ! 1811: PHP_ME(sqlite3, query, arginfo_sqlite3_query, ZEND_ACC_PUBLIC) ! 1812: PHP_ME(sqlite3, querySingle, arginfo_sqlite3_querysingle, ZEND_ACC_PUBLIC) ! 1813: PHP_ME(sqlite3, createFunction, arginfo_sqlite3_createfunction, ZEND_ACC_PUBLIC) ! 1814: PHP_ME(sqlite3, createAggregate, arginfo_sqlite3_createaggregate, ZEND_ACC_PUBLIC) ! 1815: PHP_ME(sqlite3, openBlob, argingo_sqlite3_openblob, ZEND_ACC_PUBLIC) ! 1816: PHP_ME(sqlite3, enableExceptions, argingo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC) ! 1817: /* Aliases */ ! 1818: PHP_MALIAS(sqlite3, __construct, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) ! 1819: PHP_FE_END ! 1820: }; ! 1821: /* }}} */ ! 1822: ! 1823: /* {{{ php_sqlite3_stmt_class_methods */ ! 1824: static zend_function_entry php_sqlite3_stmt_class_methods[] = { ! 1825: PHP_ME(sqlite3stmt, paramCount, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1826: PHP_ME(sqlite3stmt, close, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1827: PHP_ME(sqlite3stmt, reset, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1828: PHP_ME(sqlite3stmt, clear, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1829: PHP_ME(sqlite3stmt, execute, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1830: PHP_ME(sqlite3stmt, bindParam, arginfo_sqlite3stmt_bindparam, ZEND_ACC_PUBLIC) ! 1831: PHP_ME(sqlite3stmt, bindValue, arginfo_sqlite3stmt_bindvalue, ZEND_ACC_PUBLIC) ! 1832: PHP_ME(sqlite3stmt, readOnly, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1833: PHP_ME(sqlite3stmt, __construct, arginfo_sqlite3stmt_construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) ! 1834: PHP_FE_END ! 1835: }; ! 1836: /* }}} */ ! 1837: ! 1838: /* {{{ php_sqlite3_result_class_methods */ ! 1839: static zend_function_entry php_sqlite3_result_class_methods[] = { ! 1840: PHP_ME(sqlite3result, numColumns, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1841: PHP_ME(sqlite3result, columnName, arginfo_sqlite3result_columnname, ZEND_ACC_PUBLIC) ! 1842: PHP_ME(sqlite3result, columnType, arginfo_sqlite3result_columntype, ZEND_ACC_PUBLIC) ! 1843: PHP_ME(sqlite3result, fetchArray, arginfo_sqlite3result_fetcharray, ZEND_ACC_PUBLIC) ! 1844: PHP_ME(sqlite3result, reset, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1845: PHP_ME(sqlite3result, finalize, arginfo_sqlite3_void, ZEND_ACC_PUBLIC) ! 1846: PHP_ME(sqlite3result, __construct, arginfo_sqlite3_void, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) ! 1847: PHP_FE_END ! 1848: }; ! 1849: /* }}} */ ! 1850: ! 1851: /* {{{ Authorization Callback ! 1852: */ ! 1853: static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6) ! 1854: { ! 1855: switch (access_type) { ! 1856: case SQLITE_ATTACH: ! 1857: { ! 1858: if (strncmp(arg3, ":memory:", sizeof(":memory:")-1) && *arg3) { ! 1859: TSRMLS_FETCH(); ! 1860: ! 1861: #if PHP_API_VERSION < 20100412 ! 1862: if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ! 1863: return SQLITE_DENY; ! 1864: } ! 1865: #endif ! 1866: ! 1867: if (php_check_open_basedir(arg3 TSRMLS_CC)) { ! 1868: return SQLITE_DENY; ! 1869: } ! 1870: } ! 1871: return SQLITE_OK; ! 1872: } ! 1873: ! 1874: default: ! 1875: /* access allowed */ ! 1876: return SQLITE_OK; ! 1877: } ! 1878: } ! 1879: /* }}} */ ! 1880: ! 1881: /* {{{ php_sqlite3_free_list_dtor ! 1882: */ ! 1883: static void php_sqlite3_free_list_dtor(void **item) ! 1884: { ! 1885: php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item; ! 1886: ! 1887: if (free_item->stmt_obj && free_item->stmt_obj->initialised) { ! 1888: sqlite3_finalize(free_item->stmt_obj->stmt); ! 1889: free_item->stmt_obj->initialised = 0; ! 1890: } ! 1891: efree(*item); ! 1892: } ! 1893: /* }}} */ ! 1894: ! 1895: static int php_sqlite3_compare_stmt_zval_free( php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */ ! 1896: { ! 1897: return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj_zval); ! 1898: } ! 1899: /* }}} */ ! 1900: ! 1901: static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */ ! 1902: { ! 1903: return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt); ! 1904: } ! 1905: /* }}} */ ! 1906: ! 1907: static void php_sqlite3_object_free_storage(void *object TSRMLS_DC) /* {{{ */ ! 1908: { ! 1909: php_sqlite3_db_object *intern = (php_sqlite3_db_object *)object; ! 1910: php_sqlite3_func *func; ! 1911: ! 1912: if (!intern) { ! 1913: return; ! 1914: } ! 1915: ! 1916: while (intern->funcs) { ! 1917: func = intern->funcs; ! 1918: intern->funcs = func->next; ! 1919: if (intern->initialised && intern->db) { ! 1920: sqlite3_create_function(intern->db, func->func_name, func->argc, SQLITE_UTF8, func, NULL, NULL, NULL); ! 1921: } ! 1922: ! 1923: efree((char*)func->func_name); ! 1924: ! 1925: if (func->func) { ! 1926: zval_ptr_dtor(&func->func); ! 1927: } ! 1928: if (func->step) { ! 1929: zval_ptr_dtor(&func->step); ! 1930: } ! 1931: if (func->fini) { ! 1932: zval_ptr_dtor(&func->fini); ! 1933: } ! 1934: efree(func); ! 1935: } ! 1936: ! 1937: if (intern->initialised && intern->db) { ! 1938: sqlite3_close(intern->db); ! 1939: intern->initialised = 0; ! 1940: } ! 1941: ! 1942: zend_object_std_dtor(&intern->zo TSRMLS_CC); ! 1943: efree(intern); ! 1944: } ! 1945: /* }}} */ ! 1946: ! 1947: static void php_sqlite3_stmt_object_free_storage(void *object TSRMLS_DC) /* {{{ */ ! 1948: { ! 1949: php_sqlite3_stmt *intern = (php_sqlite3_stmt *)object; ! 1950: ! 1951: if (!intern) { ! 1952: return; ! 1953: } ! 1954: ! 1955: if (intern->bound_params) { ! 1956: zend_hash_destroy(intern->bound_params); ! 1957: FREE_HASHTABLE(intern->bound_params); ! 1958: intern->bound_params = NULL; ! 1959: } ! 1960: ! 1961: if (intern->initialised) { ! 1962: zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt, ! 1963: (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); ! 1964: } ! 1965: ! 1966: if (intern->db_obj_zval) { ! 1967: zval_ptr_dtor(&intern->db_obj_zval); ! 1968: } ! 1969: ! 1970: zend_object_std_dtor(&intern->zo TSRMLS_CC); ! 1971: efree(intern); ! 1972: } ! 1973: /* }}} */ ! 1974: ! 1975: static void php_sqlite3_result_object_free_storage(void *object TSRMLS_DC) /* {{{ */ ! 1976: { ! 1977: php_sqlite3_result *intern = (php_sqlite3_result *)object; ! 1978: ! 1979: if (!intern) { ! 1980: return; ! 1981: } ! 1982: ! 1983: if (intern->stmt_obj_zval) { ! 1984: if (intern->stmt_obj->initialised) { ! 1985: sqlite3_reset(intern->stmt_obj->stmt); ! 1986: } ! 1987: ! 1988: if (intern->is_prepared_statement == 0) { ! 1989: zval_dtor(intern->stmt_obj_zval); ! 1990: FREE_ZVAL(intern->stmt_obj_zval); ! 1991: } else { ! 1992: zval_ptr_dtor(&intern->stmt_obj_zval); ! 1993: } ! 1994: } ! 1995: ! 1996: zend_object_std_dtor(&intern->zo TSRMLS_CC); ! 1997: efree(intern); ! 1998: } ! 1999: /* }}} */ ! 2000: ! 2001: static zend_object_value php_sqlite3_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ ! 2002: { ! 2003: zval *tmp; ! 2004: zend_object_value retval; ! 2005: php_sqlite3_db_object *intern; ! 2006: ! 2007: /* Allocate memory for it */ ! 2008: intern = emalloc(sizeof(php_sqlite3_db_object)); ! 2009: memset(intern, 0, sizeof(php_sqlite3_db_object)); ! 2010: intern->exception = 0; ! 2011: ! 2012: /* Need to keep track of things to free */ ! 2013: zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0); ! 2014: ! 2015: zend_object_std_init(&intern->zo, class_type TSRMLS_CC); ! 2016: zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); ! 2017: ! 2018: retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_object_free_storage, NULL TSRMLS_CC); ! 2019: retval.handlers = (zend_object_handlers *) &sqlite3_object_handlers; ! 2020: ! 2021: return retval; ! 2022: } ! 2023: /* }}} */ ! 2024: ! 2025: static zend_object_value php_sqlite3_stmt_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ ! 2026: { ! 2027: zval *tmp; ! 2028: zend_object_value retval; ! 2029: php_sqlite3_stmt *intern; ! 2030: ! 2031: /* Allocate memory for it */ ! 2032: intern = emalloc(sizeof(php_sqlite3_stmt)); ! 2033: memset(intern, 0, sizeof(php_sqlite3_stmt)); ! 2034: ! 2035: intern->db_obj_zval = NULL; ! 2036: ! 2037: zend_object_std_init(&intern->zo, class_type TSRMLS_CC); ! 2038: zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); ! 2039: ! 2040: retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_stmt_object_free_storage, NULL TSRMLS_CC); ! 2041: retval.handlers = (zend_object_handlers *) &sqlite3_stmt_object_handlers; ! 2042: ! 2043: return retval; ! 2044: } ! 2045: /* }}} */ ! 2046: ! 2047: static zend_object_value php_sqlite3_result_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ ! 2048: { ! 2049: zval *tmp; ! 2050: zend_object_value retval; ! 2051: php_sqlite3_result *intern; ! 2052: ! 2053: /* Allocate memory for it */ ! 2054: intern = emalloc(sizeof(php_sqlite3_result)); ! 2055: memset(intern, 0, sizeof(php_sqlite3_result)); ! 2056: ! 2057: intern->complete = 0; ! 2058: intern->is_prepared_statement = 0; ! 2059: intern->stmt_obj_zval = NULL; ! 2060: ! 2061: zend_object_std_init(&intern->zo, class_type TSRMLS_CC); ! 2062: zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); ! 2063: ! 2064: retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_result_object_free_storage, NULL TSRMLS_CC); ! 2065: retval.handlers = (zend_object_handlers *) &sqlite3_result_object_handlers; ! 2066: ! 2067: return retval; ! 2068: } ! 2069: /* }}} */ ! 2070: ! 2071: static void sqlite3_param_dtor(void *data) /* {{{ */ ! 2072: { ! 2073: struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)data; ! 2074: ! 2075: if (param->name) { ! 2076: efree(param->name); ! 2077: } ! 2078: ! 2079: if (param->parameter) { ! 2080: zval_ptr_dtor(&(param->parameter)); ! 2081: param->parameter = NULL; ! 2082: } ! 2083: } ! 2084: /* }}} */ ! 2085: ! 2086: /* {{{ PHP_MINIT_FUNCTION ! 2087: */ ! 2088: PHP_MINIT_FUNCTION(sqlite3) ! 2089: { ! 2090: zend_class_entry ce; ! 2091: ! 2092: #if defined(ZTS) ! 2093: /* Refuse to load if this wasn't a threasafe library loaded */ ! 2094: if (!sqlite3_threadsafe()) { ! 2095: php_error_docref(NULL TSRMLS_CC, E_WARNING, "A thread safe version of SQLite is required when using a thread safe version of PHP."); ! 2096: return FAILURE; ! 2097: } ! 2098: #endif ! 2099: ! 2100: memcpy(&sqlite3_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); ! 2101: memcpy(&sqlite3_stmt_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); ! 2102: memcpy(&sqlite3_result_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); ! 2103: ! 2104: /* Register SQLite 3 Class */ ! 2105: INIT_CLASS_ENTRY(ce, "SQLite3", php_sqlite3_class_methods); ! 2106: ce.create_object = php_sqlite3_object_new; ! 2107: sqlite3_object_handlers.clone_obj = NULL; ! 2108: php_sqlite3_sc_entry = zend_register_internal_class(&ce TSRMLS_CC); ! 2109: ! 2110: /* Register SQLite 3 Prepared Statement Class */ ! 2111: INIT_CLASS_ENTRY(ce, "SQLite3Stmt", php_sqlite3_stmt_class_methods); ! 2112: ce.create_object = php_sqlite3_stmt_object_new; ! 2113: sqlite3_stmt_object_handlers.clone_obj = NULL; ! 2114: php_sqlite3_stmt_entry = zend_register_internal_class(&ce TSRMLS_CC); ! 2115: ! 2116: /* Register SQLite 3 Result Class */ ! 2117: INIT_CLASS_ENTRY(ce, "SQLite3Result", php_sqlite3_result_class_methods); ! 2118: ce.create_object = php_sqlite3_result_object_new; ! 2119: sqlite3_result_object_handlers.clone_obj = NULL; ! 2120: php_sqlite3_result_entry = zend_register_internal_class(&ce TSRMLS_CC); ! 2121: ! 2122: REGISTER_INI_ENTRIES(); ! 2123: ! 2124: REGISTER_LONG_CONSTANT("SQLITE3_ASSOC", PHP_SQLITE3_ASSOC, CONST_CS | CONST_PERSISTENT); ! 2125: REGISTER_LONG_CONSTANT("SQLITE3_NUM", PHP_SQLITE3_NUM, CONST_CS | CONST_PERSISTENT); ! 2126: REGISTER_LONG_CONSTANT("SQLITE3_BOTH", PHP_SQLITE3_BOTH, CONST_CS | CONST_PERSISTENT); ! 2127: ! 2128: REGISTER_LONG_CONSTANT("SQLITE3_INTEGER", SQLITE_INTEGER, CONST_CS | CONST_PERSISTENT); ! 2129: REGISTER_LONG_CONSTANT("SQLITE3_FLOAT", SQLITE_FLOAT, CONST_CS | CONST_PERSISTENT); ! 2130: REGISTER_LONG_CONSTANT("SQLITE3_TEXT", SQLITE3_TEXT, CONST_CS | CONST_PERSISTENT); ! 2131: REGISTER_LONG_CONSTANT("SQLITE3_BLOB", SQLITE_BLOB, CONST_CS | CONST_PERSISTENT); ! 2132: REGISTER_LONG_CONSTANT("SQLITE3_NULL", SQLITE_NULL, CONST_CS | CONST_PERSISTENT); ! 2133: ! 2134: REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READONLY", SQLITE_OPEN_READONLY, CONST_CS | CONST_PERSISTENT); ! 2135: REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READWRITE", SQLITE_OPEN_READWRITE, CONST_CS | CONST_PERSISTENT); ! 2136: REGISTER_LONG_CONSTANT("SQLITE3_OPEN_CREATE", SQLITE_OPEN_CREATE, CONST_CS | CONST_PERSISTENT); ! 2137: ! 2138: return SUCCESS; ! 2139: } ! 2140: /* }}} */ ! 2141: ! 2142: /* {{{ PHP_MSHUTDOWN_FUNCTION ! 2143: */ ! 2144: PHP_MSHUTDOWN_FUNCTION(sqlite3) ! 2145: { ! 2146: UNREGISTER_INI_ENTRIES(); ! 2147: ! 2148: return SUCCESS; ! 2149: } ! 2150: /* }}} */ ! 2151: ! 2152: /* {{{ PHP_MINFO_FUNCTION ! 2153: */ ! 2154: PHP_MINFO_FUNCTION(sqlite3) ! 2155: { ! 2156: php_info_print_table_start(); ! 2157: php_info_print_table_header(2, "SQLite3 support", "enabled"); ! 2158: php_info_print_table_row(2, "SQLite3 module version", PHP_SQLITE3_VERSION); ! 2159: php_info_print_table_row(2, "SQLite Library", sqlite3_libversion()); ! 2160: php_info_print_table_end(); ! 2161: ! 2162: DISPLAY_INI_ENTRIES(); ! 2163: } ! 2164: /* }}} */ ! 2165: ! 2166: /* {{{ PHP_GINIT_FUNCTION ! 2167: */ ! 2168: static PHP_GINIT_FUNCTION(sqlite3) ! 2169: { ! 2170: memset(sqlite3_globals, 0, sizeof(*sqlite3_globals)); ! 2171: } ! 2172: /* }}} */ ! 2173: ! 2174: /* {{{ sqlite3_module_entry ! 2175: */ ! 2176: zend_module_entry sqlite3_module_entry = { ! 2177: STANDARD_MODULE_HEADER, ! 2178: "sqlite3", ! 2179: NULL, ! 2180: PHP_MINIT(sqlite3), ! 2181: PHP_MSHUTDOWN(sqlite3), ! 2182: NULL, ! 2183: NULL, ! 2184: PHP_MINFO(sqlite3), ! 2185: PHP_SQLITE3_VERSION, ! 2186: PHP_MODULE_GLOBALS(sqlite3), ! 2187: PHP_GINIT(sqlite3), ! 2188: NULL, ! 2189: NULL, ! 2190: STANDARD_MODULE_PROPERTIES_EX ! 2191: }; ! 2192: /* }}} */ ! 2193: ! 2194: #ifdef COMPILE_DL_SQLITE3 ! 2195: ZEND_GET_MODULE(sqlite3) ! 2196: #endif ! 2197: ! 2198: /* ! 2199: * Local variables: ! 2200: * tab-width: 4 ! 2201: * c-basic-offset: 4 ! 2202: * End: ! 2203: * vim600: sw=4 ts=4 fdm=marker ! 2204: * vim<600: sw=4 ts=4 ! 2205: */