From f4777d14e34db9a1c85f00fde73d0e92da1eca9a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 3 Jun 2004 23:18:36 +0000 Subject: [PATCH] Let DB handle type coercion instead of PHP --- ext/interbase/php_ibase_udf.c | 87 +++++++++++++++-------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/ext/interbase/php_ibase_udf.c b/ext/interbase/php_ibase_udf.c index b71bd1b3f50d3..86fff543a7341 100644 --- a/ext/interbase/php_ibase_udf.c +++ b/ext/interbase/php_ibase_udf.c @@ -19,10 +19,10 @@ /* $Id$ */ /** -* This UDF library adds the ability to call PHP functions from your SQL -* statement. You will have to declare a different external function for +* This UDF library adds the ability to call PHP functions from SQL +* statements. You will have to declare a different external function for * each number of parameters you require. Currently, only string arguments -* are supported as both input arguments as well as the result. +* are supported as input, the output can be numeric as well. * * Declare the functions like this: * @@ -32,16 +32,17 @@ * ENTRY_POINT 'udf_call_php1' MODULE_NAME 'php_ibase_udf' * * DECLARE EXTERNAL FUNCTION CALL_PHP2 -* CSTRING(xx), BY DESCRIPTOR, CSTRING(xx),CSTRING(xx) +* CSTRING(xx), BY DESCRIPTOR, CSTRING(xx), CSTRING(xx) * RETURNS PARAMETER 2 * ENTRY_POINT 'udf_call_php2' MODULE_NAME 'php_ibase_udf' * * ... and so on. * -* The first input parameter contains the function you want to call. The second -* argument is the result, and should not be passed as an argument. Subsequent -* arguments are passed to the called function. The lengths of the input strings can -* have any value >1. The type and length of the output depends on its declaration. +* The first input parameter contains the function you want to call. The +* second argument is the result, and should not be passed as an argument. +* Subsequent arguments are passed to the called function. The lengths of +* the input strings can have any value >1. The type and length of the +* output depends on its declaration. * * The declared functions can be called from SQL like: * @@ -52,9 +53,11 @@ * NOT SUPPORTED. * * Compile with: -* gcc -shared `php-config --includes` `php-config --ldflags` -o php_ibase_udf.so php_ibase_udf.c +* gcc -shared `php-config --includes` `php-config --ldflags` \ +* -o php_ibase_udf.so php_ibase_udf.c * -* and copy the resulting file to the folder where your database expects to find it. +* and copy the resulting file to the folder where your database expects +* to find its UDFs. */ #include "zend.h" @@ -62,6 +65,7 @@ #include "php.h" #include "stdarg.h" +#include "ib_util.h" #include "ibase.h" #ifdef ZTS @@ -70,7 +74,7 @@ #define min(a,b) ((a)<(b)?(a):(b)) -static PARAMDSC *call_php(char *name, PARAMDSC *r, int argc, ...) +static void call_php(char *name, PARAMDSC *r, int argc, ...) { zval callback, args[4], *argp[4], return_value; va_list va; @@ -104,46 +108,31 @@ static PARAMDSC *call_php(char *name, PARAMDSC *r, int argc, ...) break; } - switch (r->dsc_dtype) { + switch (Z_TYPE(return_value)) { - case dtype_cstring: - convert_to_string(&return_value); - memcpy(r->dsc_address, Z_STRVAL(return_value), min(r->dsc_length,Z_STRLEN(return_value))); - r->dsc_length = min(r->dsc_length,Z_STRLEN(return_value)); - r->dsc_address[r->dsc_length] = 0; + case IS_LONG: + r->dsc_dtype = dtype_long; + *(long*)r->dsc_address = Z_LVAL(return_value); + r->dsc_length = sizeof(long); break; - case dtype_text: - convert_to_string(&return_value); - memcpy(r->dsc_address, Z_STRVAL(return_value), min(r->dsc_length,Z_STRLEN(return_value))); - r->dsc_length = min(r->dsc_length,Z_STRLEN(return_value)); + case IS_DOUBLE: + r->dsc_dtype = dtype_double; + *(double*)r->dsc_address = Z_DVAL(return_value); + r->dsc_length = sizeof(double); break; - case dtype_varying: + default: convert_to_string(&return_value); - memcpy(res->vary_string, Z_STRVAL(return_value), min(r->dsc_length-2,Z_STRLEN(return_value))); - res->vary_length = min(r->dsc_length-2,Z_STRLEN(return_value)); - r->dsc_length = res->vary_length+2; - break; - - case dtype_short: - convert_to_long(&return_value); - *(short*)r->dsc_address = Z_LVAL(return_value); - break; - case dtype_long: - convert_to_long(&return_value); - *(ISC_LONG*)r->dsc_address = Z_LVAL(return_value); - break; - - case dtype_int64: - convert_to_long(&return_value); - *(ISC_INT64*)r->dsc_address = Z_LVAL(return_value); + case IS_STRING: + r->dsc_dtype = dtype_varying; + memcpy(res->vary_string, Z_STRVAL(return_value), + (res->vary_length = min(r->dsc_length-2,Z_STRLEN(return_value)))); + r->dsc_length = res->vary_length+2; break; - } - zval_dtor(&return_value); return; @@ -157,23 +146,23 @@ static PARAMDSC *call_php(char *name, PARAMDSC *r, int argc, ...) php_error_docref(NULL, E_WARNING, "Error calling function '%s' from database", name); } -PARAMDSC *udf_call_php1(char *name, PARAMDSC *r, char *arg1) +void udf_call_php1(char *name, PARAMDSC *r, char *arg1) { - return call_php(name, r, 1, arg1); + call_php(name, r, 1, arg1); } -PARAMDSC *udf_call_php2(char *name, PARAMDSC *r, char *arg1, char *arg2) +void udf_call_php2(char *name, PARAMDSC *r, char *arg1, char *arg2) { - return call_php(name, r, 2, arg1, arg2); + call_php(name, r, 2, arg1, arg2); } -PARAMDSC *udf_call_php3(char *name, PARAMDSC *r, char *arg1, char *arg2, char *arg3) +void udf_call_php3(char *name, PARAMDSC *r, char *arg1, char *arg2, char *arg3) { - return call_php(name, r, 3, arg1, arg2, arg3); + call_php(name, r, 3, arg1, arg2, arg3); } -PARAMDSC *udf_call_php4(char *name, PARAMDSC *r, char *arg1, char *arg2, char *arg3, char *arg4) +void udf_call_php4(char *name, PARAMDSC *r, char *arg1, char *arg2, char *arg3, char *arg4) { - return call_php(name, r, 4, arg1, arg2, arg3, arg4); + call_php(name, r, 4, arg1, arg2, arg3, arg4); }