summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Karajannis <kara@php.net>1999-08-08 16:26:26 +0000
committerAndreas Karajannis <kara@php.net>1999-08-08 16:26:26 +0000
commitdaa7982110159d22b1b38cc7cea2b25fb9b6697a (patch)
treeea9cec44fbf27640bc726e79ca318867b4cf73fd
parent78f8d04e6323b1d7715db60d56275dee4fc1e554 (diff)
downloadphp-git-daa7982110159d22b1b38cc7cea2b25fb9b6697a.tar.gz
First shot at odbc for PHP4
Problems with LONGs to be investigated
-rw-r--r--ext/odbc/config.m414
-rw-r--r--ext/odbc/odbc.c384
-rw-r--r--ext/odbc/php3_odbc.h130
3 files changed, 271 insertions, 257 deletions
diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4
index e1429cd8bf..bfe05ed052 100644
--- a/ext/odbc/config.m4
+++ b/ext/odbc/config.m4
@@ -62,9 +62,9 @@ AC_ARG_WITH(adabas,
if test "$withval" != "no"; then
ODBC_INCDIR=$withval/incl
ODBC_LIBDIR=$withval/lib
- ODBC_LFLAGS=-L$ADA_LIBDIR
- ODBC_INCLUDE=-I$ADA_INCDIR
- ODBC_LIBS="${ADA_LIBDIR}/odbclib.a -lsqlrte -lsqlptc"
+ ODBC_LFLAGS=-L$ODBC_LIBDIR
+ ODBC_INCLUDE=-I$ODBC_INCDIR
+ ODBC_LIBS="${ODBC_LIBDIR}/odbclib.a -lsqlrte -lsqlptc"
ODBC_TYPE=adabas
AC_DEFINE(HAVE_ADABAS)
AC_MSG_RESULT(yes)
@@ -182,8 +182,8 @@ AC_ARG_WITH(custom-odbc,
if test "$withval" != "no"; then
ODBC_INCDIR=$withval/include
ODBC_LIBDIR=$withval/lib
- ODBC_LFLAGS=-L$CODBC_LIBDIR
- ODBC_INCLUDE=-I$CODBC_INCDIR
+ ODBC_LFLAGS=-L$ODBC_LIBDIR
+ ODBC_INCLUDE=-I$ODBC_INCDIR
ODBC_LIBS=$CUSTOM_ODBC_LIBS
ODBC_TYPE=custom
AC_DEFINE(HAVE_CODBC)
@@ -208,8 +208,8 @@ AC_ARG_WITH(iodbc,
if test "$withval" != "no"; then
ODBC_INCDIR=$withval/include
ODBC_LIBDIR=$withval/lib
- ODBC_LFLAGS=-L$IODBC_LIBDIR
- ODBC_INCLUDE=-I$IODBC_INCDIR
+ ODBC_LFLAGS=-L$ODBC_LIBDIR
+ ODBC_INCLUDE=-I$ODBC_INCDIR
ODBC_LIBS=-liodbc
ODBC_TYPE=iodbc
AC_DEFINE(HAVE_IODBC)
diff --git a/ext/odbc/odbc.c b/ext/odbc/odbc.c
index fa39583bb7..10232551bb 100644
--- a/ext/odbc/odbc.c
+++ b/ext/odbc/odbc.c
@@ -20,32 +20,22 @@
/* $Id$ */
-/* This file is based on the Adabas D extension.
- * Adabas D will no longer be supported as separate module.
- */
-#include "php.h"
+#if COMPILE_DL
+#include "dl/phpdl.h"
+#endif
-#undef THREAD_SAFE
+#include "php.h"
+#include "php_globals.h"
+#include "ext/standard/php3_standard.h"
+# include "php3_odbc.h"
#if HAVE_UODBC
-# if !(WIN32|WINNT)
-# include "php_config.h"
-# include "build-defs.h"
-# endif
-
# include <fcntl.h>
-
-# include "dl/phpdl.h"
-# include "ext/standard/php3_standard.h"
-# include "php3_odbc.h"
# include "ext/standard/head.h"
# include "snprintf.h"
# include "php_ini.h"
-
-# ifndef ZS
-php_odbc_globals odbc_globals;
-# endif
+void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
function_entry odbc_functions[] = {
PHP_FE(odbc_setoption, NULL)
@@ -73,6 +63,8 @@ function_entry odbc_functions[] = {
PHP_FE(odbc_rollback, NULL)
PHP_FE(odbc_binmode, NULL)
PHP_FE(odbc_longreadlen, NULL)
+/* PHP_FE(odbc_bind_param, NULL)
+ PHP_FE(odbc_define, NULL)*/
PHP_FALIAS(odbc_do, odbc_exec, NULL)
{ NULL, NULL, NULL }
};
@@ -88,13 +80,18 @@ php3_module_entry odbc_module_entry = {
STANDARD_MODULE_PROPERTIES
};
+#ifdef ZTS
+int odbc_globals_id;
+#else
+ZEND_API php_odbc_globals odbc_globals;
+#endif
#if COMPILE_DL
DLEXPORT php3_module_entry *get_module() { return &odbc_module_entry; };
#endif
-static void _free_result(odbc_result *res)
+static void _free_odbc_result(odbc_result *res)
{
int i;
@@ -121,49 +118,26 @@ static void _free_result(odbc_result *res)
}
}
-static int _results_cleanup(list_entry *le)
-{
- ODBC_TLS_VARS;
-
- if (le->type == ODBCG(le_result)) {
- odbc_connection *conn = ((odbc_result *) le->ptr)->conn_ptr;
- if (!conn->open && ((odbc_result *) le->ptr)->stmt){
- SQLFreeStmt(((odbc_result *) le->ptr)->stmt,SQL_DROP);
-#if !HAVE_DB2
- ((odbc_result *) le->ptr)->stmt = NULL;
-#endif
- }
- }
- return 0;
-}
-static void _close_connection(odbc_connection *conn)
+static void _close_odbc_conn(odbc_connection *conn)
{
/* FIXME
* Closing a connection will fail if there are
- * pending transactions
+ * pending transactions. It is in the responsibility
+ * of the user to avoid this.
*/
- ODBC_TLS_VARS;
- conn->open = 0;
- zend_hash_apply(ODBCG(resource_list),
- (int (*)(void *))_results_cleanup);
- SQLDisconnect(conn->hdbc);
+ SQLDisconnect(conn->hdbc);
SQLFreeConnect(conn->hdbc);
efree(conn);
ODBCG(num_links)--;
}
-static void _close_pconnection(odbc_connection *conn)
+static void _close_odbc_pconn(odbc_connection *conn)
{
- ODBC_TLS_VARS;
-
conn->open = 0;
- zend_hash_apply(ODBCG(resource_plist),
- (int (*)(void *))_results_cleanup);
-
SQLDisconnect(conn->hdbc);
SQLFreeConnect(conn->hdbc);
free(conn);
@@ -175,9 +149,10 @@ static void _close_pconnection(odbc_connection *conn)
static PHP_INI_MH(odbc_param_int)
{
- long *p;
ODBC_TLS_VARS;
+ long *p;
+
p = (long *) (globals + (size_t)mh_arg1);
*p = atoi(new_value);
@@ -187,9 +162,10 @@ static PHP_INI_MH(odbc_param_int)
static PHP_INI_MH(odbc_param_str)
{
- char **p;
ODBC_TLS_VARS;
+ char **p;
+
p = (char **) (globals + (size_t)mh_arg1);
*p = new_value;
@@ -215,15 +191,14 @@ PHP_MINIT_FUNCTION(odbc)
HDBC foobar;
RETCODE rc;
#endif
- ODBC_TLS_VARS;
REGISTER_INI_ENTRIES();
SQLAllocEnv(&ODBCG(henv));
ODBCG(num_persistent) = 0;
- ODBCG(le_result) = register_list_destructors(_free_result, NULL);
- ODBCG(le_conn) = register_list_destructors(_close_connection, NULL);
- ODBCG(le_pconn) = register_list_destructors(NULL, _close_pconnection);
+ ODBCG(le_result) = register_list_destructors(_free_odbc_result, NULL);
+ ODBCG(le_conn) = register_list_destructors(_close_odbc_conn, NULL);
+ ODBCG(le_pconn) = register_list_destructors(NULL, _close_odbc_pconn);
#ifdef SQLANY_BUG
/* Make a dumb connection to avoid crash on SQLFreeEnv(),
@@ -245,20 +220,35 @@ PHP_MINIT_FUNCTION(odbc)
REGISTER_LONG_CONSTANT("ODBC_BINMODE_PASSTHRU", 0, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ODBC_BINMODE_RETURN", 1, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ODBC_BINMODE_CONVERT", 2, CONST_CS | CONST_PERSISTENT);
- /* Define Constants for different cursor options
+ /* Define Constants for options
these Constants are are defined in <sqlext.h>
*/
- REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_PERSISTENT | CONST_CS);
- REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC, CONST_PERSISTENT | CONST_CS);
- REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_PERSISTENT | CONST_CS);
- REGISTER_MAIN_LONG_CONSTANT("SQL_CUR_DEFAULT", SQL_CUR_DEFAULT, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_ODBC_CURSORS", SQL_ODBC_CURSORS, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC, CONST_PERSISTENT | CONST_CS);
+
+
+ REGISTER_LONG_CONSTANT("SQL_CONCURRENCY", SQL_CONCURRENCY, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CONCUR_LOCK", SQL_CONCUR_LOCK, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CONCUR_VALUES", SQL_CONCUR_VALUES, CONST_PERSISTENT | CONST_CS);
+
+ REGISTER_LONG_CONSTANT("SQL_CURSOR_TYPE", SQL_CURSOR_TYPE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQL_CURSOR_STATIC", SQL_CURSOR_STATIC, CONST_PERSISTENT | CONST_CS);
+
+ REGISTER_LONG_CONSTANT("SQL_KEYSET_SIZE", SQL_KEYSET_SIZE, CONST_PERSISTENT | CONST_CS);
+
return SUCCESS;
}
PHP_RINIT_FUNCTION(odbc)
{
- ODBC_TLS_VARS;
ODBCG(defConn) = -1;
ODBCG(num_links) = ODBCG(num_persistent);
@@ -268,7 +258,6 @@ PHP_RINIT_FUNCTION(odbc)
PHP_MSHUTDOWN_FUNCTION(odbc)
{
- ODBC_TLS_VARS;
SQLFreeEnv(ODBCG(henv));
@@ -278,7 +267,6 @@ PHP_MSHUTDOWN_FUNCTION(odbc)
PHP_MINFO_FUNCTION(odbc)
{
- ODBC_TLS_VARS;
php_printf("ODBC compiled with \"" ODBC_TYPE "\" library");
php_printf("<BR>");
@@ -291,8 +279,6 @@ PHP_MINFO_FUNCTION(odbc)
php_printf("max_persistent: %d<br>\n", ODBCG(max_persistent));
php_printf("max_links: %d<br>\n", ODBCG(max_links));
}
-
-
/*
* List management functions
@@ -308,7 +294,6 @@ odbc_result *odbc_get_result(HashTable *list, int ind)
{
odbc_result *res;
int type;
- ODBC_TLS_VARS;
res = (odbc_result*)php3_list_find(ind, &type);
if (!res || type != ODBCG(le_result)) {
@@ -322,7 +307,6 @@ void odbc_del_result(HashTable *list, int ind)
{
odbc_result *res;
int type;
- ODBC_TLS_VARS;
res = (odbc_result *)php3_list_find(ind, &type);
if (!res || type != ODBCG(le_result)) {
@@ -337,7 +321,6 @@ odbc_connection *odbc_get_conn(HashTable *list, int ind)
odbc_connection *conn = NULL;
int type;
HashTable *plist;
- ODBC_TLS_VARS;
plist = ODBCG(resource_plist);
@@ -377,26 +360,6 @@ void ODBC_SQL_ERROR(HDBC conn, HSTMT stmt, char *func)
}
}
-/* Main User Functions */
-/* {{{ proto odbc_close_all(void)
- Close all ODBC connections */
-PHP_FUNCTION(odbc_close_all)
-{
- void *ptr;
- int type;
- int i, nument = zend_hash_next_free_element(list);
- ODBC_TLS_VARS;
-
- for (i = 1; i < nument; i++) {
- ptr = php3_list_find(i, &type);
- if (ptr && (type == ODBCG(le_conn) ||
- type == ODBCG(le_pconn))) {
- php3_list_delete(i);
- }
- }
-}
-/* }}} */
-
void php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode)
{
int res_ind;
@@ -430,21 +393,6 @@ void php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode)
RETURN_TRUE
}
-/* {{{ proto odbc_binmode(int result_id, int mode)
- Handle binary column data */
-PHP_FUNCTION(odbc_binmode)
-{
- php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
-}
-/* }}} */
-
-/* {{{ proto odbc_longreadlen(int result_id, int length)
- Handle LONG columns */
-PHP_FUNCTION(odbc_longreadlen)
-{
- php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
-}
-/* }}} */
int odbc_bindcols(odbc_result *result)
{
@@ -505,6 +453,70 @@ int odbc_bindcols(odbc_result *result)
return 1;
}
+void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type)
+{
+ odbc_connection *curr_conn;
+ RETCODE rc;
+ pval *arg1;
+ ODBC_TLS_VARS;
+
+ if ( getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long(arg1);
+
+ if ((curr_conn = odbc_get_conn(list, arg1->value.lval)) == NULL){
+ RETURN_FALSE;
+ }
+
+ rc = SQLTransact(ODBCG(henv), curr_conn->hdbc, (UWORD)((type)?SQL_COMMIT:SQL_ROLLBACK));
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
+ ODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SQLTransact");
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+
+/* Main User Functions */
+/* {{{ proto odbc_close_all(void)
+ Close all ODBC connections */
+PHP_FUNCTION(odbc_close_all)
+{
+ void *ptr;
+ int type;
+ int i, nument = zend_hash_next_free_element(list);
+ ODBC_TLS_VARS;
+
+ for (i = 1; i < nument; i++) {
+ ptr = php3_list_find(i, &type);
+ if (ptr && (type == ODBCG(le_conn) ||
+ type == ODBCG(le_pconn))) {
+ php3_list_delete(i);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto odbc_binmode(int result_id, int mode)
+ Handle binary column data */
+PHP_FUNCTION(odbc_binmode)
+{
+ php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+/* }}} */
+
+/* {{{ proto odbc_longreadlen(int result_id, int length)
+ Handle LONG columns */
+PHP_FUNCTION(odbc_longreadlen)
+{
+ php3_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+/* }}} */
+
+
+
/* {{{ proto odbc_prepare(int connection_id, string query)
Prepares a statement for execution */
PHP_FUNCTION(odbc_prepare)
@@ -528,10 +540,6 @@ PHP_FUNCTION(odbc_prepare)
RETURN_FALSE;
}
-#if 0
- _php3_stripslashes(query,NULL);
-#endif
-
result = (odbc_result *)emalloc(sizeof(odbc_result));
if (result == NULL){
php_error(E_WARNING, "Out of memory");
@@ -583,14 +591,14 @@ PHP_FUNCTION(odbc_prepare)
Execute a prepared statement */
PHP_FUNCTION(odbc_execute)
{
- pval *arg1, *arg2, arr, *tmp;
+ pval *arg1, *arg2, **tmp;
typedef struct params_t {
SDWORD vallen;
int fp;
} params_t;
params_t *params = NULL;
char *filename;
- SWORD sqltype, scale, nullable;
+ SWORD sqltype, ctype, scale, nullable;
UDWORD precision;
odbc_result *result=NULL;
int res_ind, numArgs, i, ne;
@@ -604,8 +612,7 @@ PHP_FUNCTION(odbc_execute)
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
WRONG_PARAM_COUNT;
- arr = *arg2;
- if (arr.type != IS_ARRAY) {
+ if (arg2->type != IS_ARRAY) {
php_error(E_WARNING, "No array passed to odbc_execute()");
return;
}
@@ -618,49 +625,58 @@ PHP_FUNCTION(odbc_execute)
if ((result = odbc_get_result(list, res_ind)) == NULL){
RETURN_FALSE;
}
-
+
+ /* XXX check for already bound parameters*/
if (result->numparams > 0 && numArgs == 1) {
php_error(E_WARNING, "No parameters to SQL statement given");
RETURN_FALSE;
}
if (result->numparams > 0){
- if ((ne = zend_hash_num_elements(arr.value.ht)) < result->numparams){
+ if ((ne = zend_hash_num_elements(arg2->value.ht)) < result->numparams){
php_error(E_WARNING,"Not enough parameters (%d should be %d) given",
ne, result->numparams);
RETURN_FALSE;
}
- pval_copy_constructor(arg2);
- zend_hash_internal_pointer_reset(arr.value.ht);
+ /* if(pval_copy_constructor(arg2) == FAILURE){
+ RETURN_FALSE;
+ }
+ */
+ zend_hash_internal_pointer_reset(arg2->value.ht);
params = (params_t *)emalloc(sizeof(params_t) * result->numparams);
for (i = 1; i <= result->numparams; i++) {
- if (zend_hash_get_current_data(arr.value.ht, (void **) &tmp) == FAILURE) {
+ if (zend_hash_get_current_data(arg2->value.ht, (void **) &tmp) == FAILURE) {
php_error(E_WARNING,"Error getting parameter");
SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
efree(params);
RETURN_FALSE;
}
- convert_to_string(tmp);
- if (tmp->type != IS_STRING) {
+ convert_to_string(*tmp);
+ if ((*tmp)->type != IS_STRING) {
php_error(E_WARNING,"Error converting parameter");
SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
- zend_hash_destroy(arr.value.ht);
- efree(arr.value.ht);
+ //zend_hash_destroy(arg2->value.ht);
+ //efree(arr.value.ht);
efree(params);
RETURN_FALSE;
}
SQLDescribeParam(result->stmt, (UWORD)i, &sqltype, &precision,
&scale, &nullable);
- params[i-1].vallen = tmp->value.str.len;
+ params[i-1].vallen = (*tmp)->value.str.len;
params[i-1].fp = -1;
+ if(IS_SQL_BINARY(sqltype))
+ ctype = SQL_C_BINARY;
+ else
+ ctype = SQL_C_CHAR;
- if (tmp->value.str.val[0] == '\'') {
- filename = &tmp->value.str.val[1];
- filename[tmp->value.str.len - 2] = '\0';
+ if ((*tmp)->value.str.val[0] == '\'' &&
+ (*tmp)->value.str.val[(*tmp)->value.str.len - 2] == '\'') {
+ filename = &(*tmp)->value.str.val[1];
+ filename[(*tmp)->value.str.len - 2] = '\0';
if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
php_error(E_WARNING,"Can't open file %s", filename);
@@ -670,8 +686,9 @@ PHP_FUNCTION(odbc_execute)
close(params[i].fp);
}
}
- zend_hash_destroy(arr.value.ht);
+ /*zend_hash_destroy(arr.value.ht);
efree(arr.value.ht);
+ */
efree(params);
RETURN_FALSE;
}
@@ -679,25 +696,16 @@ PHP_FUNCTION(odbc_execute)
params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
- SQL_C_BINARY, sqltype, precision, scale,
+ ctype, sqltype, precision, scale,
(void *)params[i-1].fp, 0,
&params[i-1].vallen);
} else {
- /*if (IS_SQL_BINARY(sqltype)){
- php_error(E_WARNING,"No Filename for binary parameter");
- SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
- zend_hash_destroy(arr.value.ht);
- efree(arr.value.ht);
- efree(params);
- RETURN_FALSE;
- }
-*/
rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
- SQL_C_CHAR, sqltype, precision, scale,
- tmp->value.str.val, 0,
+ ctype, sqltype, precision, scale,
+ (*tmp)->value.str.val, 0,
&params[i-1].vallen);
}
- zend_hash_move_forward(arr.value.ht);
+ zend_hash_move_forward(arg2->value.ht);
}
}
/* Close cursor, needed for doing multiple selects */
@@ -733,20 +741,32 @@ PHP_FUNCTION(odbc_execute)
if (params[i].fp != -1)
close(params[i].fp);
}
+ /*
zend_hash_destroy(arr.value.ht);
efree(arr.value.ht);
+ */
efree(params);
}
if (rc == SQL_SUCCESS){
RETVAL_TRUE;
}
+
+ if (result->numcols == 0){
+ SQLNumResultCols(result->stmt, &(result->numcols));
+
+ if (result->numcols > 0){
+ if (!odbc_bindcols(result)){
+ efree(result);
+ RETVAL_FALSE;
+ }
+ } else {
+ result->values = NULL;
+ }
+ }
}
/* }}} */
-/* odbc_cursor simply returns a cursor name for the given stmt
- * Adabas automagically generates cursor names, other drivers may not
- */
/* {{{ proto odbc_cursor(int result_id)
Get cursor name */
PHP_FUNCTION(odbc_cursor)
@@ -814,12 +834,12 @@ PHP_FUNCTION(odbc_cursor)
}
/* }}} */
-/* {{{ proto odbc_exec(int connection_id, string query)
+/* {{{ proto odbc_exec(int connection_id, string query [, int flags])
Prepare and execute an SQL statement */
PHP_FUNCTION(odbc_exec)
{
- pval *arg1, *arg2;
- int conn;
+ pval *arg1, *arg2, *arg3;
+ int conn, numArgs;
char *query;
odbc_result *result=NULL;
odbc_connection *curr_conn=NULL;
@@ -828,9 +848,16 @@ PHP_FUNCTION(odbc_exec)
UDWORD scrollopts;
#endif
- if (getParameters(ht, 2, &arg1, &arg2) == FAILURE){
- WRONG_PARAM_COUNT;
+ numArgs = ARG_COUNT(ht);
+ if (numArgs > 2){
+ if (getParameters(ht, 3, &arg1,&arg2, &arg3) == FAILURE)
+ WRONG_PARAM_COUNT;
+ convert_to_long(arg3);
+ } else {
+ if (getParameters(ht, 2, &arg1, &arg2) == FAILURE)
+ WRONG_PARAM_COUNT;
}
+
convert_to_long(arg1);
convert_to_string(arg2);
conn = arg1->value.lval;
@@ -839,10 +866,6 @@ PHP_FUNCTION(odbc_exec)
if ((curr_conn = odbc_get_conn(list, conn)) == NULL){
RETURN_FALSE;
}
-
-#if 0
- _php3_stripslashes(query,NULL);
-#endif
result = (odbc_result *)emalloc(sizeof(odbc_result));
if (result == NULL){
@@ -852,7 +875,7 @@ PHP_FUNCTION(odbc_exec)
rc = SQLAllocStmt(curr_conn->hdbc, &(result->stmt));
if (rc == SQL_INVALID_HANDLE){
- php_error(E_WARNING, "SQLAllocStmt error 'Invalid Handle' in PHP3_ODBC_DO");
+ php_error(E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
efree(result);
RETURN_FALSE;
}
@@ -872,7 +895,7 @@ PHP_FUNCTION(odbc_exec)
/* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other
type if not possible.
*/
- if (SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC)
+ if(SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC)
== SQL_ERROR){
ODBC_SQL_ERROR(curr_conn->hdbc, result->stmt, " SQLSetStmtOption");
SQLFreeStmt(result->stmt, SQL_DROP);
@@ -1491,7 +1514,7 @@ PHP_FUNCTION(odbc_free_result)
Connect to a datasource */
PHP_FUNCTION(odbc_connect)
{
- php3_odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+ odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */
@@ -1499,7 +1522,7 @@ PHP_FUNCTION(odbc_connect)
Establish a persistant connection to a datasource */
PHP_FUNCTION(odbc_pconnect)
{
- php3_odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+ odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
/* }}} */
@@ -1516,7 +1539,7 @@ PHP_FUNCTION(odbc_pconnect)
* "globals" in this module should actualy be per-connection variables. I
* simply fixed things to get them working for now. Shane
*/
-void php3_odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
{
char *db = NULL;
char *uid = NULL;
@@ -1528,10 +1551,8 @@ void php3_odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
char *hashed_details;
int hashed_len, len, id, cur_opt;
int type;
- ODBC_TLS_VARS;
-
- ODBCG(resource_list) = list;
- ODBCG(resource_plist) = plist;
+ ODBCLS_FETCH();
+ PLS_FETCH();
/* Now an optional 4th parameter specifying the cursor type
* defaulting to the cursors default
@@ -1616,8 +1637,10 @@ void php3_odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
if (persistent) {
db_conn = (odbc_connection *)malloc(sizeof(odbc_connection));
+ db_conn->persistent = 1;
} else {
db_conn = (odbc_connection *)emalloc(sizeof(odbc_connection));
+ db_conn->persistent = 0;
}
SQLAllocConnect(ODBCG(henv), &db_conn->hdbc);
@@ -1632,7 +1655,7 @@ void php3_odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
rc = SQLDriverConnect(db_conn->hdbc, NULL, db, SQL_NTS,
dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen,
- SQL_DRIVER_COMPLETE);
+ SQL_DRIVER_NOPROMPT);
}
#else
if(cur_opt != SQL_CUR_DEFAULT){
@@ -2047,37 +2070,11 @@ PHP_FUNCTION(odbc_autocommit)
}
/* }}} */
-void PHP3_ODBC_TRANSACT(INTERNAL_FUNCTION_PARAMETERS, int type)
-{
- odbc_connection *curr_conn;
- RETCODE rc;
- pval *arg1;
- ODBC_TLS_VARS;
-
- if ( getParameters(ht, 1, &arg1) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
-
- convert_to_long(arg1);
-
- if ((curr_conn = odbc_get_conn(list, arg1->value.lval)) == NULL){
- RETURN_FALSE;
- }
-
- rc = SQLTransact(ODBCG(henv), curr_conn->hdbc, (UWORD)((type)?SQL_COMMIT:SQL_ROLLBACK));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
- ODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SQLTransact");
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
-}
-
/* {{{ proto odbc_commit(int connection_id)
Commit an ODBC transaction */
PHP_FUNCTION(odbc_commit)
{
- PHP3_ODBC_TRANSACT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+ odbc_transact(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
/* }}} */
@@ -2085,12 +2082,19 @@ PHP_FUNCTION(odbc_commit)
Rollback a transaction */
PHP_FUNCTION(odbc_rollback)
{
- PHP3_ODBC_TRANSACT(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+ odbc_transact(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */
-/* {{{ proto odbc_setoption(??)
- ?? */
+
+/* {{{ proto odbc_setoption(int conn_id|result_id, int which, int option, int value)
+ Sets connection or statement options */
+/* This one has to be used carefully. We can't allow to set connection options for
+ persistent connections. I think that SetStmtOption is of little use, since most
+ of those can only be specified for not already prepared/executed statements.
+ On the other hand, they can be made connection wide default through SetConnectOption
+ - but will be overidden by calls to SetStmtOption() in odbc_prepare/odbc_do
+*/
PHP_FUNCTION(odbc_setoption)
{
odbc_connection *curr_conn;
@@ -2112,6 +2116,10 @@ PHP_FUNCTION(odbc_setoption)
if ((curr_conn = odbc_get_conn(list, arg1->value.lval)) == NULL){
RETURN_FALSE;
}
+ if(curr_conn->persistent){
+ php_error(E_WARNING, "Can't set option for persistent connection");
+ RETURN_FALSE;
+ }
rc = SQLSetConnectOption(curr_conn->hdbc, (unsigned short)(arg3->value.lval), (arg4->value.lval));
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO){
ODBC_SQL_ERROR(curr_conn->hdbc, SQL_NULL_HSTMT, "SetConnectOption");
diff --git a/ext/odbc/php3_odbc.h b/ext/odbc/php3_odbc.h
index d3149e51b7..647f4de918 100644
--- a/ext/odbc/php3_odbc.h
+++ b/ext/odbc/php3_odbc.h
@@ -31,89 +31,95 @@
/* $Id$ */
#ifndef _PHP_ODBC_H
-# define _PHP_ODBC_H
+#define _PHP_ODBC_H
-# if HAVE_UODBC
+#if HAVE_UODBC
-# ifndef MSVC5
-# define FAR
-# endif
+#ifndef MSVC5
+#define FAR
+#endif
/* checking in the same order as in configure.in */
-# if HAVE_SOLID /* Solid Server */
+#if HAVE_SOLID /* Solid Server */
-# include <cli0core.h>
-# include <cli0ext1.h>
-# define HAVE_SQL_EXTENDED_FETCH 0
+#define ODBC_TYPE "Solid"
+#include <cli0core.h>
+#include <cli0ext1.h>
+#define HAVE_SQL_EXTENDED_FETCH 0
PHP_FUNCTION(solid_fetch_prev);
-# elif HAVE_EMPRESS /* Empress */
+#elif HAVE_EMPRESS /* Empress */
-# include <sql.h>
-# include <sqlext.h>
-# define HAVE_SQL_EXTENDED_FETCH 0
+#define ODBC_TYPE "Empress"
+#include <sql.h>
+#include <sqlext.h>
+#define HAVE_SQL_EXTENDED_FETCH 0
-# elif HAVE_ADABAS /* Adabas D */
+#elif HAVE_ADABAS /* Adabas D */
-# include <WINDOWS.H>
-# include <sql.h>
-# include <sqlext.h>
-# define HAVE_SQL_EXTENDED_FETCH 1
+#define ODBC_TYPE "Adabas D"
+#include <WINDOWS.H>
+#include <sql.h>
+#include <sqlext.h>
+#define HAVE_SQL_EXTENDED_FETCH 1
-# elif HAVE_IODBC /* iODBC library */
+#elif HAVE_IODBC /* iODBC library */
-# include <isql.h>
-# include <isqlext.h>
-# include <odbc_types.h>
-# include <odbc_funcs.h>
-# define HAVE_SQL_EXTENDED_FETCH 1
-# define SQL_FD_FETCH_ABSOLUTE 0x00000010L
-# define SQL_CURSOR_DYNAMIC 2UL
-# define SQL_NO_TOTAL (-4)
-# define SQL_SO_DYNAMIC 0x00000004L
-# define SQL_LEN_DATA_AT_EXEC_OFFSET (-100)
-# define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)
+#define ODBC_TYPE "iODBC"
+#include <isql.h>
+#include <isqlext.h>
+#define HAVE_SQL_EXTENDED_FETCH 1
+#define SQL_FD_FETCH_ABSOLUTE 0x00000010L
+#define SQL_CURSOR_DYNAMIC 2UL
+#define SQL_NO_TOTAL (-4)
+#define SQL_SO_DYNAMIC 0x00000004L
+#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100)
+#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)
-# elif HAVE_OPENLINK /* OpenLink ODBC drivers */
+#elif HAVE_OPENLINK /* OpenLink ODBC drivers */
-# include <iodbc.h>
-# include <isql.h>
-# include <isqlext.h>
-# include <udbcext.h>
-# define HAVE_SQL_EXTENDED_FETCH 1
+#define ODBC_TYPE "Openlink"
+#include <iodbc.h>
+#include <isql.h>
+#include <isqlext.h>
+#include <udbcext.h>
+#define HAVE_SQL_EXTENDED_FETCH 1
-# elif HAVE_VELOCIS /* Raima Velocis */
+#elif HAVE_VELOCIS /* Raima Velocis */
-# define UNIX
-# define HAVE_SQL_EXTENDED_FETCH 1
-# include <sql.h>
-# include <sqlext.h>
+#define ODBC_TYPE "Velocis"
+#define UNIX
+#define HAVE_SQL_EXTENDED_FETCH 1
+#include <sql.h>
+#include <sqlext.h>
-# elif HAVE_CODBC /* Custom ODBC */
+#elif HAVE_CODBC /* Custom ODBC */
-# define HAVE_SQL_EXTENDED_FETCH 1
-# include <odbc.h>
+#define ODBC_TYPE "Custom ODBC"
+#define HAVE_SQL_EXTENDED_FETCH 1
+#include <odbc.h>
-# elif HAVE_DB2 /* DB2 CLI */
+#elif HAVE_DB2 /* DB2 CLI */
-# define HAVE_SQL_EXTENDED_FETCH 1
-# include <sqlcli1.h>
-# ifdef DB268K
+#define ODBC_TYPE "DB2 CLI"
+#define HAVE_SQL_EXTENDED_FETCH 1
+#include <sqlcli1.h>
+#ifdef DB268K
/* Need to include ASLM for 68K applications */
-# include <LibraryManager.h>
-# endif
+#include <LibraryManager.h>
+#endif
-# else /* MS ODBC */
+#else /* MS ODBC */
-# define HAVE_SQL_EXTENDED_FETCH 1
-# include <WINDOWS.H>
-# include <sql.h>
-# include <sqlext.h>
-# endif
+#define HAVE_SQL_EXTENDED_FETCH 1
+#include <WINDOWS.H>
+#include <sql.h>
+#include <sqlext.h>
+#endif
extern php3_module_entry odbc_module_entry;
-# define odbc_module_ptr &odbc_module_entry
+#define odbc_module_ptr &odbc_module_entry
/* user functions */
@@ -129,7 +135,6 @@ PHP_FUNCTION(odbc_close_all);
PHP_FUNCTION(odbc_commit);
PHP_FUNCTION(odbc_connect);
PHP_FUNCTION(odbc_pconnect);
-void php3_odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int);
PHP_FUNCTION(odbc_cursor);
PHP_FUNCTION(odbc_exec);
PHP_FUNCTION(odbc_do);
@@ -147,9 +152,12 @@ PHP_FUNCTION(odbc_prepare);
PHP_FUNCTION(odbc_result);
PHP_FUNCTION(odbc_result_all);
PHP_FUNCTION(odbc_rollback);
-void php3_odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int);
PHP_FUNCTION(odbc_binmode);
PHP_FUNCTION(odbc_longreadlen);
+/*
+ * PHP_FUNCTION(odbc_bind_param);
+ * PHP_FUNCTION(odbc_define);
+*/
typedef struct odbc_connection {
#if HAVE_DB2
@@ -158,6 +166,7 @@ typedef struct odbc_connection {
HDBC hdbc;
#endif
int open;
+ int persistent;
} odbc_connection;
typedef struct odbc_result_value {
@@ -207,9 +216,6 @@ typedef struct {
HashTable *resource_plist;
} php_odbc_globals;
-# ifndef ZTS
-extern php_odbc_globals odbc_globals;
-# endif
int odbc_add_result(HashTable *list, odbc_result *result);
odbc_result *odbc_get_result(HashTable *list, int count);