📄 query.c
字号:
tds_set_cur_cursor(TDSSOCKET *tds, TDSCURSOR *cursor){ ++cursor->ref_count; if (tds->cur_cursor) tds_release_cursor(tds, tds->cur_cursor); tds->cur_cursor = cursor;}inttds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *something_to_send){ CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_declare() cursor id = %d\n", cursor->cursor_id); if (IS_TDS7_PLUS(tds)) { cursor->srv_status |= TDS_CUR_ISTAT_DECLARED; cursor->srv_status |= TDS_CUR_ISTAT_CLOSED; cursor->srv_status |= TDS_CUR_ISTAT_RDONLY; } if (IS_TDS50(tds)) { if (!*something_to_send) { if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; tds->out_flag = TDS_NORMAL; } if (tds->state != TDS_QUERYING || tds->out_flag != TDS_NORMAL) return TDS_FAIL; tds_put_byte(tds, TDS_CURDECLARE_TOKEN); /* length of the data stream that follows */ tds_put_smallint(tds, (6 + strlen(cursor->cursor_name) + strlen(cursor->query))); tdsdump_log(TDS_DBG_ERROR, "size = %u\n", (unsigned int) (6u + strlen(cursor->cursor_name) + strlen(cursor->query))); tds_put_tinyint(tds, strlen(cursor->cursor_name)); tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name)); tds_put_byte(tds, 1); /* cursor option is read only=1, unused=0 */ tds_put_byte(tds, 0); /* status unused=0 */ /* TODO iconv */ tds_put_smallint(tds, strlen(cursor->query)); tds_put_n(tds, cursor->query, strlen(cursor->query)); tds_put_tinyint(tds, 0); /* number of columns = 0 , valid value applicable only for updatable cursor */ *something_to_send = 1; } return TDS_SUCCEED;}inttds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *something_to_send){ int converted_query_len; const char *converted_query; CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_open() cursor id = %d\n", cursor->cursor_id); if (!*something_to_send) { if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; } if (tds->state != TDS_QUERYING) return TDS_FAIL; tds_set_cur_cursor(tds, cursor); if (IS_TDS50(tds)) { tds->out_flag = TDS_NORMAL; tds_put_byte(tds, TDS_CUROPEN_TOKEN); tds_put_smallint(tds, 6 + strlen(cursor->cursor_name)); /* length of the data stream that follows */ /*tds_put_int(tds, cursor->cursor_id); *//* Only if cursor id is passed as zero, the cursor name need to be sent */ tds_put_int(tds, 0); tds_put_tinyint(tds, strlen(cursor->cursor_name)); tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name)); tds_put_byte(tds, 0); /* Cursor status : 0 for no arguments */ *something_to_send = 1; } if (IS_TDS7_PLUS(tds)) { size_t definition_len = 0; char *param_definition = NULL; int num_params = params ? params->num_cols : 0; /* cursor statement */ converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], cursor->query, strlen(cursor->query), &converted_query_len); if (!converted_query) { if (!*something_to_send) tds_set_state(tds, TDS_IDLE); return TDS_FAIL; } if (num_params) { param_definition = tds7_build_param_def_from_query(tds, converted_query, converted_query_len, params, &definition_len); if (!param_definition) { tds_convert_string_free(cursor->query, converted_query); if (!*something_to_send) tds_set_state(tds, TDS_IDLE); return TDS_FAIL; } } /* RPC call to sp_cursoropen */ tds->out_flag = TDS_RPC; START_QUERY; /* procedure identifier by number */ if (IS_TDS8_PLUS(tds)) { tds_put_smallint(tds, -1); tds_put_smallint(tds, TDS_SP_CURSOROPEN); } else { tds_put_smallint(tds, 13); TDS_PUT_N_AS_UCS2(tds, "sp_cursoropen"); } tds_put_smallint(tds, 0); /* flags */ /* return cursor handle (int) */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 1); /* output parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 0); if (definition_len) { tds7_put_query_params(tds, converted_query, converted_query_len); } else { tds_put_byte(tds, 0); tds_put_byte(tds, 0); tds_put_byte(tds, SYBNTEXT); /* must be Ntype */ tds_put_int(tds, converted_query_len); if (IS_TDS8_PLUS(tds)) tds_put_n(tds, tds->collation, 5); tds_put_int(tds, converted_query_len); tds_put_n(tds, converted_query, converted_query_len); } tds_convert_string_free(cursor->query, converted_query); /* type */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 1); /* output parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, definition_len ? cursor->type | 0x1000 : cursor->type); /* concurrency */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 1); /* output parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, cursor->concurrency); /* row count */ tds_put_byte(tds, 0); tds_put_byte(tds, 1); /* output parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, 0); if (definition_len) { int i; tds7_put_params_definition(tds, param_definition, definition_len); for (i = 0; i < num_params; i++) { TDSCOLUMN *param = params->columns[i]; /* TODO check error */ tds_put_data_info(tds, param, 0); tds_put_data(tds, param); } } free(param_definition); *something_to_send = 1; tds->internal_sp_called = TDS_SP_CURSOROPEN; tdsdump_log(TDS_DBG_ERROR, "tds_cursor_open (): RPC call set up \n"); } tdsdump_log(TDS_DBG_ERROR, "tds_cursor_open (): cursor open completed\n"); return TDS_SUCCEED;}inttds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, int *something_to_send){ CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_setrows() cursor id = %d\n", cursor->cursor_id); if (IS_TDS7_PLUS(tds)) { cursor->srv_status &= ~TDS_CUR_ISTAT_DECLARED; cursor->srv_status |= TDS_CUR_ISTAT_CLOSED; cursor->srv_status |= TDS_CUR_ISTAT_ROWCNT; } if (IS_TDS50(tds)) { if (!*something_to_send) { if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; tds->out_flag = TDS_NORMAL; } if (tds->state != TDS_QUERYING || tds->out_flag != TDS_NORMAL) return TDS_FAIL; tds_set_cur_cursor(tds, cursor); tds_put_byte(tds, TDS_CURINFO_TOKEN); tds_put_smallint(tds, 12 + strlen(cursor->cursor_name)); /* length of data stream that follows */ /* tds_put_int(tds, tds->cursor->cursor_id); */ /* Cursor id */ tds_put_int(tds, 0); tds_put_tinyint(tds, strlen(cursor->cursor_name)); tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name)); tds_put_byte(tds, 1); /* Command TDS_CUR_CMD_SETCURROWS */ tds_put_byte(tds, 0x00); /* Status - TDS_CUR_ISTAT_ROWCNT 0x0020 */ tds_put_byte(tds, 0x20); /* Status - TDS_CUR_ISTAT_ROWCNT 0x0020 */ tds_put_int(tds, cursor->cursor_rows); /* row count to set */ *something_to_send = 1; } return TDS_SUCCEED;}static voidtds7_put_cursor_fetch(TDSSOCKET * tds, TDS_INT cursor_id, TDS_TINYINT fetch_type, TDS_INT i_row, TDS_INT num_rows){ if (IS_TDS8_PLUS(tds)) { tds_put_smallint(tds, -1); tds_put_smallint(tds, TDS_SP_CURSORFETCH); } else { tds_put_smallint(tds, 14); TDS_PUT_N_AS_UCS2(tds, "sp_cursorfetch"); } /* This flag tells the SP only to */ /* output a dummy metadata token */ tds_put_smallint(tds, 2); /* input cursor handle (int) */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, cursor_id); /* fetch type - 2 = NEXT */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, fetch_type); /* row number */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); if ((fetch_type & 0x30) != 0) { tds_put_byte(tds, 4); tds_put_int(tds, i_row); } else { tds_put_byte(tds, 0); } /* number of rows to fetch */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, num_rows);}inttds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_type, TDS_INT i_row){ CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_fetch() cursor id = %d\n", cursor->cursor_id); if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; tds_set_cur_cursor(tds, cursor); if (IS_TDS50(tds)) { size_t len = strlen(cursor->cursor_name); size_t row_len = 0; tds->out_flag = TDS_NORMAL; tds_put_byte(tds, TDS_CURFETCH_TOKEN); if (len > (255-10)) len = (255-10); if (fetch_type == TDS_CURSOR_FETCH_ABSOLUTE || fetch_type == TDS_CURSOR_FETCH_RELATIVE) row_len = 4; /*tds_put_smallint(tds, 8); */ tds_put_smallint(tds, 6 + len + row_len); /* length of the data stream that follows */ /*tds_put_int(tds, cursor->cursor_id); *//* cursor id returned by the server */ tds_put_int(tds, 0); tds_put_tinyint(tds, len); tds_put_n(tds, cursor->cursor_name, len); tds_put_tinyint(tds, fetch_type); /* optional argument to fetch row at absolute/relative position */ if (row_len) tds_put_int(tds, i_row); return tds_query_flush_packet(tds); } if (IS_TDS7_PLUS(tds)) { /* RPC call to sp_cursorfetch */ static const unsigned char mssql_fetch[7] = { 0, 2, /* TDS_CURSOR_FETCH_NEXT */ 4, /* TDS_CURSOR_FETCH_PREV */ 1, /* TDS_CURSOR_FETCH_FIRST */ 8, /* TDS_CURSOR_FETCH_LAST */ 0x10, /* TDS_CURSOR_FETCH_ABSOLUTE */ 0x20 /* TDS_CURSOR_FETCH_RELATIVE */ }; tds->out_flag = TDS_RPC; START_QUERY; /* TODO enum for 2 ... */ if (cursor->type == 2 && fetch_type == TDS_CURSOR_FETCH_ABSOLUTE) { /* strangely dynamic cursor do not support absolute so emulate it with first + relative */ tds7_put_cursor_fetch(tds, cursor->cursor_id, 1, 0, 0); /* TODO define constant */ tds_put_byte(tds, IS_TDS90(tds) ? 0xff : 0x80); tds7_put_cursor_fetch(tds, cursor->cursor_id, 0x20, i_row, cursor->cursor_rows); } else { /* TODO check fetch_type ?? */ tds7_put_cursor_fetch(tds, cursor->cursor_id, mssql_fetch[fetch_type], i_row, cursor->cursor_rows); } tds->internal_sp_called = TDS_SP_CURSORFETCH; return tds_query_flush_packet(tds); } tds_set_state(tds, TDS_IDLE); return TDS_SUCCEED;}inttds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor){ CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_close() cursor id = %d\n", cursor->cursor_id); if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; tds_set_cur_cursor(tds, cursor); if (IS_TDS50(tds)) { tds->out_flag = TDS_NORMAL; tds_put_byte(tds, TDS_CURCLOSE_TOKEN); tds_put_smallint(tds, 5); /* length of the data stream that follows */ tds_put_int(tds, cursor->cursor_id); /* cursor id returned by the server is available now */ if (cursor->status.dealloc == TDS_CURSOR_STATE_REQUESTED) { tds_put_byte(tds, 0x01); /* Close option: TDS_CUR_COPT_DEALLOC */ cursor->status.dealloc = TDS_CURSOR_STATE_SENT; } else tds_put_byte(tds, 0x00); /* Close option: TDS_CUR_COPT_UNUSED */ } if (IS_TDS7_PLUS(tds)) { /* RPC call to sp_cursorclose */ tds->out_flag = TDS_RPC; START_QUERY; if (IS_TDS8_PLUS(tds)) { tds_put_smallint(tds, -1); tds_put_smallint(tds, TDS_SP_CURSORCLOSE); } else { tds_put_smallint(tds, 14); TDS_PUT_N_AS_UCS2(tds, "sp_cursorclose"); } /* This flag tells the SP to output only a dummy metadata token */ tds_put_smallint(tds, 2); /* input cursor handle (int) */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, cursor->cursor_id); tds->internal_sp_called = TDS_SP_CURSORCLOSE; } return tds_query_flush_packet(tds);}inttds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor){ int len; CHECK_TDS_EXTRA(tds); if (!cursor) return TDS_FAIL; tdsdump_log(TDS_DBG_INFO1, "tds_cursor_setname() cursor id = %d\n", cursor->cursor_id); if (!IS_TDS7_PLUS(tds)) return TDS_SUCCEED; if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING) return TDS_FAIL; tds_set_cur_cursor(tds, cursor); /* RPC call to sp_cursoroption */ tds->out_flag = TDS_RPC; START_QUERY; if (IS_TDS8_PLUS(tds)) { tds_put_smallint(tds, -1); tds_put_smallint(tds, TDS_SP_CURSOROPTION); } else { tds_put_smallint(tds, 14); TDS_PUT_N_AS_UCS2(tds, "sp_cursoroption"); } tds_put_smallint(tds, 0); /* input cursor handle (int) */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, cursor->cursor_id); /* code, 2 == set cursor name */ tds_put_byte(tds, 0); /* no parameter name */ tds_put_byte(tds, 0); /* input parameter */ tds_put_byte(tds, SYBINTN); tds_put_byte(tds, 4); tds_put_byte(tds, 4); tds_put_int(tds, 2); /* cursor name */ tds_put_byte(tds, 0); tds_put_byte(tds, 0); /* TODO convert ?? */ tds_put_byte(tds, XSYBVARCHAR); len = strlen(cursor->cursor_name); tds_put_smallint(tds, len); if (IS_TDS8_PLUS(tds)) tds_put_n(tds, tds->collation, 5); tds_put_smallint(tds, len); tds_put_n(tds, cursor->cursor_name, l
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -