📄 token.c
字号:
break; } tdsdump_log(TDS_DBG_INFO1, "processing result. column_size %d\n", curcol->column_size); /* Adjust column size according to client's encoding */ curcol->on_server.column_size = curcol->column_size; /* TODO check if this column can have collation information associated */ adjust_character_column_size(tds, curcol); /* skip locale */ if (!IS_TDS42(tds)) tds_get_n(tds, NULL, tds_get_byte(tds)); } by_cols = tds_get_byte(tds); tdsdump_log(TDS_DBG_INFO1, "processing tds compute result. by_cols = %d\n", by_cols); if (by_cols) { if ((info->bycolumns = (TDS_SMALLINT *) malloc(by_cols * sizeof(TDS_SMALLINT))) == NULL) return TDS_FAIL; memset(info->bycolumns, '\0', by_cols * sizeof(TDS_SMALLINT)); } info->by_cols = by_cols; cur_by_col = info->bycolumns; for (col = 0; col < by_cols; col++) { *cur_by_col = tds_get_byte(tds); cur_by_col++; } return tds_alloc_compute_row(info);}/** * Read data information from wire * \param tds state information for the socket and the TDS protocol * \param curcol column where to store information */static inttds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol){ int colnamelen; CHECK_TDS_EXTRA(tds); CHECK_COLUMN_EXTRA(curcol); /* User defined data type of the column */ curcol->column_usertype = IS_TDS90(tds) ? tds_get_int(tds) : tds_get_smallint(tds); curcol->column_flags = tds_get_smallint(tds); /* Flags */ curcol->column_nullable = curcol->column_flags & 0x01; curcol->column_writeable = (curcol->column_flags & 0x08) > 0; curcol->column_identity = (curcol->column_flags & 0x10) > 0; tds_set_column_type(tds, curcol, tds_get_byte(tds)); /* sets "cardinal" type */ curcol->column_timestamp = (curcol->column_type == SYBBINARY && curcol->column_usertype == TDS_UT_TIMESTAMP); switch (curcol->column_varint_size) { case 4: curcol->column_size = tds_get_int(tds); break; case 2: curcol->column_size = tds_get_smallint(tds); break; case 1: curcol->column_size = tds_get_byte(tds); break; case 0: break; } /* Adjust column size according to client's encoding */ curcol->on_server.column_size = curcol->column_size; /* numeric and decimal have extra info */ if (is_numeric_type(curcol->column_type)) { curcol->column_prec = tds_get_byte(tds); /* precision */ curcol->column_scale = tds_get_byte(tds); /* scale */ /* FIXME check prec/scale, don't let server crash us */ } if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) { /* based on true type as sent by server */ /* * first 2 bytes are windows code (such as 0x409 for english) * other 2 bytes ??? * last bytes is id in syscharsets */ tds_get_n(tds, curcol->column_collation, 5); curcol->char_conv = tds_iconv_from_collate(tds, curcol->column_collation[4], curcol->column_collation[1] * 256 + curcol->column_collation[0]); } /* NOTE adjustements must be done after curcol->char_conv initialization */ adjust_character_column_size(tds, curcol); if (is_blob_type(curcol->column_type)) { /* discard this additional byte */ /* TODO discover its meaning */ if (IS_TDS90(tds)) tds_get_byte(tds); curcol->table_namelen = tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1); } /* * under 7.0 lengths are number of characters not * number of bytes...tds_get_string handles this */ colnamelen = tds_get_string(tds, tds_get_byte(tds), curcol->column_name, sizeof(curcol->column_name) - 1); curcol->column_name[colnamelen] = 0; curcol->column_namelen = colnamelen; tdsdump_log(TDS_DBG_INFO1, "tds7_get_data_info: \n" "\tcolname = %s (%d bytes)\n" "\ttype = %d (%s)\n" "\tserver's type = %d (%s)\n" "\tcolumn_varint_size = %d\n" "\tcolumn_size = %d (%d on server)\n", curcol->column_name, curcol->column_namelen, curcol->column_type, tds_prtype(curcol->column_type), curcol->on_server.column_type, tds_prtype(curcol->on_server.column_type), curcol->column_varint_size, curcol->column_size, curcol->on_server.column_size); CHECK_COLUMN_EXTRA(curcol); return TDS_SUCCEED;}/** * tds7_process_result() is the TDS 7.0 result set processing routine. It * is responsible for populating the tds->res_info structure. * This is a TDS 7.0 only function */static inttds7_process_result(TDSSOCKET * tds){ int col, num_cols, result; TDSCOLUMN *curcol; TDSRESULTINFO *info; CHECK_TDS_EXTRA(tds); tdsdump_log(TDS_DBG_INFO1, "processing TDS7 result metadata.\n"); /* read number of columns and allocate the columns structure */ num_cols = tds_get_smallint(tds); /* This can be a DUMMY results token from a cursor fetch */ if (num_cols == -1) { tdsdump_log(TDS_DBG_INFO1, "no meta data\n"); return TDS_SUCCEED; } tds_free_all_results(tds); tds->rows_affected = TDS_NO_COUNT; if ((info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; tds->current_results = info; if (tds->cur_cursor) { tds->cur_cursor->res_info = info; tdsdump_log(TDS_DBG_INFO1, "set current_results to cursor->res_info\n"); } else { tds->res_info = info; tdsdump_log(TDS_DBG_INFO1, "set current_results (%d column%s) to tds->res_info\n", num_cols, (num_cols==1? "":"s")); } /* * loop through the columns populating COLINFO struct from * server response */ for (col = 0; col < num_cols; col++) { curcol = info->columns[col]; tdsdump_log(TDS_DBG_INFO1, "setting up column %d\n", col); tds7_get_data_info(tds, curcol); } /* all done now allocate a row for tds_process_row to use */ result = tds_alloc_row(info); CHECK_TDS_EXTRA(tds); return result;}/** * Read data information from wire * \param tds state information for the socket and the TDS protocol * \param curcol column where to store information */static inttds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param){ CHECK_TDS_EXTRA(tds); CHECK_COLUMN_EXTRA(curcol); curcol->column_namelen = tds_get_string(tds, tds_get_byte(tds), curcol->column_name, sizeof(curcol->column_name) - 1); curcol->column_name[curcol->column_namelen] = '\0'; curcol->column_flags = tds_get_byte(tds); /* Flags */ if (!is_param) { /* TODO check if all flags are the same for all TDS versions */ if (IS_TDS50(tds)) curcol->column_hidden = curcol->column_flags & 0x1; curcol->column_key = (curcol->column_flags & 0x2) > 1; curcol->column_writeable = (curcol->column_flags & 0x10) > 1; curcol->column_nullable = (curcol->column_flags & 0x20) > 1; curcol->column_identity = (curcol->column_flags & 0x40) > 1; } /* TODO what's these bytes ?? */ if (IS_TDS90(tds)) tds_get_n(tds, NULL, 2); curcol->column_usertype = tds_get_int(tds); tds_set_column_type(tds, curcol, tds_get_byte(tds)); tdsdump_log(TDS_DBG_INFO1, "processing result. type = %d(%s), varint_size %d\n", curcol->column_type, tds_prtype(curcol->column_type), curcol->column_varint_size); switch (curcol->column_varint_size) { case 4: curcol->column_size = tds_get_int(tds); /* Only read table_name for blob columns (eg. not for SYBLONGBINARY) */ if (is_blob_type (curcol->column_type)) { curcol->table_namelen = tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1); } break; case 2: /* assure > 0 */ curcol->column_size = tds_get_smallint(tds); break; case 1: curcol->column_size = tds_get_byte(tds); break; case 0: break; } tdsdump_log(TDS_DBG_INFO1, "processing result. column_size %d\n", curcol->column_size); /* numeric and decimal have extra info */ if (is_numeric_type(curcol->column_type)) { curcol->column_prec = tds_get_byte(tds); /* precision */ curcol->column_scale = tds_get_byte(tds); /* scale */ /* FIXME check prec/scale, don't let server crash us */ } /* read sql collation info */ /* TODO: we should use it ! */ if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) { tds_get_n(tds, curcol->column_collation, 5); curcol->char_conv = tds_iconv_from_collate(tds, curcol->column_collation[4], curcol->column_collation[1] * 256 + curcol->column_collation[0]); } /* Adjust column size according to client's encoding */ curcol->on_server.column_size = curcol->column_size; adjust_character_column_size(tds, curcol); return TDS_SUCCEED;}/** * tds_process_result() is the TDS 5.0 result set processing routine. It * is responsible for populating the tds->res_info structure. * This is a TDS 5.0 only function */static inttds_process_result(TDSSOCKET * tds){ int hdrsize; int col, num_cols; TDSCOLUMN *curcol; TDSRESULTINFO *info; TDSCURSOR *cursor; CHECK_TDS_EXTRA(tds); tds_free_all_results(tds); tds->rows_affected = TDS_NO_COUNT; hdrsize = tds_get_smallint(tds); /* read number of columns and allocate the columns structure */ num_cols = tds_get_smallint(tds); if (tds->cur_cursor) { cursor = tds->cur_cursor; if ((cursor->res_info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; info = cursor->res_info; tds->current_results = cursor->res_info; } else { if ((tds->res_info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; info = tds->res_info; tds->current_results = tds->res_info; } /* * loop through the columns populating COLINFO struct from * server response */ for (col = 0; col < info->num_cols; col++) { curcol = info->columns[col]; tds_get_data_info(tds, curcol, 0); /* skip locale information */ /* NOTE do not put into tds_get_data_info, param do not have locale information */ tds_get_n(tds, NULL, tds_get_byte(tds)); } return tds_alloc_row(info);}/** * tds5_process_result() is the new TDS 5.0 result set processing routine. * It is responsible for populating the tds->res_info structure. * This is a TDS 5.0 only function */static inttds5_process_result(TDSSOCKET * tds){ int hdrsize; int colnamelen; int col, num_cols; TDSCOLUMN *curcol; TDSRESULTINFO *info; CHECK_TDS_EXTRA(tds); tdsdump_log(TDS_DBG_INFO1, "tds5_process_result\n"); /* * free previous resultset */ tds_free_all_results(tds); tds->rows_affected = TDS_NO_COUNT; /* * read length of packet (4 bytes) */ hdrsize = tds_get_int(tds); /* read number of columns and allocate the columns structure */ num_cols = tds_get_smallint(tds); if ((info = tds_alloc_results(num_cols)) == NULL) return TDS_FAIL; tds->current_results = info; if (tds->cur_cursor) tds->cur_cursor->res_info = info; else tds->res_info = info; tdsdump_log(TDS_DBG_INFO1, "num_cols=%d\n", num_cols); /* TODO reuse some code... */ /* * loop through the columns populating COLINFO struct from * server response */ for (col = 0; col < info->num_cols; col++) { curcol = info->columns[col]; /* label */ curcol->column_namelen = tds_get_string(tds, tds_get_byte(tds), curcol->column_name, sizeof(curcol->column_name) - 1); curcol->column_name[curcol->column_namelen] = '\0'; /* TODO save informations somewhere */ /* database */ colnamelen = tds_get_byte(tds); tds_get_n(tds, NULL, colnamelen); /* * tds_get_n(tds, curcol->catalog_name, colnamelen); * curcol->catalog_name[colnamelen] = '\0'; */ /* owner */ colnamelen = tds_get_byte(tds); tds_get_n(tds, NULL, colnamelen); /* * tds_get_n(tds, curcol->schema_name, colnamelen); * curcol->schema_name[colnamelen] = '\0'; */ /* table */ /* TODO use with owner and database */ curcol->table_namelen = tds_get_string(tds, tds_get_byte(tds), curcol->table_name, sizeof(curcol->table_name) - 1); curcol->table_name[curcol->table_namelen] = '\0'; /* table column name */ if (curcol->table_column_name) TDS_ZERO_FREE(curcol->table_column_name); tds_alloc_get_string(tds, &curcol->table_column_name, tds_get_byte(tds)); /* if label is empty, use the table column name */ if (!curcol->column_namelen && curcol->table_column_name) { tds_strlcpy(curcol->column_name, curcol->table_column_name, sizeof(curcol->column_name)); curcol->column_namelen = strlen(curcol->column_name); } /* flags (4 bytes) */ curcol->column_flags = tds_get_int(tds); curcol->column_hidden = curcol->column_flags & 0x1; curcol->column_key = (curcol->column_flags & 0x2) > 1; curcol->column_writeable = (curcol->column_flags & 0x10) > 1; curcol->column_nullable = (curcol->column_flags & 0x20) > 1; curcol->column_identity = (curcol->column_flags & 0x40) > 1; curcol->column_usertype = tds_get_int(tds); tds_set_column_type(tds, curcol, tds_get_byte(tds)); switch (curcol->column_varint_size) { case 4: if (curcol->column_type == SYBTEXT || curcol->column_type == SYBIMAGE) { curcol->column_size = tds_get_int(tds); /* save name */ curcol->table_namelen = tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1); } else tdsdump_log(TDS_DBG_INFO1, "UNHANDLED TYPE %x\n", curcol->column_type); break; case 5: curcol->column_size = tds_get_int(tds); break; case 2: curcol->column_size = tds_get_smallint(tds); break; case 1: curcol->column_size = tds_get_byte(tds); break; case 0: curcol->column_size = tds_get_size_by_type(curcol->column_type); break; } /* numeric and decimal have extra info */ if (is_numeric_type(curcol->column_type)) { curcol->column_prec = tds_get_byte(tds); /* precision */ curcol->column_scale = tds_get_byte(tds); /* scale */ /* FIXME check prec/scale, don't let server crash us */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -