NCBI C++ ToolKit
bcp.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: bcp.cpp 99071 2023-02-09 17:00:30Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Vladimir Soussov
27  *
28  * File Description: CTLib bcp-in command
29  *
30  */
31 
32 
33 #include <ncbi_pch.hpp>
36 #include <dbapi/error_codes.hpp>
37 #include <string.h>
38 
39 
40 #define NCBI_USE_ERRCODE_X Dbapi_CTlib_Cmds
41 
42 #undef NCBI_DATABASE_THROW
43 #define NCBI_DATABASE_THROW(ex_class, message, err_code, severity) \
44  NCBI_DATABASE_THROW_ANNOTATED(ex_class, message, err_code, severity, \
45  GetDbgInfo(), GetConnection(), GetLastParams())
46 // No use of NCBI_DATABASE_RETHROW or DATABASE_DRIVER_*_EX here.
47 
49 
50 #ifdef FTDS_IN_USE
51 # if NCBI_FTDS_VERSION > 91 /* defined(CS_BIGINT_TYPE) */
52 # define NCBI_CS_BIGINT_TYPE CS_BIGINT_TYPE
53 # else
54 # define NCBI_CS_BIGINT_TYPE CS_LONG_TYPE
55 # endif
56 
57 namespace NCBI_NS_FTDS_CTLIB
58 {
59 #endif
60 
61 
62 ///////////////////////////////////////////////////////////////////////////
63 //
64 // CTL_BCPInCmd::
65 //
66 
68  const string& table_name)
70 , m_RowCount(0)
71 {
72  CheckSF(
73  blk_alloc(
74  GetConnection().GetNativeConnection().GetNativeHandle(),
75  GetConnection().GetBLKVersion(),
76  &m_Cmd
77  ),
78  "blk_alloc failed", 110004
79  );
80 
81  SetExecCntxInfo("BCP table name: " + table_name);
82 }
83 
84 
86 CTL_BCPInCmd::CheckSF(CS_RETCODE rc, const char* msg, unsigned int msg_num)
87 {
88  switch (Check(rc)) {
89  case CS_SUCCEED:
90  break;
91  case CS_FAIL:
92  SetHasFailed();
93  DATABASE_DRIVER_ERROR( msg, msg_num );
94  }
95 
96  return rc;
97 }
98 
99 
100 
102 CTL_BCPInCmd::CheckSFB(CS_RETCODE rc, const char* msg, unsigned int msg_num)
103 {
104  switch (Check(rc)) {
105  case CS_SUCCEED:
106  break;
107  case CS_FAIL:
108  SetHasFailed();
109  DATABASE_DRIVER_ERROR( msg, msg_num );
110 #ifdef CS_BUSY
111  case CS_BUSY:
112  DATABASE_DRIVER_ERROR( "the connection is busy", 122002 );
113 #endif
114  }
115 
116  return rc;
117 }
118 
119 
121 CTL_BCPInCmd::CheckSentSFB(CS_RETCODE rc, const char* msg, unsigned int msg_num)
122 {
123  switch (Check(rc)) {
124  case CS_SUCCEED:
125  SetWasSent(false);
126  break;
127  case CS_FAIL:
128  SetHasFailed();
129  DATABASE_DRIVER_ERROR( msg, msg_num );
130 #ifdef CS_BUSY
131  case CS_BUSY:
132  SetWasSent(false);
133  // DATABASE_DRIVER_ERROR( "the connection is busy", 122002 );
134 #endif
135  }
136 
137  return rc;
138 }
139 
140 
141 
142 bool CTL_BCPInCmd::Bind(unsigned int column_num, CDB_Object* pVal)
143 {
144  return GetBindParamsImpl().BindParam(column_num, kEmptyStr, pVal);
145 }
146 
147 
149 {
150  switch (GetConnection().GetCTLibContext().GetTDSVersion()) {
151  case 70:
152  case 80:
153  return true;
154  };
155 
156  return false;
157 }
158 
159 
162 {
164  = static_cast<CDB_String&>(*GetBindParamsImpl().GetParam(i));
165  CTempString ts;
166 
167 // #if defined(HAVE_WSTRING)
168 // if (x_IsUnicodeClientAPI()) {
169 // const wstring& ws = value.AsWString(eEncoding_UTF8);
170 // ts.assign((const char*)ws.data(), ws.size() * sizeof(wchar_t));
171 // }
172 // #endif
173 
174  value.GetBulkInsertionData(&ts);
175 #ifdef USE_STRUCT_CS_VARCHAR
176  static const auto kMax = numeric_limits<decltype(CS_VARCHAR::len)>::max();
177  if (ts.size() > kMax) {
178  string msg = FORMAT("Value for column " << (i + 1)
179  << " is too wide for [N]VARCHAR: " << ts.size()
180  << " > " << kMax);
181  DATABASE_DRIVER_ERROR(msg, 123004);
182  }
183 #endif
184  SBcpBind& b = GetBind()[i];
185  b.varchar.SetValue(ts);
186  return b.varchar.GetValue();
187 }
188 
189 
191 {
192  CS_DATAFMT param_fmt;
193  memset(&param_fmt, 0, sizeof(param_fmt));
194  param_fmt.format = CS_FMT_UNUSED;
195  param_fmt.count = 1;
196 
197  for (unsigned int i = 0; i < GetBindParamsImpl().NofParams(); i++) {
198 
199  if (GetBindParamsImpl().GetParamStatus(i) == 0)
200  continue;
201 
202  CDB_Object& param = *GetBindParamsImpl().GetParam(i);
203  SBcpBind& bind = GetBind()[i];
204  bind.indicator = param.IsNULL() ? -1 : 0;
205  bind.datalen = (bind.indicator == 0) ? CS_UNUSED : 0;
206 
207  CS_RETCODE ret_code;
208 
209  switch ( param.GetType() ) {
210  case eDB_Bit: {
211  CDB_Bit& par = dynamic_cast<CDB_Bit&> (param);
212  param_fmt.datatype = CS_BIT_TYPE;
213  CS_BOOL value = (CS_BOOL) par.Value();
214  memcpy(bind.buffer, &value, sizeof(CS_BOOL));
215  bind.datalen = bind.indicator + 1;
216  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
217  (CS_VOID*) bind.buffer,
218  &bind.datalen,
219  &bind.indicator));
220  break;
221  }
222  case eDB_Int: {
223  CDB_Int& par = dynamic_cast<CDB_Int&> (param);
224  param_fmt.datatype = CS_INT_TYPE;
225  CS_INT value = (CS_INT) par.Value();
226  memcpy(bind.buffer, &value, sizeof(CS_INT));
227  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
228  (CS_VOID*) bind.buffer,
229  &bind.datalen,
230  &bind.indicator));
231  break;
232  }
233  case eDB_SmallInt: {
234  CDB_SmallInt& par = dynamic_cast<CDB_SmallInt&> (param);
235  param_fmt.datatype = CS_SMALLINT_TYPE;
237  memcpy(bind.buffer, &value, sizeof(CS_SMALLINT));
238  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
239  (CS_VOID*) bind.buffer,
240  &bind.datalen,
241  &bind.indicator));
242  break;
243  }
244  case eDB_TinyInt: {
245  CDB_TinyInt& par = dynamic_cast<CDB_TinyInt&> (param);
246  param_fmt.datatype = CS_TINYINT_TYPE;
247  CS_TINYINT value = (CS_TINYINT) par.Value();
248  memcpy(bind.buffer, &value, sizeof(CS_TINYINT));
249  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
250  (CS_VOID*) bind.buffer,
251  &bind.datalen,
252  &bind.indicator));
253  break;
254  }
255  case eDB_BigInt: {
256  CDB_BigInt& par = dynamic_cast<CDB_BigInt&> (param);
257 
258 #ifdef FTDS_IN_USE
259  param_fmt.datatype = NCBI_CS_BIGINT_TYPE;
260  Int8 value = par.Value();
261  memcpy(bind.buffer, &value, sizeof(value));
262 #else
263  // Old code ...
264  param_fmt.datatype = CS_NUMERIC_TYPE;
266  Int8 val8 = par.Value();
267  memset(&value, 0, sizeof(value));
268  value.precision = 20;
269  if (longlong_to_numeric(val8, 20, value.array) == 0)
270  return false;
271  param_fmt.scale = 0;
272  param_fmt.precision = 20;
273  memcpy(bind.buffer, &value, sizeof(CS_NUMERIC));
274  bind.datalen = sizeof(CS_NUMERIC);
275 #endif
276 
277  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
278  (CS_VOID*) bind.buffer,
279  &bind.datalen,
280  &bind.indicator));
281  break;
282  }
283  case eDB_Char:
284  case eDB_VarChar: {
285  CDB_String& par = dynamic_cast<CDB_String&> (param);
286  param_fmt.datatype = NCBI_CS_STRING_TYPE;
287  param_fmt.maxlength = (CS_INT) par.Size() + 1;
289  bind.datalen =
290  (bind.indicator == -1) ? 0 : (CS_INT) ts.size();
291  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
292  (CS_VOID*) ts.data(),
293  &bind.datalen,
294  &bind.indicator));
295  break;
296  }
297  case eDB_LongChar: {
298  CDB_LongChar& par = dynamic_cast<CDB_LongChar&> (param);
301  param_fmt.datatype = CS_LONGCHAR_TYPE;
302  param_fmt.maxlength = (CS_INT) par.Size() + 1;
303  bind.datalen =
304  (bind.indicator == -1) ? 0 : (CS_INT) data.size();
305  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
306  par.IsNULL()? (CS_VOID*)bind.buffer :
307  (CS_VOID*) data.data(),
308  &bind.datalen,
309  &bind.indicator));
310  break;
311  }
312  case eDB_Binary: {
313  CDB_Binary& par = dynamic_cast<CDB_Binary&> (param);
314  param_fmt.datatype = CS_BINARY_TYPE;
315  param_fmt.maxlength = (CS_INT) par.Size() + 1;
316  bind.datalen =
317  (bind.indicator == -1) ? 0 : (CS_INT) par.Size();
318  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
319  par.IsNULL()? (CS_VOID*)bind.buffer :
320  (CS_VOID*) par.Value(),
321  &bind.datalen,
322  &bind.indicator));
323  break;
324  }
325  case eDB_LongBinary: {
326  CDB_LongBinary& par = dynamic_cast<CDB_LongBinary&> (param);
327  param_fmt.datatype = CS_LONGBINARY_TYPE;
328  param_fmt.maxlength = (CS_INT) par.Size();
329  bind.datalen =
330  (bind.indicator == -1) ? 0 : (CS_INT) par.DataSize();
331  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
332  // par.Value() may return NULL. But NULL has a special
333  // meaning for this parameter. So, it is replaced a by
334  // a fake pointer (bind.buffer).
335  par.IsNULL()? (CS_VOID*)bind.buffer :
336  (CS_VOID*) par.Value(),
337  &bind.datalen,
338  &bind.indicator));
339  break;
340  }
341  case eDB_VarBinary: {
342  CDB_VarBinary& par = dynamic_cast<CDB_VarBinary&> (param);
343  param_fmt.datatype = CS_BINARY_TYPE;
344  param_fmt.maxlength = (CS_INT) par.Size() + 1;
345  bind.datalen = (CS_INT) par.Size();
346  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
347  par.IsNULL()? (CS_VOID*)bind.buffer :
348  (CS_VOID*) par.Value(),
349  &bind.datalen,
350  &bind.indicator));
351  break;
352  }
353  case eDB_Float: {
354  CDB_Float& par = dynamic_cast<CDB_Float&> (param);
355  param_fmt.datatype = CS_REAL_TYPE;
356  CS_REAL value = (CS_REAL) par.Value();
357  memcpy(bind.buffer, &value, sizeof(CS_REAL));
358  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
359  (CS_VOID*) bind.buffer,
360  &bind.datalen,
361  &bind.indicator));
362  break;
363  }
364  case eDB_Double: {
365  CDB_Double& par = dynamic_cast<CDB_Double&> (param);
366  param_fmt.datatype = CS_FLOAT_TYPE;
367  CS_FLOAT value = (CS_FLOAT) par.Value();
368  memcpy(bind.buffer, &value, sizeof(CS_FLOAT));
369  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
370  (CS_VOID*) bind.buffer,
371  &bind.datalen,
372  &bind.indicator));
373  break;
374  }
375  case eDB_SmallDateTime: {
376  CDB_SmallDateTime& par = dynamic_cast<CDB_SmallDateTime&> (param);
377  param_fmt.datatype = CS_DATETIME4_TYPE;
378 
379  CS_DATETIME4 dt;
380  if (param.IsNULL()) {
381  dt.days = 0;
382  dt.minutes = 0;
383  } else {
384  dt.days = par.GetDays();
385  dt.minutes = par.GetMinutes();
386  }
387 
388  memcpy(bind.buffer, &dt, sizeof(CS_DATETIME4));
389  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
390  (CS_VOID*) bind.buffer,
391  &bind.datalen,
392  &bind.indicator));
393  break;
394  }
395  case eDB_DateTime: {
396  CDB_DateTime& par = dynamic_cast<CDB_DateTime&> (param);
397  param_fmt.datatype = CS_DATETIME_TYPE;
398 
399  CS_DATETIME dt;
400  if (param.IsNULL()) {
401  dt.dtdays = 0;
402  dt.dttime = 0;
403  } else {
404  dt.dtdays = par.GetDays();
405  dt.dttime = par.Get300Secs();
406  }
407 
408  _ASSERT(sizeof(SBcpBind::buffer) >= sizeof(CS_DATETIME));
409  memcpy(bind.buffer, &dt, sizeof(CS_DATETIME));
410  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
411  (CS_VOID*) bind.buffer,
412  &bind.datalen,
413  &bind.indicator));
414  break;
415  }
416  case eDB_BigDateTime: {
417  CDB_BigDateTime& par = dynamic_cast<CDB_BigDateTime&> (param);
418  auto syntax = GetConnection().GetDateTimeSyntax();
419  bool need_date = true, need_time = true;
420  if (syntax == CDB_BigDateTime::eSyntax_Sybase) {
421  // Sybase claims to use classic DATETIME when working
422  // with clients that don't advertise support for newer
423  // types, but expects BCP-ed data to use new formats
424  // when the corresponding columns do.
425  switch (par.GetSQLType()) {
427  need_time = false;
428 #ifdef CS_DATE_TYPE
429  param_fmt.datatype = CS_DATE_TYPE;
430  bind.datalen = sizeof(CS_DATE_TYPE);
431 #else
432  param_fmt.datatype = CS_DATETIME_TYPE;
433  bind.datalen = 4; // 8? Might not work either way.
434 #endif
435  break;
437  need_date = false;
438 #ifdef CS_BIGTIME_TYPE
439  param_fmt.datatype = CS_BIGTIME_TYPE;
440  bind.datalen = sizeof(CS_BIGTIME_TYPE);
441 #else
442  param_fmt.datatype = CS_DATETIME_TYPE;
443  bind.datalen = 8;
444 #endif
445  break;
448 #ifdef CS_BIGTIME_TYPE
449  param_fmt.datatype = CS_BIGDATETIME_TYPE;
450  bind.datalen = sizeof(CS_BIGDATETIME_TYPE);
451 #else
452  param_fmt.datatype = CS_DATETIME_TYPE;
453  bind.datalen = 8;
454 #endif
455  break;
456  }
457 
458 #ifdef CS_DATE_TYPE
459  CS_DATE days = 0;
460 #else
461  CS_INT days = 0;
462 #endif
463 #ifdef CS_BIGTIME_TYPE
464  CS_BIGTIME us = 0;
465 #else
466  Uint8 us = 0;
467 #endif
468  if (param.IsNULL()) {
469  bind.datalen = 0;
470  } else {
471 # ifndef FTDS_IN_USE
472  bind.datalen = CS_UNUSED;
473 # endif
474  CTime t = par.GetCTime().GetLocalTime();
475  if (need_date) {
476  days = t.DiffWholeDays(CTime(1900, 1, 1));
477  }
478  if (need_time) {
479  us = (((t.Hour() * 60 + t.Minute()) * 60 + t.Second())
480  * NCBI_CONST_UINT8(1000000) + t.MicroSecond());
481  }
482  }
483 
484  if ( !need_time ) {
485  memcpy(bind.buffer, &days, sizeof(days));
486  } else if ( !need_date ) {
487  memcpy(bind.buffer, &us, sizeof(us));
488  } else {
489  static const Uint8 kMicrosecPerDay
490  = NCBI_CONST_UINT8(86400000000);
491 #ifdef CS_BIGDATETIME_TYPE
492  CS_BIGDATETIME dt
493 #else
494  Uint8 dt
495 #endif
496  = (days + 693961) * kMicrosecPerDay + us;
497  memcpy(bind.buffer, &dt, sizeof(dt));
498  }
499  } else {
500  const CTime& t = par.GetCTime();
501  CS_DATETIME dt = { 0, 0 };
502  param_fmt.datatype = CS_DATETIME_TYPE;
503  if ( !param.IsNULL() ) {
504  TDBTimeI dbt = t.GetTimeDBI();
505  if (CTime().SetTimeDBI(dbt) == t) {
506  dt.dtdays = dbt.days;
507  dt.dttime = dbt.time;
508  } else {
509  param_fmt.datatype = CS_CHAR_TYPE;
510  }
511  }
512 
513  if (param_fmt.datatype == CS_CHAR_TYPE) {
514  string s = (t.GetLocalTime()
516  (syntax, par.GetSQLType(),
517  par.GetOffset())));
520 #ifdef CS_TDS_73
522 #endif
523  ) {
524  param_fmt.maxlength
525  = static_cast<CS_INT>(sizeof(TCharUCS2)
526  * (s.size() + 1));
527  _ASSERT((size_t) param_fmt.maxlength
528  <= sizeof(SBcpBind::buffer));
529  TStringUCS2 ws = CUtf8::AsBasicString<TCharUCS2>(s);
530  memcpy(bind.buffer, ws.c_str(), param_fmt.maxlength);
531  bind.datalen = param_fmt.maxlength - sizeof(TCharUCS2);
532  } else {
533  _ASSERT(s.size() < sizeof(SBcpBind::buffer));
534  memcpy(bind.buffer, s.c_str(), s.size() + 1);
535  bind.datalen = static_cast<CS_INT>(s.size());
536  param_fmt.maxlength = bind.datalen + 1;
537  }
538  } else {
539  memcpy(bind.buffer, &dt, sizeof(CS_DATETIME));
540  }
541  }
542  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
543  (CS_VOID*) bind.buffer,
544  &bind.datalen,
545  &bind.indicator));
546  break;
547  }
548  case eDB_Text:
549  case eDB_VarCharMax: {
550  CDB_Stream& par = dynamic_cast<CDB_Stream&> (param);
551  param_fmt.datatype = CS_TEXT_TYPE;
552  param_fmt.maxlength = (CS_INT) par.Size();
553  bind.datalen = (CS_INT) par.Size();
554  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
555  0, &bind.datalen,
556  &bind.indicator));
557  break;
558  }
559  case eDB_Image:
560  case eDB_VarBinaryMax: {
561  CDB_Stream& par = dynamic_cast<CDB_Stream&> (param);
562  param_fmt.datatype = CS_IMAGE_TYPE;
563  param_fmt.maxlength = (CS_INT) par.Size();
564  bind.datalen = (CS_INT) par.Size();
565  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
566  0, &bind.datalen,
567  &bind.indicator));
568  break;
569  }
570  case eDB_Numeric: {
571  CDB_Numeric& par = dynamic_cast<CDB_Numeric&> (param);
572  param_fmt.datatype = CS_NUMERIC_TYPE;
573 
574  CS_NUMERIC numeric;
575  if ( !param.IsNULL() ) {
576  numeric.precision = par.Precision();
577  numeric.scale = par.Scale();
578  memcpy(numeric.array, par.RawData(), sizeof(numeric.array));
579 
580  param_fmt.precision = numeric.precision;
581  param_fmt.scale = numeric.scale;
582 
583  // cutoffs per
584  // http://msdn.microsoft.com/en-us/library/ms187746.aspx
585  int precision = par.Precision();
586  if (precision < 10) {
587  bind.datalen = 5;
588  } else if (precision < 20) {
589  bind.datalen = 9;
590  } else if (precision < 29) {
591  bind.datalen = 13;
592  } else {
593  bind.datalen = 17;
594  }
595 
596  memcpy(bind.buffer, &numeric, sizeof(CS_NUMERIC));
597  }
598  ret_code = Check(blk_bind(x_GetSybaseCmd(), i + 1, &param_fmt,
599  (CS_VOID*) bind.buffer,
600  &bind.datalen,
601  &bind.indicator));
602 
603  break;
604  }
605 
606  default:
607  return false;
608  }
609 
610  if (ret_code != CS_SUCCEED) {
611  return false;
612  }
613  }
614 
616  return true;
617 }
618 
619 
620 #if 0 // defined(HAVE_WSTRING)
621 static
622 string MakeUCS2LE(const wstring& str)
623 {
624  string result;
625 
626 #if defined(WORDS_BIGENDIAN)
627  if (!str.empty()) {
628  result.resize(str.size() * 2);
629  for(wstring::size_type i = 0; i < str.size(); ++i) {
630  wchar_t chracter = str.at(i);
631 
632  result.at(i * 2) = (chracter & 0x000000FF);
633  result.at(i * 2 + 1) = (chracter & 0x0000FF00);
634  }
635  }
636 #else
637  result.assign((const char*)str.data(), str.size() * sizeof(wchar_t));
638 #endif
639 
640  return result;
641 }
642 #endif
643 
644 
646 {
647  unsigned int i;
648  CS_INT datalen = 0;
649  size_t len = 0;
650  char buff[2048];
651 
652  CheckIsDead();
653 
654  if ( !WasSent() ) {
655  // we need to init the bcp
657  const_cast<CS_CHAR*>(GetQuery().data()),
658  static_cast<CS_INT>(GetQuery().size())),
659  "blk_init failed", 123001);
660 
661  SetWasSent();
662 
663  // check what needs to be default
664  CS_DATAFMT fmt;
665 
666  for (i = 0; i < GetBindParamsImpl().NofParams(); i++) {
667  if (GetBindParamsImpl().GetParamStatus(i) != 0) {
668  continue;
669  }
670 
671 
673  i + 1,
674  &fmt)) != CS_SUCCEED));
676  HasFailed(),
677  "blk_describe failed (check the number of "
678  "columns in a table)." + GetDbgInfo(),
679  123002 );
680  }
681  }
682 
683 
685  CHECK_DRIVER_ERROR( HasFailed(), "Cannot assign the params." + GetDbgInfo(), 123004 );
686 
687  switch ( Check(blk_rowxfer(x_GetSybaseCmd())) ) {
688  case CS_BLK_HAS_TEXT:
689  for (i = 0; i < GetBindParamsImpl().NofParams(); i++) {
690  if (GetBindParamsImpl().GetParamStatus(i) == 0)
691  continue;
692 
693  CDB_Object& param = *GetBindParamsImpl().GetParam(i);
694 
695  if (param.IsNULL()) {
696  continue;
697  }
698  else if (CDB_Object::IsBlobType(param.GetType())) {
699  CDB_Stream& par = dynamic_cast<CDB_Stream&> (param);
700  datalen = (CS_INT) par.Size();
701 
702  do {
703  len = par.Read(buff, sizeof(buff));
704 
706  (CS_BYTE*) buff,
707  (CS_INT) len,
708  0)
709  ) == CS_FAIL));
710 
712  HasFailed(),
713  "blk_textxfer failed for the BLOB field."
714  + GetDbgInfo(),
715  123005
716  );
717 
718  datalen -= (CS_INT) len;
719  } while (datalen > 0);
720  }
721  }
722  case CS_SUCCEED:
723  ++m_RowCount;
724  return true;
725  default:
726  SetHasFailed();
727  CHECK_DRIVER_ERROR( HasFailed(), "blk_rowxfer failed." + GetDbgInfo(), 123007 );
728  }
729 
730  return false;
731 }
732 
733 
735 {
736 #ifndef FTDS_IN_USE
737  DATABASE_DRIVER_ERROR("Cancelling is not available in ctlib.", 125000);
738 #endif
739 
740  if(WasSent()) {
741  if (IsDead()) {
742  SetWasSent(false);
743  return true;
744  }
745 
746  CS_INT outrow = 0;
747 
748  size_t was_timeout = GetConnection().PrepareToCancel();
749  try {
751  "blk_done failed", 123020) == CS_SUCCEED);
752  GetConnection().CancelFinished(was_timeout);
753  return result;
754  }
755  catch (CDB_Exception&) {
756  GetConnection().CancelFinished(was_timeout);
757  throw;
758  }
759  }
760 
761  return true;
762 }
763 
765 {
766  if(!WasSent()) return false;
767 
768  CheckIsDead();
769 
770  CS_INT outrow = 0;
771 
772  switch( Check(blk_done(x_GetSybaseCmd(), CS_BLK_BATCH, &outrow)) ) {
773  case CS_SUCCEED:
774  return (outrow > 0);
775  case CS_FAIL:
776  SetHasFailed();
777  DATABASE_DRIVER_ERROR( "blk_done failed." + GetDbgInfo(), 123020 );
778  default:
779  return false;
780  }
781 }
782 
783 
785 {
786  if(!WasSent()) return false;
787 
788  CheckIsDead();
789 
790  CS_INT outrow = 0;
791 
793  "blk_done failed", 123020) == CS_SUCCEED) {
794  return (outrow > 0);
795  }
796 
797  return false;
798 }
799 
800 
801 int CTL_BCPInCmd::RowCount(void) const
802 {
803  return m_RowCount;
804 }
805 
806 
808 {
809  try {
810  DetachInterface();
811 
812  DropCmd(*this);
813 
814  Close();
815 
816  if (!IsDead()) {
818  }
819  }
821 }
822 
823 
824 void
826 {
827  if (x_GetSybaseCmd()) {
828  // ????
829  DetachInterface();
830 
831  try {
832 
833 #ifdef FTDS_IN_USE
834  SetDead(!Cancel());
835 #else
836  if (WasSent()) {
837  SetDead(!EndBCP());
838  }
839 #endif
840 
841  } catch (...) {
842  SetDead();
843  throw;
844  }
845  }
846 }
847 
848 
850 {
851 #if defined(FTDS_IN_USE) && defined(blk_sethints)
852  m_Hints.clear();
853  if (Check(blk_sethints(x_GetSybaseCmd(), (CS_CHAR*)hints.data(), CS_INT(hints.size()))) == CS_FAIL) {
854  DATABASE_DRIVER_ERROR("blk_sethints failed." + GetDbgInfo(), 123018);
855  }
856 #else
857  _ASSERT(false);
858 #endif
859 }
860 
861 
863 {
864 #if defined(FTDS_IN_USE) && defined(blk_sethints)
865  string hints;
866  ITERATE(THintsMap, it, m_Hints) {
867  if (!hints.empty())
868  hints += ",";
869  hints += it->second;
870  }
871  if (Check(blk_sethints(x_GetSybaseCmd(), (CS_CHAR*)hints.data(), CS_INT(hints.size()))) == CS_FAIL) {
872  DATABASE_DRIVER_ERROR("blk_sethints failed." + GetDbgInfo(), 123019);
873  }
874 #endif
875 }
876 
877 
879 {
880 #ifdef FTDS_IN_USE
881  string str_hint;
882  bool need_value = false;
883  switch (hint) {
885  str_hint = "ROWS_PER_BATCH";
886  need_value = true;
887  break;
889  str_hint = "KILOBYTES_PER_BATCH";
890  need_value = true;
891  break;
893  str_hint = "TABLOCK";
894  break;
896  str_hint = "CHECK_CONSTRAINTS";
897  break;
899  str_hint = "FIRE_TRIGGERS";
900  break;
901  default:
902  DATABASE_DRIVER_ERROR("Wrong hint type in AddHint." + GetDbgInfo(), 123015);
903  }
904  if (need_value) {
905  if (value == 0) {
906  DATABASE_DRIVER_ERROR("Value in AddHint should not be 0."
907  + GetDbgInfo(), 123016);
908  }
909  str_hint += "=";
910  str_hint += NStr::IntToString(value);
911  }
912  else if (value != 0) {
913  DATABASE_DRIVER_ERROR("Cannot set value for a given hint type ("
914  + NStr::IntToString(hint) + ")."
915  + GetDbgInfo(), 123016);
916  }
917  m_Hints[hint] = str_hint;
918 
919  x_BlkSetHints();
920 #else
921  _ASSERT(false);
922 #endif
923 }
924 
926 {
927 #ifdef FTDS_IN_USE
928  string str_hint = "ORDER (";
929  str_hint += columns;
930  str_hint += ")";
931  m_Hints[CDB_BCPInCmd::eOrder] = str_hint;
932 
933  x_BlkSetHints();
934 #else
935  _ASSERT(false);
936 #endif
937 }
938 
939 
940 #ifdef FTDS_IN_USE
941 } // namespace NCBI_NS_FTDS_CTLIB
942 #endif
943 
945 
CDB_Exception –.
Definition: exception.hpp:118
virtual bool CommitBCPTrans(void)
Complete batch – to store all rows transferred by far in this batch into the table.
Definition: bcp.cpp:764
CTempString x_GetStringValue(unsigned int i)
Definition: bcp.cpp:161
virtual void SetHints(CTempString hints)
Set hints by one call.
Definition: bcp.cpp:849
THintsMap m_Hints
void Close(void)
Definition: bcp.cpp:825
CS_BLKDESC * m_Cmd
AutoArray< SBcpBind > & GetBind(void)
virtual int RowCount(void) const
Get the number of rows affected by the command Special case: negative on error or if there is no way ...
Definition: bcp.cpp:801
virtual bool Bind(unsigned int column_num, CDB_Object *param_ptr)
Definition: bcp.cpp:142
CS_RETCODE CheckSentSFB(CS_RETCODE rc, const char *msg, unsigned int msg_num)
Definition: bcp.cpp:121
CS_BLKDESC * x_GetSybaseCmd(void) const
virtual ~CTL_BCPInCmd(void)
Definition: bcp.cpp:807
virtual bool Cancel(void)
Cancel the command execution.
Definition: bcp.cpp:734
virtual void AddOrderHint(CTempString columns)
Add "ORDER" hint.
Definition: bcp.cpp:925
CS_RETCODE CheckSF(CS_RETCODE rc, const char *msg, unsigned int msg_num)
Definition: bcp.cpp:86
CS_RETCODE CheckSFB(CS_RETCODE rc, const char *msg, unsigned int msg_num)
Definition: bcp.cpp:102
bool x_IsUnicodeClientAPI(void) const
Definition: bcp.cpp:148
CTL_BCPInCmd(CTL_Connection &con, const string &table_name)
Definition: bcp.cpp:67
bool x_AssignParams(void)
Definition: bcp.cpp:190
virtual bool EndBCP(void)
Complete the BCP and store all rows transferred in last batch into the table.
Definition: bcp.cpp:784
virtual bool Send(void)
Send command to the server.
Definition: bcp.cpp:645
virtual void AddHint(CDB_BCPInCmd::EBCP_Hints hint, unsigned int value)
Add hint with value.
Definition: bcp.cpp:878
void x_BlkSetHints(void)
Definition: bcp.cpp:862
void SetDead(bool flag=true)
Definition: interfaces.hpp:688
void DropCmd(impl::CCommand &cmd)
CS_RETCODE Check(CS_RETCODE rc)
Definition: lang_cmd.cpp:102
CTL_Connection & GetConnection(void)
bool IsDead(void) const
Definition: interfaces.hpp:684
void CheckIsDead(void)
Definition: interfaces.hpp:692
virtual void SetHasFailed(bool flag=true)
Definition: interfaces.hpp:700
void SetExecCntxInfo(const string &info)
Definition: interfaces.hpp:675
const TDbgInfo & GetDbgInfo(void) const
Definition: interfaces.hpp:711
size_t PrepareToCancel(void)
Definition: connection.cpp:621
void CancelFinished(size_t was_timeout)
Definition: connection.cpp:631
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTime –.
Definition: ncbitime.hpp:296
const string & GetQuery(void) const
virtual bool HasFailed(void) const
const CDB_Params & GetBindParamsImpl(void) const
void DetachInterface(void)
void SetWasSent(bool flag=true)
bool WasSent(void) const
CDB_BigDateTime::ESyntax GetDateTimeSyntax(void)
CDB_Object * GetParam(unsigned int param_no) const
Definition: parameters.hpp:63
void LockBinding(void)
Definition: parameters.hpp:87
bool BindParam(unsigned int param_no, const string &param_name, CDB_Object *param, bool is_out=false)
Definition: parameters.cpp:151
TStatus GetParamStatus(unsigned int param_no) const
Definition: parameters.hpp:83
unsigned int NofParams() const
Definition: parameters.hpp:59
void clear()
Definition: map.hpp:169
#define NCBI_CS_STRING_TYPE
Definition: interfaces.hpp:102
CS_RETCODE blk_init(CS_BLKDESC *blkdesc, CS_INT direction, CS_CHAR *tablename, CS_INT tnamelen)
Definition: blk.c:340
CS_RETCODE blk_drop(CS_BLKDESC *blkdesc)
Definition: blk.c:310
CS_RETCODE blk_rowxfer(CS_BLKDESC *blkdesc)
Definition: blk.c:442
CS_RETCODE blk_textxfer(CS_BLKDESC *blkdesc, CS_BYTE *buffer, CS_INT buflen, CS_INT *outlen)
Definition: blk.c:518
CS_RETCODE blk_bind(CS_BLKDESC *blkdesc, CS_INT colnum, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT *datalen, CS_SMALLINT *indicator)
Definition: blk.c:70
CS_RETCODE blk_done(CS_BLKDESC *blkdesc, CS_INT type, CS_INT *outrow)
Definition: blk.c:228
CS_RETCODE blk_sethints(CS_BLKDESC *blkdesc, CS_CHAR *hints, CS_INT hintslen)
Definition: blk.c:494
CS_RETCODE blk_describe(CS_BLKDESC *blkdesc, CS_INT colnum, CS_DATAFMT *datafmt)
Definition: blk.c:184
CS_RETCODE blk_alloc(CS_CONNECTION *connection, CS_INT version, CS_BLKDESC **blk_pointer)
Definition: blk.c:51
#define CS_LONGCHAR_TYPE
Definition: cspublic.h:552
#define CS_SMALLINT_TYPE
Definition: cspublic.h:557
#define CS_BINARY_TYPE
Definition: cspublic.h:551
#define CS_FAIL
Definition: cspublic.h:41
#define CS_BLK_BATCH
Definition: cspublic.h:518
#define CS_FMT_UNUSED
Definition: cspublic.h:398
#define CS_DATETIME4_TYPE
Definition: cspublic.h:563
#define CS_TDS_73
Definition: cspublic.h:279
#define CS_BIGTIME_TYPE
Definition: cspublic.h:586
#define CS_FLOAT_TYPE
Definition: cspublic.h:560
#define CS_LONGBINARY_TYPE
Definition: cspublic.h:553
#define CS_BLK_ALL
Definition: cspublic.h:519
#define CS_DATE_TYPE
Definition: cspublic.h:577
#define CS_BIT_TYPE
Definition: cspublic.h:561
#define CS_BUSY
Definition: cspublic.h:45
#define CS_REAL_TYPE
Definition: cspublic.h:559
#define CS_BLK_IN
Definition: cspublic.h:515
#define CS_CHAR_TYPE
Definition: cspublic.h:550
@ CS_TDS_50
Definition: cspublic.h:272
#define CS_BIGDATETIME_TYPE
Definition: cspublic.h:585
#define CS_DATETIME_TYPE
Definition: cspublic.h:562
#define CS_INT_TYPE
Definition: cspublic.h:558
#define CS_TINYINT_TYPE
Definition: cspublic.h:556
#define CS_UNUSED
Definition: cspublic.h:425
#define CS_TEXT_TYPE
Definition: cspublic.h:554
#define CS_SUCCEED
Definition: cspublic.h:40
#define CS_BLK_HAS_TEXT
Definition: cspublic.h:47
#define CS_BLK_CANCEL
Definition: cspublic.h:520
#define CS_IMAGE_TYPE
Definition: cspublic.h:555
#define CS_NUMERIC_TYPE
Definition: cspublic.h:566
Int4 CS_INT
Definition: cstypes.h:41
double CS_FLOAT
Definition: cstypes.h:51
float CS_REAL
Definition: cstypes.h:50
Int2 CS_SMALLINT
Definition: cstypes.h:45
CS_UBIGINT CS_BIGTIME
Definition: cstypes.h:152
Int4 CS_BOOL
Definition: cstypes.h:52
unsigned char CS_TINYINT
Definition: cstypes.h:47
CS_UBIGINT CS_BIGDATETIME
Definition: cstypes.h:151
void CS_VOID
Definition: cstypes.h:53
unsigned char CS_BYTE
Definition: cstypes.h:49
CS_INT CS_RETCODE
Definition: cstypes.h:63
CS_INT CS_DATE
Definition: cstypes.h:147
char CS_CHAR
Definition: cstypes.h:48
struct _cs_numeric CS_NUMERIC
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
static const char table_name[]
Definition: bcp.c:249
static char precision
Definition: genparams.c:28
static const char * str(char *buf, int n)
Definition: stats.c:84
static const column_t columns[]
Definition: utf8_2.c:22
char data[12]
Definition: iconv.c:80
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define DATABASE_DRIVER_ERROR(message, err_code)
Definition: exception.hpp:740
#define CHECK_DRIVER_ERROR(failed, message, err_code)
Definition: exception.hpp:765
EBCP_Hints
Type of hint that can be set.
Definition: public.hpp:776
@ eCheckConstraints
Definition: public.hpp:781
@ eKilobytesPerBatch
Definition: public.hpp:779
static bool IsBlobType(EDB_Type db_type)
Definition: types.hpp:320
Uint2 GetMinutes(void) const
Definition: types.cpp:2401
double Value() const
Definition: types.hpp:850
const void * Value() const
Definition: types.hpp:756
float Value() const
Definition: types.hpp:825
size_t Size() const
Definition: types.hpp:726
const TOffset & GetOffset(void) const
Definition: types.hpp:1109
const unsigned char * RawData() const
Definition: types.hpp:1193
const void * Value() const
Definition: types.hpp:723
size_t Size() const
Definition: types.hpp:693
size_t Size() const
Definition: types.hpp:759
virtual EDB_Type GetType() const =0
const CTime & GetCTime(void) const
Definition: types.hpp:1107
size_t DataSize() const
Definition: types.hpp:797
size_t Size() const
Definition: types.hpp:795
Int4 Value() const
Definition: types.hpp:373
Int2 Value() const
Definition: types.hpp:400
Uint1 Scale() const
Definition: types.hpp:1187
Uint2 GetDays(void) const
Definition: types.cpp:2391
size_t Size(void) const
Definition: types.hpp:522
int Value() const
Definition: types.hpp:1145
Uint1 Value() const
Definition: types.hpp:427
ESQLType GetSQLType(void) const
Definition: types.hpp:1111
static CTimeFormat GetTimeFormat(ESyntax syntax, ESQLType sql_type=eDateTime, TOffset offset=null)
Definition: types.cpp:2623
Int4 GetDays(void) const
Definition: types.cpp:2501
virtual size_t Read(void *buff, size_t nof_bytes)
Definition: types.cpp:1987
Int4 Get300Secs(void) const
Definition: types.cpp:2511
void GetBulkInsertionData(CTempString *ts, bool convert_raw_bytes=false) const
Definition: types.cpp:1084
Uint1 Precision() const
Definition: types.hpp:1183
virtual size_t Size() const
Definition: types.cpp:2014
Int8 Value() const
Definition: types.hpp:454
bool IsNULL() const
Definition: types.hpp:303
const void * Value() const
Definition: types.hpp:792
@ eDB_Bit
Definition: types.hpp:68
@ eDB_Char
Definition: types.hpp:58
@ eDB_SmallDateTime
Definition: types.hpp:65
@ eDB_VarChar
Definition: types.hpp:57
@ eDB_TinyInt
Definition: types.hpp:55
@ eDB_LongChar
Definition: types.hpp:70
@ eDB_Double
Definition: types.hpp:62
@ eDB_Image
Definition: types.hpp:67
@ eDB_Float
Definition: types.hpp:61
@ eDB_Int
Definition: types.hpp:53
@ eDB_VarCharMax
Definition: types.hpp:72
@ eDB_Numeric
Definition: types.hpp:69
@ eDB_BigInt
Definition: types.hpp:56
@ eDB_BigDateTime
Definition: types.hpp:64
@ eDB_Binary
Definition: types.hpp:60
@ eDB_Text
Definition: types.hpp:66
@ eDB_SmallInt
Definition: types.hpp:54
@ eDB_DateTime
Definition: types.hpp:63
@ eDB_LongBinary
Definition: types.hpp:71
@ eDB_VarBinary
Definition: types.hpp:59
@ eDB_VarBinaryMax
Definition: types.hpp:73
@ eDateTimeOffset
DATETIMEOFFSET (MS); no Sybase equivalent.
Definition: types.hpp:1086
@ eDateTime
DATETIME2 (MS), BIGDATETIME (Sybase)
Definition: types.hpp:1085
@ eTime
TIME (MS), (BIG)TIME (Sybase)
Definition: types.hpp:1084
@ eDate
DATE (MS, Sybase)
Definition: types.hpp:1083
#define NCBI_CURRENT_FUNCTION
Get current function name.
Definition: ncbidiag.hpp:142
#define NCBI_CATCH_ALL_X(err_subcode, message)
Definition: ncbiexpt.hpp:619
#define FORMAT(message)
Format message using iostreams library.
Definition: ncbiexpt.hpp:672
#define numeric_limits
Pre-declaration of the "numeric_limits<>" template Forcibly overrides (using preprocessor) the origin...
Definition: ncbi_limits.hpp:92
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
const char * data(void) const
Return a pointer to the array represented.
Definition: tempstr.hpp:313
Uint2 TCharUCS2
Type for character in UCS-2 encoding.
Definition: ncbistr.hpp:3847
basic_string< TCharUCS2 > TStringUCS2
Type for string in UCS-2 encoding.
Definition: ncbistr.hpp:3849
size_type size(void) const
Return the length of the represented array.
Definition: tempstr.hpp:327
Int4 days
days from 1/1/1900
Definition: ncbitime.hpp:115
Int4 time
x/300 seconds from the beginning of current day
Definition: ncbitime.hpp:116
CTime GetLocalTime(void) const
Get the time as local time.
Definition: ncbitime.cpp:2047
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
int i
int len
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
EIPRangeType t
Definition: ncbi_localip.c:101
#define NCBI_CONST_UINT8(v)
Definition: ncbi_std.h:196
T max(T x_, T y_)
unsigned char * longlong_to_numeric(Int8 l_num, unsigned int prec, unsigned char *cs_num)
static const string kMax
Definition: showdefline.cpp:95
Database format for time where day and time is signed 32 bit.
Definition: ncbitime.hpp:114
CS_INT format
Definition: cstypes.h:126
CS_INT maxlength
Definition: cstypes.h:127
CS_INT precision
Definition: cstypes.h:129
CS_INT count
Definition: cstypes.h:131
CS_INT datatype
Definition: cstypes.h:125
CS_INT scale
Definition: cstypes.h:128
CS_USHORT minutes
Definition: cstypes.h:163
CS_USHORT days
Definition: cstypes.h:162
CS_INT dttime
Definition: cstypes.h:157
CS_INT dtdays
Definition: cstypes.h:156
unsigned char array[33]
Definition: cstypes.h:80
unsigned char precision
Definition: cstypes.h:78
unsigned char scale
Definition: cstypes.h:79
CS_SMALLINT len
Definition: cstypes.h:93
#define _ASSERT
else result
Definition: token2.c:20
Modified on Tue Apr 23 07:39:57 2024 by modify_doxy.py rev. 669887