wez             Thu Jun  9 22:50:38 2005 EDT

  Modified files:              
    /php-src/ext/pdo_sqlite     php_pdo_sqlite_int.h sqlite_driver.c 
  Log:
  work in progress on UDF.
  Something is hokey in HEAD, checking it in to try it on another box.
  
  
http://cvs.php.net/diff.php/php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h?r1=1.2&r2=1.3&ty=u
Index: php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h
diff -u php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h:1.2 
php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h:1.3
--- php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h:1.2     Sun Sep 26 16:46:35 2004
+++ php-src/ext/pdo_sqlite/php_pdo_sqlite_int.h Thu Jun  9 22:50:37 2005
@@ -2,7 +2,7 @@
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
-  | Copyright (c) 1997-2004 The PHP Group                                |
+  | Copyright (c) 1997-2005 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.0 of the PHP license,       |
   | that is bundled with this package in the file LICENSE, and is        |
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: php_pdo_sqlite_int.h,v 1.2 2004/09/26 20:46:35 wez Exp $ */
+/* $Id: php_pdo_sqlite_int.h,v 1.3 2005/06/10 02:50:37 wez Exp $ */
 
 #ifndef PHP_PDO_SQLITE_INT_H
 #define PHP_PDO_SQLITE_INT_H
@@ -30,9 +30,26 @@
        char *errmsg;
 } pdo_sqlite_error_info;
 
+struct pdo_sqlite_fci {
+       zend_fcall_info fci;
+       zend_fcall_info_cache fcc;
+};
+
+struct pdo_sqlite_func {
+       struct pdo_sqlite_func *next;
+
+       zval *func, *step, *fini;
+       int argc;
+       const char *funcname;
+       
+       /* accelerated callback references */
+       struct pdo_sqlite_fci afunc, astep, afini;
+};
+
 typedef struct {
        sqlite3 *db;
        pdo_sqlite_error_info einfo;
+       struct pdo_sqlite_func *funcs;
 } pdo_sqlite_db_handle;
 
 typedef struct {
http://cvs.php.net/diff.php/php-src/ext/pdo_sqlite/sqlite_driver.c?r1=1.15&r2=1.16&ty=u
Index: php-src/ext/pdo_sqlite/sqlite_driver.c
diff -u php-src/ext/pdo_sqlite/sqlite_driver.c:1.15 
php-src/ext/pdo_sqlite/sqlite_driver.c:1.16
--- php-src/ext/pdo_sqlite/sqlite_driver.c:1.15 Sat Feb 26 12:27:51 2005
+++ php-src/ext/pdo_sqlite/sqlite_driver.c      Thu Jun  9 22:50:37 2005
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: sqlite_driver.c,v 1.15 2005/02/26 17:27:51 wez Exp $ */
+/* $Id: sqlite_driver.c,v 1.16 2005/06/10 02:50:37 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -96,11 +96,44 @@
        return 1;
 }
 
+static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H TSRMLS_DC)
+{
+       struct pdo_sqlite_func *func;
+
+       while (H->funcs) {
+               func = H->funcs;
+               H->funcs = func->next;
+
+               if (H->db) {
+                       /* delete the function from the handle */
+                       sqlite3_create_function(H->db,
+                               func->funcname,
+                               func->argc,
+                               SQLITE_UTF8,
+                               func,
+                               NULL, NULL, NULL);
+               }
+
+               efree((char*)func->funcname);
+               if (func->func) {
+                       zval_ptr_dtor(&func->func);
+               }
+               if (func->step) {
+                       zval_ptr_dtor(&func->step);
+               }
+               if (func->fini) {
+                       zval_ptr_dtor(&func->fini);
+               }
+               efree(func);
+       }
+}
+
 static int sqlite_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
 {
        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
        
        if (H) {
+               pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
                if (H->db) {
                        sqlite3_close(H->db);
                        H->db = NULL;
@@ -245,18 +278,169 @@
        return 0;
 }
 
-static PHP_FUNCTION(sqlite_create_function)
+static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
+               int argc, sqlite3_value **argv, zval **retval TSRMLS_DC)
+{
+       zval ***zargs = NULL;
+       int i;
+       int ret;
+       
+       fc->fci.size = sizeof(fc->fci);
+       fc->fci.function_table = EG(function_table);
+       fc->fci.function_name = cb;
+       fc->fci.symbol_table = NULL;
+       fc->fci.object_pp = NULL;
+       fc->fci.retval_ptr_ptr = retval;
+       fc->fci.param_count = argc;
+       
+       /* build up the params */
+       if (argc) {
+               zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
+
+               for (i = 0; i < argc; i++) {
+                       zargs[i] = emalloc(sizeof(zval *));
+                       MAKE_STD_ZVAL(*zargs[i]);
+               
+                       /* get the value */
+                       switch (sqlite3_value_type(argv[i])) {
+                               case SQLITE_INTEGER:
+                                       ZVAL_LONG(*zargs[i], 
sqlite3_value_int(argv[i]));
+                                       break;
+
+                               case SQLITE_FLOAT:
+                                       ZVAL_DOUBLE(*zargs[i], 
sqlite3_value_double(argv[i]));
+                                       break;
+                                       
+                               case SQLITE_NULL:
+                                       ZVAL_NULL(*zargs[i]);
+                                       break;
+                                       
+                               case SQLITE_BLOB:
+                               case SQLITE3_TEXT:
+                               default:
+                                       ZVAL_STRINGL(*zargs[i], 
(char*)sqlite3_value_text(argv[i]),
+                                               sqlite3_value_bytes(argv[i]), 
1);
+                                       break;
+                       }
+               }
+       }
+
+
+       fc->fci.params = zargs;
+
+       if ((ret = zend_call_function(&fc->fci, &fc->fcc TSRMLS_CC)) == 
FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred 
while invoking the callback");
+       }
+
+       /* clean up the params */
+       if (argc) {
+               for (i = 0; i < argc; i++) {
+                       zval_ptr_dtor(zargs[i]);
+                       efree(zargs[i]);
+               }
+               efree(zargs);
+       }
+
+       return ret;
+}
+
+static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
+       sqlite3_value **argv)
 {
-       /* TODO: implement this stuff */
+       struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)context;
+       zval *retval = NULL;
+       TSRMLS_FETCH();
+
+       do_callback(&func->afunc, func->func, argc, argv, &retval TSRMLS_CC);
+}
+
+static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
+       sqlite3_value **argv)
+{
+       struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)context;
+       zval *retval = NULL;
+       TSRMLS_FETCH();
+
+       do_callback(&func->astep, func->step, argc, argv, &retval TSRMLS_CC);
+}
+
+static void php_sqlite3_func_final_callback(sqlite3_context *context)
+{
+       struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)context;
+       zval *retval = NULL;
+       TSRMLS_FETCH();
+
+       do_callback(&func->afini, func->fini, 0, NULL, &retval TSRMLS_CC);
 }
 
