📄 bcp.c
字号:
return FAIL; } sprintf(query,"select * from %s", dbproc->bcp_tablename); tds_submit_query(tds, query); if (tds_process_result_tokens(tds) == TDS_FAIL) { fclose(hostfile); return FAIL; } if (!tds->res_info) { fclose(hostfile); return FAIL; } resinfo = tds->res_info; dbproc->bcp_colcount = resinfo->num_cols; dbproc->bcp_columns = (BCP_COLINFO **) malloc(resinfo->num_cols * sizeof(BCP_COLINFO *)); for (i = 0; i < resinfo->num_cols; i++) { dbproc->bcp_columns[i] = (BCP_COLINFO *) malloc(sizeof(BCP_COLINFO)); memset(dbproc->bcp_columns[i], '\0', sizeof(BCP_COLINFO)); dbproc->bcp_columns[i]->tab_colnum = i + 1; /* turn offset into ordinal */ dbproc->bcp_columns[i]->db_type = resinfo->columns[i]->column_type; dbproc->bcp_columns[i]->db_length = resinfo->columns[i]->column_size; if (is_numeric_type(resinfo->columns[i]->column_type)) dbproc->bcp_columns[i]->data = (BYTE *) malloc(sizeof(TDS_NUMERIC)); else dbproc->bcp_columns[i]->data = (BYTE *) malloc(dbproc->bcp_columns[i]->db_length); dbproc->bcp_columns[i]->data_size = 0; } row_of_query = 0; rows_written = 0; while (tds_process_row_tokens(tds)==TDS_SUCCEED) { row_of_query++; if ((dbproc->firstrow == 0 && dbproc->lastrow == 0) || /** FIX this! */ ((dbproc->firstrow > 0 && row_of_query >= dbproc->firstrow) && (dbproc->lastrow > 0 && row_of_query <= dbproc->lastrow))) { for (i = 0; i < dbproc->bcp_colcount; i++) { bcpcol = dbproc->bcp_columns[i]; curcol = resinfo->columns[bcpcol->tab_colnum - 1]; src = &resinfo->current_row[curcol->column_offset]; if (is_blob_type(curcol->column_type)) { /* FIX ME -- no converts supported */ src = (BYTE*) ((TDSBLOBINFO *) src)->textvalue; len = curcol->cur_row_size; } else { srctype = tds_get_conversion_type(curcol->column_type, curcol->column_size); if (srctype != bcpcol->db_type) { bcpcol->db_type = srctype; } if (is_numeric_type(curcol->column_type)) memcpy(bcpcol->data, src, sizeof(TDS_NUMERIC)); else memcpy(bcpcol->data, src, curcol->column_size); /* null columns have zero output */ if (tds_get_null(resinfo->current_row, bcpcol->tab_colnum - 1)) bcpcol->data_size = 0; else bcpcol->data_size = curcol->cur_row_size; } } for (i = 0; i < dbproc->host_colcount; i++) { hostcol = dbproc->host_columns[i]; if ((hostcol->tab_colnum < 1) || (hostcol->tab_colnum > dbproc->bcp_colcount)) { continue; } if (hostcol->tab_colnum) { bcpcol = dbproc->bcp_columns[hostcol->tab_colnum - 1]; if (bcpcol->tab_colnum != hostcol->tab_colnum) { return FAIL; } } /*assert(bcpcol);*/ if (hostcol->datatype == 0) hostcol->datatype = bcpcol->db_type; /* work out how much space to allocate for output data */ switch (hostcol->datatype) { case SYBINT1: buflen = destlen = 1; break; case SYBINT2: buflen = destlen = 2; break; case SYBINT4: buflen = destlen = 4; break; case SYBREAL: buflen = destlen = 4; break; case SYBFLT8: buflen = destlen = 8; break; case SYBDATETIME: buflen = destlen = 8; break; case SYBDATETIME4: buflen = destlen = 4; break; case SYBBIT: buflen = destlen = 1; break; case SYBBITN: buflen = destlen = 1; break; case SYBMONEY: buflen = destlen = 8; break; case SYBMONEY4: buflen = destlen = 4; break; case SYBCHAR: case SYBVARCHAR: switch (bcpcol->db_type) { case SYBVARCHAR: buflen = bcpcol->db_length + 1; destlen = -1; break; case SYBCHAR: buflen = bcpcol->db_length + 1; destlen = -2; break; case SYBINT1: buflen = 4 + 1; /* 255 */ destlen = -1; break; case SYBINT2: buflen = 6 + 1; /* -32768 */ destlen = -1; break; case SYBINT4: buflen = 11 + 1; /* -2147483648 */ destlen = -1; break; case SYBNUMERIC: buflen = 40 + 1; /* 10 to the 38 */ destlen = -1; break; case SYBDECIMAL: buflen = 40 + 1; /* 10 to the 38 */ destlen = -1; break; case SYBFLT8: buflen = 40 + 1; /* 10 to the 38 */ destlen = -1; break; case SYBDATETIME: buflen = 255 + 1; destlen = -1; break; default: buflen = 255 + 1; destlen = -1; break; } break; default: buflen = destlen = 255; } outbuf = (BYTE*) malloc(buflen); /* if we are converting datetime to string, need to override any * date time formats already established */ if ((bcpcol->db_type == SYBDATETIME || bcpcol->db_type == SYBDATETIME4) && (hostcol->datatype == SYBCHAR || hostcol->datatype == SYBVARCHAR)) { memset(&when, 0, sizeof(when)); tds_datecrack(bcpcol->db_type, bcpcol->data, &when); buflen = tds_strftime((char*)outbuf, buflen, "%Y-%m-%d %H:%M:%S.%z", &when); } else { /* * For null columns, the above work to determine the output buffer size is moot, * because bcpcol->data_size is zero, so dbconvert() won't write anything, and returns zero. */ buflen = dbconvert(dbproc, bcpcol->db_type, bcpcol->data, bcpcol->data_size, hostcol->datatype, outbuf, destlen); } /* FIX ME -- does not handle prefix_len == -1 */ /* The prefix */ switch (hostcol->prefix_len) { case -1: if (!(is_fixed_type(hostcol->datatype))) { si = buflen; fwrite(&si, sizeof(si), 1, hostfile); } break; case 1: ti = buflen; fwrite(&ti, sizeof(ti), 1, hostfile); break; case 2: si = buflen; fwrite(&si, sizeof(si), 1, hostfile); break; case 4: li = buflen; fwrite(&li, sizeof(li), 1, hostfile); break; } /* The data */ if (is_blob_type(curcol->column_type)) { fwrite(src, len, 1, hostfile); } else { if (hostcol->column_len != -1) { buflen = buflen > hostcol->column_len ? hostcol->column_len : buflen; } fwrite(outbuf, buflen, 1, hostfile); } free(outbuf); /* The terminator */ if (hostcol->terminator && hostcol->term_len > 0) { fwrite(hostcol->terminator, hostcol->term_len, 1, hostfile); } } rows_written++; } } if (fclose(hostfile) != 0) { _bcp_err_handler(dbproc, BCPEBCUC); return (FAIL); } printf("firstrow = %d row_of_query = %d rows written %d\n", dbproc->firstrow, row_of_query, rows_written); if (dbproc->firstrow > 0 && row_of_query < dbproc->firstrow) { /* The table which bulk-copy is attempting to * copy to a host-file is shorter than the * number of rows which bulk-copy was instructed * to skip. */ _bcp_err_handler(dbproc, BCPETTS); return (FAIL); } *rows_copied = rows_written; return SUCCEED;}RETCODE _bcp_read_hostfile(DBPROCESS *dbproc, FILE *hostfile){BCP_COLINFO *bcpcol;BCP_HOSTCOLINFO *hostcol;int i;TDS_TINYINT ti;TDS_SMALLINT si;TDS_INT li;int collen;int data_is_null;int bytes_read;int converted_data_size;TDS_INT desttype; /* for each host file column defined by calls to bcp_colfmt */ for (i = 0; i < dbproc->host_colcount; i++) { BYTE coldata[256]; hostcol = dbproc->host_columns[i]; data_is_null = 0; collen = 0; /* if a prefix length specified, read the correct */ /* amount of data... */ if (hostcol->prefix_len > 0) { switch (hostcol->prefix_len) { case 1: if (fread(&ti, 1, 1, hostfile) != 1) { _bcp_err_handler(dbproc, BCPEBCRE); return (FAIL); } collen = ti; break; case 2: if (fread(&si, 2, 1, hostfile) != 1) { _bcp_err_handler(dbproc, BCPEBCRE); return (FAIL); } collen = si; break; case 4: if (fread(&li, 4, 1, hostfile) != 1) { _bcp_err_handler(dbproc, BCPEBCRE); return (FAIL); } collen = li; break; default: /*assert(hostcol->prefix_len <= 4);*/ break; } if (collen == 0) data_is_null = 1; } /* if (Max) column length specified take that into */ /* consideration... */ if (!data_is_null && hostcol->column_len >= 0) { if (hostcol->column_len == 0) data_is_null = 1; else { if (collen) collen = (hostcol->column_len < collen) ? hostcol->column_len : collen; else collen = hostcol->column_len; } } /* Fixed Length data - this over-rides anything else specified */ if (is_fixed_type(hostcol->datatype)) { collen = get_size_by_type(hostcol->datatype); }#ifdef NCBI_FTDS else if(hostcol->prefix_len <= 0 && hostcol->term_len <= 0) { /* we need to know the size anyway */ if (fread(&si, 2, 1, hostfile) != 1) { _bcp_err_handler(dbproc, BCPEBCRE); return (FAIL); } collen = si; }#endif /* if this host file column contains table data, */ /* find the right element in the table/column list */ if (hostcol->tab_colnum) { bcpcol = dbproc->bcp_columns[hostcol->tab_colnum - 1]; if (bcpcol->tab_colnum != hostcol->tab_colnum) { return FAIL; } } /* a terminated field is specified - get the data into temporary space... */ memset(coldata, '\0', sizeof(coldata)); if (hostcol->term_len > 0) { bytes_read = _bcp_get_term_data(hostfile, hostcol, coldata); if (bytes_read == -1) return FAIL; if (collen) collen = (bytes_read < collen) ? bytes_read : collen; else collen = bytes_read; if (collen == 0) data_is_null = 1; } else { if (collen) { if (fread(coldata, collen, 1, hostfile) != 1) { _bcp_err_handler(dbproc, BCPEBCRE); return (FAIL); } } } if (hostcol->tab_colnum) { if (data_is_null) { bcpcol->data_size = 0; } else { desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length); converted_data_size = dbconvert(dbproc, hostcol->datatype, coldata, collen, desttype, bcpcol->data, bcpcol->db_length); if (converted_data_size == FAIL) return (FAIL); if (desttype == SYBVARCHAR) { bcpcol->data_size = _bcp_rtrim_varchar(bcpcol->data, converted_data_size); } else { bcpcol->data_size = converted_data_size; } } } } return SUCCEED;}/* read a terminated variable from a hostfile */RETCODE _bcp_get_term_data(FILE *hostfile, BCP_HOSTCOLINFO *hostcol, BYTE *coldata ){int j = 0;int termfound = 1;char x;char *tester = NULL;int bufpos = 0;int found = 0; if (hostcol->term_len > 1) tester = (char *) malloc(hostcol->term_len); while (!found && (x = getc(hostfile)) != EOF) { if (x != *hostcol->terminator) { *(coldata + bufpos) = x; bufpos++; } else { if (hostcol->term_len == 1) { *(coldata + bufpos) = '\0'; found = 1; } else { ungetc(x, hostfile); fread(tester, hostcol->term_len, 1, hostfile); termfound = 1; for (j = 0; j < hostcol->term_len; j++) if (*(tester + j) != *(hostcol->terminator + j)) termfound = 0; if (termfound) { *(coldata + bufpos) = '\0'; found = 1; } else { for (j = 0; j < hostcol->term_len; j++) { *(coldata + bufpos) = *(tester + j); bufpos++; } } } } } if (found) { return (bufpos); } else { return (-1); }}/*** Add fixed size columns to the row*/static int _bcp_add_fixed_columns(DBPROCESS *dbproc, BYTE *rowbuffer, int start){ TDS_NUMERIC *num; int row_pos = start; BCP_COLINFO *bcpcol; int cpbytes; int i; for (i = 0; i < dbproc->bcp_colcount; i++) { bcpcol = dbproc->bcp_columns[i]; if (!is_nullable_type(bcpcol->db_type) && !(bcpcol->db_nullable)) { if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) { _bcp_err_handler(dbproc, BCPEBCNN); return FAIL; } if (is_numeric_type(bcpcol->db_type)) { num = (TDS_NUMERIC *) bcpcol->data; cpbytes = g__numeric_bytes_per_prec[num->precision]; memcpy(&rowbuffer[row_pos], num->array, cpbytes); } else { cpbytes = bcpcol->data_size > bcpcol->db_length ? bcpcol->db_length : bcpcol->data_size; memcpy(&rowbuffer[row_pos], bcpcol->data, cpbytes); } /* Bill T commenting this out. It always seems to print This error message regardless... if (row_pos != bcpcol->db_offset) { fprintf(stderr,"Error: computed offset does not match one returned from database engine\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -