diff options
author | Wez Furlong <wez@php.net> | 2003-04-17 03:14:14 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2003-04-17 03:14:14 +0000 |
commit | c73e304dc25c44a45505f60450f788fac773ac61 (patch) | |
tree | 71e1551b70b4cf35904dcdc828f475f7387c5137 /ext/sqlite/sqlite.c | |
parent | 2cd55ce73bb5de9a842276c5acf0b619863ca756 (diff) | |
download | php-git-c73e304dc25c44a45505f60450f788fac773ac61.tar.gz |
Implement a php function so that the following SQL can be used:
SELECT php('md5', sql) from sqlite_master
The php function has takes the name of a php function to call as the first
parameter; each additional parameter is passed on to the function, much like
call_user_func().
You can call both built-in and script-defined functions in this way.
Diffstat (limited to 'ext/sqlite/sqlite.c')
-rw-r--r-- | ext/sqlite/sqlite.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c index bd4ec3f855..a6249c5dc8 100644 --- a/ext/sqlite/sqlite.c +++ b/ext/sqlite/sqlite.c @@ -98,6 +98,82 @@ static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor) efree(res); } +/* PHP Function interface */ + +static void php_sqlite_function_callback(sqlite_func *func, int argc, const char **argv) +{ + zval *retval = NULL; + zval ***zargs; + zval funcname; + int i, res; + + /* sanity check the args */ + if (argc == 0) { + sqlite_set_result_error(func, "not enough parameters", -1); + return; + } + + ZVAL_STRING(&funcname, (char*)argv[0], 0); + + if (!zend_is_callable(&funcname, 0, NULL)) { + sqlite_set_result_error(func, "function is not callable", -1); + return; + } + + if (argc > 1) { + zargs = (zval ***)emalloc((argc - 1) * sizeof(zval **)); + + for (i = 0; i < argc-1; i++) { + zargs[i] = emalloc(sizeof(zval *)); + MAKE_STD_ZVAL(*zargs[i]); + + ZVAL_STRING(*zargs[i], (char*)argv[i+1], 0); + } + } + + res = call_user_function_ex(EG(function_table), + NULL, + &funcname, + &retval, + argc-1, + zargs, + 0, NULL TSRMLS_CC); + + if (res == SUCCESS) { + if (retval == NULL) { + sqlite_set_result_string(func, NULL, 0); + } else { + switch (Z_TYPE_P(retval)) { + case IS_STRING: + sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + break; + case IS_LONG: + case IS_BOOL: + sqlite_set_result_int(func, Z_LVAL_P(retval)); + break; + case IS_DOUBLE: + sqlite_set_result_double(func, Z_DVAL_P(retval)); + break; + case IS_NULL: + default: + sqlite_set_result_string(func, NULL, 0); + } + } + } else { + sqlite_set_result_error(func, "call_user_function_ex failed", -1); + } + + if (retval) { + zval_ptr_dtor(&retval); + } + + if (zargs) { + for (i = 0; i < argc-1; i++) { + efree(zargs[i]); + } + efree(zargs); + } +} PHP_MINIT_FUNCTION(sqlite) { le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number); @@ -158,6 +234,9 @@ PHP_FUNCTION(sqlite_open) RETURN_FALSE; } + /* register the PHP functions */ + sqlite_create_function(db, "php", -1, php_sqlite_function_callback, 0); + ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_db); } |