Annotation of embedaddon/php/ext/sqlite3/sqlite3.c, revision 1.1
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: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>