wez             Fri Mar 11 18:57:04 2005 EDT

  Added files:                 
    /php-src/ext/sqlite pdo_sqlite2.c 

  Modified files:              
    /php-src/ext/sqlite config.m4 config.w32 sqlite.c 
  Log:
  Implement a PDO driver for sqlite 2
  
  
http://cvs.php.net/diff.php/php-src/ext/sqlite/config.m4?r1=1.31&r2=1.32&ty=u
Index: php-src/ext/sqlite/config.m4
diff -u php-src/ext/sqlite/config.m4:1.31 php-src/ext/sqlite/config.m4:1.32
--- php-src/ext/sqlite/config.m4:1.31   Tue Feb 15 16:09:42 2005
+++ php-src/ext/sqlite/config.m4        Fri Mar 11 18:57:01 2005
@@ -1,4 +1,4 @@
-dnl $Id: config.m4,v 1.31 2005/02/15 21:09:42 helly Exp $
+dnl $Id: config.m4,v 1.32 2005/03/11 23:57:01 wez Exp $
 dnl config.m4 for extension sqlite
 dnl vim:et:ts=2:sw=2
 
@@ -12,6 +12,23 @@
                           if not using bundled library.], yes)
 
 if test "$PHP_SQLITE" != "no"; then
+  AC_MSG_CHECKING([for PDO includes])
+  if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
+    pdo_inc_path=$abs_srcdir/ext
+  elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then
+    pdo_inc_path=$abs_srcdir/ext
+  elif test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then
+    pdo_inc_path=$prefix/include/php/ext
+  else
+    AC_MSG_WARN([Cannot find php_pdo_driver.h.])
+    pdo_inc_path=""
+  fi
+  if test -n "$pdo_inc_path"; then
+    AC_DEFINE([PHP_SQLITE2_HAVE_PDO], [1], [Have PDO])
+    pdo_inc_path="-I$pdo_inc_path"
+  fi
+  
+  AC_MSG_RESULT($pdo_inc_path)
 
   if test "$PHP_SQLITE" != "yes"; then
     SEARCH_PATH="/usr/local /usr"
@@ -49,11 +66,11 @@
     ])
  
     PHP_SUBST(SQLITE_SHARED_LIBADD)
-    PHP_NEW_EXTENSION(sqlite, sqlite.c sess_sqlite.c libsqlite/src/encode.c, 
$ext_shared)
+    PHP_NEW_EXTENSION(sqlite, sqlite.c sess_sqlite.c pdo_sqlite2.c 
libsqlite/src/encode.c, $ext_shared,,$pdo_inc_path)
   else
     # use bundled library
 
-    PHP_SQLITE_CFLAGS="[EMAIL PROTECTED]@/libsqlite/src"
+    PHP_SQLITE_CFLAGS="[EMAIL PROTECTED]@/libsqlite/src $pdo_inc_path"
 
     sources="libsqlite/src/opcodes.c
         libsqlite/src/parse.c libsqlite/src/encode.c \
@@ -69,8 +86,9 @@
         libsqlite/src/vdbeaux.c libsqlite/src/date.c \
         libsqlite/src/where.c libsqlite/src/trigger.c"
     
-    PHP_NEW_EXTENSION(sqlite, sqlite.c sess_sqlite.c $sources, 
$ext_shared,,$PHP_SQLITE_CFLAGS)
+    PHP_NEW_EXTENSION(sqlite, sqlite.c sess_sqlite.c pdo_sqlite2.c $sources, 
$ext_shared,,$PHP_SQLITE_CFLAGS)
     PHP_ADD_EXTENSION_DEP(sqlite, spl)
+    PHP_ADD_EXTENSION_DEP(sqlite, pdo)
     PHP_ADD_BUILD_DIR($ext_builddir/libsqlite)
     PHP_ADD_BUILD_DIR($ext_builddir/libsqlite/src)
     AC_CHECK_SIZEOF(char *,4)
http://cvs.php.net/diff.php/php-src/ext/sqlite/config.w32?r1=1.6&r2=1.7&ty=u
Index: php-src/ext/sqlite/config.w32
diff -u php-src/ext/sqlite/config.w32:1.6 php-src/ext/sqlite/config.w32:1.7
--- php-src/ext/sqlite/config.w32:1.6   Tue Feb 15 16:09:42 2005
+++ php-src/ext/sqlite/config.w32       Fri Mar 11 18:57:01 2005
@@ -1,4 +1,4 @@
-// $Id: config.w32,v 1.6 2005/02/15 21:09:42 helly Exp $
+// $Id: config.w32,v 1.7 2005/03/11 23:57:01 wez Exp $
 // vim:ft=javascript
 
 ARG_WITH("sqlite", "SQLite support", "yes");
