bcp.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:71k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bcp.c,v $
  4.  * PRODUCTION Revision 1000.1  2003/11/17 22:20:13  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [ORIGINAL] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include "tdsutil.h"
  29. #include "tds.h"
  30. #include "sybfront.h"
  31. #include "sybdb.h"
  32. #include "dblib.h"
  33. #include <unistd.h>
  34. #ifdef TARGET_API_MAC_OS8
  35. #include <stdlib.h>
  36. #include "tdsconvert.h"
  37. #endif
  38. /*    was hard coded as 32768, but that made the local stack data size > 32K,
  39.     which is not allowed on Mac OS 8/9. (mlilback, 11/7/01) */
  40. #ifdef TARGET_API_MAC_OS8
  41. #define ROWBUF_SIZE 31000
  42. #else
  43. #define ROWBUF_SIZE 32768
  44. #endif
  45. extern int (*g_dblib_msg_handler)();
  46. extern int (*g_dblib_err_handler)();
  47. extern const int g__numeric_bytes_per_prec[];
  48. static char  software_version[]   = "$Id: bcp.c,v 1000.1 2003/11/17 22:20:13 gouriano Exp $";
  49. static void *no_unused_var_warn[] = { software_version,
  50.                                      no_unused_var_warn};
  51. static RETCODE _bcp_start_copy_in(DBPROCESS *);
  52. static RETCODE _bcp_build_bulk_insert_stmt(char *, BCP_COLINFO *, int);
  53. static RETCODE _bcp_start_new_batch(DBPROCESS *);
  54. static RETCODE _bcp_send_colmetadata(DBPROCESS *);
  55. static int _bcp_rtrim_varchar(char *, int);
  56. static int _bcp_err_handler(DBPROCESS * dbproc, int bcp_errno);
  57. #ifdef NCBI_FTDS
  58. /*
  59. ** The following little table is indexed by precision-1 and will
  60. ** tell us the number of bytes required to store the specified
  61. ** precision (with the sign).
  62. ** Support precision up to 77 digits
  63. */
  64. static const int tds_numeric_bytes_per_prec[] = {
  65.         -1, 2, 2, 3, 3, 4, 4, 4, 5, 5,
  66.         6, 6, 6, 7, 7, 8, 8, 9, 9, 9,
  67.         10, 10, 11, 11, 11, 12, 12, 13, 13, 14,
  68.         14, 14, 15, 15, 16, 16, 16, 17, 17, 18,
  69.         18, 19, 19, 19, 20, 20, 21, 21, 21, 22,
  70.         22, 23, 23, 24, 24, 24, 25, 25, 26, 26,
  71.         26, 27, 27, 28, 28, 28, 29, 29, 30, 30,
  72.         31, 31, 31, 32, 32, 33, 33, 33
  73. };
  74. #endif
  75. RETCODE bcp_init(DBPROCESS *dbproc, char *tblname, char *hfile, char *errfile, int direction)
  76. {
  77. TDSSOCKET *tds = dbproc->tds_socket;
  78. BCP_COLINFO *bcpcol;
  79. TDSRESULTINFO *resinfo;
  80. int i;
  81. int rc;
  82.     char query[256];
  83. /* free allocated storage in dbproc & initialise flags, etc. */
  84. _bcp_clear_storage(dbproc);
  85. /* check validity of parameters */
  86. if (hfile != (char *) NULL) {
  87. dbproc->bcp_hostfile = (char *) malloc(strlen(hfile) + 1);
  88. strcpy(dbproc->bcp_hostfile, hfile);
  89. if (errfile != (char *) NULL) {
  90. dbproc->bcp_errorfile = (char *) malloc(strlen(errfile) + 1);
  91. strcpy(dbproc->bcp_errorfile, errfile);
  92.         }
  93.         else {
  94. dbproc->bcp_errorfile = (char *) NULL;
  95. }
  96.     }
  97.     else {
  98. dbproc->bcp_hostfile = (char *) NULL;
  99. dbproc->bcp_errorfile = (char *) NULL;
  100. dbproc->sendrow_init = 0;
  101. }
  102. if (tblname == (char *) NULL) {
  103.         _bcp_err_handler(dbproc, BCPEBCITBNM);
  104. return (FAIL);
  105. }
  106. if (strlen(tblname) > 92) { /* 30.30.30 */
  107.         _bcp_err_handler(dbproc, BCPEBCITBLEN);
  108. return (FAIL);
  109. }
  110. dbproc->bcp_tablename = (char *) malloc(strlen(tblname) + 1);
  111. strcpy(dbproc->bcp_tablename, tblname);
  112. if (direction == DB_IN || direction == DB_OUT)
  113. dbproc->bcp_direction = direction;
  114. else {
  115.         _bcp_err_handler(dbproc, BCPEBDIO);
  116. return (FAIL);
  117. }
  118. if (dbproc->bcp_direction == DB_IN) {
  119.         sprintf(query,"select * from %s where 0 = 1", dbproc->bcp_tablename);
  120.         if(tds_submit_query(tds,query) == TDS_FAIL) {
  121. return FAIL;
  122. }
  123.         while((rc= tds_process_result_tokens(tds)) == TDS_SUCCEED);
  124. if (rc != TDS_NO_MORE_RESULTS) {
  125. return FAIL;
  126. }
  127. if (!tds->res_info) {
  128. return FAIL;
  129. }
  130. resinfo = tds->res_info;
  131. dbproc->bcp_colcount = resinfo->num_cols;
  132. dbproc->bcp_columns = (BCP_COLINFO **) malloc(resinfo->num_cols * sizeof(BCP_COLINFO *));
  133. for (i = 0; i < dbproc->bcp_colcount; i++) {
  134. dbproc->bcp_columns[i] = (BCP_COLINFO *) malloc(sizeof(BCP_COLINFO));
  135. bcpcol = dbproc->bcp_columns[i];
  136. memset(bcpcol, '', sizeof(BCP_COLINFO));
  137. bcpcol->tab_colnum = i + 1; /* turn offset into ordinal */
  138. bcpcol->db_type = resinfo->columns[i]->column_type;
  139. bcpcol->db_length = resinfo->columns[i]->column_size;
  140. bcpcol->db_nullable = resinfo->columns[i]->column_nullable;
  141. if (is_numeric_type(bcpcol->db_type)) {
  142. bcpcol->data = (BYTE *) malloc(sizeof(TDS_NUMERIC));
  143. ((TDS_NUMERIC *) bcpcol->data)->precision = resinfo->columns[i]->column_prec;
  144. ((TDS_NUMERIC *) bcpcol->data)->scale = resinfo->columns[i]->column_scale;
  145.             }
  146.             else if(is_blob_type(bcpcol->db_type)) {
  147.                 bcpcol->data= (BYTE*)malloc(16);
  148.                 memset(bcpcol->data, 0, 16);
  149.             }
  150.             else {
  151. bcpcol->data = (BYTE *) malloc(bcpcol->db_length);
  152. if (bcpcol->data == (BYTE *) NULL) {
  153. printf("could not allocate %d bytes of memoryn", bcpcol->db_length);
  154. }
  155. }
  156. bcpcol->data_size = 0;
  157. if (IS_TDS7_PLUS(tds)) {
  158. bcpcol->db_usertype = resinfo->columns[i]->column_usertype;
  159. bcpcol->db_flags = resinfo->columns[i]->column_flags;
  160. bcpcol->db_type_save = resinfo->columns[i]->column_type_save;
  161. bcpcol->db_prec = resinfo->columns[i]->column_prec;
  162. bcpcol->db_scale = resinfo->columns[i]->column_scale;
  163.                 memcpy(bcpcol->db_collate, resinfo->columns[i]->collation, 5);
  164. strcpy(bcpcol->db_name, resinfo->columns[i]->column_name);
  165. bcpcol->db_varint_size = resinfo->columns[i]->column_varint_size;
  166. bcpcol->db_unicodedata = resinfo->columns[i]->column_unicodedata;
  167. }
  168. }
  169.         if(dbproc->bcp_hostfile == NULL) {
  170. dbproc->host_colcount = dbproc->bcp_colcount;
  171. dbproc->host_columns = (BCP_HOSTCOLINFO **) malloc(dbproc->host_colcount * sizeof(BCP_HOSTCOLINFO *));
  172. for (i = 0; i < dbproc->host_colcount; i++) {
  173.                 dbproc->host_columns[i] = (BCP_HOSTCOLINFO *) malloc(sizeof(BCP_HOSTCOLINFO));
  174. memset(dbproc->host_columns[i], '', sizeof(BCP_HOSTCOLINFO));
  175. }
  176. }
  177. }
  178. return SUCCEED;
  179. }
  180. RETCODE bcp_collen(DBPROCESS *dbproc, DBINT varlen, int table_column)
  181. {
  182. BCP_HOSTCOLINFO *hostcol;
  183. if (dbproc->bcp_direction == 0) {
  184.         _bcp_err_handler(dbproc, BCPEBCPI);
  185. return FAIL;
  186. }
  187. if (dbproc->bcp_direction != DB_IN) {
  188.         _bcp_err_handler(dbproc, BCPEBCPN);
  189. return FAIL;
  190. }
  191. if (table_column > dbproc->host_colcount)
  192. return FAIL;
  193. hostcol = dbproc->host_columns[table_column - 1];
  194. hostcol->column_len = varlen;
  195. return SUCCEED;
  196. }
  197. RETCODE bcp_columns(DBPROCESS *dbproc, int host_colcount)
  198. {
  199. int i;
  200. if (dbproc->bcp_direction == 0) {
  201.         _bcp_err_handler(dbproc, BCPEBCPI);
  202. return FAIL;
  203. }
  204. if (dbproc->bcp_hostfile == (char *) NULL) {
  205.         _bcp_err_handler(dbproc, BCPEBIVI);
  206. return FAIL;
  207. }
  208. if (host_colcount < 1) {
  209.         _bcp_err_handler(dbproc, BCPEBCFO);
  210. return FAIL;
  211. }
  212. dbproc->host_colcount = host_colcount;
  213. dbproc->host_columns = (BCP_HOSTCOLINFO **) malloc(host_colcount * sizeof(BCP_HOSTCOLINFO *));
  214. for (i = 0; i < host_colcount; i++) {
  215. dbproc->host_columns[i] = (BCP_HOSTCOLINFO *) malloc(sizeof(BCP_HOSTCOLINFO));
  216. memset(dbproc->host_columns[i], '', sizeof(BCP_HOSTCOLINFO));
  217. }
  218. return SUCCEED;
  219. }
  220. RETCODE bcp_colfmt(DBPROCESS *dbproc, int host_colnum, int host_type, 
  221.                    int host_prefixlen, DBINT host_collen, BYTE *host_term,
  222.                    int host_termlen, int table_colnum)
  223. {
  224. BCP_HOSTCOLINFO *hostcol;
  225. #ifdef MSDBLIB
  226. /* Microsoft specifies a "file_termlen" of zero if there's no terminator */
  227. if (host_termlen == 0)
  228. host_termlen = -1;
  229. #endif
  230. if (dbproc->bcp_direction == 0) {
  231.         _bcp_err_handler(dbproc, BCPEBCPI);
  232. return FAIL;
  233. }
  234. if (dbproc->bcp_hostfile == (char *) NULL) {
  235.         _bcp_err_handler(dbproc, BCPEBIVI);
  236. return FAIL;
  237. }
  238. if (dbproc->host_colcount == 0) {
  239.         _bcp_err_handler(dbproc, BCPEBCBC);
  240. return FAIL;
  241. }
  242. if (host_colnum < 1)
  243. return FAIL;
  244.     if (host_prefixlen != 0 && host_prefixlen != 1 &&
  245.         host_prefixlen != 2 && host_prefixlen != 4 &&
  246.         host_prefixlen != -1 ) {
  247.         _bcp_err_handler(dbproc, BCPEBCPREF);
  248. return FAIL;
  249. }
  250. if (table_colnum == 0 && host_type == 0) {
  251.         _bcp_err_handler(dbproc, BCPEBCPCTYP);
  252. return FAIL;
  253. }
  254.     if (host_prefixlen == 0 && host_collen == -1 && 
  255.         host_termlen == -1 && !is_fixed_type(host_type)) {
  256.         _bcp_err_handler(dbproc, BCPEVDPT);
  257. return FAIL;
  258. }
  259. if (host_collen < -1) {
  260.         _bcp_err_handler(dbproc, BCPEBCHLEN);
  261. return FAIL;
  262. }
  263.     if (is_fixed_type(host_type) && 
  264.         (host_collen != -1 && host_collen != 0))
  265. return FAIL;
  266. /* 
  267.  * If there's a positive terminator length, we need a valid terminator pointer.
  268.  * If the terminator length is 0 or -1, then there's no terminator.
  269.  * FIXME: look up the correct error code for a bad terminator pointer or length and return that before arriving here.   
  270.  */
  271.     /*assert ((host_termlen > 0)? (host_term != NULL) : 1);*/
  272. hostcol = dbproc->host_columns[host_colnum - 1];
  273. hostcol->host_column = host_colnum;
  274. hostcol->datatype = host_type;
  275. hostcol->prefix_len = host_prefixlen;
  276. hostcol->column_len = host_collen;
  277. if (host_term && host_termlen >= 0) { 
  278. hostcol->terminator = (BYTE *) malloc(host_termlen + 1);
  279. memcpy(hostcol->terminator, host_term, host_termlen);
  280. }
  281. hostcol->term_len = host_termlen;
  282. hostcol->tab_colnum = table_colnum;
  283. return SUCCEED;
  284. }
  285. RETCODE bcp_colfmt_ps(DBPROCESS *dbproc, int host_colnum, int host_type, int host_prefixlen, DBINT host_collen, BYTE *host_term,int host_termlen, int table_colnum, DBTYPEINFO *typeinfo)
  286. {
  287. if (dbproc->bcp_direction == 0) {
  288.         _bcp_err_handler(dbproc, BCPEBCPI);
  289. return FAIL;
  290. }
  291. return SUCCEED;
  292. }
  293. RETCODE bcp_control(DBPROCESS *dbproc, int field, DBINT value)
  294. {
  295. if (dbproc->bcp_direction == 0) {
  296.         _bcp_err_handler(dbproc, BCPEBCPI);
  297. return FAIL;
  298. }
  299. switch (field) {
  300.     case BCPMAXERRS: dbproc->maxerrs  = value; break;
  301.     case BCPFIRST:   dbproc->firstrow = value; break;
  302.     case BCPLAST:    dbproc->firstrow = value; break;
  303.     case BCPBATCH:   dbproc->bcpbatch = value; break;
  304. default:
  305.         _bcp_err_handler(dbproc, BCPEIFNB);
  306. return FAIL;
  307. }
  308. return SUCCEED;
  309. }
  310. RETCODE bcp_options(DBPROCESS *dbproc, int option, BYTE *value, int valuelen)
  311. {
  312. int i;
  313. static const char *hints[] =  { "ORDER"
  314. , "ROWS_PER_BATCH"
  315. , "KILOBYTES_PER_BATCH"
  316. , "TABLOCK"
  317. , "CHECK_CONSTRAINTS"
  318. , NULL
  319. };
  320. if (!dbproc)
  321. return FAIL;
  322. switch (option) {
  323. case BCPLABELED:
  324. tdsdump_log (TDS_DBG_FUNC, "%L UNIMPLEMENTED bcp option: BCPLABELEDn");
  325. return FAIL;
  326. case BCPHINTS:
  327.                 if (!value || valuelen <= 0)
  328.                         return FAIL;
  329.                 if (dbproc->bcp_hint != NULL) /* hint already set */
  330.                         return FAIL;
  331. for(i=0; hints[i]; i++ ) { /* do we know about this hint? */
  332. if (strncasecmp((char*) value, hints[i], strlen(hints[i])) == 0)
  333. break;
  334. }
  335. if (!hints[i]) { /* no such hint */
  336. return FAIL;
  337. }
  338. /* 
  339.  * Store the bare hint, as passed from the application.  
  340.  * The process that constructs the "insert bulk" statement will incorporate the hint text.
  341.  */
  342. dbproc->bcp_hint = (char*) malloc(1+valuelen);
  343. memcpy(dbproc->bcp_hint, value, valuelen);
  344. dbproc->bcp_hint[valuelen] = ''; /* null terminate it */
  345. break;
  346. default:
  347. tdsdump_log (TDS_DBG_FUNC, "%L UNIMPLEMENTED bcp option: %un", option);
  348. return FAIL;
  349. }
  350. return SUCCEED;
  351. }
  352. RETCODE
  353. bcp_colptr(DBPROCESS * dbproc, BYTE * colptr, int table_column)
  354. {
  355. BCP_HOSTCOLINFO *hostcol;
  356. if (dbproc->bcp_direction == 0) {
  357.         _bcp_err_handler(dbproc, BCPEBCPI);
  358. return FAIL;
  359. }
  360. if (dbproc->bcp_direction != DB_IN) {
  361.         _bcp_err_handler(dbproc, BCPEBCPN);
  362. return FAIL;
  363. }
  364. if (table_column > dbproc->host_colcount)
  365. return FAIL;
  366. hostcol = dbproc->host_columns[table_column - 1];
  367. hostcol->host_var = colptr;
  368. return SUCCEED;
  369. }
  370. DBBOOL bcp_getl(LOGINREC *login)
  371. {
  372. TDSLOGIN *tdsl = (TDSLOGIN *) login->tds_login;
  373. return (tdsl->bulk_copy);
  374. }
  375. static RETCODE _bcp_exec_out(DBPROCESS *dbproc, DBINT *rows_copied)
  376. {
  377. FILE *hostfile;
  378.     int  ret;
  379. int i;
  380.     int  j;
  381.     int  k;
  382.     char *xx;
  383.     TDSSOCKET     *tds = dbproc->tds_socket;
  384. TDSRESULTINFO *resinfo;
  385. BCP_COLINFO *bcpcol;
  386. TDSCOLINFO *curcol;
  387. BCP_HOSTCOLINFO *hostcol;
  388. BYTE *src;
  389. int srctype;
  390. long len;
  391. int buflen;
  392. int destlen;
  393. BYTE *outbuf;
  394.     char          query[256];
  395. TDS_INT rowtype;
  396. TDS_INT computeid;
  397. TDS_INT result_type;
  398. TDS_TINYINT ti;
  399. TDS_SMALLINT si;
  400. TDS_INT li;
  401. TDSDATEREC when;
  402. int row_of_query;
  403. int rows_written;
  404. if (!(hostfile = fopen(dbproc->bcp_hostfile, "w"))) {
  405.         _bcp_err_handler(dbproc, BCPEBCUO);
  406. return FAIL;
  407. }
  408.     sprintf(query,"select * from %s", dbproc->bcp_tablename);
  409.     tds_submit_query(tds, query);
  410.     if (tds_process_result_tokens(tds) == TDS_FAIL) {
  411. fclose(hostfile);
  412. return FAIL;
  413. }
  414. if (!tds->res_info) {
  415. fclose(hostfile);
  416. return FAIL;
  417. }
  418. resinfo = tds->res_info;
  419. dbproc->bcp_colcount = resinfo->num_cols;
  420. dbproc->bcp_columns = (BCP_COLINFO **) malloc(resinfo->num_cols * sizeof(BCP_COLINFO *));
  421. for (i = 0; i < resinfo->num_cols; i++) {
  422. dbproc->bcp_columns[i] = (BCP_COLINFO *) malloc(sizeof(BCP_COLINFO));
  423. memset(dbproc->bcp_columns[i], '', sizeof(BCP_COLINFO));
  424. dbproc->bcp_columns[i]->tab_colnum = i + 1; /* turn offset into ordinal */
  425. dbproc->bcp_columns[i]->db_type = resinfo->columns[i]->column_type;
  426. dbproc->bcp_columns[i]->db_length = resinfo->columns[i]->column_size;
  427. if (is_numeric_type(resinfo->columns[i]->column_type))
  428. dbproc->bcp_columns[i]->data = (BYTE *) malloc(sizeof(TDS_NUMERIC));
  429. else
  430. dbproc->bcp_columns[i]->data = (BYTE *) malloc(dbproc->bcp_columns[i]->db_length);
  431. dbproc->bcp_columns[i]->data_size = 0;
  432. }
  433. row_of_query = 0;
  434. rows_written = 0;
  435.     while (tds_process_row_tokens(tds)==TDS_SUCCEED) {
  436. row_of_query++;
  437. if ((dbproc->firstrow == 0 && dbproc->lastrow == 0) ||
  438.    /** FIX this! */
  439.             ((dbproc->firstrow > 0 && row_of_query >= dbproc->firstrow) &&
  440.              (dbproc->lastrow > 0 && row_of_query <= dbproc->lastrow))) {
  441. for (i = 0; i < dbproc->bcp_colcount; i++) {
  442. bcpcol = dbproc->bcp_columns[i];
  443. curcol = resinfo->columns[bcpcol->tab_colnum - 1];
  444. src = &resinfo->current_row[curcol->column_offset];
  445. if (is_blob_type(curcol->column_type)) {
  446. /* FIX ME -- no converts supported */
  447. src = (BYTE*) ((TDSBLOBINFO *) src)->textvalue;
  448. len = curcol->cur_row_size;
  449. } else {
  450. srctype = tds_get_conversion_type(curcol->column_type, curcol->column_size);
  451. if (srctype != bcpcol->db_type) {
  452. bcpcol->db_type = srctype;
  453. }
  454. if (is_numeric_type(curcol->column_type))
  455. memcpy(bcpcol->data, src, sizeof(TDS_NUMERIC));
  456. else
  457. memcpy(bcpcol->data, src, curcol->column_size);
  458. /* null columns have zero output */
  459. if (tds_get_null(resinfo->current_row, bcpcol->tab_colnum - 1))
  460. bcpcol->data_size = 0;
  461. else
  462. bcpcol->data_size = curcol->cur_row_size;
  463. }
  464. }
  465. for (i = 0; i < dbproc->host_colcount; i++) {
  466. hostcol = dbproc->host_columns[i];
  467. if ((hostcol->tab_colnum < 1)
  468.     || (hostcol->tab_colnum > dbproc->bcp_colcount)) {
  469. continue;
  470. }
  471. if (hostcol->tab_colnum) {
  472. bcpcol = dbproc->bcp_columns[hostcol->tab_colnum - 1];
  473. if (bcpcol->tab_colnum != hostcol->tab_colnum) {
  474. return FAIL;
  475. }
  476. }
  477. /*assert(bcpcol);*/
  478. if (hostcol->datatype == 0)
  479. hostcol->datatype = bcpcol->db_type;
  480. /* work out how much space to allocate for output data */
  481. switch (hostcol->datatype) {
  482.                 case SYBINT1:        buflen = destlen = 1;  break;
  483.                 case SYBINT2:        buflen = destlen = 2;  break;
  484.                 case SYBINT4:        buflen = destlen = 4;  break;
  485.                 case SYBREAL:        buflen = destlen = 4;  break;
  486.                 case SYBFLT8:        buflen = destlen = 8;  break;
  487.                 case SYBDATETIME:    buflen = destlen = 8;  break;
  488.                 case SYBDATETIME4:   buflen = destlen = 4;  break;
  489.                 case SYBBIT:         buflen = destlen = 1;  break;
  490.                 case SYBBITN:        buflen = destlen = 1;  break;
  491.                 case SYBMONEY:       buflen = destlen = 8;  break;
  492.                 case SYBMONEY4:      buflen = destlen = 4;  break;
  493. case SYBCHAR:
  494. case SYBVARCHAR:
  495. switch (bcpcol->db_type) {
  496. case SYBVARCHAR:
  497. buflen = bcpcol->db_length + 1;
  498. destlen = -1;
  499. break;
  500. case SYBCHAR:
  501. buflen = bcpcol->db_length + 1;
  502. destlen = -2;
  503. break;
  504. case SYBINT1:
  505. buflen = 4 + 1; /*  255         */
  506. destlen = -1;
  507. break;
  508. case SYBINT2:
  509. buflen = 6 + 1; /* -32768       */
  510. destlen = -1;
  511. break;
  512. case SYBINT4:
  513. buflen = 11 + 1; /* -2147483648  */
  514. destlen = -1;
  515. break;
  516. case SYBNUMERIC:
  517. buflen = 40 + 1; /* 10 to the 38 */
  518. destlen = -1;
  519. break;
  520. case SYBDECIMAL:
  521. buflen = 40 + 1; /* 10 to the 38 */
  522. destlen = -1;
  523. break;
  524. case SYBFLT8:
  525. buflen = 40 + 1; /* 10 to the 38 */
  526. destlen = -1;
  527. break;
  528. case SYBDATETIME:
  529. buflen = 255 + 1;
  530. destlen = -1;
  531. break;
  532. default:
  533. buflen = 255 + 1;
  534. destlen = -1;
  535. break;
  536. }
  537. break;
  538. default:
  539. buflen = destlen = 255;
  540. }
  541. outbuf = (BYTE*) malloc(buflen);
  542. /* if we are converting datetime to string, need to override any 
  543.  * date time formats already established
  544.  */
  545. if ((bcpcol->db_type == SYBDATETIME || bcpcol->db_type == SYBDATETIME4)
  546.     && (hostcol->datatype == SYBCHAR || hostcol->datatype == SYBVARCHAR)) {
  547. memset(&when, 0, sizeof(when));
  548. tds_datecrack(bcpcol->db_type, bcpcol->data, &when);
  549. buflen = tds_strftime((char*)outbuf, buflen, "%Y-%m-%d %H:%M:%S.%z", &when);
  550. } else {
  551. /* 
  552.  * For null columns, the above work to determine the output buffer size is moot, 
  553.  * because bcpcol->data_size is zero, so dbconvert() won't write anything, and returns zero. 
  554.  */
  555. buflen = dbconvert(dbproc,
  556.    bcpcol->db_type,
  557.    bcpcol->data, bcpcol->data_size, hostcol->datatype, outbuf, destlen);
  558. }
  559. /* FIX ME -- does not handle prefix_len == -1 */
  560. /* The prefix */
  561. switch (hostcol->prefix_len) {
  562. case -1:
  563. if (!(is_fixed_type(hostcol->datatype))) {
  564. si = buflen;
  565. fwrite(&si, sizeof(si), 1, hostfile);
  566. }
  567. break;
  568. case 1:
  569. ti = buflen;
  570. fwrite(&ti, sizeof(ti), 1, hostfile);
  571. break;
  572. case 2:
  573. si = buflen;
  574. fwrite(&si, sizeof(si), 1, hostfile);
  575. break;
  576. case 4:
  577. li = buflen;
  578. fwrite(&li, sizeof(li), 1, hostfile);
  579. break;
  580. }
  581. /* The data */
  582. if (is_blob_type(curcol->column_type)) {
  583. fwrite(src, len, 1, hostfile);
  584. } else {
  585. if (hostcol->column_len != -1) {
  586. buflen = buflen > hostcol->column_len ? hostcol->column_len : buflen;
  587. }
  588. fwrite(outbuf, buflen, 1, hostfile);
  589. }
  590. free(outbuf);
  591. /* The terminator */
  592. if (hostcol->terminator && hostcol->term_len > 0) {
  593. fwrite(hostcol->terminator, hostcol->term_len, 1, hostfile);
  594. }
  595. }
  596. rows_written++;
  597. }
  598. }
  599. if (fclose(hostfile) != 0) {
  600.         _bcp_err_handler(dbproc, BCPEBCUC);
  601. return (FAIL);
  602. }
  603.     printf("firstrow = %d row_of_query = %d rows written %dn",
  604.            dbproc->firstrow, row_of_query, rows_written);
  605. if (dbproc->firstrow > 0 && row_of_query < dbproc->firstrow) {
  606. /* The table which bulk-copy is attempting to
  607.  * copy to a host-file is shorter than the
  608.  * number of rows which bulk-copy was instructed
  609.  * to skip.  
  610.  */
  611.         _bcp_err_handler(dbproc, BCPETTS);
  612. return (FAIL);
  613. }
  614. *rows_copied = rows_written;
  615. return SUCCEED;
  616. }
  617. RETCODE _bcp_read_hostfile(DBPROCESS *dbproc, FILE *hostfile)
  618. {
  619. BCP_COLINFO *bcpcol;
  620. BCP_HOSTCOLINFO *hostcol;
  621. int i;
  622. TDS_TINYINT ti;
  623. TDS_SMALLINT si;
  624. TDS_INT li;
  625. int collen;
  626. int data_is_null;
  627. int bytes_read;
  628. int converted_data_size;
  629. TDS_INT desttype;
  630. /* for each host file column defined by calls to bcp_colfmt */
  631. for (i = 0; i < dbproc->host_colcount; i++) {
  632. BYTE coldata[256];
  633. hostcol = dbproc->host_columns[i];
  634. data_is_null = 0;
  635. collen = 0;
  636. /* if a prefix length specified, read the correct */
  637. /* amount of data...                              */
  638. if (hostcol->prefix_len > 0) {
  639. switch (hostcol->prefix_len) {
  640. case 1:
  641. if (fread(&ti, 1, 1, hostfile) != 1) {
  642.                     _bcp_err_handler(dbproc, BCPEBCRE);
  643. return (FAIL);
  644. }
  645. collen = ti;
  646. break;
  647. case 2:
  648. if (fread(&si, 2, 1, hostfile) != 1) {
  649.                     _bcp_err_handler(dbproc, BCPEBCRE);
  650. return (FAIL);
  651. }
  652. collen = si;
  653. break;
  654. case 4:
  655. if (fread(&li, 4, 1, hostfile) != 1) {
  656.                     _bcp_err_handler(dbproc, BCPEBCRE);
  657. return (FAIL);
  658. }
  659. collen = li;
  660. break;
  661. default:
  662.              /*assert(hostcol->prefix_len <= 4);*/
  663. break;
  664. }
  665. if (collen == 0)
  666. data_is_null = 1;
  667. }
  668. /* if (Max) column length specified take that into */
  669. /* consideration...                                */
  670. if (!data_is_null && hostcol->column_len >= 0) {
  671. if (hostcol->column_len == 0)
  672. data_is_null = 1;
  673. else {
  674. if (collen)
  675. collen = (hostcol->column_len < collen) ? hostcol->column_len : collen;
  676. else
  677. collen = hostcol->column_len;
  678. }
  679. }
  680. /* Fixed Length data - this over-rides anything else specified */
  681. if (is_fixed_type(hostcol->datatype)) {
  682.             collen = get_size_by_type(hostcol->datatype);
  683. }
  684. #ifdef NCBI_FTDS
  685.       else if(hostcol->prefix_len <= 0 && hostcol->term_len <= 0) {
  686.           /* we need to know the size anyway */
  687.           if (fread(&si, 2, 1, hostfile) != 1) {
  688.               _bcp_err_handler(dbproc, BCPEBCRE);
  689.               return (FAIL);
  690.           }
  691.           collen = si;
  692.       }
  693. #endif
  694. /* if this host file column contains table data,   */
  695. /* find the right element in the table/column list */
  696. if (hostcol->tab_colnum) {
  697. bcpcol = dbproc->bcp_columns[hostcol->tab_colnum - 1];
  698. if (bcpcol->tab_colnum != hostcol->tab_colnum) {
  699. return FAIL;
  700. }
  701. }
  702. /* a terminated field is specified - get the data into temporary space... */
  703. memset(coldata, '', sizeof(coldata));
  704. if (hostcol->term_len > 0) {
  705. bytes_read = _bcp_get_term_data(hostfile, hostcol, coldata);
  706. if (bytes_read == -1)
  707. return FAIL;
  708. if (collen)
  709. collen = (bytes_read < collen) ? bytes_read : collen;
  710. else
  711. collen = bytes_read;
  712. if (collen == 0)
  713. data_is_null = 1;
  714. } else {
  715. if (collen) {
  716. if (fread(coldata, collen, 1, hostfile) != 1) {
  717.                     _bcp_err_handler(dbproc, BCPEBCRE);
  718. return (FAIL);
  719. }
  720. }
  721. }
  722. if (hostcol->tab_colnum) {
  723. if (data_is_null) {
  724. bcpcol->data_size = 0;
  725.                 }
  726.                 else {
  727. desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
  728. converted_data_size =
  729. dbconvert(dbproc, hostcol->datatype, coldata, collen, desttype, 
  730.   bcpcol->data, bcpcol->db_length);
  731.   
  732. if (converted_data_size == FAIL) 
  733. return (FAIL);
  734. if (desttype == SYBVARCHAR) {
  735.                         bcpcol->data_size = _bcp_rtrim_varchar(bcpcol->data, converted_data_size);
  736.                     }
  737.                     else {
  738. bcpcol->data_size = converted_data_size;
  739. }
  740. }
  741. }
  742. }
  743. return SUCCEED;
  744. }
  745. /* read a terminated variable from a hostfile */
  746. RETCODE _bcp_get_term_data(FILE *hostfile, BCP_HOSTCOLINFO *hostcol, BYTE *coldata )
  747. {
  748. int j = 0;
  749. int termfound = 1;
  750. char x;
  751. char *tester = NULL;
  752. int bufpos = 0;
  753. int found = 0;
  754. if (hostcol->term_len > 1)
  755. tester = (char *) malloc(hostcol->term_len);
  756. while (!found && (x = getc(hostfile)) != EOF) {
  757. if (x != *hostcol->terminator) {
  758. *(coldata + bufpos) = x;
  759. bufpos++;
  760.         }
  761.         else {
  762. if (hostcol->term_len == 1) {
  763. *(coldata + bufpos) = '';
  764. found = 1;
  765.             }
  766.             else {
  767. ungetc(x, hostfile);
  768. fread(tester, hostcol->term_len, 1, hostfile);
  769. termfound = 1;
  770. for (j = 0; j < hostcol->term_len; j++)
  771. if (*(tester + j) != *(hostcol->terminator + j))
  772. termfound = 0;
  773. if (termfound) {
  774. *(coldata + bufpos) = '';
  775. found = 1;
  776.                 }
  777.                 else {
  778. for (j = 0; j < hostcol->term_len; j++) {
  779. *(coldata + bufpos) = *(tester + j);
  780. bufpos++;
  781. }
  782. }
  783. }
  784. }
  785. }
  786. if (found) {
  787. return (bufpos);
  788.     }
  789.     else {
  790. return (-1);
  791. }
  792. }
  793. /*
  794. ** Add fixed size columns to the row
  795. */
  796. static int _bcp_add_fixed_columns(DBPROCESS *dbproc, BYTE *rowbuffer, int start)
  797. {
  798. TDS_NUMERIC *num;
  799. int row_pos = start;
  800. BCP_COLINFO *bcpcol;
  801. int cpbytes;
  802. int i;
  803. for (i = 0; i < dbproc->bcp_colcount; i++) {
  804. bcpcol = dbproc->bcp_columns[i];
  805.         if (!is_nullable_type(bcpcol->db_type) &&
  806.             !(bcpcol->db_nullable)) {
  807. if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
  808.                 _bcp_err_handler(dbproc, BCPEBCNN);
  809. return FAIL;
  810. }
  811. if (is_numeric_type(bcpcol->db_type)) {
  812. num = (TDS_NUMERIC *) bcpcol->data;
  813.                 cpbytes = g__numeric_bytes_per_prec[num->precision];
  814. memcpy(&rowbuffer[row_pos], num->array, cpbytes);
  815.             }
  816.             else {
  817.                 cpbytes = bcpcol->data_size > bcpcol->db_length 
  818.                     ? bcpcol->db_length : bcpcol->data_size;
  819. memcpy(&rowbuffer[row_pos], bcpcol->data, cpbytes);
  820. }
  821. /* Bill T commenting this out. It always seems to print 
  822.                This error message regardless...
  823.                if (row_pos != bcpcol->db_offset) {
  824.                fprintf(stderr,"Error: computed offset does not match one returned from database enginen");
  825.                }
  826.  */
  827. row_pos += bcpcol->db_length;
  828. }
  829. }
  830. return row_pos;
  831. }
  832. /*
  833. ** Add variable size columns to the row
  834. */
  835. static int _bcp_add_variable_columns(DBPROCESS *dbproc, BYTE *rowbuffer, int start)
  836. {
  837. TDSSOCKET *tds = dbproc->tds_socket;
  838. BCP_COLINFO *bcpcol;
  839. TDS_NUMERIC *num;
  840. int row_pos = start;
  841. int cpbytes;
  842. int eod_ptr;
  843. BYTE offset_table[256];
  844. int offset_pos = 0;
  845. BYTE adjust_table[256];
  846. int adjust_pos = 0;
  847. int num_cols = 0;
  848. int i;
  849. for (i = 0; i < dbproc->bcp_colcount; i++) {
  850. bcpcol = dbproc->bcp_columns[i];
  851.         if (is_nullable_type(bcpcol->db_type) || 
  852.             bcpcol->db_nullable) {
  853. if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
  854.                 _bcp_err_handler(dbproc, BCPEBCNN);
  855. return FAIL;
  856. }
  857. if (is_blob_type(bcpcol->db_type)) {
  858. /* no need to copy they are all zero bytes */
  859. cpbytes = 16;
  860. /* save for data write */
  861. bcpcol->txptr_offset = row_pos;
  862.             } 
  863.             else if (is_numeric_type(bcpcol->db_type)) {
  864. num = (TDS_NUMERIC *) bcpcol->data;
  865.                 cpbytes = g__numeric_bytes_per_prec[num->precision];
  866. memcpy(&rowbuffer[row_pos], num->array, cpbytes);
  867.             }
  868.             else {
  869. /* compute the length to copy to the row ** buffer */
  870.                 cpbytes = bcpcol->data_size > bcpcol->db_length 
  871.                     ? bcpcol->db_length : bcpcol->data_size;
  872. memcpy(&rowbuffer[row_pos], bcpcol->data, cpbytes);
  873. }
  874. /* update offset and adjust tables (if necessary) */
  875. offset_table[offset_pos++] = row_pos % 256;
  876.             if (row_pos > 255 && 
  877.                 (adjust_pos==0 || row_pos/256 != adjust_table[adjust_pos])) {
  878. adjust_table[adjust_pos++] = row_pos / 256;
  879. }
  880. num_cols++;
  881. row_pos += cpbytes;
  882. }
  883. }
  884. eod_ptr = row_pos;
  885. /* write the marker */
  886. if (IS_TDS50(tds))
  887. rowbuffer[row_pos++] = num_cols + 1;
  888. /* write the adjust table (right to left) */
  889. for (i = adjust_pos - 1; i >= 0; i--) {
  890. /* fprintf(stderr,"adjust %dn",adjust_table[i]); */
  891. rowbuffer[row_pos++] = adjust_table[i];
  892. }
  893. /* the EOD (end of data) pointer */
  894. rowbuffer[row_pos++] = eod_ptr;
  895. /* write the offset table (right to left) */
  896. for (i = offset_pos - 1; i >= 0; i--) {
  897. /* fprintf(stderr,"offset %dn",offset_table[i]); */
  898. rowbuffer[row_pos++] = offset_table[i];
  899. }
  900. return row_pos;
  901. }
  902. RETCODE bcp_sendrow(DBPROCESS *dbproc)
  903. {
  904. TDSSOCKET *tds = dbproc->tds_socket;
  905. BCP_COLINFO *bcpcol;
  906.     BCP_HOSTCOLINFO *hostcol;
  907.     TDSCOLINFO      *curcol;
  908. int i;
  909.     int collen;
  910. /* FIX ME -- calculate dynamically */
  911. unsigned char rowbuffer[ROWBUF_SIZE];
  912. int row_pos;
  913. int row_sz_pos;
  914. TDS_SMALLINT row_size;
  915.     TDS_SMALLINT row_size_saved;
  916.     int marker;
  917. int blob_cols = 0;
  918. unsigned char CHARBIN_NULL[] = { 0xff, 0xff };
  919. unsigned char GEN_NULL = 0x00;
  920. TDS_NUMERIC *num;
  921. TDS_TINYINT numeric_size;
  922. unsigned char row_token = 0xd1;
  923. if (dbproc->bcp_direction == 0) {
  924.         _bcp_err_handler(dbproc, BCPEBCPI);
  925. return FAIL;
  926. }
  927. if (dbproc->bcp_hostfile != (char *) NULL) {
  928.         _bcp_err_handler(dbproc, BCPEBCPB);
  929. return FAIL;
  930. }
  931. if (dbproc->bcp_direction != DB_IN) {
  932.         _bcp_err_handler(dbproc, BCPEBCPN);
  933. return FAIL;
  934. }
  935. /* The first time sendrow is called after bcp_init,  */
  936. /* there is a certain amount of initialisation to be */
  937. /* done...                                           */
  938. if (!(dbproc->sendrow_init)) {
  939. /* first call the start_copy function, which will */
  940. /* retrieve details of the database table columns */
  941. if (_bcp_start_copy_in(dbproc) == FAIL)
  942. return (FAIL);
  943. #ifndef NCBI_FTDS
  944.         /* Next, allocate the storage to hold data about the */
  945.         /* program variable data - these must be the same in */
  946.         /* number as the table columns...                    */
  947.         dbproc->host_colcount = dbproc->bcp_colcount;
  948.         dbproc->host_columns  = (BCP_HOSTCOLINFO **) malloc(dbproc->host_colcount * sizeof(BCP_HOSTCOLINFO *));
  949.         for ( i = 0; i < dbproc->host_colcount; i++ ) {
  950.             dbproc->host_columns[i] = (BCP_HOSTCOLINFO *) malloc(sizeof(BCP_HOSTCOLINFO));
  951.             memset(dbproc->host_columns[i], '', sizeof(BCP_HOSTCOLINFO));
  952.         }
  953. #endif
  954. /* set packet type to send bulk data */
  955. tds->out_flag = 0x07;
  956. if (IS_TDS7_PLUS(tds)) {
  957. _bcp_send_colmetadata(dbproc);
  958. }
  959. dbproc->sendrow_init = 1;
  960. }
  961. if (_bcp_get_prog_data(dbproc) == SUCCEED) {
  962. if (IS_TDS7_PLUS(tds)) {
  963. tds_put_byte(tds, row_token); /* 0xd1 */
  964. #ifdef NCBI_FTDS
  965.             dbproc->curr_text_col= 0;
  966. #endif
  967. for (i = 0; i < dbproc->bcp_colcount; i++) {
  968. bcpcol = dbproc->bcp_columns[i];
  969. #ifdef NCBI_FTDS
  970.                 if(dbproc->host_columns[i]->datatype == 0) continue;
  971.                 if(is_blob_type(bcpcol->db_type)) continue;
  972. #endif
  973.                 if (bcpcol->data_size == 0 ) /* Are we trying to insert a NULL ? */ {
  974.                     if(bcpcol->db_nullable)   /* is the column nullable ? */ {
  975.                         if (bcpcol->db_type_save == XSYBCHAR || 
  976.                             bcpcol->db_type_save == XSYBVARCHAR ||
  977.                             bcpcol->db_type_save == XSYBBINARY ||
  978.                             bcpcol->db_type_save == XSYBVARBINARY|| 
  979.                             bcpcol->db_type_save == XSYBNCHAR || 
  980.                             bcpcol->db_type_save == XSYBNVARCHAR) {
  981. tds_put_n(tds, CHARBIN_NULL, 2);
  982.                         }
  983.                         else {
  984. tds_put_byte(tds, GEN_NULL);
  985. }
  986.                     }
  987.                     else {
  988.                         _bcp_err_handler(dbproc, BCPEBCNN);
  989.                         return FAIL;
  990.                     }
  991.                 }
  992.                 else {   
  993. switch (bcpcol->db_varint_size) {
  994.                     case 4: tds_put_int(tds, bcpcol->data_size);
  995. break;
  996.                     case 2: tds_put_smallint(tds, bcpcol->data_size);
  997. break;
  998.                     case 1: if (is_numeric_type(bcpcol->db_type)) {
  999.                         numeric_size = g__numeric_bytes_per_prec[bcpcol->db_prec];
  1000. tds_put_byte(tds, numeric_size);
  1001.                     }
  1002.                     else
  1003. tds_put_byte(tds, bcpcol->data_size);
  1004. break;
  1005.                     case 0: break;
  1006. }
  1007. #if WORDS_BIGENDIAN
  1008.                if (tds->emul_little_endian) {
  1009.                     tds_swap_datatype(tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length),
  1010.                                       bcpcol->data);
  1011.                }
  1012. #endif
  1013. if (is_numeric_type(bcpcol->db_type)) {
  1014. num = (TDS_NUMERIC *) bcpcol->data;
  1015. #ifdef NCBI_FTDS
  1016.                         tds_put_n(tds, num->array, g__numeric_bytes_per_prec[bcpcol->db_prec]);
  1017. #else
  1018.                         tds_put_n(tds, num->array, g__numeric_bytes_per_prec[num->precision]);
  1019. #endif
  1020.                     }
  1021. #if 0
  1022.                     else if(is_blob_type(bcpcol->db_type)) { //add blob data
  1023.                         int ss;
  1024.                         char blob_buff[256];
  1025.                         for(marker= 0; marker < 256;) {
  1026.                             blob_buff[marker++]= 'T';
  1027.                             blob_buff[marker++]= 'E';
  1028.                             blob_buff[marker++]= 'S';
  1029.                             blob_buff[marker++]= 't';
  1030.                         }
  1031.                         for(marker = bcpcol->data_size; marker > 0; marker-= ss) {
  1032.                             ss= (marker > 256)? 256 : marker;
  1033.                             tds_put_n(tds, blob_buff, ss);
  1034.                         }
  1035.                     }
  1036. #endif
  1037.                     else
  1038. tds_put_n(tds, bcpcol->data, bcpcol->data_size);
  1039. }
  1040. }
  1041. return SUCCEED;
  1042.         }
  1043.         else    /* Not TDS 7 or 8 */    {
  1044. memset(rowbuffer, '', ROWBUF_SIZE); /* zero the rowbuffer */
  1045. /* offset 0 = number of var columns */
  1046. /* offset 1 = row number.  zeroed (datasever assigns) */
  1047. row_pos = 2;
  1048. rowbuffer[0] = dbproc->var_cols;
  1049.             if (row_pos = _bcp_add_fixed_columns(dbproc, rowbuffer, row_pos) == FAIL)
  1050. return (FAIL);
  1051. row_sz_pos = row_pos;
  1052. if (dbproc->var_cols) {
  1053. row_pos += 2; /* skip over row length */
  1054. if ((row_pos = _bcp_add_variable_columns(dbproc, rowbuffer, row_pos)) == FAIL)
  1055. return (FAIL);
  1056. }
  1057. row_size = row_pos;
  1058. if (dbproc->var_cols)
  1059. memcpy(&rowbuffer[row_sz_pos], &row_size, sizeof(row_size));
  1060. tds_put_smallint(tds, row_size);
  1061. tds_put_n(tds, rowbuffer, row_size);
  1062. /* row is done, now handle any text/image data */
  1063. blob_cols = 0;
  1064. for (i = 0; i < dbproc->bcp_colcount; i++) {
  1065. bcpcol = dbproc->bcp_columns[i];
  1066. if (is_blob_type(bcpcol->db_type)) {
  1067. /* unknown but zero */
  1068. tds_put_smallint(tds, 0);
  1069. tds_put_byte(tds, bcpcol->db_type);
  1070. tds_put_byte(tds, 0xff - blob_cols);
  1071. /* offset of txptr we stashed during variable
  1072.                     ** column processing */
  1073. tds_put_smallint(tds, bcpcol->txptr_offset);
  1074. tds_put_int(tds, bcpcol->data_size);
  1075. tds_put_n(tds, bcpcol->data, bcpcol->data_size);
  1076. blob_cols++;
  1077. }
  1078. }
  1079. return SUCCEED;
  1080. }
  1081. }
  1082. return FAIL;
  1083. }
  1084. static RETCODE _bcp_exec_in(DBPROCESS *dbproc, DBINT *rows_copied)
  1085. {
  1086. FILE *hostfile, *errfile;
  1087. TDSSOCKET *tds = dbproc->tds_socket;
  1088. BCP_COLINFO *bcpcol;
  1089. /* FIX ME -- calculate dynamically */
  1090. unsigned char rowbuffer[ROWBUF_SIZE];
  1091. int row_pos;
  1092. /* end of data pointer...the last byte of var data before the adjust table */
  1093. int row_sz_pos;
  1094. TDS_SMALLINT row_size;
  1095. const unsigned char CHARBIN_NULL[] = { 0xff, 0xff };
  1096. const unsigned char GEN_NULL = 0x00;
  1097. const unsigned char row_token = 0xd1;
  1098. TDS_NUMERIC *num;
  1099. TDS_TINYINT numeric_size;
  1100. int i;
  1101. int marker;
  1102. int blob_cols = 0;
  1103. int row_of_hostfile;
  1104. int rows_written_so_far;
  1105. int rows_copied_this_batch = 0;
  1106. int rows_copied_so_far = 0;
  1107. if (!(hostfile = fopen(dbproc->bcp_hostfile, "r"))) {
  1108.         _bcp_err_handler(dbproc, BCPEBCUO);
  1109. return FAIL;
  1110. }
  1111. if (dbproc->bcp_errorfile) {
  1112. if (!(errfile = fopen(dbproc->bcp_errorfile, "w"))) {
  1113. _bcp_err_handler(dbproc, SYBEBUOE);
  1114. return FAIL;
  1115. }
  1116. }
  1117. if (_bcp_start_copy_in(dbproc) == FAIL)
  1118. return (FAIL);
  1119. tds->out_flag = 0x07;
  1120. if (IS_TDS7_PLUS(tds)) {
  1121. _bcp_send_colmetadata(dbproc);
  1122. }
  1123. row_of_hostfile = 0;
  1124. rows_written_so_far = 0;
  1125. while (_bcp_read_hostfile(dbproc, hostfile/*, errfile*/) == SUCCEED) {
  1126. row_of_hostfile++;
  1127. if ((dbproc->firstrow == 0 && dbproc->lastrow == 0) ||
  1128.     ((dbproc->firstrow > 0 && row_of_hostfile >= dbproc->firstrow)
  1129.      && (dbproc->lastrow > 0 && row_of_hostfile <= dbproc->lastrow))
  1130. ) {
  1131. if (IS_TDS7_PLUS(tds)) {
  1132. tds_put_byte(tds, row_token); /* 0xd1 */
  1133. for (i = 0; i < dbproc->bcp_colcount; i++) {
  1134. bcpcol = dbproc->bcp_columns[i];
  1135. if (bcpcol->data_size == 0) { /* Are we trying to insert a NULL ? */
  1136. if (!bcpcol->db_nullable){
  1137. /* too bad if the column is not nullable */
  1138. fprintf(errfile, "Column is not nullable. Row %d, Column %dn", 
  1139. row_of_hostfile, i);
  1140. fwrite(bcpcol->data, bcpcol->data_size, 1, errfile);
  1141. _bcp_err_handler(dbproc, BCPEBCNN);
  1142. return FAIL;
  1143. }
  1144. switch (bcpcol->db_type_save) {
  1145. case XSYBCHAR:
  1146. case XSYBVARCHAR:
  1147. case XSYBBINARY:
  1148. case XSYBVARBINARY:
  1149. case XSYBNCHAR:
  1150. case XSYBNVARCHAR:
  1151. tds_put_n(tds, CHARBIN_NULL, 2);
  1152. break;
  1153. default :
  1154. tds_put_byte(tds, GEN_NULL);
  1155. break;
  1156. }
  1157. } else {
  1158. switch (bcpcol->db_varint_size) {
  1159. case 4:
  1160. tds_put_int(tds, bcpcol->data_size);
  1161. break;
  1162. case 2:
  1163. tds_put_smallint(tds, bcpcol->data_size);
  1164. break;
  1165. case 1:
  1166. if (is_numeric_type(bcpcol->db_type)) {
  1167. numeric_size = tds_numeric_bytes_per_prec[bcpcol->db_prec];
  1168. tds_put_byte(tds, numeric_size);
  1169. } else
  1170. tds_put_byte(tds, bcpcol->data_size);
  1171. break;
  1172. case 0:
  1173. break;
  1174. default:
  1175.                       /*assert(bcpcol->db_varint_size <= 4);*/
  1176. break;
  1177. }
  1178. #ifdef WORDS_BIGENDIAN
  1179. tds_swap_datatype
  1180. (tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length), bcpcol->data);
  1181. #else
  1182. if (is_numeric_type(bcpcol->db_type)) {
  1183. tds_swap_datatype
  1184. (tds_get_conversion_type
  1185.  (bcpcol->db_type, bcpcol->db_length), bcpcol->data);
  1186. }
  1187. #endif
  1188. if (is_numeric_type(bcpcol->db_type)) {
  1189. num = (TDS_NUMERIC *) bcpcol->data;
  1190.                             tds_put_n(tds, num->array, g__numeric_bytes_per_prec[num->precision]);
  1191.                         }
  1192.                         else
  1193. tds_put_n(tds, bcpcol->data, bcpcol->data_size);
  1194. }
  1195. }
  1196.             }
  1197.             else    /* Not TDS 7 or 8 */    {
  1198. memset(rowbuffer, '', ROWBUF_SIZE); /* zero the rowbuffer */
  1199. /* offset 0 = number of var columns */
  1200. /* offset 1 = row number.  zeroed (datasever assigns) */
  1201. row_pos = 2;
  1202. rowbuffer[0] = dbproc->var_cols;
  1203. if ((row_pos = _bcp_add_fixed_columns(dbproc, rowbuffer, row_pos)) == FAIL)
  1204. return (FAIL);
  1205. row_sz_pos = row_pos;
  1206. if (dbproc->var_cols) {
  1207. row_pos += 2; /* skip over row length */
  1208.                     if ((row_pos = _bcp_add_variable_columns(dbproc, rowbuffer, row_pos)) == FAIL)
  1209. return (FAIL);
  1210. }
  1211. row_size = row_pos;
  1212. if (dbproc->var_cols)
  1213. memcpy(&rowbuffer[row_sz_pos], &row_size, sizeof(row_size));
  1214. tds_put_smallint(tds, row_size);
  1215. tds_put_n(tds, rowbuffer, row_size);
  1216. /* row is done, now handle any text/image data */
  1217. blob_cols = 0;
  1218. for (i = 0; i < dbproc->bcp_colcount; i++) {
  1219. bcpcol = dbproc->bcp_columns[i];
  1220. if (is_blob_type(bcpcol->db_type)) {
  1221. /* unknown but zero */
  1222. tds_put_smallint(tds, 0);
  1223. tds_put_byte(tds, bcpcol->db_type);
  1224. tds_put_byte(tds, 0xff - blob_cols);
  1225. /* offset of txptr we stashed during variable
  1226.                         ** column processing */
  1227. tds_put_smallint(tds, bcpcol->txptr_offset);
  1228. tds_put_int(tds, bcpcol->data_size);
  1229. tds_put_n(tds, bcpcol->data, bcpcol->data_size);
  1230. blob_cols++;
  1231. }
  1232. }
  1233. } /* Not TDS  7.0 or 8.0 */
  1234. rows_written_so_far++;
  1235. if (dbproc->bcpbatch > 0 && rows_written_so_far == dbproc->bcpbatch) {
  1236. rows_written_so_far = 0;
  1237. tds_flush_packet(tds);
  1238. do {
  1239. marker = tds_get_byte(tds);
  1240. if (marker == TDS_DONE_TOKEN) {
  1241. tds_process_end(tds, marker, NULL,NULL);
  1242. rows_copied_this_batch = tds->rows_affected;
  1243. rows_copied_so_far += rows_copied_this_batch;
  1244.                     } 
  1245.                     else {
  1246. tds_process_default_tokens(tds, marker);
  1247. }
  1248. } while (marker != TDS_DONE_TOKEN);
  1249. _bcp_start_new_batch(dbproc);
  1250. }
  1251. }
  1252. }
  1253. if (fclose(hostfile) != 0) {
  1254.         _bcp_err_handler(dbproc, BCPEBCUC);
  1255. return (FAIL);
  1256. }
  1257. tds_flush_packet(tds);
  1258. do {
  1259. marker = tds_get_byte(tds);
  1260. if (marker == TDS_DONE_TOKEN) {
  1261. tds_process_end(tds, marker, NULL,NULL);
  1262. rows_copied_this_batch = tds->rows_affected;
  1263. rows_copied_so_far += rows_copied_this_batch;
  1264. *rows_copied = rows_copied_so_far;
  1265.         } 
  1266.         else {
  1267. tds_process_default_tokens(tds, marker);
  1268. }
  1269. } while (marker != TDS_DONE_TOKEN);
  1270. return SUCCEED;
  1271. }
  1272. RETCODE bcp_exec(DBPROCESS *dbproc, DBINT *rows_copied)
  1273. {
  1274. RETCODE ret;
  1275. if (dbproc->bcp_direction == 0) {
  1276.         _bcp_err_handler(dbproc, BCPEBCPI);
  1277. return FAIL;
  1278. }
  1279. if (dbproc->bcp_hostfile) {
  1280. if (dbproc->bcp_direction == DB_OUT) {
  1281. ret = _bcp_exec_out(dbproc, rows_copied);
  1282.         } 
  1283.         else if (dbproc->bcp_direction==DB_IN) {
  1284. ret = _bcp_exec_in(dbproc, rows_copied);
  1285. }
  1286. _bcp_clear_storage(dbproc);
  1287. return ret;
  1288.     }
  1289.     else {
  1290.         _bcp_err_handler(dbproc, BCPEBCVH );
  1291. return FAIL;
  1292. }
  1293. }
  1294. static RETCODE _bcp_start_copy_in(DBPROCESS *dbproc)
  1295. {
  1296. TDSSOCKET *tds = dbproc->tds_socket;
  1297. BCP_COLINFO *bcpcol;
  1298.     TDSCOLINFO      *curcol;
  1299.     TDSRESULTINFO   *resinfo;
  1300. int i;
  1301. int marker;
  1302.     char colstatus;
  1303. #ifdef NCBI_FTDS
  1304.     char query[2048];
  1305.     char colclause[2048];
  1306. #else
  1307.     char query[256];
  1308.     char colclause[256];
  1309. #endif
  1310. int firstcol;
  1311. if (IS_TDS7_PLUS(tds)) {
  1312. int erc;
  1313. char *hint;
  1314.         firstcol = 1;
  1315. #ifdef NCBI_FTDS
  1316.         colclause[0]= '';
  1317.         for(i= 0; i < dbproc->bcp_colcount; i++) {
  1318.             if((!is_blob_type(dbproc->bcp_columns[i]->db_type)) &&
  1319.                (dbproc->host_columns[i]->datatype != 0)){
  1320.                 _bcp_build_bulk_insert_stmt(colclause, dbproc->bcp_columns[i], firstcol);
  1321.                 firstcol = 0;
  1322.             }
  1323.         }
  1324.         for(i= 0; i < dbproc->bcp_colcount; i++) {
  1325.             if(is_blob_type(dbproc->bcp_columns[i]->db_type) &&
  1326.                (dbproc->host_columns[i]->datatype != 0)) {
  1327.                 _bcp_build_bulk_insert_stmt(colclause, dbproc->bcp_columns[i], firstcol);
  1328.                 firstcol = 0;
  1329.             }
  1330.         }
  1331. #else
  1332. strcpy(colclause, "");
  1333. for (i = 0; i < dbproc->bcp_colcount; i++) {
  1334. bcpcol = dbproc->bcp_columns[i];
  1335. if (IS_TDS7_PLUS(tds)) {
  1336. _bcp_build_bulk_insert_stmt(colclause, bcpcol, firstcol);
  1337. firstcol = 0;
  1338. }
  1339. }
  1340. #endif
  1341. if (dbproc->bcp_hint) {
  1342. if (asprintf(&hint, " with (%s)", dbproc->bcp_hint) < 0) {
  1343. return FAIL;
  1344. }
  1345. } else {
  1346. hint = strdup("");
  1347. }
  1348. if (!hint) return FAIL;
  1349. sprintf(query, "insert bulk %s (%s)%s", dbproc->bcp_tablename, colclause, hint);
  1350. free(hint); 
  1351.    else {
  1352.        sprintf(query, "insert bulk %s", dbproc->bcp_tablename);
  1353. }
  1354. tds_submit_query(tds, query);
  1355. /* save the statement for later... */
  1356.     dbproc->bcp_insert_stmt = (char *) malloc(strlen(query)+1);
  1357.     strcpy(dbproc->bcp_insert_stmt, query);
  1358. /* In TDS 5 we get the column information as a */
  1359. /* result set from the "insert bulk" command.  */
  1360. /* we're going to ignore this....              */
  1361. if (IS_TDS50(tds)) {
  1362.         if (tds_process_result_tokens(tds) == TDS_FAIL) {
  1363. return FAIL;
  1364. }
  1365. if (!tds->res_info) {
  1366. return FAIL;
  1367. }
  1368.         while (tds_process_row_tokens(tds) == SUCCEED); 
  1369.     }
  1370.     else {
  1371. marker = tds_get_byte(tds);
  1372. tds_process_default_tokens(tds, marker);
  1373. if (!is_end_token(marker)) {
  1374. return FAIL;
  1375. }
  1376. }
  1377. /* work out the number of "variable" columns -         */
  1378. /* either varying length type e.g. varchar or nullable */
  1379. dbproc->var_cols = 0;
  1380. for (i = 0; i < dbproc->bcp_colcount; i++) {
  1381. bcpcol = dbproc->bcp_columns[i];
  1382.         if (is_nullable_type(bcpcol->db_type) ||
  1383.             bcpcol->db_nullable) {
  1384. dbproc->var_cols++;
  1385. }
  1386. }
  1387. return SUCCEED;
  1388. }
  1389. static RETCODE _bcp_build_bulk_insert_stmt(char *clause, BCP_COLINFO *bcpcol, int first)
  1390. {
  1391. char column_type[32];
  1392. switch (bcpcol->db_type_save) {
  1393.     case SYBINT1:      strcpy(column_type,"tinyint");
  1394. break;
  1395.     case SYBBIT:       strcpy(column_type,"bit");
  1396. break;
  1397.     case SYBINT2:      strcpy(column_type,"smallint");
  1398. break;
  1399.     case SYBINT4:      strcpy(column_type,"int");
  1400. break;
  1401.     case SYBDATETIME:  strcpy(column_type,"datetime");
  1402. break;
  1403.     case SYBDATETIME4: strcpy(column_type,"smalldatetime");
  1404. break;
  1405.     case SYBREAL:      strcpy(column_type,"real");
  1406. break;
  1407.     case SYBMONEY:     strcpy(column_type,"money");
  1408. break;
  1409.     case SYBMONEY4:    strcpy(column_type,"smallmoney");
  1410. break;
  1411.     case SYBFLT8:      strcpy(column_type,"float");
  1412. break;
  1413.     case SYBINT8:      strcpy(column_type,"bigint");
  1414. break;
  1415.     case SYBINTN:      switch (bcpcol->db_length) {
  1416.     case 1: strcpy(column_type,"tinyint");
  1417. break;
  1418.     case 2: strcpy(column_type,"smallint");
  1419. break;
  1420.     case 4: strcpy(column_type,"int");
  1421. break;
  1422.     case 8: strcpy(column_type,"bigint");
  1423. break;
  1424. }
  1425. break;
  1426.     case SYBBITN:      strcpy(column_type,"bit");
  1427. break;
  1428.     case SYBFLTN:      switch (bcpcol->db_length) {
  1429.     case 4: strcpy(column_type,"real");
  1430. break;
  1431.     case 8: strcpy(column_type,"float");
  1432. break;
  1433. }
  1434. break;
  1435.     case SYBMONEYN:    switch (bcpcol->db_length) {
  1436.     case 4: strcpy(column_type,"smallmoney");
  1437. break;
  1438.     case 8: strcpy(column_type,"money");
  1439. break;
  1440. }
  1441. break;
  1442.     case SYBDATETIMN:  switch (bcpcol->db_length) {
  1443.     case 4: strcpy(column_type,"smalldatetime");
  1444. break;
  1445.     case 8: strcpy(column_type,"datetime");
  1446. break;
  1447. }
  1448. break;
  1449.     case SYBDECIMAL:   sprintf(column_type,"decimal(%d,%d)", bcpcol->db_prec, bcpcol->db_scale);
  1450. break;
  1451.     case SYBNUMERIC:   sprintf(column_type,"numeric(%d,%d)", bcpcol->db_prec, bcpcol->db_scale);
  1452. break;
  1453.     case XSYBVARBINARY: sprintf(column_type,"varbinary(%d)", bcpcol->db_length);
  1454. break;
  1455.     case XSYBVARCHAR  : sprintf(column_type,"varchar(%d)", bcpcol->db_length);
  1456. break;
  1457.     case XSYBBINARY   : sprintf(column_type,"binary(%d)", bcpcol->db_length);
  1458. break;
  1459.     case XSYBCHAR     : sprintf(column_type,"char(%d)", bcpcol->db_length);
  1460. break;
  1461.     case SYBTEXT      : sprintf(column_type,"text");
  1462. break;
  1463.     case SYBIMAGE     : sprintf(column_type,"image");
  1464. break;
  1465.     case XSYBNVARCHAR : sprintf(column_type,"nvarchar(%d)", bcpcol->db_length);
  1466. break;
  1467.     case XSYBNCHAR    : sprintf(column_type,"nchar(%d)", bcpcol->db_length);
  1468. break;
  1469.     case SYBNTEXT     : sprintf(column_type,"ntext");
  1470. break;
  1471. }
  1472. if (!first)
  1473. strcat(clause, ", ");
  1474. strcat(clause, bcpcol->db_name);
  1475. strcat(clause, " ");
  1476. strcat(clause, column_type);
  1477. #ifdef NCBI_FTDS
  1478. return SUCCEED;
  1479. #endif
  1480. }
  1481. static RETCODE _bcp_start_new_batch(DBPROCESS *dbproc)
  1482. {
  1483. TDSSOCKET *tds = dbproc->tds_socket;
  1484. int marker;
  1485. if (IS_TDS50(tds)) {
  1486. tds_submit_query(tds, dbproc->bcp_insert_stmt);
  1487.         if (tds_process_result_tokens(tds) == TDS_FAIL) {
  1488. return FAIL;
  1489. }
  1490. if (!tds->res_info) {
  1491. return FAIL;
  1492. }
  1493.         while (tds_process_row_tokens(tds) == SUCCEED); 
  1494.     }   
  1495.     else {
  1496. tds_submit_query(tds, dbproc->bcp_insert_stmt);
  1497. marker = tds_get_byte(tds);
  1498. tds_process_default_tokens(tds, marker);
  1499. if (!is_end_token(marker)) {
  1500. return FAIL;
  1501. }
  1502. }
  1503. tds->out_flag = 0x07;
  1504. if (IS_TDS7_PLUS(tds)) {
  1505. _bcp_send_colmetadata(dbproc);
  1506. }
  1507. return SUCCEED;
  1508. }
  1509. static RETCODE _bcp_send_colmetadata(DBPROCESS *dbproc)
  1510. {
  1511. TDSSOCKET *tds = dbproc->tds_socket;
  1512.     int          marker;
  1513. unsigned char colmetadata_token = 0x81;
  1514. BCP_COLINFO *bcpcol;
  1515. char unicode_string[256];
  1516. int i;
  1517. #ifdef NCBI_FTDS
  1518.     int n;
  1519. #endif
  1520. if (IS_TDS7_PLUS(tds)) {
  1521. /* Deep joy! - for TDS 8 we have to send a 
  1522.            colmetadata message followed by row data 
  1523.  */
  1524. tds_put_byte(tds, colmetadata_token); /* 0x81 */
  1525. #ifdef NCBI_FTDS
  1526.         for (i = 0, n= 0; i < dbproc->bcp_colcount; i++) {
  1527.             if(dbproc->host_columns[i]->datatype != 0) n++;
  1528.         }
  1529.         tds_put_smallint(tds, n);
  1530. #else
  1531. tds_put_smallint(tds, dbproc->bcp_colcount);
  1532. #endif
  1533. #ifdef NCBI_FTDS
  1534.         for(n= 2; n--;)
  1535. #endif
  1536.         for (i = 0; i < dbproc->bcp_colcount; i++) {
  1537. #ifdef NCBI_FTDS
  1538.             if(dbproc->host_columns[i]->datatype == 0) continue;
  1539.             if(n) {
  1540.                 if(is_blob_type(dbproc->bcp_columns[i]->db_type)) continue;
  1541.             }
  1542.             else
  1543.                 if(!is_blob_type(dbproc->bcp_columns[i]->db_type)) continue;
  1544. #endif
  1545. bcpcol = dbproc->bcp_columns[i];
  1546. tds_put_smallint(tds, bcpcol->db_usertype);
  1547. tds_put_smallint(tds, bcpcol->db_flags);
  1548. tds_put_byte(tds, bcpcol->db_type_save);
  1549. switch (bcpcol->db_varint_size) {
  1550.             case 4: tds_put_int(tds, bcpcol->db_length);
  1551. break;
  1552.             case 2: tds_put_smallint(tds, bcpcol->db_length);
  1553. break;
  1554.             case 1: tds_put_byte(tds, bcpcol->db_length);
  1555. break;
  1556.             case 0: break;
  1557. }
  1558. if (is_numeric_type(bcpcol->db_type)) {
  1559. tds_put_byte(tds, bcpcol->db_prec);
  1560. tds_put_byte(tds, bcpcol->db_scale);
  1561. }
  1562. #ifndef NCBI_FTDS
  1563.             if (IS_TDS80(tds) && is_collate_type(bcpcol->db_type_save)) {
  1564. #else
  1565.             if (IS_TDS80(tds) && 
  1566.                 (((bcpcol->db_flags & 0x2) != 0) || is_collate_type(bcpcol->db_type_save))) {
  1567. #endif
  1568. tds_put_n(tds, bcpcol->db_collate, 5);
  1569. }
  1570. #ifdef NCBI_FTDS
  1571.             if(is_blob_type(bcpcol->db_type)) {
  1572.                 tds_put_byte(tds, 0x0); tds_put_byte(tds, 0x0); /* don't know what it is */
  1573.             }
  1574. #endif
  1575. tds_put_byte(tds, strlen(bcpcol->db_name));
  1576. tds7_ascii2unicode(tds, bcpcol->db_name, unicode_string, 255);
  1577. tds_put_n(tds, unicode_string, strlen(bcpcol->db_name) * 2);
  1578. }
  1579. }
  1580. return SUCCEED;
  1581. }
  1582. RETCODE bcp_readfmt(DBPROCESS *dbproc, char *filename)
  1583. {
  1584. FILE *ffile;
  1585. char buffer[1024];
  1586. float lf_version = 0.0;
  1587. int li_numcols = 0;
  1588. int colinfo_count = 0;
  1589.     struct fflist {
  1590. struct fflist *nextptr;
  1591. BCP_HOSTCOLINFO colinfo;
  1592. };
  1593. struct fflist *topptr = (struct fflist *) NULL;
  1594. struct fflist *curptr = (struct fflist *) NULL;
  1595. BCP_HOSTCOLINFO *hostcol;
  1596. if (dbproc->bcp_direction == 0) {
  1597.         _bcp_err_handler(dbproc, BCPEBCPI);
  1598. return FAIL;
  1599. }
  1600. if ((ffile = fopen(filename, "r")) == (FILE *) NULL) {
  1601.         _bcp_err_handler(dbproc, BCPEBUOF);
  1602. return (FAIL);
  1603. }
  1604. if ((fgets(buffer, sizeof(buffer), ffile)) != (char *) NULL) {
  1605. buffer[strlen(buffer) - 1] = ''; /* discard newline */
  1606. lf_version = atof(buffer);
  1607. }
  1608. if ((fgets(buffer, sizeof(buffer), ffile)) != (char *) NULL) {
  1609. buffer[strlen(buffer) - 1] = ''; /* discard newline */
  1610. li_numcols = atoi(buffer);
  1611. }
  1612. while ((fgets(buffer, sizeof(buffer), ffile)) != (char *) NULL) {
  1613. buffer[strlen(buffer) - 1] = ''; /* discard newline */
  1614. if (topptr == (struct fflist *) NULL) { /* first time */
  1615. if ((topptr = (struct fflist *) malloc(sizeof(struct fflist))) == (struct fflist *) NULL) {
  1616. fprintf(stderr, "out of memoryn");
  1617. return (FAIL);
  1618. }
  1619. curptr = topptr;
  1620. curptr->nextptr = NULL;
  1621. if (_bcp_readfmt_colinfo(dbproc, buffer, &(curptr->colinfo)))
  1622. colinfo_count++;
  1623. else
  1624. return (FAIL);
  1625. } else {
  1626. if ((curptr->nextptr = (struct fflist *) malloc(sizeof(struct fflist))) == (struct fflist *) NULL) {
  1627. fprintf(stderr, "out of memoryn");
  1628. return (FAIL);
  1629. }
  1630. curptr = curptr->nextptr;
  1631. curptr->nextptr = NULL;
  1632. if (_bcp_readfmt_colinfo(dbproc, buffer, &(curptr->colinfo)))
  1633. colinfo_count++;
  1634. else
  1635. return (FAIL);
  1636. }
  1637. }
  1638. if (fclose(ffile) != 0) {
  1639.         _bcp_err_handler(dbproc, BCPEBUCF);
  1640. return (FAIL);
  1641. }
  1642. if (colinfo_count != li_numcols)
  1643. return (FAIL);
  1644. if (bcp_columns(dbproc, li_numcols) == FAIL) {
  1645. return (FAIL);
  1646. }
  1647. for (curptr = topptr; curptr->nextptr != (struct fflist *) NULL; curptr = curptr->nextptr) {
  1648. hostcol = &(curptr->colinfo);
  1649. if (bcp_colfmt(dbproc, hostcol->host_column, hostcol->datatype,
  1650.        hostcol->prefix_len, hostcol->column_len,
  1651.                        hostcol->terminator,  hostcol->term_len ,
  1652.                        hostcol->tab_colnum ) == FAIL) {
  1653. return (FAIL);
  1654. }
  1655. }
  1656. hostcol = &(curptr->colinfo);
  1657. if (bcp_colfmt(dbproc, hostcol->host_column, hostcol->datatype,
  1658.        hostcol->prefix_len, hostcol->column_len,
  1659.                    hostcol->terminator,  hostcol->term_len ,
  1660.                    hostcol->tab_colnum ) == FAIL) {
  1661. return (FAIL);
  1662. }
  1663. return (SUCCEED);
  1664. }
  1665. int _bcp_readfmt_colinfo(DBPROCESS *dbproc, char *buf, BCP_HOSTCOLINFO *ci)
  1666. {
  1667. char *tok;
  1668. int whichcol;
  1669. char term[30];
  1670. int i;
  1671.     enum nextcol {
  1672. HOST_COLUMN,
  1673. DATATYPE,
  1674. PREFIX_LEN,
  1675. COLUMN_LEN,
  1676. TERMINATOR,
  1677. TAB_COLNUM,
  1678. NO_MORE_COLS
  1679. };
  1680. tok = strtok(buf, " t");
  1681. whichcol = HOST_COLUMN;
  1682. while (tok != (char *) NULL && whichcol != NO_MORE_COLS) {
  1683. switch (whichcol) {
  1684. case HOST_COLUMN:
  1685. ci->host_column = atoi(tok);
  1686. if (ci->host_column < 1) {
  1687.                 _bcp_err_handler(dbproc, BCPEBIHC);
  1688. return (FALSE);
  1689. }
  1690. whichcol = DATATYPE;
  1691. break;
  1692. case DATATYPE:
  1693. if (strcmp(tok, "SYBCHAR") == 0)
  1694. ci->datatype = SYBCHAR;
  1695. else if (strcmp(tok, "SYBTEXT") == 0)
  1696. ci->datatype = SYBTEXT;
  1697. else if (strcmp(tok, "SYBBINARY") == 0)
  1698. ci->datatype = SYBBINARY;
  1699. else if (strcmp(tok, "SYBIMAGE") == 0)
  1700. ci->datatype = SYBIMAGE;
  1701. else if (strcmp(tok, "SYBINT1") == 0)
  1702. ci->datatype = SYBINT1;
  1703. else if (strcmp(tok, "SYBINT2") == 0)
  1704. ci->datatype = SYBINT2;
  1705. else if (strcmp(tok, "SYBINT4") == 0)
  1706. ci->datatype = SYBINT4;
  1707. else if (strcmp(tok, "SYBFLT8") == 0)
  1708. ci->datatype = SYBFLT8;
  1709. else if (strcmp(tok, "SYBREAL") == 0)
  1710. ci->datatype = SYBREAL;
  1711. else if (strcmp(tok, "SYBBIT") == 0)
  1712. ci->datatype = SYBBIT;
  1713. else if (strcmp(tok, "SYBNUMERIC") == 0)
  1714. ci->datatype = SYBNUMERIC;
  1715. else if (strcmp(tok, "SYBDECIMAL") == 0)
  1716. ci->datatype = SYBDECIMAL;
  1717. else if (strcmp(tok, "SYBMONEY") == 0)
  1718. ci->datatype = SYBMONEY;
  1719. else if (strcmp(tok, "SYBDATETIME") == 0)
  1720. ci->datatype = SYBDATETIME;
  1721. else if (strcmp(tok, "SYBDATETIME4") == 0)
  1722. ci->datatype = SYBDATETIME4;
  1723. else {
  1724.                 _bcp_err_handler(dbproc, BCPEBUDF);
  1725. return (FALSE);
  1726. }
  1727. whichcol = PREFIX_LEN;
  1728. break;
  1729. case PREFIX_LEN:
  1730. ci->prefix_len = atoi(tok);
  1731. whichcol = COLUMN_LEN;
  1732. break;
  1733. case COLUMN_LEN:
  1734. ci->column_len = atoi(tok);
  1735. whichcol = TERMINATOR;
  1736. break;
  1737. case TERMINATOR:
  1738. if (*tok++ != '"')
  1739. return (FALSE);
  1740. for (i = 0; *tok != '"' && i < 30; i++) {
  1741. if (*tok == '\') {
  1742. tok++;
  1743. switch (*tok) {
  1744.                     case 't':  term[i] = 't'; break;
  1745.                     case 'n':  term[i] = 'n'; break;
  1746.                     case 'r':  term[i] = 'r'; break;
  1747.                     case '\': term[i] = '\'; break;
  1748.                     case '0':  term[i] = ''; break;
  1749.                     default:   return(FALSE);
  1750. }
  1751. tok++;
  1752.                 }
  1753.                 else
  1754. term[i] = *tok++;
  1755. }
  1756. if (*tok != '"')
  1757. return (FALSE);
  1758. term[i] = '';
  1759. ci->terminator = (BYTE*) malloc(i + 1);
  1760. strcpy((char*) ci->terminator, term);
  1761. ci->term_len = strlen(term);
  1762. whichcol = TAB_COLNUM;
  1763. break;
  1764. case TAB_COLNUM:
  1765. ci->tab_colnum = atoi(tok);
  1766. whichcol = NO_MORE_COLS;
  1767. break;
  1768. }
  1769. tok = strtok((char *) NULL, " t");
  1770. }
  1771. if (whichcol == NO_MORE_COLS)
  1772. return (TRUE);
  1773. else
  1774. return (FALSE);
  1775. }
  1776. RETCODE bcp_writefmt(DBPROCESS *dbproc, char *filename)
  1777. {
  1778. if (dbproc->bcp_direction == 0) {
  1779.         _bcp_err_handler(dbproc, BCPEBCPI);
  1780. return FAIL;
  1781. }
  1782. return SUCCEED;
  1783. }
  1784. RETCODE bcp_moretext(DBPROCESS *dbproc, DBINT size, BYTE *text)
  1785. {
  1786. #ifdef NCBI_FTDS
  1787.     static unsigned char txtptr_and_timestamp[24]= {
  1788.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  1789.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  1790.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  1791.     };
  1792.     int i;
  1793.     DBINT s;
  1794.     BCP_COLINFO *bcpcol;
  1795.     TDSSOCKET *tds = dbproc->tds_socket;
  1796.     if (dbproc == NULL || text== NULL || tds == NULL) {
  1797.         return FAIL;
  1798.     }
  1799.     if ( dbproc->text_sent == 0 ) {
  1800.         for (i=dbproc->curr_text_col; i < dbproc->bcp_colcount; i++) {
  1801.             if(dbproc->host_columns[i]->datatype == 0) continue;
  1802.             bcpcol = dbproc->bcp_columns[i];
  1803.             if (bcpcol == NULL) {
  1804.                 return FAIL;
  1805.             }
  1806.             if (is_blob_type (bcpcol->db_type) ) { 
  1807.                 dbproc->curr_text_col = i;
  1808.                 tds_put_byte (tds,0x10);
  1809.                 tds_put_n(tds, txtptr_and_timestamp, 24);
  1810.                 tds_put_int (tds,  bcpcol->data_size);
  1811.                 break;
  1812.             }
  1813.         }
  1814.         if(i >= dbproc->bcp_colcount) return FAIL;
  1815.     }
  1816.     if(dbproc->bcp_columns[dbproc->curr_text_col]->data_size == 0 &&
  1817.        size == 0) { /* this is a NULL */
  1818.         dbproc->curr_text_col++;
  1819.         dbproc->text_sent = 0;
  1820.         return SUCCEED;
  1821.     }
  1822.     s= dbproc->bcp_columns[dbproc->curr_text_col]->data_size - dbproc->text_sent;
  1823.     if(s <= 0) return FAIL;
  1824.     if(size > s) size= s;
  1825.     tds_put_n (tds, text, size);
  1826.     dbproc->text_sent += size;
  1827.     if (dbproc->text_sent >= dbproc->bcp_columns[dbproc->curr_text_col]->data_size) {
  1828.         dbproc->text_sent = 0;
  1829.         dbproc->curr_text_col++;
  1830.     }
  1831. #else
  1832. if (dbproc->bcp_direction == 0) {
  1833.         _bcp_err_handler(dbproc, BCPEBCPI);
  1834. return FAIL;
  1835. }
  1836. #endif
  1837. return SUCCEED;
  1838. }
  1839. RETCODE bcp_batch(DBPROCESS *dbproc)
  1840. {
  1841. TDSSOCKET *tds = dbproc->tds_socket;
  1842. int marker;
  1843. int rows_copied;
  1844. if (dbproc->bcp_direction == 0) {
  1845.         _bcp_err_handler(dbproc, BCPEBCPI);
  1846.         return FAIL;
  1847. }
  1848. tds_flush_packet(tds);
  1849. do {
  1850. marker = tds_get_byte(tds);
  1851.         if ( marker == TDS_DONE_TOKEN ) 
  1852.             rows_copied = tds_process_end(tds,marker,NULL,NULL);
  1853.         else 
  1854. tds_process_default_tokens(tds, marker);
  1855. } while (marker != TDS_DONE_TOKEN);
  1856. _bcp_start_new_batch(dbproc);
  1857.     return rows_copied;
  1858. }
  1859. /* end the transfer of data from program variables */
  1860. RETCODE bcp_done(DBPROCESS *dbproc)
  1861. {
  1862. TDSSOCKET *tds = dbproc->tds_socket;
  1863. int marker;
  1864. int rows_copied = -1;
  1865. if (dbproc->bcp_direction == 0) {
  1866.         _bcp_err_handler(dbproc, BCPEBCPI);
  1867.         return FAIL;
  1868. }
  1869. tds_flush_packet(tds);
  1870. do {
  1871. marker = tds_get_byte(tds);
  1872.         if ( marker == TDS_DONE_TOKEN ) 
  1873.             rows_copied = tds_process_end(tds,marker,NULL,NULL);
  1874.         else 
  1875. tds_process_default_tokens(tds, marker);
  1876. } while (marker != TDS_DONE_TOKEN);
  1877. _bcp_clear_storage(dbproc);
  1878. return (rows_copied);
  1879. }
  1880. /* bind a program host variable to a database column */
  1881. RETCODE bcp_bind(DBPROCESS *dbproc, BYTE *varaddr, int prefixlen, DBINT varlen,
  1882.  BYTE * terminator, int termlen, int type, int table_column)
  1883. {
  1884. BCP_HOSTCOLINFO *hostcol;
  1885. if (dbproc->bcp_direction == 0) {
  1886.         _bcp_err_handler(dbproc, BCPEBCPI);
  1887. return FAIL;
  1888. }
  1889. if (dbproc->bcp_hostfile != (char *) NULL) {
  1890.         _bcp_err_handler(dbproc, BCPEBCPB);
  1891. return FAIL;
  1892. }
  1893. if (dbproc->bcp_direction != DB_IN) {
  1894.         _bcp_err_handler(dbproc, BCPEBCPN);
  1895. return FAIL;
  1896. }
  1897. if (varlen < -1) {
  1898.         _bcp_err_handler(dbproc, BCPEBCVLEN);
  1899. return FAIL;
  1900. }
  1901.     if (prefixlen != 0 && prefixlen != 1 &&
  1902.         prefixlen != 2 && prefixlen != 4 ) {
  1903.         _bcp_err_handler(dbproc, BCPEBCBPREF);
  1904. return FAIL;
  1905. }
  1906.     if (prefixlen == 0 && varlen == -1 && 
  1907.         termlen == -1 && !is_fixed_type(type)) {
  1908. return FAIL;
  1909. }
  1910.     if (is_fixed_type(type) && 
  1911.         (varlen != -1 && varlen != 0)) {
  1912. return FAIL;
  1913. }
  1914. if (table_column > dbproc->host_colcount) {
  1915. return FAIL;
  1916. }
  1917. #ifndef NCBI_FTDS
  1918.     if (varaddr == (BYTE *)NULL && 
  1919.         (prefixlen != 0 || termlen != 0)) {
  1920.         _bcp_err_handler(dbproc, BCPEBCBNPR);
  1921. return FAIL;
  1922. }
  1923. #endif
  1924. hostcol = dbproc->host_columns[table_column - 1];
  1925. hostcol->host_var = varaddr;
  1926. hostcol->datatype = type;
  1927. hostcol->prefix_len = prefixlen;
  1928. hostcol->column_len = varlen;
  1929.     if(termlen > 0) {
  1930. hostcol->terminator = (BYTE *) malloc(termlen + 1);
  1931. memcpy(hostcol->terminator, terminator, termlen);
  1932.     }
  1933.     else hostcol->terminator= NULL;
  1934. hostcol->term_len = termlen;
  1935. hostcol->tab_colnum = table_column;
  1936. return SUCCEED;
  1937. }
  1938. /* for a bcp in from program variables, collate all the data */
  1939. /* into the column arrays held in dbproc...                  */
  1940. RETCODE _bcp_get_prog_data(DBPROCESS *dbproc)
  1941. {
  1942.     BCP_COLINFO *bcpcol;
  1943.     BCP_HOSTCOLINFO *hostcol;
  1944.     int i;
  1945.     TDS_TINYINT ti;
  1946.     TDS_SMALLINT si;
  1947.     TDS_INT li;
  1948.     TDS_INT desttype;
  1949.     int collen;
  1950.     int data_is_null;
  1951.     int bytes_read;
  1952.     int converted_data_size;
  1953.     BYTE *dataptr;
  1954.     /* for each host file column defined by calls to bcp_colfmt */
  1955.     for (i = 0; i < dbproc->host_colcount; i++) {
  1956.         BYTE coldata[4096];
  1957.         hostcol = dbproc->host_columns[i];
  1958. #ifdef NCBI_FTDS
  1959.         if(hostcol->datatype == 0) continue;
  1960. #endif
  1961.         dataptr = hostcol->host_var;
  1962.         data_is_null = 0;
  1963.         collen = 0;
  1964.         /* if a prefix length specified, read the correct */
  1965.         /* amount of data...                              */
  1966.         if (hostcol->prefix_len > 0) {
  1967.             switch (hostcol->prefix_len) {
  1968.             case 1:
  1969.                 memcpy(&ti, dataptr, 1);
  1970.                 dataptr += 1;
  1971.                 collen = ti;
  1972.                 break;
  1973.             case 2:
  1974.                 memcpy(&si, dataptr, 2);
  1975.                 dataptr += 2;
  1976.                 collen = si;
  1977.                 break;
  1978.             case 4:
  1979.                 memcpy(&li, dataptr, 4);
  1980.                 dataptr += 4;
  1981.                 collen = li;
  1982.                 break;
  1983.             }
  1984.             if (collen == 0)
  1985.                 data_is_null = 1;
  1986.         }
  1987.         /* if (Max) column length specified take that into */
  1988.         /* consideration...                                */
  1989.         if (!data_is_null && hostcol->column_len >= 0) {
  1990.             if (hostcol->column_len == 0)
  1991.                 data_is_null = 1;
  1992.             else {
  1993.                 if (collen)
  1994.                     collen = (hostcol->column_len < collen) ? hostcol->column_len : collen;
  1995.                 else
  1996.                     collen = hostcol->column_len;
  1997.             }
  1998.         }
  1999.         /* Fixed Length data - this over-rides anything else specified */
  2000.         if (is_fixed_type(hostcol->datatype)) {
  2001.             collen = get_size_by_type(hostcol->datatype);
  2002.         }
  2003. #ifdef NCBI_FTDS
  2004.         else if(is_numeric_type(hostcol->datatype)) {
  2005.             collen= sizeof(DBNUMERIC);
  2006.         }
  2007. #endif
  2008.         /* if this host file column contains table data,   */
  2009.         /* find the right element in the table/column list */
  2010.         if (hostcol->tab_colnum) {
  2011.             bcpcol = dbproc->bcp_columns[hostcol->tab_colnum - 1];
  2012.             if (bcpcol->tab_colnum != hostcol->tab_colnum) {
  2013.                 return FAIL;
  2014.             }
  2015.         }
  2016. #ifdef NCBI_FTDS
  2017.         if(dataptr == NULL) {
  2018.             bcpcol->data_size= collen;
  2019.             continue;
  2020.         }
  2021. #endif
  2022.         /* a terminated field is specified - get the data into temporary space... */
  2023.         memset(coldata, '', sizeof(coldata));
  2024.         if (hostcol->term_len > 0) {
  2025.             bytes_read = _bcp_get_term_var(dataptr, hostcol->terminator, hostcol->term_len, coldata);
  2026.             if (bytes_read == -1)
  2027.                 return FAIL;
  2028.             if (collen)
  2029.                 collen = (bytes_read < collen) ? bytes_read : collen;
  2030.             else
  2031.                 collen = bytes_read;
  2032.             if (collen == 0)
  2033.                 data_is_null = 1;
  2034.             if (hostcol->tab_colnum) {
  2035.                 if (data_is_null) {
  2036.                     bcpcol->data_size = 0;
  2037.                 }
  2038.                 else {
  2039.                     desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
  2040.                     if ((converted_data_size = dbconvert(dbproc, hostcol->datatype, 
  2041.                                                          (BYTE *) coldata, collen,
  2042.                                                          desttype, bcpcol->data, 
  2043.                                                          bcpcol->db_length)) == FAIL) {
  2044.                         return (FAIL);
  2045.                     }
  2046.                     bcpcol->data_size = converted_data_size;
  2047.                 }
  2048.             }
  2049.         }
  2050.         else {
  2051.             if (collen) {
  2052.                 memcpy(coldata, dataptr, collen);
  2053.             }
  2054.             if (hostcol->tab_colnum) {
  2055.                 if (data_is_null) {
  2056.                     bcpcol->data_size = 0;
  2057.                 }
  2058.                 else {
  2059.                     desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
  2060.                     if ((converted_data_size = dbconvert(dbproc, hostcol->datatype, 
  2061.                                                          (BYTE *) coldata, collen,
  2062.                                                          desttype, bcpcol->data, 
  2063.                                                          bcpcol->db_length)) == FAIL) {
  2064.                         return (FAIL);
  2065.                     }
  2066.                     bcpcol->data_size = converted_data_size;
  2067.                 }
  2068.             }
  2069.         }
  2070.     }
  2071.     return SUCCEED;
  2072. }
  2073. /* for bcp in from program variables, where the program data */
  2074. /* has been identified as character terminated, get the data */
  2075. RETCODE _bcp_get_term_var(BYTE *dataptr, BYTE *term, int term_len, BYTE *coldata )
  2076. {
  2077. int bufpos = 0;
  2078. int found = 0;
  2079. BYTE *tptr;
  2080. for (tptr = dataptr; !found; tptr++) {
  2081. if (memcmp(tptr, term, term_len) != 0) {
  2082. *(coldata + bufpos) = *tptr;
  2083. bufpos++;
  2084.         }
  2085.         else
  2086. found = 1;
  2087. }
  2088. if (found) {
  2089. return (bufpos);
  2090.     }
  2091.     else {
  2092. return (-1);
  2093. }
  2094. }
  2095. static int _bcp_rtrim_varchar(char *istr, int ilen)
  2096. {
  2097. char *t;
  2098. int olen = ilen;
  2099. for (t = istr + (ilen - 1); *t == ' '; t--) {
  2100. *t = '';
  2101. olen--;
  2102. }
  2103. return olen;
  2104. }
  2105. RETCODE _bcp_clear_storage(DBPROCESS *dbproc)
  2106. {
  2107. int i;
  2108. if (dbproc->bcp_hostfile) {
  2109. free(dbproc->bcp_hostfile);
  2110. dbproc->bcp_hostfile = (char *) NULL;
  2111. }
  2112. if (dbproc->bcp_errorfile) {
  2113. free(dbproc->bcp_errorfile);
  2114. dbproc->bcp_errorfile = (char *) NULL;
  2115. }
  2116. if (dbproc->bcp_tablename) {
  2117. free(dbproc->bcp_tablename);
  2118. dbproc->bcp_tablename = (char *) NULL;
  2119. }
  2120. if (dbproc->bcp_insert_stmt) {
  2121. free(dbproc->bcp_insert_stmt);
  2122. dbproc->bcp_insert_stmt = (char *) NULL;
  2123. }
  2124. dbproc->bcp_direction = 0;
  2125. if (dbproc->bcp_columns) {
  2126. for (i = 0; i < dbproc->bcp_colcount; i++) {
  2127. if (dbproc->bcp_columns[i]->data) {
  2128. free(dbproc->bcp_columns[i]->data);
  2129. dbproc->bcp_columns[i]->data = NULL;
  2130. }
  2131. free(dbproc->bcp_columns[i]);
  2132. dbproc->bcp_columns[i] = NULL;
  2133. }
  2134. free(dbproc->bcp_columns);
  2135. dbproc->bcp_columns = NULL;
  2136. }
  2137. dbproc->bcp_colcount = 0;
  2138. #ifdef NCBI_FTDS
  2139.     dbproc->curr_text_col= 0;
  2140. #endif
  2141. /* free up storage that holds details of hostfile columns */
  2142. if (dbproc->host_columns) {
  2143. for (i = 0; i < dbproc->host_colcount; i++) {
  2144. if (dbproc->host_columns[i]->terminator) {
  2145. free(dbproc->host_columns[i]->terminator);
  2146. dbproc->host_columns[i]->terminator = NULL;
  2147. }
  2148. free(dbproc->host_columns[i]);
  2149. dbproc->host_columns[i] = NULL;
  2150. }
  2151. free(dbproc->host_columns);
  2152. dbproc->host_columns = NULL;
  2153. }
  2154. #ifdef NCBI_FTDS
  2155.    if(dbproc->bcp_hint) {
  2156.        free(dbproc->bcp_hint);
  2157.        dbproc->bcp_hint= NULL;
  2158.    }
  2159. #endif
  2160. dbproc->host_colcount = 0;
  2161. dbproc->var_cols = 0;
  2162. dbproc->sendrow_init = 0;
  2163. return (SUCCEED);
  2164. }
  2165. RETCODE _bcp_err_handler(DBPROCESS *dbproc, int bcp_errno)
  2166. {
  2167. const char *errmsg;
  2168. char *p;
  2169. int severity;
  2170. int erc;
  2171. switch (bcp_errno) {
  2172. case SYBETTS:
  2173. errmsg = "The table which bulk-copy is attempting to copy to a "
  2174. "host-file is shorter than the number of rows which bulk-copy " "was instructed to skip.";
  2175. severity = EXUSER;
  2176. break;
  2177. case SYBEBDIO:
  2178. errmsg = "Bad bulk-copy direction. Must be either IN or OUT.";
  2179. severity = EXPROGRAM;
  2180. break;
  2181. case SYBEBCVH:
  2182. errmsg = "bcp_exec() may be called only after bcp_init() has " "been passed a valid host file.";
  2183. severity = EXPROGRAM;
  2184. break;
  2185. case SYBEBIVI:
  2186. errmsg = "bcp_columns(), bcp_colfmt() and * bcp_colfmt_ps() may be used "
  2187. "only after bcp_init() has been passed a valid input file.";
  2188. severity = EXPROGRAM;
  2189. break;
  2190. case SYBEBCBC:
  2191. errmsg = "bcp_columns() must be called before bcp_colfmt().";
  2192. severity = EXPROGRAM;
  2193. break;
  2194. case SYBEBCFO:
  2195. errmsg = "Bcp host-files must contain at least one column.";
  2196. severity = EXUSER;
  2197. break;
  2198. case SYBEBCPB:
  2199. errmsg = "bcp_bind(), bcp_moretext() and bcp_sendrow() * may NOT be used "
  2200. "after bcp_init() has been passed a non-NULL input file name.";
  2201. severity = EXPROGRAM;
  2202. break;
  2203. case SYBEBCPN:
  2204. errmsg = "bcp_bind(), bcp_collen(), bcp_colptr(), bcp_moretext() and "
  2205. "bcp_sendrow() may be used only after bcp_init() has been called " "with the copy direction set to DB_IN.";
  2206. severity = EXPROGRAM;
  2207. break;
  2208. case SYBEBCPI:
  2209. errmsg = "bcp_init() must be called before any other bcp routines.";
  2210. severity = EXPROGRAM;
  2211. break;
  2212. case SYBEBCITBNM:
  2213. errmsg = "bcp_init(): tblname parameter cannot be NULL.";
  2214. severity = EXPROGRAM;
  2215. break;
  2216. case SYBEBCITBLEN:
  2217. errmsg = "bcp_init(): tblname parameter is too long.";
  2218. severity = EXPROGRAM;
  2219. break;
  2220. case SYBEBCBNPR:
  2221. errmsg = "bcp_bind(): if varaddr is NULL, prefixlen must be 0 and no " "terminator should be ** specified.";
  2222. severity = EXPROGRAM;
  2223. break;
  2224. case SYBEBCBPREF:
  2225. errmsg = "Illegal prefix length. Legal values are 0, 1, 2 or 4.";
  2226. severity = EXPROGRAM;
  2227. break;
  2228. case SYBEVDPT:
  2229. errmsg = "For bulk copy, all variable-length data * must have either " "a length-prefix or a terminator specified.";
  2230. severity = EXUSER;
  2231. break;
  2232. case SYBEBCPCTYP:
  2233. errmsg = "bcp_colfmt(): If table_colnum is 0, ** host_type cannot be 0.";
  2234. severity = EXPROGRAM;
  2235. break;
  2236. case SYBEBCHLEN:
  2237. errmsg = "host_collen should be greater than or equal to -1.";
  2238. severity = EXPROGRAM;
  2239. break;
  2240. case SYBEBCPREF:
  2241. errmsg = "Illegal prefix length. Legal values are -1, 0, 1, 2 or 4.";
  2242. severity = EXPROGRAM;
  2243. break;
  2244. case SYBEBCVLEN:
  2245. errmsg = "varlen should be greater than or equal to -1.";
  2246. severity = EXPROGRAM;
  2247. break;
  2248. case SYBEBCUO:
  2249. errmsg = "Unable to open host data-file.";
  2250. severity = EXRESOURCE;
  2251. break;
  2252. case SYBEBUOE:
  2253. erc = asprintf( &p, "Unable to open bcp error file "%s".", dbproc->bcp_errorfile );
  2254. if (p && erc != -1) {
  2255.           if(g_dblib_err_handler) {
  2256.               g_dblib_err_handler(dbproc, EXRESOURCE, bcp_errno, 0, errmsg, p);
  2257.           }
  2258.           free (p);
  2259.           return SUCCEED;
  2260. }
  2261. /* try to print silly message if unable to allocate memory */
  2262. errmsg = "Unable to open error file.";
  2263. severity = EXRESOURCE;
  2264. break;
  2265. case SYBEBUOF:
  2266. errmsg = "Unable to open format-file.";
  2267. severity = EXPROGRAM;
  2268. break;
  2269. case SYBEBUDF:
  2270. errmsg = "Unrecognized datatype found in format-file.";
  2271. severity = EXPROGRAM;
  2272. break;
  2273. case SYBEBIHC:
  2274. errmsg = "Incorrect host-column number found in bcp format-file.";
  2275. severity = EXPROGRAM;
  2276. break;
  2277. case SYBEBCUC:
  2278. errmsg = "Unable to close host data-file.";
  2279. severity = EXRESOURCE;
  2280. break;
  2281. case SYBEBUCE:
  2282. errmsg = "Unable to close error file.";
  2283. severity = EXPROGRAM;
  2284. break;
  2285. case SYBEBUCF:
  2286. errmsg = "Unable to close format-file.";
  2287. severity = EXPROGRAM;
  2288. break;
  2289. case SYBEIFNB:
  2290. errmsg = "Illegal field number passed to bcp_control().";
  2291. severity = EXPROGRAM;
  2292. break;
  2293. case SYBEBCRE:
  2294. errmsg = "I/O error while reading bcp data-file.";
  2295. severity = EXNONFATAL;
  2296. break;
  2297. case SYBEBCNN:
  2298. errmsg = "Attempt to bulk-copy a NULL value into Server column which " "does not accept NULL values.";
  2299. severity = EXUSER;
  2300. break;
  2301. case SYBEBBCI:
  2302. errmsg = "Batch successfully bulk-copied to SQL Server.";
  2303. severity = EXINFO;
  2304. break;
  2305. default:
  2306. errmsg = "Unknown bcp error";
  2307. severity = EXNONFATAL;
  2308. break;
  2309. }
  2310.     if(g_dblib_err_handler) {
  2311.         g_dblib_err_handler(dbproc, severity, bcp_errno, 0, errmsg, "");
  2312.         return (SUCCEED);
  2313.     }
  2314. }