summaryrefslogtreecommitdiff
path: root/ext/sqlite/sqlite.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-04-17 03:14:14 +0000
committerWez Furlong <wez@php.net>2003-04-17 03:14:14 +0000
commitc73e304dc25c44a45505f60450f788fac773ac61 (patch)
tree71e1551b70b4cf35904dcdc828f475f7387c5137 /ext/sqlite/sqlite.c
parent2cd55ce73bb5de9a842276c5acf0b619863ca756 (diff)
downloadphp-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.c79
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);
}