@@ -13,7 +13,7 @@
        FSO.CopyFile(configure_module_dirname + 
"\\libsqlite\\src\\sqlite_config.w32.h",
                configure_module_dirname + "\\libsqlite\\src\\config.h");
        
-       EXTENSION("sqlite", "sqlite.c sess_sqlite.c", null,
+       EXTENSION("sqlite", "sqlite.c sess_sqlite.c pdo_sqlite2.c", null,
                "/D PHP_SQLITE_EXPORTS /I " + configure_module_dirname + 
"/libsqlite/src");
                
        
http://cvs.php.net/diff.php/php-src/ext/sqlite/sqlite.c?r1=1.157&r2=1.158&ty=u
Index: php-src/ext/sqlite/sqlite.c
diff -u php-src/ext/sqlite/sqlite.c:1.157 php-src/ext/sqlite/sqlite.c:1.158
--- php-src/ext/sqlite/sqlite.c:1.157   Tue Feb 15 16:09:42 2005
+++ php-src/ext/sqlite/sqlite.c Fri Mar 11 18:57:01 2005
@@ -17,7 +17,7 @@
    |          Marcus Boerger <[EMAIL PROTECTED]>                              |
    +----------------------------------------------------------------------+
 
-   $Id: sqlite.c,v 1.157 2005/02/15 21:09:42 helly Exp $ 
+   $Id: sqlite.c,v 1.158 2005/03/11 23:57:01 wez Exp $ 
 */
 
 #ifdef HAVE_CONFIG_H
@@ -49,6 +49,12 @@
 extern PHPAPI zend_class_entry *spl_ce_Countable;
 #endif
 
+#if PHP_SQLITE2_HAVE_PDO
+# include "pdo/php_pdo.h"
+# include "pdo/php_pdo_driver.h"
+extern pdo_driver_t pdo_sqlite2_driver;
+#endif
+
 #ifndef safe_emalloc
 # define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
 #endif
@@ -1068,12 +1074,23 @@
        REGISTER_LONG_CONSTANT("SQLITE_ROW",                    SQLITE_ROW, 
CONST_CS|CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SQLITE_DONE",                   SQLITE_DONE, 
CONST_CS|CONST_PERSISTENT);
 
+#if PHP_SQLITE2_HAVE_PDO
+    if (FAILURE == php_pdo_register_driver(&pdo_sqlite2_driver)) {
+        return FAILURE;
+    }
+#endif
+
        return SUCCESS;
 }
 
 PHP_MSHUTDOWN_FUNCTION(sqlite)
 {
        UNREGISTER_INI_ENTRIES();
+
+#if PHP_SQLITE2_HAVE_PDO
+    php_pdo_unregister_driver(&pdo_sqlite2_driver);
+#endif
+
        return SUCCESS;
 }
 
@@ -1086,7 +1103,7 @@
 {
        php_info_print_table_start();
        php_info_print_table_header(2, "SQLite support", "enabled");
-       php_info_print_table_row(2, "PECL Module version", 
PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c,v 1.157 2005/02/15 21:09:42 helly Exp 
$");
+       php_info_print_table_row(2, "PECL Module version", 
PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c,v 1.158 2005/03/11 23:57:01 wez Exp 
$");
        php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
        php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
        php_info_print_table_end();

http://cvs.php.net/co.php/php-src/ext/sqlite/pdo_sqlite2.c?r=1.1&p=1
Index: php-src/ext/sqlite/pdo_sqlite2.c
+++ php-src/ext/sqlite/pdo_sqlite2.c
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"

#if PHP_SQLITE2_HAVE_PDO
#include "sqlite.h"
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
#include "zend_exceptions.h"

#define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const 
unsigned char *)in, n, (unsigned char *)out)
#define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const 
unsigned char *)in, (unsigned char *)out)


typedef struct {
        const char *file;
        int line;
        unsigned int errcode;
        char *errmsg;
} pdo_sqlite2_error_info;

typedef struct {
        sqlite *db;
        pdo_sqlite2_error_info einfo;
} pdo_sqlite2_db_handle;

