CVS update: php3/functions

From: Date: Wed, 04 Nov 1998 01:23:51 +0000
Subject: CVS update: php3/functions
Groups: php.dev 
Request: Send a blank email to php-dev+get-2180@lists.php.net to get a copy of this message
Date: Tuesday November 3, 1998 @ 20:23 Author: tommay Update of /repository/php3/functions In directory asf:/u2/tmp/cvs-serv5584 Modified Files: sybase-ct.c Log Message: php3_sybct_query(): better error checking, be sure to read all the results, split the result fetch out into its own function for readability. Index: php3/functions/sybase-ct.c diff -c php3/functions/sybase-ct.c:1.49 php3/functions/sybase-ct.c:1.50 *** php3/functions/sybase-ct.c:1.49 Tue Nov 3 14:31:09 1998 --- php3/functions/sybase-ct.c Tue Nov 3 20:23:50 1998 *************** *** 27,33 **** +----------------------------------------------------------------------+ */ ! /* $Id: sybase-ct.c,v 1.49 1998/11/03 19:31:09 tommay Exp $ */ #ifndef MSVC5 --- 27,33 ---- +----------------------------------------------------------------------+ */ ! /* $Id: sybase-ct.c,v 1.50 1998/11/04 01:23:50 tommay Exp $ */ #ifndef MSVC5 *************** *** 696,788 **** } ! void php3_sybct_query(INTERNAL_FUNCTION_PARAMETERS) { - pval *query,*sybct_link_index; - int id,type; - sybct_link *sybct_ptr; - sybct_result *result; int num_fields; ! CS_INT rows_read; ! int blocks_initialized=1; ! int i,j,retcode; ! CS_INT restype; ! CS_DATAFMT *datafmt; char **tmp_buffer; CS_INT *lengths; CS_SMALLINT *indicators; - int failure=0; unsigned char *numerics; CS_INT *types; ! ! switch(ARG_COUNT(ht)) { ! case 1: ! if (getParameters(ht, 1, &query)==FAILURE) { ! RETURN_FALSE; ! } ! id = php3_sybct_module.default_link; ! break; ! case 2: ! if (getParameters(ht, 2, &query, &sybct_link_index)==FAILURE) { ! RETURN_FALSE; ! } ! convert_to_long(sybct_link_index); ! id = sybct_link_index->value.lval; ! break; ! default: ! WRONG_PARAM_COUNT; ! break; ! } ! ! sybct_ptr = (sybct_link *) php3_list_find(id,&type); ! if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) { ! php3_error(E_WARNING,"%d is not a Sybase link index",id); ! RETURN_FALSE; ! } ! ! convert_to_string(query); ! ! if (ct_command(sybct_ptr->cmd, CS_LANG_CMD, query->value.str.val, CS_NULLTERM, CS_UNUSED)!=CS_SUCCEED) { ! RETURN_FALSE; ! } ! if (ct_send(sybct_ptr->cmd)!=CS_SUCCEED) { ! ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_CURRENT); ! RETURN_FALSE; ! } ! ! ct_results(sybct_ptr->cmd, &restype); ! switch ((int) restype) { ! case CS_CMD_FAIL: ! failure=1; ! case CS_CMD_SUCCEED: ! case CS_CMD_DONE: ! case CS_COMPUTEFMT_RESULT: ! case CS_ROWFMT_RESULT: ! case CS_DESCRIBE_RESULT: ! case CS_MSG_RESULT: ! while(ct_results(sybct_ptr->cmd,&restype)==CS_SUCCEED); ! if (failure) { ! RETURN_FALSE; ! } else { ! RETURN_TRUE; ! } ! break; ! } /* The following is more or less the equivalent of mysql_store_result(). * fetch all rows from the server into the row buffer, thus: * 1) Being able to fire up another query without explicitly reading all rows * 2) Having numrows accessible */ - - ct_res_info(sybct_ptr->cmd, CS_NUMDATA, &num_fields, CS_UNUSED, NULL); ! if (num_fields<=0) { ! RETURN_FALSE; } result = (sybct_result *) emalloc(sizeof(sybct_result)); result->data = (pval **) emalloc(sizeof(pval *)*SYBASE_ROWS_BLOCK); result->sybct_ptr = sybct_ptr; result->cur_field=result->cur_row=result->num_rows=0; result->num_fields = num_fields; --- 696,728 ---- } ! static sybct_result * _php3_sybct_fetch_result_set (sybct_link *sybct_ptr) { int num_fields; ! sybct_result *result; char **tmp_buffer; CS_INT *lengths; CS_SMALLINT *indicators; unsigned char *numerics; CS_INT *types; ! CS_DATAFMT *datafmt; ! int i,j,retcode; ! int blocks_initialized=1; /* The following is more or less the equivalent of mysql_store_result(). * fetch all rows from the server into the row buffer, thus: * 1) Being able to fire up another query without explicitly reading all rows * 2) Having numrows accessible */ ! if (ct_res_info(sybct_ptr->cmd, CS_NUMDATA, &num_fields, CS_UNUSED, NULL)!=CS_SUCCEED) { ! ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); ! return NULL; } result = (sybct_result *) emalloc(sizeof(sybct_result)); result->data = (pval **) emalloc(sizeof(pval *)*SYBASE_ROWS_BLOCK); + result->fields = NULL; result->sybct_ptr = sybct_ptr; result->cur_field=result->cur_row=result->num_rows=0; result->num_fields = num_fields; *************** *** 856,879 **** ct_bind(sybct_ptr->cmd,i+1,&datafmt[i],tmp_buffer[i],&lengths[i],&indicators[i]); } ! i=0; ! while ((retcode=ct_fetch(sybct_ptr->cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read))==CS_SUCCEED || retcode==CS_ROW_FAIL) { - result->num_rows += rows_read; - if (result->num_rows > blocks_initialized*SYBASE_ROWS_BLOCK) { - result->data = (pval **) erealloc(result->data,sizeof(pval *)*SYBASE_ROWS_BLOCK*(++blocks_initialized)); - } /* if (retcode==CS_ROW_FAIL) { php3_error(E_WARNING,"Sybase: Error reading row %d",result->num_rows); } */ ! if (rows_read<=0) { ! break; } ! result->data[result->num_rows-1] = (pval *) emalloc(sizeof(pval)*num_fields); for (j=0; j<num_fields; j++) { ! if (indicators[j] && (!tmp_buffer[j] || lengths[j]==0)) { /* null value */ var_reset(&result->data[i][j]); } else { result->data[i][j].value.str.len = lengths[j]-1; /* we don't need the NULL in the length */ --- 796,815 ---- ct_bind(sybct_ptr->cmd,i+1,&datafmt[i],tmp_buffer[i],&lengths[i],&indicators[i]); } ! while ((retcode=ct_fetch(sybct_ptr->cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,NULL))==CS_SUCCEED || retcode==CS_ROW_FAIL) { /* if (retcode==CS_ROW_FAIL) { php3_error(E_WARNING,"Sybase: Error reading row %d",result->num_rows); } */ ! i = result->num_rows++; ! if (result->num_rows > blocks_initialized*SYBASE_ROWS_BLOCK) { ! result->data = (pval **) erealloc(result->data,sizeof(pval *)*SYBASE_ROWS_BLOCK*(++blocks_initialized)); } ! result->data[i] = (pval *) emalloc(sizeof(pval)*num_fields); for (j=0; j<num_fields; j++) { ! if (indicators[j] == -1) { /* null value */ var_reset(&result->data[i][j]); } else { result->data[i][j].value.str.len = lengths[j]-1; /* we don't need the NULL in the length */ *************** *** 881,910 **** result->data[i][j].type = IS_STRING; } } - i++; } ! ! result->fields = (sybct_field *) emalloc(sizeof(sybct_field)*num_fields); ! j=0; ! for (i=0; i<num_fields; i++) { ! char computed_buf[16]; ! if (datafmt[i].namelen>0) { ! result->fields[i].name = estrndup(datafmt[i].name,datafmt[i].namelen); ! } else { ! if (j>0) { ! snprintf(computed_buf,16,"computed%d",j); } else { ! strcpy(computed_buf,"computed"); } ! result->fields[i].name = estrdup(computed_buf); ! j++; } - result->fields[i].column_source = empty_string; - result->fields[i].max_length = datafmt[i].maxlength-1; - result->fields[i].numeric = numerics[i]; - result->fields[i].type = types[i]; } efree(datafmt); efree(lengths); efree(indicators); --- 817,852 ---- result->data[i][j].type = IS_STRING; } } } ! ! if (retcode != CS_END_DATA) { ! _free_sybct_result(result); ! result = NULL; ! ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); ! } else { ! result->fields = (sybct_field *) emalloc(sizeof(sybct_field)*num_fields); ! j=0; ! for (i=0; i<num_fields; i++) { ! char computed_buf[16]; ! if (datafmt[i].namelen>0) { ! result->fields[i].name = estrndup(datafmt[i].name,datafmt[i].namelen); } else { ! if (j>0) { ! snprintf(computed_buf,16,"computed%d",j); ! } else { ! strcpy(computed_buf,"computed"); ! } ! result->fields[i].name = estrdup(computed_buf); ! j++; } ! result->fields[i].column_source = empty_string; ! result->fields[i].max_length = datafmt[i].maxlength-1; ! result->fields[i].numeric = numerics[i]; ! result->fields[i].type = types[i]; } } + efree(datafmt); efree(lengths); efree(indicators); *************** *** 915,941 **** } efree(tmp_buffer); ! while (ct_results(sybct_ptr->cmd, &restype)==CS_SUCCEED) { switch ((int) restype) { case CS_CMD_SUCCEED: case CS_CMD_DONE: break; ! case CS_CMD_FAIL: ! failure=1; break; case CS_STATUS_RESULT: ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_CURRENT); break; default: ! failure=1; break; } ! if (failure) { ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); } } return_value->value.lval = php3_list_insert(result,php3_sybct_module.le_result); --- 857,1016 ---- } efree(tmp_buffer); ! return result; ! } ! ! ! void php3_sybct_query(INTERNAL_FUNCTION_PARAMETERS) ! { ! pval *query,*sybct_link_index; ! int id,type; ! sybct_link *sybct_ptr; ! sybct_result *result; ! CS_INT restype; ! CS_RETCODE retcode; ! enum { ! Q_SUCCESS, ! Q_FAILURE, ! Q_RESULT, ! } status; ! ! switch(ARG_COUNT(ht)) { ! case 1: ! if (getParameters(ht, 1, &query)==FAILURE) { ! RETURN_FALSE; ! } ! id = php3_sybct_module.default_link; ! break; ! case 2: ! if (getParameters(ht, 2, &query, &sybct_link_index)==FAILURE) { ! RETURN_FALSE; ! } ! convert_to_long(sybct_link_index); ! id = sybct_link_index->value.lval; ! break; ! default: ! WRONG_PARAM_COUNT; ! break; ! } ! ! sybct_ptr = (sybct_link *) php3_list_find(id,&type); ! if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) { ! php3_error(E_WARNING,"%d is not a Sybase link index",id); ! RETURN_FALSE; ! } ! ! convert_to_string(query); ! ! if (ct_command(sybct_ptr->cmd, CS_LANG_CMD, query->value.str.val, CS_NULLTERM, CS_UNUSED)!=CS_SUCCEED) { ! RETURN_FALSE; ! } ! if (ct_send(sybct_ptr->cmd)!=CS_SUCCEED) { ! ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); ! RETURN_FALSE; ! } ! ! /* Use the first result set or succeed/fail status and discard the ! * others. Applications really shouldn't be making calls that ! * return multiple result sets, but if they do then we need to ! * properly read or cancel them or the connection will become ! * unusable. ! */ ! if (ct_results(sybct_ptr->cmd, &restype)!=CS_SUCCEED) { ! ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); ! RETURN_FALSE; ! } ! ! switch ((int) restype) { ! case CS_CMD_FAIL: ! default: ! status = Q_FAILURE; ! break; ! case CS_CMD_SUCCEED: ! case CS_CMD_DONE: ! case CS_COMPUTEFMT_RESULT: ! case CS_ROWFMT_RESULT: ! case CS_DESCRIBE_RESULT: ! case CS_MSG_RESULT: ! status = Q_SUCCESS; ! break; ! case CS_COMPUTE_RESULT: ! case CS_CURSOR_RESULT: ! case CS_PARAM_RESULT: ! case CS_ROW_RESULT: ! case CS_STATUS_RESULT: ! status = Q_RESULT; ! result = _php3_sybct_fetch_result_set(sybct_ptr); ! break; ! } ! ! /* The only restype we should get now is CS_CMD_DONE, possibly ! * followed by a CS_STATUS_RESULT/CS_CMD_SUCCEED/CS_CMD_DONE ! * sequence if the command was a stored procedure call. But we ! * still need to read and discard unexpected results. We might ! * want to return a failure in this case because the application ! * won't be getting all the results it asked for. ! */ ! while ((retcode = ct_results(sybct_ptr->cmd, &restype))==CS_SUCCEED) { switch ((int) restype) { case CS_CMD_SUCCEED: case CS_CMD_DONE: break; ! case CS_CMD_FAIL: ! status = Q_FAILURE; break; + case CS_COMPUTE_RESULT: + case CS_CURSOR_RESULT: + case CS_PARAM_RESULT: + case CS_ROW_RESULT: + /* Unexpected results, cancel them. */ case CS_STATUS_RESULT: ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_CURRENT); break; default: ! status = Q_FAILURE; break; } ! if (status == Q_FAILURE) { ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); } + } + + switch (retcode) { + case CS_END_RESULTS: + /* Normal. */ + break; + + case CS_FAIL: + /* Hopefully this either cleans up the connection, or the + * connection ends up marked dead so it will be reopened + * if it is persistent. We may want to do + * ct_close(CS_FORCE_CLOSE) if ct_cancel() fails; see the + * doc for ct_results()==CS_FAIL. + */ + ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL); + case CS_CANCELED: + default: + status = Q_FAILURE; + break; + } + + if (status == Q_SUCCESS) { + RETURN_TRUE; + } + + if (status == Q_FAILURE) { + if (result != NULL) { + _free_sybct_result(result); + } + RETURN_FALSE; + } + + if (result == NULL) { + RETURN_FALSE; } return_value->value.lval = php3_list_insert(result,php3_sybct_module.le_result); -- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net For help: php-dev-help@lists.php.net

« previous php.dev (#2180) next »