Back to index

php5  5.3.10
pdo_sqlite2.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Author: Wez Furlong <wez@php.net>                                    |
00016   +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: pdo_sqlite2.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023 #include "php.h"
00024 
00025 #ifdef PHP_SQLITE2_HAVE_PDO
00026 #include "sqlite.h"
00027 #include "pdo/php_pdo.h"
00028 #include "pdo/php_pdo_driver.h"
00029 #include "zend_exceptions.h"
00030 
00031 #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
00032 #define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
00033 
00034 
00035 typedef struct {
00036        const char *file;
00037        int line;
00038        unsigned int errcode;
00039        char *errmsg;
00040 } pdo_sqlite2_error_info;
00041 
00042 typedef struct {
00043        sqlite *db;
00044        pdo_sqlite2_error_info einfo;
00045 } pdo_sqlite2_db_handle;
00046 
00047 typedef struct {
00048        pdo_sqlite2_db_handle       *H;
00049        sqlite_vm *vm;
00050        const char **rowdata, **colnames;
00051        int ncols;
00052        unsigned pre_fetched:1;
00053        unsigned done:1;
00054        pdo_sqlite2_error_info einfo;
00055 } pdo_sqlite2_stmt;
00056 
00057 extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
00058 #define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
00059 #define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
00060 
00061 extern struct pdo_stmt_methods sqlite2_stmt_methods;
00062 
00063 static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
00064 {
00065        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
00066 
00067        if (S->vm) {
00068               char *errmsg = NULL;
00069               sqlite_finalize(S->vm, &errmsg);
00070               if (errmsg) {
00071                      sqlite_freemem(errmsg);
00072               }
00073               S->vm = NULL;
00074        }
00075        if (S->einfo.errmsg) {
00076               pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
00077        }
00078        efree(S);
00079        return 1;
00080 }
00081 
00082 static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
00083 {
00084        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
00085        char *errmsg = NULL;
00086        const char *tail;
00087 
00088        if (stmt->executed && !S->done) {
00089               sqlite_finalize(S->vm, &errmsg);
00090               pdo_sqlite2_error_stmt(errmsg, stmt);
00091               errmsg = NULL;
00092               S->vm = NULL;
00093        }
00094 
00095        S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
00096        if (S->einfo.errcode != SQLITE_OK) {
00097               pdo_sqlite2_error_stmt(errmsg, stmt);
00098               return 0;
00099        }
00100 
00101        S->done = 0;
00102        S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
00103        switch (S->einfo.errcode) {
00104               case SQLITE_ROW:
00105                      S->pre_fetched = 1;
00106                      stmt->column_count = S->ncols;
00107                      return 1;
00108 
00109               case SQLITE_DONE:
00110                      stmt->column_count = S->ncols;
00111                      stmt->row_count = sqlite_changes(S->H->db);
00112                      S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
00113                      if (S->einfo.errcode != SQLITE_OK) {
00114                             pdo_sqlite2_error_stmt(errmsg, stmt);
00115                      }
00116                      S->done = 1;
00117                      return 1;
00118 
00119               case SQLITE_ERROR:
00120               case SQLITE_MISUSE:
00121               case SQLITE_BUSY:
00122               default:
00123                      pdo_sqlite2_error_stmt(errmsg, stmt);
00124                      return 0;
00125        }
00126 }
00127 
00128 static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
00129               enum pdo_param_event event_type TSRMLS_DC)
00130 {
00131        return 1;
00132 }
00133 
00134 static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
00135        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
00136 {
00137        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
00138        char *errmsg = NULL;
00139 
00140        if (!S->vm) {
00141               return 0;     
00142        }
00143        if (S->pre_fetched) {
00144               S->pre_fetched = 0;
00145               return 1;
00146        }
00147        if (S->done) {
00148               return 0;
00149        }
00150 
00151        S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
00152        switch (S->einfo.errcode) {
00153               case SQLITE_ROW:
00154                      return 1;
00155 
00156               case SQLITE_DONE:
00157                      S->done = 1;
00158                      S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
00159                      if (S->einfo.errcode != SQLITE_OK) {
00160                             pdo_sqlite2_error_stmt(errmsg, stmt);
00161                             errmsg = NULL;
00162                      }
00163                      return 0;
00164 
00165               default:
00166                      pdo_sqlite2_error_stmt(errmsg, stmt);
00167                      return 0;
00168        }
00169 }
00170 
00171 static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
00172 {
00173        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
00174 
00175        if(colno >= S->ncols) {
00176               /* error invalid column */
00177               pdo_sqlite2_error_stmt(NULL, stmt);
00178               return 0;
00179        }
00180 
00181        stmt->columns[colno].name = estrdup(S->colnames[colno]);
00182        stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
00183        stmt->columns[colno].maxlen = 0xffffffff;
00184        stmt->columns[colno].precision = 0;
00185        stmt->columns[colno].param_type = PDO_PARAM_STR;
00186 
00187        return 1;
00188 }
00189 
00190 static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
00191 {
00192        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
00193        if (!S->vm) {
00194               return 0;
00195        }
00196        if(colno >= S->ncols) {
00197               /* error invalid column */
00198               pdo_sqlite2_error_stmt(NULL, stmt);
00199               return 0;
00200        }
00201        if (S->rowdata[colno]) {
00202               if (S->rowdata[colno][0] == '\x01') {
00203                      /* encoded */
00204                      *caller_frees = 1;
00205                      *ptr = emalloc(strlen(S->rowdata[colno]));
00206                      *len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
00207                      (*(char**)ptr)[*len] = '\0';
00208               } else {
00209                      *ptr = (char*)S->rowdata[colno];
00210                      *len = strlen(*ptr);
00211               }
00212        } else {
00213               *ptr = NULL;
00214               *len = 0;
00215        }
00216        return 1;
00217 }
00218 
00219 struct pdo_stmt_methods sqlite2_stmt_methods = {
00220        pdo_sqlite2_stmt_dtor,
00221        pdo_sqlite2_stmt_execute,
00222        pdo_sqlite2_stmt_fetch,
00223        pdo_sqlite2_stmt_describe,
00224        pdo_sqlite2_stmt_get_col,
00225        pdo_sqlite2_stmt_param_hook,
00226        NULL, /* set_attr */
00227        NULL, /* get_attr */
00228        NULL
00229 };
00230 
00231 
00232 int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
00233 {
00234        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00235        pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
00236        pdo_sqlite2_error_info *einfo = &H->einfo;
00237        pdo_sqlite2_stmt *S;
00238 
00239        if (stmt) {
00240               S = stmt->driver_data;
00241               einfo = &S->einfo;
00242        }
00243 
00244        einfo->file = file;
00245        einfo->line = line;
00246 
00247        if (einfo->errmsg) {
00248               pefree(einfo->errmsg, dbh->is_persistent);
00249               einfo->errmsg = NULL;
00250        }
00251 
00252        if (einfo->errcode != SQLITE_OK) {
00253               if (errmsg) {
00254                      einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
00255                      sqlite_freemem(errmsg);
00256               } else {
00257                      einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
00258               }
00259        } else { /* no error */
00260               strcpy(*pdo_err, PDO_ERR_NONE);
00261               return 0;
00262        }
00263        switch (einfo->errcode) {
00264               case SQLITE_NOTFOUND:
00265                      strcpy(*pdo_err, "42S02");
00266                      break; 
00267 
00268               case SQLITE_INTERRUPT:
00269                      strcpy(*pdo_err, "01002");
00270                      break;
00271 
00272               case SQLITE_NOLFS:
00273                      strcpy(*pdo_err, "HYC00");
00274                      break;
00275 
00276               case SQLITE_TOOBIG:
00277                      strcpy(*pdo_err, "22001");
00278                      break;
00279 
00280               case SQLITE_CONSTRAINT:
00281                      strcpy(*pdo_err, "23000");
00282                      break;
00283 
00284               case SQLITE_ERROR:
00285               default:
00286                      strcpy(*pdo_err, "HY000");
00287                      break;
00288        }
00289 
00290        if (!dbh->methods) {
00291               zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
00292                             *pdo_err, einfo->errcode, einfo->errmsg);
00293        }
00294 
00295        return einfo->errcode;
00296 }
00297 /* }}} */
00298 
00299 static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
00300 {
00301        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00302        pdo_sqlite2_error_info *einfo = &H->einfo;
00303        pdo_sqlite2_stmt *S;
00304 
00305        if (stmt) {
00306               S = stmt->driver_data;
00307               einfo = &S->einfo;
00308        }
00309 
00310        if (einfo->errcode) {
00311               add_next_index_long(info, einfo->errcode);
00312               if (einfo->errmsg) {
00313                      add_next_index_string(info, einfo->errmsg, 1);
00314               }
00315        }
00316 
00317        return 1;
00318 }
00319 
00320 static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
00321 {
00322        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00323        
00324        if (H) {
00325               if (H->db) {
00326                      sqlite_close(H->db);
00327                      H->db = NULL;
00328               }
00329               if (H->einfo.errmsg) {
00330                      pefree(H->einfo.errmsg, dbh->is_persistent);
00331                      H->einfo.errmsg = NULL;
00332               }
00333               pefree(H, dbh->is_persistent);
00334               dbh->driver_data = NULL;
00335        }
00336        return 0;
00337 }
00338 /* }}} */
00339 
00340 static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
00341 {
00342        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00343        pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
00344 
00345        S->H = H;
00346        stmt->driver_data = S;
00347        stmt->methods = &sqlite2_stmt_methods;
00348        stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
00349 
00350        if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
00351               H->einfo.errcode = SQLITE_ERROR;
00352               pdo_sqlite2_error(NULL, dbh);
00353               return 0;
00354        }
00355 
00356        return 1;
00357 }
00358 
00359 static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
00360 {
00361        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00362        char *errmsg = NULL;
00363 
00364        if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
00365               pdo_sqlite2_error(errmsg, dbh);
00366               return -1;
00367        } else {
00368               return sqlite_changes(H->db);
00369        }
00370 }
00371 
00372 static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
00373 {
00374        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00375        char *id;
00376        
00377        id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
00378        *len = strlen(id);
00379        return id;
00380 }
00381 
00382 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)
00383 {
00384        char *ret;
00385 
00386        if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
00387               /* binary string */
00388               int len;
00389               ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
00390               ret[0] = '\'';
00391               ret[1] = '\x01';
00392               len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
00393               ret[len + 2] = '\'';
00394               ret[len + 3] = '\0';
00395               *quoted = ret;
00396               *quotedlen = len + 3;
00397               /* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
00398               return 1;
00399        } else if (unquotedlen) {
00400               ret = sqlite_mprintf("'%q'", unquoted);
00401               if (ret) {
00402                      *quoted = estrdup(ret);
00403                      *quotedlen = strlen(ret);
00404                      sqlite_freemem(ret);
00405                      return 1;
00406               }
00407               return 0;
00408        } else {
00409               *quoted = estrdup("''");
00410               *quotedlen = 2;
00411               return 1;
00412        }
00413 }
00414 
00415 static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
00416 {
00417        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00418        char *errmsg = NULL;
00419 
00420        if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
00421               pdo_sqlite2_error(errmsg, dbh);
00422               return 0;
00423        }
00424        return 1;
00425 }
00426 
00427 static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
00428 {
00429        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00430        char *errmsg = NULL;
00431 
00432        if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
00433               pdo_sqlite2_error(errmsg, dbh);
00434               return 0;
00435        }
00436        return 1;
00437 }
00438 
00439 static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
00440 {
00441        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00442        char *errmsg = NULL;
00443 
00444        if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
00445               pdo_sqlite2_error(errmsg, dbh);
00446               return 0;
00447        }
00448        return 1;
00449 }
00450 
00451 static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
00452 {
00453        switch (attr) {
00454               case PDO_ATTR_CLIENT_VERSION:
00455               case PDO_ATTR_SERVER_VERSION:
00456                      ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
00457                      break;
00458               
00459               default:
00460                      return 0;     
00461        }
00462 
00463        return 1;
00464 }
00465 
00466 static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
00467 {
00468        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
00469 
00470        switch (attr) {
00471               case PDO_ATTR_TIMEOUT:
00472                      convert_to_long(val);
00473                      sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
00474                      return 1;
00475        }
00476        return 0;
00477 }
00478 
00479 static PHP_FUNCTION(sqlite2_create_function)
00480 {
00481        /* TODO: implement this stuff */
00482 }
00483 
00484 static const zend_function_entry dbh_methods[] = {
00485        PHP_FE(sqlite2_create_function, NULL)
00486        {NULL, NULL, NULL}
00487 };
00488 
00489 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
00490 {
00491        switch (kind) {
00492               case PDO_DBH_DRIVER_METHOD_KIND_DBH:
00493                      return dbh_methods;
00494 
00495               default:
00496                      return NULL;
00497        }
00498 }
00499 
00500 static struct pdo_dbh_methods sqlite2_methods = {
00501        sqlite2_handle_closer,
00502        sqlite2_handle_preparer,
00503        sqlite2_handle_doer,
00504        sqlite2_handle_quoter,
00505        sqlite2_handle_begin,
00506        sqlite2_handle_commit,
00507        sqlite2_handle_rollback,
00508        pdo_sqlite2_set_attr,
00509        pdo_sqlite2_last_insert_id,
00510        pdo_sqlite2_fetch_error_func,
00511        pdo_sqlite2_get_attribute,
00512        NULL,  /* check_liveness: not needed */
00513        get_driver_methods
00514 };
00515 
00516 static char *make_filename_safe(const char *filename TSRMLS_DC)
00517 {
00518        if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
00519               char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
00520 
00521               if (!fullpath) {
00522                      return NULL;
00523               }
00524 
00525               if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
00526                      efree(fullpath);
00527                      return NULL;
00528               }
00529 
00530               if (php_check_open_basedir(fullpath TSRMLS_CC)) {
00531                      efree(fullpath);
00532                      return NULL;
00533               }
00534               return fullpath;
00535        }
00536        return estrdup(filename);
00537 }
00538 
00539 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
00540               const char *arg5, const char *arg6)
00541 {
00542        char *filename;
00543        switch (access_type) {
00544               case SQLITE_COPY: {
00545                      TSRMLS_FETCH();
00546                      filename = make_filename_safe(arg4 TSRMLS_CC);
00547                      if (!filename) {
00548                             return SQLITE_DENY;
00549                      }
00550                      efree(filename);
00551                      return SQLITE_OK;
00552               }
00553 
00554               case SQLITE_ATTACH: {
00555                      TSRMLS_FETCH();
00556                      filename = make_filename_safe(arg3 TSRMLS_CC);
00557                      if (!filename) {
00558                             return SQLITE_DENY;
00559                      }
00560                      efree(filename);
00561                      return SQLITE_OK;
00562               }
00563 
00564               default:
00565                      /* access allowed */
00566                      return SQLITE_OK;
00567        }
00568 }
00569 
00570 static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
00571 {
00572        pdo_sqlite2_db_handle *H;
00573        int ret = 0;
00574        long timeout = 60;
00575        char *filename;
00576        char *errmsg = NULL;
00577 
00578        H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
00579 
00580        H->einfo.errcode = 0;
00581        H->einfo.errmsg = NULL;
00582        dbh->driver_data = H;
00583 
00584        filename = make_filename_safe(dbh->data_source TSRMLS_CC);
00585 
00586        if (!filename) {
00587               zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
00588                             "safe_mode/open_basedir prohibits opening %s",
00589                             dbh->data_source);
00590               goto cleanup;
00591        }
00592 
00593        H->db = sqlite_open(filename, 0666, &errmsg);
00594        efree(filename);
00595 
00596        if (!H->db) {
00597               H->einfo.errcode = SQLITE_ERROR;
00598               pdo_sqlite2_error(errmsg, dbh);
00599               goto cleanup;
00600        }
00601 
00602        sqlite_set_authorizer(H->db, authorizer, NULL);
00603 
00604        if (driver_options) {
00605               timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
00606        }
00607        sqlite_busy_timeout(H->db, timeout * 1000);
00608 
00609        dbh->alloc_own_columns = 1;
00610        dbh->max_escaped_char_length = 2;
00611 
00612        ret = 1;
00613 
00614 cleanup:
00615        dbh->methods = &sqlite2_methods;
00616 
00617        return ret;
00618 }
00619 /* }}} */
00620 
00621 pdo_driver_t pdo_sqlite2_driver = {
00622        PDO_DRIVER_HEADER(sqlite2),
00623        pdo_sqlite2_handle_factory
00624 };
00625 
00626 
00627 
00628 #endif
00629 
00630 
00631 /*
00632  * Local variables:
00633  * tab-width: 4
00634  * c-basic-offset: 4
00635  * End:
00636  * vim600: noet sw=4 ts=4 fdm=marker
00637  * vim<600: noet sw=4 ts=4
00638  */