typedef struct {
        pdo_sqlite2_db_handle   *H;
        sqlite_vm *vm;
        const char **rowdata, **colnames;
  int ncols;
        unsigned pre_fetched:1;
        unsigned done:1;
        pdo_sqlite2_error_info einfo;
} pdo_sqlite2_stmt;

extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, 
const char *file, int line TSRMLS_DC);
#define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, 
__LINE__ TSRMLS_CC)
#define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, 
__FILE__, __LINE__ TSRMLS_CC)

extern struct pdo_stmt_methods sqlite2_stmt_methods;

static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
{
        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;

        if (S->vm) {
    char *errmsg = NULL;
                sqlite_finalize(S->vm, &errmsg);
    if (errmsg) {
      sqlite_freemem(errmsg);
    }
                S->vm = NULL;
        }
  if (S->einfo.errmsg) {
    pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
  }
        efree(S);
        return 1;
}

static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
{
        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  char *errmsg = NULL;
  const char *tail;

        if (stmt->executed && !S->done) {
                sqlite_finalize(S->vm, &errmsg);
    pdo_sqlite2_error_stmt(errmsg, stmt);
    errmsg = NULL;
    S->vm = NULL;
        }

  S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, 
&S->vm, &errmsg);
  if (S->einfo.errcode != SQLITE_OK) {
    fprintf(stderr, "SQL:%s\n", stmt->active_query_string);
    pdo_sqlite2_error_stmt(errmsg, stmt);
    return 0;
  }

        S->done = 0;
  S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
        switch (S->einfo.errcode) {
                case SQLITE_ROW:
                        S->pre_fetched = 1;
                        stmt->column_count = S->ncols;
                        return 1;

                case SQLITE_DONE:
                        stmt->column_count = S->ncols;
      stmt->row_count = sqlite_changes(S->H->db);
                        S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
      if (S->einfo.errcode != SQLITE_OK) {
        pdo_sqlite2_error_stmt(errmsg, stmt);
      }
                        S->done = 1;
                        return 1;

                case SQLITE_ERROR:
                case SQLITE_MISUSE:
                case SQLITE_BUSY:
                default:
                        pdo_sqlite2_error_stmt(errmsg, stmt);
                        return 0;
        }
}

static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct 
pdo_bound_param_data *param,
                enum pdo_param_event event_type TSRMLS_DC)
{
  return 1;
}

static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
{
        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
  char *errmsg = NULL;

        if (!S->vm) {
                return 0;       
        }
        if (S->pre_fetched) {
                S->pre_fetched = 0;
                return 1;
        }
        if (S->done) {
                return 0;
        }

        S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, 
&S->colnames);
        switch (S->einfo.errcode) {
                case SQLITE_ROW:
                        return 1;

                case SQLITE_DONE:
                        S->done = 1;
                        S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
                        if (S->einfo.errcode != SQLITE_OK) {
        pdo_sqlite2_error_stmt(errmsg, stmt);
        errmsg = NULL;
      }
                        return 0;

                default:
                        pdo_sqlite2_error_stmt(errmsg, stmt);
                        return 0;
        }
}

static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
{
        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;

        if(colno >= S->ncols) {
                /* error invalid column */
                pdo_sqlite2_error_stmt(NULL, stmt);
                return 0;
        }

        stmt->columns[colno].name = estrdup(S->colnames[colno]);
        stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
        stmt->columns[colno].maxlen = 0xffffffff;
        stmt->columns[colno].precision = 0;
  stmt->columns[colno].param_type = PDO_PARAM_STR;
        
        return 1;
}

static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, 
unsigned long *len, int *caller_frees TSRMLS_DC)
{
        pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
        if (!S->vm) {
                return 0;
        }
        if(colno >= S->ncols) {
                /* error invalid column */
                pdo_sqlite2_error_stmt(NULL, stmt);
                return 0;
        }
  if (S->rowdata[colno]) {
    if (S->rowdata[colno][0] == '\x01') {
      /* encoded */
      *caller_frees = 1;
      *ptr = emalloc(strlen(S->rowdata[colno]));
      *len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
      (*(char**)ptr)[*len] = '\0';
    } else {
      *ptr = (char*)S->rowdata[colno];
      *len = strlen(*ptr);
    }
  } else {
    *ptr = NULL;
    *len = 0;
  }
  return 1;
}