+/* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int 
argcount])
+   Registers a UDF with the sqlite db handle */
+static PHP_METHOD(SQLite, sqliteCreateFunction)
+{
+       struct pdo_sqlite_func *func;
+       zval *callback;
+       char *func_name;
+       int func_name_len;
+       long argc = -1;
+       char *cbname = NULL;
+       pdo_dbh_t *dbh;
+       pdo_sqlite_db_handle *H;
+       int ret;
+
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l",
+                       &func_name, &func_name_len, &callback, &argc)) {
+               RETURN_FALSE;
+       }
+       
+       dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+       if (dbh->is_persistent) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "wont work on 
persistent handles");
+               RETURN_FALSE;
+       }
+
+       if (!zend_is_callable(callback, 0, &cbname)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is 
not callable", cbname);
+               efree(cbname);
+               RETURN_FALSE;
+       }
+       efree(cbname);
+       
+       H = (pdo_sqlite_db_handle *)dbh->driver_data;
+
+       func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
+
+       ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
+                       func, php_sqlite3_func_callback, NULL, NULL);
+
+       if (ret == SQLITE_OK) {
+               func->funcname = estrdup(func_name);
+               
+               MAKE_STD_ZVAL(func->func);
+               *(func->func) = *callback;
+               zval_copy_ctor(func->func);
+               
+               func->argc = argc;
+
+               func->next = H->funcs;
+               H->funcs = func;
+
+               RETURN_TRUE;
+       }
+
+       efree(func);
+       RETURN_FALSE;
+}
+/* }}} */
+
 static function_entry dbh_methods[] = {
-       PHP_FE(sqlite_create_function, NULL)
+       PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
        {NULL, NULL, NULL}
 };
 
 static function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
 {
+       printf("get_driver_methods\n");
        switch (kind) {
                case PDO_DBH_DRIVER_METHOD_KIND_DBH:
                        return dbh_methods;

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

Reply via email to