Annotation of embedaddon/php/ext/pdo_sqlite/sqlite_driver.c, revision 1.1.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:   | Author: Wez Furlong <wez@php.net>                                    |
                     16:   +----------------------------------------------------------------------+
                     17: */
                     18: 
                     19: /* $Id: sqlite_driver.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 "pdo/php_pdo.h"
                     29: #include "pdo/php_pdo_driver.h"
                     30: #include "php_pdo_sqlite.h"
                     31: #include "php_pdo_sqlite_int.h"
                     32: #include "zend_exceptions.h"
                     33: 
                     34: int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
                     35: {
                     36:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                     37:        pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
                     38:        pdo_sqlite_error_info *einfo = &H->einfo;
                     39: 
                     40:        einfo->errcode = sqlite3_errcode(H->db);
                     41:        einfo->file = file;
                     42:        einfo->line = line;
                     43: 
                     44:        if (einfo->errcode != SQLITE_OK) {
                     45:                if (einfo->errmsg) {
                     46:                        pefree(einfo->errmsg, dbh->is_persistent);
                     47:                }
                     48:                einfo->errmsg = pestrdup((char*)sqlite3_errmsg(H->db), dbh->is_persistent);
                     49:        } else { /* no error */
                     50:                strncpy(*pdo_err, PDO_ERR_NONE, sizeof(PDO_ERR_NONE));
                     51:                return 0;
                     52:        }
                     53:        switch (einfo->errcode) {
                     54:                case SQLITE_NOTFOUND:
                     55:                        strncpy(*pdo_err, "42S02", sizeof("42S02"));
                     56:                        break;  
                     57: 
                     58:                case SQLITE_INTERRUPT:
                     59:                        strncpy(*pdo_err, "01002", sizeof("01002"));
                     60:                        break;
                     61: 
                     62:                case SQLITE_NOLFS:
                     63:                        strncpy(*pdo_err, "HYC00", sizeof("HYC00"));
                     64:                        break;
                     65: 
                     66:                case SQLITE_TOOBIG:
                     67:                        strncpy(*pdo_err, "22001", sizeof("22001"));
                     68:                        break;
                     69:        
                     70:                case SQLITE_CONSTRAINT:
                     71:                        strncpy(*pdo_err, "23000", sizeof("23000"));
                     72:                        break;
                     73: 
                     74:                case SQLITE_ERROR:
                     75:                default:
                     76:                        strncpy(*pdo_err, "HY000", sizeof("HY000"));
                     77:                        break;
                     78:        }
                     79: 
                     80:        if (!dbh->methods) {
                     81:                zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
                     82:                                *pdo_err, einfo->errcode, einfo->errmsg);
                     83:        }
                     84:        
                     85:        return einfo->errcode;
                     86: }
                     87: /* }}} */
                     88: 
                     89: static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
                     90: {
                     91:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                     92:        pdo_sqlite_error_info *einfo = &H->einfo;
                     93: 
                     94:        if (einfo->errcode) {
                     95:                add_next_index_long(info, einfo->errcode);
                     96:                add_next_index_string(info, einfo->errmsg, 1);
                     97:        }
                     98: 
                     99:        return 1;
                    100: }
                    101: 
                    102: static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H TSRMLS_DC)
                    103: {
                    104:        struct pdo_sqlite_func *func;
                    105: 
                    106:        while (H->funcs) {
                    107:                func = H->funcs;
                    108:                H->funcs = func->next;
                    109: 
                    110:                if (H->db) {
                    111:                        /* delete the function from the handle */
                    112:                        sqlite3_create_function(H->db,
                    113:                                func->funcname,
                    114:                                func->argc,
                    115:                                SQLITE_UTF8,
                    116:                                func,
                    117:                                NULL, NULL, NULL);
                    118:                }
                    119: 
                    120:                efree((char*)func->funcname);
                    121:                if (func->func) {
                    122:                        zval_ptr_dtor(&func->func);
                    123:                }
                    124:                if (func->step) {
                    125:                        zval_ptr_dtor(&func->step);
                    126:                }
                    127:                if (func->fini) {
                    128:                        zval_ptr_dtor(&func->fini);
                    129:                }
                    130:                efree(func);
                    131:        }
                    132: }
                    133: 
                    134: static int sqlite_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
                    135: {
                    136:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    137:        
                    138:        if (H) {
                    139:                pdo_sqlite_error_info *einfo = &H->einfo;
                    140: 
                    141:                pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
                    142:                if (H->db) {
                    143:                        sqlite3_close(H->db);
                    144:                        H->db = NULL;
                    145:                }
                    146:                if (einfo->errmsg) {
                    147:                        pefree(einfo->errmsg, dbh->is_persistent);
                    148:                        einfo->errmsg = NULL;
                    149:                }
                    150:                pefree(H, dbh->is_persistent);
                    151:                dbh->driver_data = NULL;
                    152:        }
                    153:        return 0;
                    154: }
                    155: /* }}} */
                    156: 
                    157: static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
                    158: {
                    159:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    160:        pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
                    161:        int i;
                    162:        const char *tail;
                    163: 
                    164:        S->H = H;
                    165:        stmt->driver_data = S;
                    166:        stmt->methods = &sqlite_stmt_methods;
                    167:        stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL|PDO_PLACEHOLDER_NAMED;
                    168: 
                    169:        if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
                    170:                H->einfo.errcode = SQLITE_ERROR;
                    171:                pdo_sqlite_error(dbh);
                    172:                return 0;
                    173:        }
                    174: 
                    175:        i = sqlite3_prepare(H->db, sql, sql_len, &S->stmt, &tail);
                    176:        if (i == SQLITE_OK) {
                    177:                return 1;
                    178:        }
                    179: 
                    180:        pdo_sqlite_error(dbh);
                    181: 
                    182:        return 0;
                    183: }
                    184: 
                    185: static long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
                    186: {
                    187:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    188:        char *errmsg = NULL;
                    189: 
                    190:        if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
                    191:                pdo_sqlite_error(dbh);
                    192:                if (errmsg)
                    193:                        sqlite3_free(errmsg);
                    194: 
                    195:                return -1;
                    196:        } else {
                    197:                return sqlite3_changes(H->db);
                    198:        }
                    199: }
                    200: 
                    201: static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
                    202: {
                    203:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    204:        char *id;
                    205:        
                    206:        id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db) TSRMLS_CC);
                    207:        *len = strlen(id);
                    208:        return id;
                    209: }
                    210: 
                    211: /* NB: doesn't handle binary strings... use prepared stmts for that */
                    212: static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
                    213: {
                    214:        *quoted = safe_emalloc(2, unquotedlen, 3);
                    215:        sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
                    216:        *quotedlen = strlen(*quoted);
                    217:        return 1;
                    218: }
                    219: 
                    220: static int sqlite_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
                    221: {
                    222:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    223:        char *errmsg = NULL;
                    224: 
                    225:        if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
                    226:                pdo_sqlite_error(dbh);
                    227:                if (errmsg)
                    228:                        sqlite3_free(errmsg);
                    229:                return 0;
                    230:        }
                    231:        return 1;
                    232: }
                    233: 
                    234: static int sqlite_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
                    235: {
                    236:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    237:        char *errmsg = NULL;
                    238: 
                    239:        if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
                    240:                pdo_sqlite_error(dbh);
                    241:                if (errmsg)
                    242:                        sqlite3_free(errmsg);
                    243:                return 0;
                    244:        }
                    245:        return 1;
                    246: }
                    247: 
                    248: static int sqlite_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
                    249: {
                    250:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    251:        char *errmsg = NULL;
                    252: 
                    253:        if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
                    254:                pdo_sqlite_error(dbh);
                    255:                if (errmsg)
                    256:                        sqlite3_free(errmsg);
                    257:                return 0;
                    258:        }
                    259:        return 1;
                    260: }
                    261: 
                    262: static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
                    263: {
                    264:        switch (attr) {
                    265:                case PDO_ATTR_CLIENT_VERSION:
                    266:                case PDO_ATTR_SERVER_VERSION:
                    267:                        ZVAL_STRING(return_value, (char *)sqlite3_libversion(), 1);
                    268:                        break;
                    269:                
                    270:                default:
                    271:                        return 0;       
                    272:        }
                    273: 
                    274:        return 1;
                    275: }
                    276: 
                    277: static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
                    278: {
                    279:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    280: 
                    281:        switch (attr) {
                    282:                case PDO_ATTR_TIMEOUT:
                    283:                        convert_to_long(val);
                    284:                        sqlite3_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
                    285:                        return 1;
                    286:        }
                    287:        return 0;
                    288: }
                    289: 
                    290: static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
                    291:                int argc, sqlite3_value **argv, sqlite3_context *context,
                    292:                int is_agg TSRMLS_DC)
                    293: {
                    294:        zval ***zargs = NULL;
                    295:        zval *retval = NULL;
                    296:        int i;
                    297:        int ret;
                    298:        int fake_argc;
                    299:        zval **agg_context = NULL;
                    300:        
                    301:        if (is_agg) {
                    302:                is_agg = 2;
                    303:        }
                    304:        
                    305:        fake_argc = argc + is_agg;
                    306:        
                    307:        fc->fci.size = sizeof(fc->fci);
                    308:        fc->fci.function_table = EG(function_table);
                    309:        fc->fci.function_name = cb;
                    310:        fc->fci.symbol_table = NULL;
                    311:        fc->fci.object_ptr = NULL;
                    312:        fc->fci.retval_ptr_ptr = &retval;
                    313:        fc->fci.param_count = fake_argc;
                    314:        
                    315:        /* build up the params */
                    316: 
                    317:        if (fake_argc) {
                    318:                zargs = (zval ***)safe_emalloc(fake_argc, sizeof(zval **), 0);
                    319:        }
                    320: 
                    321:        if (is_agg) {
                    322:                /* summon the aggregation context */
                    323:                agg_context = (zval**)sqlite3_aggregate_context(context, sizeof(zval*));
                    324:                if (!*agg_context) {
                    325:                        MAKE_STD_ZVAL(*agg_context);
                    326:                        ZVAL_NULL(*agg_context);
                    327:                }
                    328:                zargs[0] = agg_context;
                    329: 
                    330:                zargs[1] = emalloc(sizeof(zval*));
                    331:                MAKE_STD_ZVAL(*zargs[1]);
                    332:                ZVAL_LONG(*zargs[1], sqlite3_aggregate_count(context));
                    333:        }
                    334:        
                    335:        for (i = 0; i < argc; i++) {
                    336:                zargs[i + is_agg] = emalloc(sizeof(zval *));
                    337:                MAKE_STD_ZVAL(*zargs[i + is_agg]);
                    338: 
                    339:                /* get the value */
                    340:                switch (sqlite3_value_type(argv[i])) {
                    341:                        case SQLITE_INTEGER:
                    342:                                ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int(argv[i]));
                    343:                                break;
                    344: 
                    345:                        case SQLITE_FLOAT:
                    346:                                ZVAL_DOUBLE(*zargs[i + is_agg], sqlite3_value_double(argv[i]));
                    347:                                break;
                    348: 
                    349:                        case SQLITE_NULL:
                    350:                                ZVAL_NULL(*zargs[i + is_agg]);
                    351:                                break;
                    352: 
                    353:                        case SQLITE_BLOB:
                    354:                        case SQLITE3_TEXT:
                    355:                        default:
                    356:                                ZVAL_STRINGL(*zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]),
                    357:                                                sqlite3_value_bytes(argv[i]), 1);
                    358:                                break;
                    359:                }
                    360:        }
                    361: 
                    362: 
                    363:        fc->fci.params = zargs;
                    364: 
                    365: 
                    366:        if ((ret = zend_call_function(&fc->fci, &fc->fcc TSRMLS_CC)) == FAILURE) {
                    367:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the callback");
                    368:        }
                    369: 
                    370:        /* clean up the params */
                    371:        if (zargs) {
                    372:                for (i = is_agg; i < fake_argc; i++) {
                    373:                        zval_ptr_dtor(zargs[i]);
                    374:                        efree(zargs[i]);
                    375:                }
                    376:                if (is_agg) {
                    377:                        zval_ptr_dtor(zargs[1]);
                    378:                        efree(zargs[1]);
                    379:                }
                    380:                efree(zargs);
                    381:        }
                    382: 
                    383:        if (!is_agg || !argv) {
                    384:                /* only set the sqlite return value if we are a scalar function,
                    385:                 * or if we are finalizing an aggregate */
                    386:                if (retval) {
                    387:                        switch (Z_TYPE_P(retval)) {
                    388:                                case IS_LONG:
                    389:                                        sqlite3_result_int(context, Z_LVAL_P(retval));
                    390:                                        break;
                    391: 
                    392:                                case IS_NULL:
                    393:                                        sqlite3_result_null(context);
                    394:                                        break;
                    395: 
                    396:                                case IS_DOUBLE:
                    397:                                        sqlite3_result_double(context, Z_DVAL_P(retval));
                    398:                                        break;
                    399: 
                    400:                                default:
                    401:                                        convert_to_string_ex(&retval);
                    402:                                        sqlite3_result_text(context, Z_STRVAL_P(retval),
                    403:                                                Z_STRLEN_P(retval), SQLITE_TRANSIENT);
                    404:                                        break;
                    405:                        }
                    406:                } else {
                    407:                        sqlite3_result_error(context, "failed to invoke callback", 0);
                    408:                }
                    409: 
                    410:                if (agg_context) {
                    411:                        zval_ptr_dtor(agg_context);
                    412:                }
                    413:        } else {
                    414:                /* we're stepping in an aggregate; the return value goes into
                    415:                 * the context */
                    416:                if (agg_context) {
                    417:                        zval_ptr_dtor(agg_context);
                    418:                }
                    419:                if (retval) {
                    420:                        *agg_context = retval;
                    421:                        retval = NULL;
                    422:                } else {
                    423:                        *agg_context = NULL;
                    424:                }
                    425:        }
                    426: 
                    427:        if (retval) {
                    428:                zval_ptr_dtor(&retval);
                    429:        }
                    430: 
                    431:        return ret;
                    432: }
                    433: 
                    434: static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
                    435:        sqlite3_value **argv)
                    436: {
                    437:        struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
                    438:        TSRMLS_FETCH();
                    439: 
                    440:        do_callback(&func->afunc, func->func, argc, argv, context, 0 TSRMLS_CC);
                    441: }
                    442: 
                    443: static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
                    444:        sqlite3_value **argv)
                    445: {
                    446:        struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
                    447:        TSRMLS_FETCH();
                    448: 
                    449:        do_callback(&func->astep, func->step, argc, argv, context, 1 TSRMLS_CC);
                    450: }
                    451: 
                    452: static void php_sqlite3_func_final_callback(sqlite3_context *context)
                    453: {
                    454:        struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
                    455:        TSRMLS_FETCH();
                    456: 
                    457:        do_callback(&func->afini, func->fini, 0, NULL, context, 1 TSRMLS_CC);
                    458: }
                    459: 
                    460: /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
                    461:    Registers a UDF with the sqlite db handle */
                    462: static PHP_METHOD(SQLite, sqliteCreateFunction)
                    463: {
                    464:        struct pdo_sqlite_func *func;
                    465:        zval *callback;
                    466:        char *func_name;
                    467:        int func_name_len;
                    468:        long argc = -1;
                    469:        char *cbname = NULL;
                    470:        pdo_dbh_t *dbh;
                    471:        pdo_sqlite_db_handle *H;
                    472:        int ret;
                    473: 
                    474:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l",
                    475:                        &func_name, &func_name_len, &callback, &argc)) {
                    476:                RETURN_FALSE;
                    477:        }
                    478:        
                    479:        dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
                    480:        PDO_CONSTRUCT_CHECK;
                    481: 
                    482:        if (!zend_is_callable(callback, 0, &cbname TSRMLS_CC)) {
                    483:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
                    484:                efree(cbname);
                    485:                RETURN_FALSE;
                    486:        }
                    487:        efree(cbname);
                    488:        
                    489:        H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    490: 
                    491:        func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
                    492: 
                    493:        ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
                    494:                        func, php_sqlite3_func_callback, NULL, NULL);
                    495:        if (ret == SQLITE_OK) {
                    496:                func->funcname = estrdup(func_name);
                    497:                
                    498:                MAKE_STD_ZVAL(func->func);
                    499:                MAKE_COPY_ZVAL(&callback, func->func);
                    500:                
                    501:                func->argc = argc;
                    502: 
                    503:                func->next = H->funcs;
                    504:                H->funcs = func;
                    505: 
                    506:                RETURN_TRUE;
                    507:        }
                    508: 
                    509:        efree(func);
                    510:        RETURN_FALSE;
                    511: }
                    512: /* }}} */
                    513: 
                    514: /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
                    515:    Registers a UDF with the sqlite db handle */
                    516: 
                    517: /* The step function should have the prototype:
                    518:    mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
                    519: 
                    520:    $context will be null for the first row; on subsequent rows it will have
                    521:    the value that was previously returned from the step function; you should
                    522:    use this to maintain state for the aggregate.
                    523: 
                    524:    The fini function should have the prototype:
                    525:    mixed fini(mixed $context, int $rownumber)
                    526: 
                    527:    $context will hold the return value from the very last call to the step function.
                    528:    rownumber will hold the number of rows over which the aggregate was performed.
                    529:    The return value of this function will be used as the return value for this
                    530:    aggregate UDF.
                    531: */
                    532:    
                    533: static PHP_METHOD(SQLite, sqliteCreateAggregate)
                    534: {
                    535:        struct pdo_sqlite_func *func;
                    536:        zval *step_callback, *fini_callback;
                    537:        char *func_name;
                    538:        int func_name_len;
                    539:        long argc = -1;
                    540:        char *cbname = NULL;
                    541:        pdo_dbh_t *dbh;
                    542:        pdo_sqlite_db_handle *H;
                    543:        int ret;
                    544: 
                    545:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l",
                    546:                        &func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
                    547:                RETURN_FALSE;
                    548:        }
                    549:        
                    550:        dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
                    551:        PDO_CONSTRUCT_CHECK;
                    552: 
                    553:        if (!zend_is_callable(step_callback, 0, &cbname TSRMLS_CC)) {
                    554:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
                    555:                efree(cbname);
                    556:                RETURN_FALSE;
                    557:        }
                    558:        efree(cbname);
                    559:        if (!zend_is_callable(fini_callback, 0, &cbname TSRMLS_CC)) {
                    560:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
                    561:                efree(cbname);
                    562:                RETURN_FALSE;
                    563:        }
                    564:        efree(cbname);
                    565:        
                    566:        H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    567: 
                    568:        func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
                    569: 
                    570:        ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
                    571:                        func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
                    572:        if (ret == SQLITE_OK) {
                    573:                func->funcname = estrdup(func_name);
                    574:                
                    575:                MAKE_STD_ZVAL(func->step);
                    576:                MAKE_COPY_ZVAL(&step_callback, func->step);
                    577: 
                    578:                MAKE_STD_ZVAL(func->fini);
                    579:                MAKE_COPY_ZVAL(&fini_callback, func->fini);
                    580:                
                    581:                func->argc = argc;
                    582: 
                    583:                func->next = H->funcs;
                    584:                H->funcs = func;
                    585: 
                    586:                RETURN_TRUE;
                    587:        }
                    588: 
                    589:        efree(func);
                    590:        RETURN_FALSE;
                    591: }
                    592: /* }}} */
                    593: static const zend_function_entry dbh_methods[] = {
                    594:        PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
                    595:        PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
                    596:        PHP_FE_END
                    597: };
                    598: 
                    599: static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
                    600: {
                    601:        switch (kind) {
                    602:                case PDO_DBH_DRIVER_METHOD_KIND_DBH:
                    603:                        return dbh_methods;
                    604: 
                    605:                default:
                    606:                        return NULL;
                    607:        }
                    608: }
                    609: 
                    610: static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh TSRMLS_DC)
                    611: {
                    612:        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
                    613:        /* unregister functions, so that they don't linger for the next
                    614:         * request */
                    615:        if (H) {
                    616:                pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
                    617:        }
                    618: }
                    619: 
                    620: static struct pdo_dbh_methods sqlite_methods = {
                    621:        sqlite_handle_closer,
                    622:        sqlite_handle_preparer,
                    623:        sqlite_handle_doer,
                    624:        sqlite_handle_quoter,
                    625:        sqlite_handle_begin,
                    626:        sqlite_handle_commit,
                    627:        sqlite_handle_rollback,
                    628:        pdo_sqlite_set_attr,
                    629:        pdo_sqlite_last_insert_id,
                    630:        pdo_sqlite_fetch_error_func,
                    631:        pdo_sqlite_get_attribute,
                    632:        NULL,   /* check_liveness: not needed */
                    633:        get_driver_methods,
                    634:        pdo_sqlite_request_shutdown
                    635: };
                    636: 
                    637: static char *make_filename_safe(const char *filename TSRMLS_DC)
                    638: {
                    639:        if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
                    640:                char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
                    641: 
                    642:                if (!fullpath) {
                    643:                        return NULL;
                    644:                }
                    645: 
                    646:                if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
                    647:                        efree(fullpath);
                    648:                        return NULL;
                    649:                }
                    650: 
                    651:                if (php_check_open_basedir(fullpath TSRMLS_CC)) {
                    652:                        efree(fullpath);
                    653:                        return NULL;
                    654:                }
                    655:                return fullpath;
                    656:        }
                    657:        return estrdup(filename);
                    658: }
                    659: 
                    660: static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
                    661:                const char *arg5, const char *arg6)
                    662: {
                    663:        char *filename;
                    664:        switch (access_type) {
                    665:                case SQLITE_COPY: {
                    666:                        TSRMLS_FETCH();
                    667:                        filename = make_filename_safe(arg4 TSRMLS_CC);
                    668:                        if (!filename) {
                    669:                                return SQLITE_DENY;
                    670:                        }
                    671:                        efree(filename);
                    672:                        return SQLITE_OK;
                    673:                }
                    674: 
                    675:                case SQLITE_ATTACH: {
                    676:                        TSRMLS_FETCH();
                    677:                        filename = make_filename_safe(arg3 TSRMLS_CC);
                    678:                        if (!filename) {
                    679:                                return SQLITE_DENY;
                    680:                        }
                    681:                        efree(filename);
                    682:                        return SQLITE_OK;
                    683:                }
                    684: 
                    685:                default:
                    686:                        /* access allowed */
                    687:                        return SQLITE_OK;
                    688:        }
                    689: }
                    690: 
                    691: static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
                    692: {
                    693:        pdo_sqlite_db_handle *H;
                    694:        int i, ret = 0;
                    695:        long timeout = 60;
                    696:        char *filename;
                    697: 
                    698:        H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
                    699:        
                    700:        H->einfo.errcode = 0;
                    701:        H->einfo.errmsg = NULL;
                    702:        dbh->driver_data = H;
                    703: 
                    704:        filename = make_filename_safe(dbh->data_source TSRMLS_CC);
                    705: 
                    706:        if (!filename) {
                    707:                zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
                    708:                        "safe_mode/open_basedir prohibits opening %s",
                    709:                        dbh->data_source);
                    710:                goto cleanup;
                    711:        }
                    712: 
                    713:        i = sqlite3_open(filename, &H->db);
                    714:        efree(filename);
                    715: 
                    716:        if (i != SQLITE_OK) {
                    717:                pdo_sqlite_error(dbh);
                    718:                goto cleanup;
                    719:        }
                    720: 
                    721:        if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
                    722:                sqlite3_set_authorizer(H->db, authorizer, NULL);
                    723:        }
                    724: 
                    725:        if (driver_options) {
                    726:                timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
                    727:        }
                    728:        sqlite3_busy_timeout(H->db, timeout * 1000);
                    729: 
                    730:        dbh->alloc_own_columns = 1;
                    731:        dbh->max_escaped_char_length = 2;
                    732: 
                    733:        ret = 1;
                    734:        
                    735: cleanup:
                    736:        dbh->methods = &sqlite_methods;
                    737:        
                    738:        return ret;
                    739: }
                    740: /* }}} */
                    741: 
                    742: pdo_driver_t pdo_sqlite_driver = {
                    743:        PDO_DRIVER_HEADER(sqlite),
                    744:        pdo_sqlite_handle_factory
                    745: };
                    746: 
                    747: /*
                    748:  * Local variables:
                    749:  * tab-width: 4
                    750:  * c-basic-offset: 4
                    751:  * End:
                    752:  * vim600: noet sw=4 ts=4 fdm=marker
                    753:  * vim<600: noet sw=4 ts=4
                    754:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>