struct pdo_stmt_methods sqlite2_stmt_methods = {
        pdo_sqlite2_stmt_dtor,
        pdo_sqlite2_stmt_execute,
        pdo_sqlite2_stmt_fetch,
        pdo_sqlite2_stmt_describe,
        pdo_sqlite2_stmt_get_col,
        pdo_sqlite2_stmt_param_hook,
        NULL, /* set_attr */
        NULL, /* get_attr */
        NULL
};


int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const 
char *file, int line TSRMLS_DC) /* {{{ */
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
        pdo_sqlite2_error_info *einfo = &H->einfo;
  pdo_sqlite2_stmt *S;
  
  if (stmt) {
    S = stmt->driver_data;
    einfo = &S->einfo;
  }

        einfo->file = file;
        einfo->line = line;

  if (einfo->errmsg) {
    pefree(einfo->errmsg, dbh->is_persistent);
    einfo->errmsg = NULL;
  }

        if (einfo->errcode != SQLITE_OK) {
    if (errmsg) {
      einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
      sqlite_freemem(errmsg);
    } else {
      einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), 
dbh->is_persistent);
    }
        } else { /* no error */
                strcpy(*pdo_err, PDO_ERR_NONE);
                return 0;
        }
        switch (einfo->errcode) {
                case SQLITE_NOTFOUND:
                        strcpy(*pdo_err, "42S02");
                        break;  

                case SQLITE_INTERRUPT:
                        strcpy(*pdo_err, "01002");
                        break;

                case SQLITE_NOLFS:
                        strcpy(*pdo_err, "HYC00");
                        break;

                case SQLITE_TOOBIG:
                        strcpy(*pdo_err, "22001");
                        break;
        
                case SQLITE_CONSTRAINT:
                        strcpy(*pdo_err, "23000");
                        break;

                case SQLITE_ERROR:
                default:
                        strcpy(*pdo_err, "HY000");
                        break;
        }

        if (!dbh->methods) {
                zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, 
"SQLSTATE[%s] [%d] %s",
                                *pdo_err, einfo->errcode, einfo->errmsg);
        }
        
        return einfo->errcode;
}
/* }}} */

static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval 
*info TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        pdo_sqlite2_error_info *einfo = &H->einfo;
  pdo_sqlite2_stmt *S;
  
  if (stmt) {
    S = stmt->driver_data;
    einfo = &S->einfo;
  }

        if (einfo->errcode) {
                add_next_index_long(info, einfo->errcode);
                add_next_index_string(info, einfo->errmsg, 1);
        }

        return 1;
}

static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        
        if (H) {
                if (H->db) {
                        sqlite_close(H->db);
                        H->db = NULL;
                }
                pefree(H, dbh->is_persistent);
                dbh->driver_data = NULL;
        }
        return 0;
}
/* }}} */

static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long 
sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));

        S->H = H;
        stmt->driver_data = S;
        stmt->methods = &sqlite2_stmt_methods;
        stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;

        if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, 
PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
                H->einfo.errcode = SQLITE_ERROR;
                pdo_sqlite2_error(NULL, dbh);
                return 0;
        }

        return 1;
}

static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len 
TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        char *errmsg = NULL;

        if (sqlite_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
                pdo_sqlite2_error(errmsg, dbh);
                return -1;
        } else {
                return sqlite_changes(H->db);
        }
}

static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, 
unsigned int *len TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        char *id;
        
        id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
        *len = strlen(id);
        return id;
}

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)
{
  char *ret;

  if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', 
unquotedlen) != NULL)) {
    /* binary string */
    int len;
                ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
                ret[0] = '\'';
                ret[1] = '\x01';
                len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
    ret[len + 2] = '\'';
    ret[len + 3] = '\0';
    *quoted = ret;
    *quotedlen = len + 3;
    //fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted);
    return 1;
  } else if (unquotedlen) {
    ret = sqlite_mprintf("'%q'", unquoted);
    if (ret) {
      *quoted = estrdup(ret);
      *quotedlen = strlen(ret);
      sqlite_freemem(ret);
      return 1;
    }
    return 0;
  } else {
    *quoted = estrdup("''");
    *quotedlen = 2;
    return 1;
  }
}

static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        char *errmsg = NULL;

        if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
                pdo_sqlite2_error(errmsg, dbh);
                return 0;
        }
        return 1;
}

