diff options
author | Wez Furlong <wez@php.net> | 2005-02-07 03:27:54 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2005-02-07 03:27:54 +0000 |
commit | ac018c38a882171d72137d282703772f5f13d557 (patch) | |
tree | 770932ecdbd381b291388d12a6d334ad2bee56ee /ext/pdo_odbc/odbc_stmt.c | |
parent | 149d9e8407d6f774be60928f726e91607de3ab06 (diff) | |
download | php-git-ac018c38a882171d72137d282703772f5f13d557.tar.gz |
This might allow piecewise sending of LOB data for input parameters.
Diffstat (limited to 'ext/pdo_odbc/odbc_stmt.c')
-rwxr-xr-x | ext/pdo_odbc/odbc_stmt.c | 130 |
1 files changed, 121 insertions, 9 deletions
diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 7de4ad51b1..d2e70fc72a 100755 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -69,6 +69,7 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) { RETCODE rc; pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data; + char *buf = NULL; if (stmt->executed) { SQLCancel(S->stmt); @@ -76,6 +77,58 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) rc = SQLExecute(S->stmt); + while (rc == SQL_NEED_DATA) { + int param_no; + struct pdo_bound_param_data *param; + + rc = SQLParamData(S->stmt, (SQLPOINTER*)¶m_no); + if (rc == SQL_NEED_DATA) { + php_stream *stm; + int len; + + if (FAILURE == zend_hash_index_find(stmt->bound_params, param_no, (void **)¶m)) { + /* shouldn't happen! */ + pdo_odbc_stmt_error("while looking up LOB for input"); +clean_out: + SQLCancel(S->stmt); + if (buf) { + efree(buf); + } + return 0; + } + + if (Z_TYPE_P(param->parameter) != IS_RESOURCE) { + /* they passed in a string */ + SQLPutData(S->stmt, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); + continue; + } + + php_stream_from_zval_no_verify(stm, ¶m->parameter); + if (!stm) { + /* shouldn't happen either */ + pdo_odbc_stmt_error("input LOB is no longer a stream"); + goto clean_out; + } + + /* now suck data from the stream and stick it into the database */ + if (buf == NULL) { + buf = emalloc(8192); + } + + do { + len = php_stream_read(stm, buf, 8192); + if (len == 0) { + break; + } + SQLPutData(S->stmt, buf, len); + } while (1); + } + } + + if (buf) { + efree(buf); + } + switch (rc) { case SQL_SUCCESS: break; @@ -111,16 +164,27 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p RETCODE rc; SWORD sqltype, ctype, scale, nullable; UDWORD precision; + pdo_odbc_param *P; /* we're only interested in parameters for prepared SQL right now */ if (param->is_param) { switch (event_type) { + case PDO_PARAM_EVT_FREE: + P = param->driver_data; + if (P) { + efree(P); + } + break; + case PDO_PARAM_EVT_ALLOC: - + { + /* figure out what we're doing */ switch (PDO_PARAM_TYPE(param->param_type)) { case PDO_PARAM_LOB: + break; + case PDO_PARAM_STMT: return 0; @@ -135,16 +199,33 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p } else { ctype = SQL_C_CHAR; } + + P = emalloc(sizeof(*P)); + param->driver_data = P; + + P->len = 0; /* is re-populated each EXEC_PRE */ + + if ((param->param_type & PDO_PARAM_INPUT_OUTPUT) == PDO_PARAM_INPUT_OUTPUT) { + P->paramtype = SQL_PARAM_INPUT_OUTPUT; + } else if (param->max_value_len <= 0) { + P->paramtype = SQL_PARAM_INPUT; + } else { + P->paramtype = SQL_PARAM_OUTPUT; + } + + if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->paramtype != SQL_PARAM_INPUT) { + pdo_odbc_stmt_error("Can bind a lob for output"); + return 0; + } + rc = SQLBindParameter(S->stmt, param->paramno+1, - ((param->param_type & PDO_PARAM_INPUT_OUTPUT) == PDO_PARAM_INPUT_OUTPUT) ? - SQL_PARAM_INPUT_OUTPUT : - param->max_value_len <= 0 ? - SQL_PARAM_INPUT : SQL_PARAM_OUTPUT, - ctype, sqltype, precision, scale, - Z_STRVAL_P(param->parameter), + P->paramtype, ctype, sqltype, precision, scale, + P->paramtype == SQL_PARAM_INPUT && + PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB ? + (SQLPOINTER)param : + Z_STRVAL_P(param->parameter), param->max_value_len <= 0 ? 0 : param->max_value_len, - /* XXX: this has the wrong type for DB2 (should be SQLINTEGER*) */ - &Z_STRLEN_P(param->parameter) + &P->len ); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { @@ -152,6 +233,37 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p } pdo_odbc_stmt_error("SQLBindParameter"); return 0; + } + + case PDO_PARAM_EVT_EXEC_PRE: + P = param->driver_data; + if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) { + if (Z_TYPE_P(param->parameter) == IS_RESOURCE) { + php_stream *stm; + php_stream_statbuf sb; + + php_stream_from_zval_no_verify(stm, ¶m->parameter); + + if (!stm) { + return 0; + } + + if (0 == php_stream_stat(stm, &sb)) { + P->len = SQL_LEN_DATA_AT_EXEC(sb.sb.st_size); + } else { + P->len = SQL_LEN_DATA_AT_EXEC(0); + } + } else { + convert_to_string(param->parameter); + P->len = Z_STRLEN_P(param->parameter); + } + } else { + P->len = Z_STRLEN_P(param->parameter); + } + return 1; + + case PDO_PARAM_EVT_EXEC_POST: + break; } } return 1; |