PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - sqlite - pdo_sqlite2.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 286
Code covered: 67.8 % Executed lines: 194
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:10 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.