static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        char *errmsg = NULL;

        if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
                pdo_sqlite2_error(errmsg, dbh);
                return 0;
        }
        return 1;
}

static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
        char *errmsg = NULL;

        if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
                pdo_sqlite2_error(errmsg, dbh);
                return 0;
        }
        return 1;
}

static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval 
*return_value TSRMLS_DC)
{
        switch (attr) {
                case PDO_ATTR_CLIENT_VERSION:
                case PDO_ATTR_SERVER_VERSION:
                        ZVAL_STRING(return_value, (char *)sqlite_libversion(), 
1);
                        break;
                
                default:
                        return 0;       
        }

        return 1;
}

static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
{
        pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;

        switch (attr) {
                case PDO_ATTR_TIMEOUT:
                        convert_to_long(val);
                        sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
                        return 1;
        }
        return 0;
}

static PHP_FUNCTION(sqlite2_create_function)
{
        /* TODO: implement this stuff */
}

static function_entry dbh_methods[] = {
        PHP_FE(sqlite2_create_function, NULL)
        {NULL, NULL, NULL}
};

static function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
{
        switch (kind) {
                case PDO_DBH_DRIVER_METHOD_KIND_DBH:
                        return dbh_methods;

                default:
                        return NULL;
        }
}

static struct pdo_dbh_methods sqlite2_methods = {
        sqlite2_handle_closer,
        sqlite2_handle_preparer,
        sqlite2_handle_doer,
        sqlite2_handle_quoter,
        sqlite2_handle_begin,
        sqlite2_handle_commit,
        sqlite2_handle_rollback,
        pdo_sqlite2_set_attr,
        pdo_sqlite2_last_insert_id,
        pdo_sqlite2_fetch_error_func,
        pdo_sqlite2_get_attribute,
        NULL,   /* check_liveness: not needed */
        get_driver_methods
};

static char *make_filename_safe(const char *filename TSRMLS_DC)
{
        if (strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
                char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);

                if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
                        efree(fullpath);
                        return NULL;
                }

                if (php_check_open_basedir(fullpath TSRMLS_CC)) {
                        efree(fullpath);
                        return NULL;
                }
                return fullpath;
        }
        return estrdup(filename);
}

static int authorizer(void *autharg, int access_type, const char *arg3, const 
char *arg4,
                const char *arg5, const char *arg6)
{
        char *filename;
        switch (access_type) {
                case SQLITE_COPY: {
                        TSRMLS_FETCH();
                        filename = make_filename_safe(arg4 TSRMLS_CC);
                        if (!filename) {
                                return SQLITE_DENY;
                        }
                        efree(filename);
                        return SQLITE_OK;
                }

                case SQLITE_ATTACH: {
                        TSRMLS_FETCH();
                        filename = make_filename_safe(arg3 TSRMLS_CC);
                        if (!filename) {
                                return SQLITE_DENY;
                        }
                        efree(filename);
                        return SQLITE_OK;
                }

                default:
                        /* access allowed */
                        return SQLITE_OK;
        }
}

static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options 
TSRMLS_DC) /* {{{ */
{
        pdo_sqlite2_db_handle *H;
        int i, ret = 0;
        long timeout = 60;
        char *filename;
  char *errmsg = NULL;

        H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
        
        H->einfo.errcode = 0;
        H->einfo.errmsg = NULL;
        dbh->driver_data = H;

        filename = make_filename_safe(dbh->data_source TSRMLS_CC);

        if (!filename) {
                zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
                        "safe_mode/open_basedir prohibits opening %s",
                        dbh->data_source);
                goto cleanup;
        }

        H->db = sqlite_open(filename, 0666, &errmsg);
        efree(filename);

        if (!H->db) {
                pdo_sqlite2_error(errmsg, dbh);
                goto cleanup;
        }

        sqlite_set_authorizer(H->db, authorizer, NULL);

        if (driver_options) {
                timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 
timeout TSRMLS_CC);
        }
        sqlite_busy_timeout(H->db, timeout * 1000);

        dbh->alloc_own_columns = 1;
        dbh->max_escaped_char_length = 2;

        ret = 1;
        
cleanup:
        dbh->methods = &sqlite2_methods;
        
        return ret;
}
/* }}} */

pdo_driver_t pdo_sqlite2_driver = {
        PDO_DRIVER_HEADER(sqlite2),
        pdo_sqlite2_handle_factory
};



#endif


-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to