php_info_print_table_start();
php_info_print_table_row(2, "dbx support", "enabled");
php_info_print_table_row(2, "dbx version", "1.0.0");
- php_info_print_table_row(2, "supported databases", "MySQL\nODBC\nPostgreSQL\nMicrosoft SQL Server\nFrontBase\nOracle 8 (not really)\nSybase-CT");
+ php_info_print_table_row(2, "supported databases", "MySQL\nODBC\nPostgreSQL\nMicrosoft SQL Server\nFrontBase\nOracle 8 (oci8)\nSybase-CT");
php_info_print_table_end();
}
case DBX_PGSQL: return dbx_pgsql_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_MSSQL: return dbx_mssql_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_FBSQL: return dbx_fbsql_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
- case DBX_OCI8: zend_error(E_WARNING, "dbx_connect: OCI8 extension is still highly experimental!");
- return dbx_oci8_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_OCI8: return dbx_oci8_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_SYBASECT: return dbx_sybasect_connect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
zend_error(E_WARNING, "dbx_connect: not supported in this module");
case DBX_PGSQL: return dbx_pgsql_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_MSSQL: return dbx_mssql_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_FBSQL: return dbx_fbsql_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
- case DBX_OCI8: zend_error(E_WARNING, "dbx_pconnect: OCI8 extension is still highly experimental!");
- return dbx_oci8_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ case DBX_OCI8: return dbx_oci8_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_SYBASECT: return dbx_sybasect_pconnect(rv, host, db, username, password, INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
zend_error(E_WARNING, "dbx_pconnect: not supported in this module");
case DBX_PGSQL: return dbx_pgsql_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_MSSQL: return dbx_mssql_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
case DBX_FBSQL: return dbx_fbsql_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
- case DBX_OCI8: return dbx_oci8_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ /* case DBX_OCI8: return dbx_oci8_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU); */
case DBX_SYBASECT: return dbx_sybasect_error(rv, dbx_handle, INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
zend_error(E_WARNING, "dbx_error: not supported in this module");
int dbx_oci8_close(zval **rv, zval **dbx_handle, INTERNAL_FUNCTION_PARAMETERS)
{
/* returns 1 as long on success or 0 as long on failure */
+ /* actually, ocilogoff officially does nothing, so what should I return? */
+ /* I will just return NULL right now and change the test accordingly */
int number_of_arguments=1;
zval **arguments[1];
zval *returned_zval=NULL;
int dbx_oci8_query(zval **rv, zval **dbx_handle, zval **db_name, zval **sql_statement, INTERNAL_FUNCTION_PARAMETERS)
{
- /* returns 1 as long or a result identifier as resource on success or 0 as long on failure */
+ /* returns 1 as long or a result identifier as resource on success or 0 as long on failure */
int number_of_arguments=2;
zval **arguments[2];
zval *returned_zval=NULL;
zval *execute_zval=NULL;
+ zval *statementtype_zval=NULL;
arguments[0]=dbx_handle;
arguments[1]=sql_statement;
number_of_arguments=1;
arguments[0]=&returned_zval;
dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "OCIExecute", &execute_zval, number_of_arguments, arguments);
- /* OCIExecute returns a bool for success or failure???? */
- if (!execute_zval || Z_TYPE_P(execute_zval)!=IS_BOOL) {
+ /* OCIExecute returns a bool for success or failure */
+ if (!execute_zval || Z_TYPE_P(execute_zval)!=IS_BOOL || Z_BVAL_P(execute_zval)==FALSE) {
if (execute_zval) zval_ptr_dtor(&execute_zval);
zval_ptr_dtor(&returned_zval);
return 0;
}
- MOVE_RETURNED_TO_RV(rv, returned_zval);
+ number_of_arguments=1;
+ arguments[0]=&returned_zval;
+ dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "OCIStatementType", &statementtype_zval, number_of_arguments, arguments);
+ /* OCIStatementType returns a string. 'SELECT' means there are results */
+ if (!statementtype_zval || Z_TYPE_P(statementtype_zval)!=IS_STRING) {
+ if (statementtype_zval) zval_ptr_dtor(&statementtype_zval);
+ if (execute_zval) zval_ptr_dtor(&execute_zval);
+ zval_ptr_dtor(&returned_zval);
+ return 0;
+ }
+
+ if (!zend_binary_strcmp(Z_STRVAL_P(statementtype_zval), Z_STRLEN_P(statementtype_zval), "SELECT", sizeof("SELECT")-sizeof(""))) {
+ /* it is a select, so results are returned */
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ } else {
+ /* it is not a select, so just return success */
+ zval_ptr_dtor(&returned_zval);
+ MAKE_STD_ZVAL(returned_zval);
+ ZVAL_BOOL(returned_zval, TRUE);
+ MOVE_RETURNED_TO_RV(rv, returned_zval);
+ }
+ if (statementtype_zval) zval_ptr_dtor(&statementtype_zval);
+ if (execute_zval) zval_ptr_dtor(&execute_zval);
+
return 1;
}
zval *zval_returned_array=NULL;
zval *returned_zval=NULL;
+ MAKE_STD_ZVAL(zval_returned_array); /* no value needed, it will be overwritten anyway */
MAKE_STD_ZVAL(zval_resulttype);
- ZVAL_LONG(zval_resulttype, OCI_NUM | OCI_RETURN_NULLS); /* no ASSOC, dbx handles that part */
+ ZVAL_LONG(zval_resulttype, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS); /* no ASSOC, dbx handles that part */
arguments[0]=result_handle;
arguments[1]=&zval_returned_array;
arguments[2]=&zval_resulttype;
dbx_call_any_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "OCIFetchInto", &returned_zval, number_of_arguments, arguments);
- /* OCIFetchInto returns an integer, but the actual array is passed back in arg[1] */
- /* I'm not sure how this will work, Thies, so this is something that should be especially tested! */
- if (!returned_zval || Z_TYPE_P(returned_zval)!=IS_BOOL || Z_LVAL_P(returned_zval)==0) {
+ /* OCIFetchInto returns the number of columns as an integer on success and FALSE */
+ /* on failure. The actual array is passed back in arg[1] */
+ if (!returned_zval || Z_TYPE_P(returned_zval)!=IS_LONG || Z_LVAL_P(returned_zval)==0) {
if (returned_zval) zval_ptr_dtor(&returned_zval);
FREE_ZVAL(zval_resulttype);
+ FREE_ZVAL(zval_returned_array);
return 0;
}
FREE_ZVAL(zval_resulttype);
int dbx_oci8_error(zval **rv, zval **dbx_handle, INTERNAL_FUNCTION_PARAMETERS)
{
/* returns string */
+ /* OCIError needs a statement handle most of the times, and I can only provide */
+ /* a db-handle which is only needed some of the time. For now, I have disabled */
+ /* the dbx_error for the oci8 extension */
int number_of_arguments=1;
zval **arguments[1];
zval *returned_zval=NULL;