static boolean reinit_results(TDSSOCKET * tds, size_t num_cols, const struct metadata_t meta[]) { TDSRESULTINFO *info; int i; assert(tds); assert(num_cols); assert(meta); tds_free_all_results(tds); tds->rows_affected = TDS_NO_COUNT; if ((info = alloc_results(num_cols)) == NULL) return false; tds_set_current_results(tds, info); if (tds->cur_cursor) { tds_free_results(tds->cur_cursor->res_info); 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 (%u column%s) to tds->res_info\n", (unsigned) num_cols, (num_cols==1? "":"s")); } tdsdump_log(TDS_DBG_INFO1, "setting up %u columns\n", (unsigned) num_cols); for (i = 0; i < num_cols; i++) { set_result_column(tds, info->columns[i], meta[i].name, &meta[i].col); info->columns[i]->bcp_terminator = (char*) meta[i].pacross; /* overload available pointer */ } if (num_cols > 0) { static char dashes[31] = "------------------------------"; tdsdump_log(TDS_DBG_INFO1, " %-20s %-15s %-15s %-7s\n", "name", "size/wsize", "type/wtype", "utype"); tdsdump_log(TDS_DBG_INFO1, " %-20s %15s %15s %7s\n", dashes+10, dashes+30-15, dashes+30-15, dashes+30-7); } for (i = 0; i < num_cols; i++) { TDSCOLUMN *curcol = info->columns[i]; tdsdump_log(TDS_DBG_INFO1, " %-20s %7d/%-7d %7d/%-7d %7d\n", tds_dstr_cstr(&curcol->column_name), curcol->column_size, curcol->on_server.column_size, curcol->column_type, curcol->on_server.column_type, curcol->column_usertype); } #if 1 /* all done now allocate a row for tds_process_row to use */ if (TDS_FAILED(tds_alloc_row(info))) return false; #endif return true; }
void TdsResultSet::Close() { //fprintf(stderr, "TdsResultSet::Close()\n"); CloseMetaData(); //if (m_pResultInfo == NULL) //fprintf(stderr, "m_pResultInfo is still NULL!!!\n"); if (m_pResultInfo != NULL) tds_free_results(m_pResultInfo); FreeResultSets(); }
static TDSRESULTINFO * alloc_results(size_t num_cols) { TDSRESULTINFO *res_info; TDSCOLUMN **ppcol; TEST_MALLOC(res_info, TDSRESULTINFO); res_info->ref_count = 1; TEST_CALLOC(res_info->columns, TDSCOLUMN *, num_cols); for (ppcol = res_info->columns; ppcol < res_info->columns + num_cols; ppcol++) if ((*ppcol = tds_alloc_column()) == NULL) goto Cleanup; res_info->num_cols = num_cols; res_info->row_size = 0; return res_info; Cleanup: tds_free_results(res_info); return NULL; }
/** * Initialize BCP information. * Query structure of the table to server. * \tds * \param bcpinfo BCP information to initialize. Structure should be allocate * and table name and direction should be already set. */ TDSRET tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo) { TDSRESULTINFO *resinfo; TDSRESULTINFO *bindinfo = NULL; TDSCOLUMN *curcol; TDS_INT result_type; int i; TDSRET rc; const char *fmt; /* FIXME don't leave state in processing state */ /* TODO quote tablename if needed */ if (bcpinfo->direction != TDS_BCP_QUERYOUT) fmt = "SET FMTONLY ON select * from %s SET FMTONLY OFF"; else fmt = "SET FMTONLY ON %s SET FMTONLY OFF"; if (TDS_FAILED(rc=tds_submit_queryf(tds, fmt, bcpinfo->tablename))) /* TODO return an error ?? */ /* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */ return rc; /* TODO possibly stop at ROWFMT and copy before going to idle */ /* TODO check what happen if table is not present, cleanup on error */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) continue; if (TDS_FAILED(rc)) return rc; /* copy the results info from the TDS socket */ if (!tds->res_info) return TDS_FAIL; resinfo = tds->res_info; if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) { rc = TDS_FAIL; goto cleanup; } bindinfo->row_size = resinfo->row_size; /* Copy the column metadata */ rc = TDS_FAIL; for (i = 0; i < bindinfo->num_cols; i++) { curcol = bindinfo->columns[i]; /* * TODO use memcpy ?? * curcol and resinfo->columns[i] are both TDSCOLUMN. * Why not "curcol = resinfo->columns[i];"? Because the rest of TDSCOLUMN (below column_timestamp) * isn't being used. Perhaps this "upper" part of TDSCOLUMN should be a substructure. * Or, see if the "lower" part is unused (and zeroed out) at this point, and just do one assignment. */ curcol->funcs = resinfo->columns[i]->funcs; curcol->column_type = resinfo->columns[i]->column_type; curcol->column_usertype = resinfo->columns[i]->column_usertype; curcol->column_flags = resinfo->columns[i]->column_flags; if (curcol->column_varint_size == 0) curcol->column_cur_size = resinfo->columns[i]->column_cur_size; else curcol->column_cur_size = -1; curcol->column_size = resinfo->columns[i]->column_size; curcol->column_varint_size = resinfo->columns[i]->column_varint_size; curcol->column_prec = resinfo->columns[i]->column_prec; curcol->column_scale = resinfo->columns[i]->column_scale; curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type; curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size; curcol->char_conv = resinfo->columns[i]->char_conv; if (!tds_dstr_dup(&curcol->column_name, &resinfo->columns[i]->column_name)) goto cleanup; if (!tds_dstr_dup(&curcol->table_column_name, &resinfo->columns[i]->table_column_name)) goto cleanup; curcol->column_nullable = resinfo->columns[i]->column_nullable; curcol->column_identity = resinfo->columns[i]->column_identity; curcol->column_timestamp = resinfo->columns[i]->column_timestamp; memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5); if (is_numeric_type(curcol->column_type)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC)); ((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec; ((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale; } else if (bcpinfo->bind_count != 0 /* ctlib */ && is_blob_col(curcol)) { curcol->bcp_column_data = tds_alloc_bcp_column_data(0); } else { curcol->bcp_column_data = tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size)); } if (!curcol->bcp_column_data) goto cleanup; } if (!IS_TDS7_PLUS(tds->conn)) { bindinfo->current_row = (unsigned char*) malloc(bindinfo->row_size); if (!bindinfo->current_row) goto cleanup; bindinfo->row_free = tds_bcp_row_free; } if (bcpinfo->identity_insert_on) { rc = tds_submit_queryf(tds, "set identity_insert %s on", bcpinfo->tablename); if (TDS_FAILED(rc)) goto cleanup; /* TODO use tds_process_simple_query */ while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCESS) { } if (rc != TDS_NO_MORE_RESULTS) goto cleanup; } bcpinfo->bindinfo = bindinfo; bcpinfo->bind_count = 0; return TDS_SUCCESS; cleanup: tds_free_results(bindinfo); return rc; }
int main(int argc, char **argv) { TDSCONTEXT *ctx; TDSSOCKET *tds; TDSLOGIN *login; TDSRESULTINFO *resinfo; if (argc < 2 || atoi(argv[1]) <= 0) { fprintf(stderr, "syntax: %s <port>\n", argv[0]); return 1; } ctx = tds_alloc_context(NULL); tds = tds_listen(ctx, atoi(argv[1])); if (!tds) return 1; /* get_incoming(tds->s); */ login = tds_alloc_read_login(tds); if (!login) { fprintf(stderr, "Error reading login\n"); exit(1); } dump_login(login); if (!strcmp(tds_dstr_cstr(&login->user_name), "guest") && !strcmp(tds_dstr_cstr(&login->password), "sybase")) { tds->out_flag = TDS_REPLY; tds_env_change(tds, TDS_ENV_DATABASE, "master", "pubs2"); tds_send_msg(tds, 5701, 2, 10, "Changed database context to 'pubs2'.", "JDBC", "ZZZZZ", 1); if (!login->suppress_language) { tds_env_change(tds, TDS_ENV_LANG, NULL, "us_english"); tds_send_msg(tds, 5703, 1, 10, "Changed language setting to 'us_english'.", "JDBC", "ZZZZZ", 1); } tds_env_change(tds, TDS_ENV_PACKSIZE, NULL, "512"); /* TODO set mssql if tds7+ */ tds_send_login_ack(tds, "sql server"); if (IS_TDS50(tds)) tds_send_capabilities_token(tds); tds_send_done_token(tds, 0, 1); } else { /* send nack before exiting */ exit(1); } tds_flush_packet(tds); tds_free_login(login); login = NULL; /* printf("incoming packet %d\n", tds_read_packet(tds)); */ printf("query : %s\n", tds_get_generic_query(tds)); tds->out_flag = TDS_REPLY; resinfo = tds_alloc_results(1); resinfo->columns[0]->column_type = SYBVARCHAR; resinfo->columns[0]->column_size = 30; strcpy(resinfo->columns[0]->column_name, "name"); resinfo->columns[0]->column_namelen = 4; resinfo->current_row = (TDS_UCHAR*) "pubs2"; resinfo->columns[0]->column_data = resinfo->current_row; tds_send_result(tds, resinfo); tds_send_control_token(tds, 1); tds_send_row(tds, resinfo); tds_send_done_token(tds, 16, 1); tds_flush_packet(tds); sleep(30); tds_free_results(resinfo); tds_free_socket(tds); tds_free_context(ctx); return 0; }