?? ct.c
字號:
cursor->status.declare = _CS_CURS_TYPE_SENT; /* Cursor is declared */ if (something_to_send == 0) { cmd->results_state = _CS_RES_END_RESULTS; } } else { tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor declare failed \n"); return CS_FAIL; } } if (cursor->status.cursor_row == _CS_CURS_TYPE_REQUESTED && cursor->status.declare == _CS_CURS_TYPE_SENT) { ret = tds_cursor_setrows(tds, cursor, &something_to_send); if (ret == CS_SUCCEED){ cursor->status.cursor_row = _CS_CURS_TYPE_SENT; /* Cursor rows set */ if (something_to_send == 0) { cmd->results_state = _CS_RES_END_RESULTS; } } else { tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor set rows failed\n"); return CS_FAIL; } } if (cursor->status.open == _CS_CURS_TYPE_REQUESTED && cursor->status.declare == _CS_CURS_TYPE_SENT) { ret = tds_cursor_open(tds, cursor, NULL, &something_to_send); if (ret == CS_SUCCEED){ cursor->status.open = _CS_CURS_TYPE_SENT; cmd->results_state = _CS_RES_INIT; } else { tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor open failed\n"); return CS_FAIL; } } if (something_to_send) { tdsdump_log(TDS_DBG_WARN, "ct_send(): sending cursor commands\n"); tds_flush_packet(tds); tds_set_state(tds, TDS_PENDING); something_to_send = 0; ct_set_command_state(cmd, _CS_COMMAND_SENT); return CS_SUCCEED; } if (cursor->status.close == _CS_CURS_TYPE_REQUESTED){ if (cursor->status.dealloc == TDS_CURSOR_STATE_REQUESTED) { /* FIXME what happen if tds_cursor_dealloc return TDS_FAIL ?? */ ret = tds_cursor_close(tds, cursor); tds_release_cursor(tds, cursor); cmd->cursor = cursor = NULL; } else { ret = tds_cursor_close(tds, cursor); cursor->status.close = _CS_CURS_TYPE_SENT; } } if (cursor && cursor->status.dealloc == _CS_CURS_TYPE_REQUESTED) { /* FIXME what happen if tds_cursor_dealloc return TDS_FAIL ?? */ ret = tds_cursor_dealloc(tds, cursor); cmd->cursor = NULL; tds_free_all_results(tds); } ct_set_command_state(cmd, _CS_COMMAND_SENT); return CS_SUCCEED; } if (cmd->command_type == CS_SEND_DATA_CMD) { tds_flush_packet(tds); tds_set_state(tds, TDS_PENDING); ct_set_command_state(cmd, _CS_COMMAND_SENT); } return CS_SUCCEED;}CS_RETCODEct_results(CS_COMMAND * cmd, CS_INT * result_type){ TDSSOCKET *tds; CS_CONTEXT *context; int tdsret; CS_INT res_type; CS_INT done_flags; tdsdump_log(TDS_DBG_FUNC, "ct_results()\n"); if (cmd->cancel_state == _CS_CANCEL_PENDING) { _ct_cancel_cleanup(cmd); return CS_CANCELED; } if (!cmd->con || !cmd->con->tds_socket) return CS_FAIL; cmd->bind_count = CS_UNUSED; context = cmd->con->ctx; tds = cmd->con->tds_socket; cmd->row_prefetched = 0; /* * depending on the current results state, we may * not need to call tds_process_tokens... */ switch (cmd->results_state) { case _CS_RES_CMD_SUCCEED: *result_type = CS_CMD_SUCCEED; cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; case _CS_RES_CMD_DONE: *result_type = CS_CMD_DONE; cmd->results_state = _CS_RES_INIT; return CS_SUCCEED; case _CS_RES_END_RESULTS: *result_type = CS_CMD_DONE; cmd->results_state = _CS_RES_INIT; return CS_END_RESULTS; case _CS_RES_DESCRIBE_RESULT: *result_type = CS_DESCRIBE_RESULT; cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; case _CS_RES_NONE: /* first time in after ct_send */ cmd->results_state = _CS_RES_INIT; break; default: break; } /* * see what "result" tokens we have. a "result" in ct-lib terms also * includes row data. Some result types always get reported back to * the calling program, others are only reported back if the relevant * config flag is set. */ for (;;) { tdsret = tds_process_tokens(tds, &res_type, &done_flags, TDS_TOKEN_RESULTS); tdsdump_log(TDS_DBG_FUNC, "ct_results() process_result_tokens returned %d (type %d) \n", tdsret, res_type); switch (tdsret) { case TDS_SUCCEED: cmd->curr_result_type = res_type; switch (res_type) { case CS_COMPUTEFMT_RESULT: case CS_ROWFMT_RESULT: /* * set results state to indicate that we * have a result set (empty for the moment) * If the CS_EXPOSE_FMTS property has been * set in ct_config(), we need to return an * appropraite format result, otherwise just * carry on and get the next token..... */ cmd->results_state = _CS_RES_RESULTSET_EMPTY; if (context->config.cs_expose_formats) { *result_type = res_type; return CS_SUCCEED; } break; case CS_ROW_RESULT: /* * we've hit a data row. pass back that fact * to the calling program. set results state * to show that the result set has rows... */ cmd->results_state = _CS_RES_RESULTSET_ROWS; if (cmd->command_type == CS_CUR_CMD) { *result_type = CS_CURSOR_RESULT; } else { *result_type = CS_ROW_RESULT; } return CS_SUCCEED; break; case CS_COMPUTE_RESULT: /* * we've hit a compute data row. We have to get hold of this * data now, as it's necessary to tie this data back to its * result format...the user may call ct_res_info() & friends * after getting back a compute "result". * * but first, if we've hit this compute row without having * hit a data row first, we need to return a CS_ROW_RESULT * before letting them have the compute row... */ if (cmd->results_state == _CS_RES_RESULTSET_EMPTY) { *result_type = CS_ROW_RESULT; tds->current_results = tds->res_info; cmd->results_state = _CS_RES_RESULTSET_ROWS; return CS_SUCCEED; } tdsret = tds_process_tokens(tds, &res_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE); /* set results state to show that the result set has rows... */ cmd->results_state = _CS_RES_RESULTSET_ROWS; *result_type = res_type; if (tdsret == TDS_SUCCEED && (res_type == TDS_ROW_RESULT || res_type == TDS_COMPUTE_RESULT)) { if (res_type == TDS_COMPUTE_RESULT) { cmd->row_prefetched = 1; return CS_SUCCEED; } else { /* this couldn't really happen, but... */ return CS_FAIL; } } else return CS_FAIL; break; case TDS_DONE_RESULT: /* * A done token signifies the end of a logical * command. There are three possibilities... * 1. Simple command with no result set, i.e. * update, delete, insert * 2. Command with result set but no rows * 3. Command with result set and rows * in these cases we need to: * 1. return CS_CMD_FAIL/SUCCED depending on * the status returned in done_flags * 2. "manufacture" a CS_ROW_RESULT return, * and set the results state to DONE * 3. return with CS_CMD_DONE and reset the * results_state */ tdsdump_log(TDS_DBG_FUNC, "ct_results() results state = %d\n",cmd->results_state); tdsdump_log(TDS_DBG_FUNC, "ct_results() command type = %d\n",cmd->command_type); tdsdump_log(TDS_DBG_FUNC, "ct_results() dynamic cmd = %d\n",cmd->dynamic_cmd); if ((cmd->command_type == CS_DYNAMIC_CMD) && (cmd->dynamic_cmd == CS_PREPARE || cmd->dynamic_cmd == CS_DEALLOC)) { *result_type = CS_CMD_SUCCEED; cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; } switch (cmd->results_state) { case _CS_RES_INIT: case _CS_RES_STATUS: if (done_flags & TDS_DONE_ERROR) *result_type = CS_CMD_FAIL; else *result_type = CS_CMD_SUCCEED; cmd->results_state = _CS_RES_CMD_DONE; break; case _CS_RES_RESULTSET_EMPTY: if (cmd->command_type == CS_CUR_CMD) { *result_type = CS_CURSOR_RESULT; cmd->results_state = _CS_RES_RESULTSET_ROWS; } else { *result_type = CS_ROW_RESULT; cmd->results_state = _CS_RES_CMD_DONE; } break; case _CS_RES_RESULTSET_ROWS: *result_type = CS_CMD_DONE; cmd->results_state = _CS_RES_INIT; break; } return CS_SUCCEED; break; case TDS_DONEINPROC_RESULT: /* * A doneinproc token may signify the end of a * logical command if the command had a result * set. Otherwise it is ignored.... */ switch (cmd->results_state) { case _CS_RES_INIT: /* command had no result set */ break; case _CS_RES_RESULTSET_EMPTY: if (cmd->command_type == CS_CUR_CMD) { *result_type = CS_CURSOR_RESULT; } else { *result_type = CS_ROW_RESULT; } cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; break; case _CS_RES_RESULTSET_ROWS: *result_type = CS_CMD_DONE; cmd->results_state = _CS_RES_INIT; return CS_SUCCEED; break; } break; case TDS_DONEPROC_RESULT: /* * A DONEPROC result means the end of a logical * command only if it was one of the commands * directly sent from ct_send, not as a result * of a nested stored procedure call. We know * if this is the case if a STATUS_RESULT was * received immediately prior to the DONE_PROC */ if (cmd->results_state == _CS_RES_STATUS) { if (done_flags & TDS_DONE_ERROR) *result_type = CS_CMD_FAIL; else *result_type = CS_CMD_SUCCEED; cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; } else { if (cmd->command_type == CS_DYNAMIC_CMD) { *result_type = CS_CMD_SUCCEED; cmd->results_state = _CS_RES_CMD_DONE; return CS_SUCCEED; } } break; case TDS_PARAM_RESULT: cmd->row_prefetched = 1; *result_type = res_type; return CS_SUCCEED; break; case TDS_STATUS_RESULT: _ct_process_return_status(tds); cmd->row_prefetched = 1; *result_type = res_type; cmd->results_state = _CS_RES_STATUS; return CS_SUCCEED; break; case TDS_DESCRIBE_RESULT: if (cmd->dynamic_cmd == CS_DESCRIBE_INPUT || cmd->dynamic_cmd == CS_DESCRIBE_OUTPUT) { *result_type = res_type; return CS_SUCCEED; } break; default: *result_type = res_type; return CS_SUCCEED; break; } break; case TDS_NO_MORE_RESULTS: /* some commands can be re-sent once completed */ /* so mark the command state as 'ready'... */ if (cmd->command_type == CS_LANG_CMD || cmd->command_type == CS_RPC_CMD || cmd->command_type == CS_CUR_CMD || cmd->command_type == CS_DYNAMIC_CMD) { ct_set_command_state(cmd, _CS_COMMAND_READY); } /* if we have just completed processing a dynamic deallocate */ /* get rid of our dynamic statement structure... */ if (cmd->command_type == CS_DYNAMIC_CMD && cmd->dynamic_cmd == CS_DEALLOC) { _ct_deallocate_dynamic(cmd->con, cmd->dyn); cmd->dyn = NULL; } return CS_END_RESULTS; break; case TDS_CANCELLED: cmd->cancel_state = _CS_CANCEL_NOCANCEL; return CS_CANCELED; break; case TDS_FAIL: default: return CS_FAIL; break; } /* switch (tdsret) */ } /* for (;;) */}CS_RETCODEct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, CS_INT * copied, CS_SMALLINT * indicator){ TDSCOLUMN *colinfo; TDSRESULTINFO *resinfo; TDSSOCKET *tds; CS_CONNECTION *con = cmd->con; CS_INT bind_count; tdsdump_log(TDS_DBG_FUNC, "ct_bind() datafmt count = %d column_number = %d\n", datafmt->count, item); if (!con || !con->tds_socket) return CS_FAIL; tds = con->tds_socket; resinfo = tds->current_results; /* check item value */ if (!resinfo || item <= 0 || item > resinfo->num_cols) return CS_FAIL; colinfo = resinfo->columns[item - 1]; /* check whether the request is for array binding and ensure that user */ /* supplies the same datafmt->count to the subsequent ct_bind calls */ bind_count = (datafmt->count == 0) ? 1 : datafmt->count; /* first bind for this result set */ if (cmd->bind_count == CS_UNUSED) { cmd->bind_count = bind_count; } else { /* all subsequent binds for this result set - the bind counts must be the same */ if (cmd->bind_count != bind_count) { _ctclient_msg(con, "ct_bind", 1, 1, 1, 137, "%d, %d", bind_count, cmd->bind_count); return CS_FAIL; } } /* bind the column_varaddr to the address of the buffer */ colinfo = resinfo->columns[item - 1]; colinfo->column_varaddr = (char *) buffer; colinfo->column_bindtype = datafmt->datatype; colinfo->column_bindfmt = datafmt->format; colinfo->column_bindlen = datafmt->maxlength; if (indicator) { colinfo->column_nullbind = indicator; } if (copied) { colinfo->column_lenbind = copied; } return CS_SUCCEED;}CS_RETCODEct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * rows_read){ TDS_INT ret_type; TDS_INT ret; TDS_INT marker; TDS_INT temp_count; TDSSOCKET *tds; tdsdump_log(TDS_DBG_FUNC, "ct_fetch()\n"); if (!cmd->con || !cmd->con->tds_socket) return CS_FAIL; if (cmd->command_state == _CS_COMMAND_IDLE) { _ctclient_msg(cmd->con, "ct_fetch", 1, 1, 1, 16843163, ""); return CS_FAIL; } if (cmd->cancel_state == _CS_CANCEL_PENDING) { _ct_cancel_cleanup(cmd); return CS_CANCELED; } tds = cmd->con->tds_socket;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -