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

Go to the SVN repository for this file.

1 /* $Id: rs_impl.cpp 79243 2017-08-24 15:46:37Z satskyse $
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 * File Name: $Id: rs_impl.cpp 79243 2017-08-24 15:46:37Z satskyse $
27 *
28 * Author: Michael Kholodov
29 *
30 * File Description: Resultset implementation
31 *
32 */
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbistr.hpp>
36 
37 #include "stmt_impl.hpp"
38 #include "cstmt_impl.hpp"
39 #include "conn_impl.hpp"
40 #include "cursor_impl.hpp"
41 #include "rs_impl.hpp"
42 #include "rsmeta_impl.hpp"
43 #include "dbexception.hpp"
44 
45 #include <dbapi/driver/public.hpp>
47 #include <dbapi/error_codes.hpp>
48 
49 
50 #include <typeinfo>
51 
52 
53 #define NCBI_USE_ERRCODE_X Dbapi_ObjImpls
54 
55 
57 
59  m_conn(conn),
60  m_rs(rs),
61  m_metaData(NULL),
62  m_istr(0),
63  m_ostr(0),
64  m_column(-1),
65  m_bindBlob(true),
66  m_disableBind(false),
67  m_wasNull(true),
68  m_rd(0),
69  m_totalRows(0),
70  m_LastVariantNum(0),
71  m_RowReadType(eReadUnknown)
72 {
73  SetIdent("CResultSet");
74 
75  if( m_rs == 0 ) {
76  _TRACE("CResultSet::ctor(): null CDB_Result* object");
77  _ASSERT(0);
78  }
79  else {
80  Init();
81  }
82 }
83 
84 
86 {
87  _ASSERT(m_rs);
88 
89  // Reserve storage for column data
90  EDB_Type type;
91  for(unsigned int i = 0; i < m_rs->NofItems(); ++i ) {
92  type = m_rs->ItemDataType(i);
93  switch( type ) {
94  case eDB_Char:
95  m_data.push_back(CVariant::Char(m_rs->ItemMaxSize(i), 0));
96  break;
97  case eDB_Binary:
98  m_data.push_back(CVariant::Binary(m_rs->ItemMaxSize(i), 0, 0));
99  break;
100  case eDB_LongChar:
101  m_data.push_back(CVariant::LongChar(0, m_rs->ItemMaxSize(i)));
102  break;
103  case eDB_LongBinary:
104  m_data.push_back(CVariant::LongBinary(m_rs->ItemMaxSize(i), 0, 0));
105  break;
106  default:
107  m_data.push_back(CVariant(type));
108  break;
109  }
110  }
111 
112  _TRACE("CResultSet::Init(): Space reserved for " << m_data.size()
113  << " columns");
114 
115 }
116 
118 {
119  try {
120  Notify(CDbapiClosedEvent(this));
121  FreeResources();
122  Notify(CDbapiDeletedEvent(this));
123  _TRACE(GetIdent() << " " << (void*)this << " deleted.");
124  }
126 }
127 
129 {
130  int index = 0;
131 
132  if (param.IsPositional()) {
133  index = param.GetPosition();
134  } else {
135  index = GetColNum(param.GetName());
136  }
137 
138  CheckIdx(index);
139  --index;
140 
141  if (index < m_LastVariantNum) {
142  x_CacheItems(index);
143  }
144  else {
145  switch (m_RowReadType) {
146  case eReadRaw:
147  // Here we will be also when IsDisableBind() == true
148  m_data[index].SetNull();
149  break;
150  case eReadUnknown:
152  m_column = -1;
153  // fall through
154  //case eReadVariant:
155  default:
156  x_CacheItems(index);
157  break;
158  }
159  }
160 
161  return m_data[index];
162 }
163 
165 {
166  if (ownership == eTakeOwnership) {
167  return new CResultSetMetaData(m_rs);
168  }
169 
170  if (m_metaData == NULL) {
172  m_metaData->AddListener(this);
174  }
175  return m_metaData;
176 }
177 
179 {
180  _ASSERT(m_rs);
181  return m_rs->ResultType();
182 }
183 
185 {
186  m_bindBlob = b;
187 }
188 
190 {
191  m_disableBind = b;
192 }
193 
195 {
196  bool more = false;
197 
198  if (m_rs) {
199  more = m_rs->Fetch();
200  m_LastVariantNum = 0;
202  }
203 
204  if (more && m_data.size() == 0) {
205  Init();
206  }
207 
208  m_column = 0;
209  if( more && !IsDisableBind() ) {
210  for(unsigned int i = 0; i < m_rs->NofItems(); ++i ) {
213  break;
214  }
215  ++m_column;
216  }
217 
219  if ((unsigned int)m_column >= m_rs->NofItems()) {
220  m_column = -1;
221  }
222  }
223  else {
225  }
226 
227  if( !more ) {
228  if( m_ostr ) {
229  _TRACE("CResulstSet: deleting BLOB output stream...");
230  delete m_ostr;
231  m_ostr = 0;
232  }
233  if( m_istr ) {
234  _TRACE("CResulstSet: deleting BLOB input stream...");
235  delete m_istr;
236  m_istr = 0;
237  }
238  if( m_rd ) {
239  _TRACE("CResulstSet: deleting BLOB reader...");
240  delete m_rd;
241  m_rd = 0;
242  }
243 
245  }
246  else {
247  ++m_totalRows;
248  }
249 
250  return more;
251 }
252 
253 void CResultSet::x_CacheItems(int last_num) {
254  int ind;
255  while ((ind = m_rs->CurrentItemNo()) >= 0 && ind <= last_num) {
256  EDB_Type type = m_rs->ItemDataType(ind);
257 
258  CVariant& var = m_data[ind];
260  ((CDB_Stream*)var.GetNonNullData())->Truncate();
262  }
263  m_rs->GetItem(var.GetNonNullData());
264 
265  if (m_rs->ResultType() == eDB_StatusResult)
266  break;
267  }
268 }
269 
270 size_t CResultSet::Read(void* buf, size_t size)
271 {
272  _ASSERT(m_rs);
273 
274  if( m_column < 0 ) {
275  _TRACE("CResulstSet: No available column for Read(), current column: "
276  << m_rs->CurrentItemNo());
277  NCBI_DBAPI_THROW( "No available column for Read()" );
278  }
279 
280  x_CacheItems(m_column - 1);
282 
283  if( m_column != m_rs->CurrentItemNo() ) {
284 
286  return 0;
287  }
288  else {
289  size_t ret = m_rs->ReadItem(buf, size, &m_wasNull);
290  if( ret == 0 ) {
292  }
293  return ret;
294  }
295 }
296 
298 {
299  return m_wasNull;
300 }
301 
302 
304 {
305  _ASSERT(m_rs);
306  return m_rs->CurrentItemNo() + 1;
307 }
308 
310 {
311  _ASSERT(m_rs);
312  return m_rs->NofItems();
313 }
314 
316 {
317  delete m_istr;
318  m_istr = 0;
319  m_istr = new CRStream(new CxBlobReader(this), buf_size, 0,
322  return *m_istr;
323 }
324 
326  EAllowLog log_it,
327  size_t buf_size)
328 {
329  return IResultSet::GetBlobOStream(blob_size, log_it, buf_size);
330 }
331 
333  size_t blob_size,
334  EAllowLog log_it,
335  size_t buf_size)
336 {
337  return IResultSet::GetBlobOStream(conn, blob_size, log_it, buf_size);
338 }
339 
341 {
342  delete m_rd;
343  m_rd = 0;
344  m_rd = new CxBlobReader(this);
345  return m_rd;
346 }
347 
350  size_t buf_size)
351 {
352  _ASSERT(m_conn);
353  return xGetBlobOStream(m_conn->CloneCDB_Conn(), blob_size,
354  flags, buf_size, true);
355 }
356 
358  size_t blob_size,
360  size_t buf_size)
361 {
362  _ASSERT(m_conn);
363  return xGetBlobOStream(conn->GetCDB_Connection(), blob_size,
364  flags, buf_size, false);
365 }
366 
368  size_t blob_size,
370  size_t buf_size,
371  bool destroy)
372 {
373  _ASSERT(m_rs);
374 
375  // GetConnAux() returns pointer to pooled CDB_Connection.
376  // we need to delete it every time we request new one.
377  // The same with BlobDescriptor
378  delete m_ostr;
379 
380  // Call ReadItem(0, 0) before getting BLOB descriptor
381  m_rs->ReadItem(0, 0);
382 
383 
384  unique_ptr<I_BlobDescriptor> desc(m_rs->GetBlobDescriptor());
385  if(desc.get() == NULL) {
386 #ifdef _DEBUG
387  NcbiCerr << "CResultSet::GetBlobOStream(): zero IT Descriptor" << endl;
388  _ASSERT(0);
389 #else
390  NCBI_DBAPI_THROW( "CResultSet::GetBlobOStream(): Invalid IT Descriptor" );
391 #endif
392  }
393 
394  m_ostr = new CWStream(new CxBlobWriter(cdb_conn, *desc, blob_size, flags, destroy),
395  buf_size, 0, CRWStreambuf::fOwnWriter);
396  return *m_ostr;
397 }
398 
400 {
401  Notify(CDbapiClosedEvent(this));
402  FreeResources();
403 }
404 
406 {
407  //_TRACE("CResultSet::Close(): deleting CDB_Result " << (void*)m_rs);
408  Invalidate();
409 
410  delete m_istr;
411  m_istr = 0;
412  delete m_ostr;
413  m_ostr = 0;
414  delete m_rd;
415  m_rd = 0;
416  m_totalRows = -1;
417 }
418 
420 {
421  _TRACE(GetIdent() << " " << (void*)this
422  << ": '" << e.GetName()
423  << "' received from " << e.GetSource()->GetIdent());
424 
425  if(dynamic_cast<const CDbapiClosedEvent*>(&e) != 0 ) {
426  if( dynamic_cast<CStatement*>(e.GetSource()) != 0
427  || dynamic_cast<CCallableStatement*>(e.GetSource()) != 0 ) {
428  if( m_rs != 0 ) {
429  _TRACE("Discarding old CDB_Result " << (void*)m_rs);
430  Invalidate();
431  }
432  }
433  }
434  else if(dynamic_cast<const CDbapiDeletedEvent*>(&e) != 0 ) {
435 
437 
438  if(dynamic_cast<CStatement*>(e.GetSource()) != 0
439  || dynamic_cast<CCursor*>(e.GetSource()) != 0
440  || dynamic_cast<CCallableStatement*>(e.GetSource()) != 0 ) {
441  _TRACE("Deleting " << GetIdent() << " " << (void*)this);
442  delete this;
443  }
444  }
445 }
446 
447 
448 int CResultSet::GetColNum(const string& name)
449 {
450  _ASSERT(m_rs);
451 
452  unsigned int i = 0;
453  for( ; i < m_rs->NofItems(); ++i ) {
454 
455  if( !NStr::Compare(m_rs->ItemName(i), name) )
456  return i+1;
457  }
458 
459  NCBI_DBAPI_THROW( "CResultSet::GetColNum(): invalid column name [" + name + "]" );
460 }
461 
462 void CResultSet::CheckIdx(unsigned int idx)
463 {
464  if ( idx > m_data.size() ) {
465 #ifdef _DEBUG
466  NcbiCerr << "CResultSet::CheckIdx(): Column index " << idx << " out of range" << endl;
467  _ASSERT(0);
468 #else
469  NCBI_DBAPI_THROW( "CResultSet::CheckIdx(): Column index" + NStr::IntToString(idx) + " out of range" );
470 #endif
471  }
472 }
473 
void RemoveListener(CActiveObject *obj)
Definition: active_obj.cpp:60
void SetIdent(const string &name)
Definition: active_obj.cpp:98
void AddListener(CActiveObject *obj)
Definition: active_obj.cpp:50
string GetIdent() const
Definition: active_obj.cpp:93
void Notify(const CDbapiEvent &e)
Definition: active_obj.cpp:71
CDB_Connection * CloneCDB_Conn()
Definition: conn_impl.cpp:208
string GetName() const
Definition: active_obj.hpp:57
CActiveObject * GetSource() const
Definition: active_obj.hpp:55
Note about the "buf_size" parameter for streams in this API.
Definition: rwstream.hpp:122
@ fLogExceptions
Exceptions logged only.
Definition: rwstreambuf.hpp:71
@ fOwnReader
Own the underlying reader.
Definition: rwstreambuf.hpp:66
@ fOwnWriter
Own the underlying writer.
Definition: rwstreambuf.hpp:67
void FreeResources()
Definition: rs_impl.cpp:405
CDB_Result * m_rs
Definition: rs_impl.hpp:147
void CheckIdx(unsigned int idx)
Definition: rs_impl.cpp:462
virtual CNcbiIstream & GetBlobIStream(size_t buf_size)
Get Blob input stream.
Definition: rs_impl.cpp:315
bool m_wasNull
Definition: rs_impl.hpp:155
void Init()
Definition: rs_impl.cpp:85
CNcbiOstream & xGetBlobOStream(CDB_Connection *cdb_conn, size_t blob_size, TBlobOStreamFlags flags, size_t buf_size, bool destroy)
Definition: rs_impl.cpp:367
virtual const CVariant & GetVariant(const CDBParamVariant &param)
Retrieve a CVariant class describing the data stored in a given column.
Definition: rs_impl.cpp:128
void Invalidate()
Definition: rs_impl.hpp:111
class CConnection * m_conn
Definition: rs_impl.hpp:146
virtual bool Next()
Get next row.
Definition: rs_impl.cpp:194
int m_totalRows
Definition: rs_impl.hpp:157
bool IsDisableBind()
Definition: rs_impl.hpp:130
bool m_disableBind
Definition: rs_impl.hpp:154
CWStream * m_ostr
Definition: rs_impl.hpp:151
int GetColNum(const string &name)
Definition: rs_impl.cpp:448
virtual void Close()
Close resultset.
Definition: rs_impl.cpp:399
int m_LastVariantNum
Definition: rs_impl.hpp:158
vector< CVariant > m_data
Definition: rs_impl.hpp:149
virtual int GetColumnNo()
Get column number, currently available for Read()
Definition: rs_impl.cpp:303
@ eReadVariant
Definition: rs_impl.hpp:162
@ eReadUnknown
Definition: rs_impl.hpp:161
bool m_bindBlob
Definition: rs_impl.hpp:153
virtual void BindBlobToVariant(bool b)
Bind blob to variant.
Definition: rs_impl.cpp:184
ERowReadType m_RowReadType
Definition: rs_impl.hpp:166
CRStream * m_istr
Definition: rs_impl.hpp:150
virtual size_t Read(void *buf, size_t size)
Read unformatted data.
Definition: rs_impl.cpp:270
virtual EDB_ResType GetResultType()
Get result type.
Definition: rs_impl.cpp:178
virtual void DisableBind(bool b)
Disables column binding.
Definition: rs_impl.cpp:189
CResultSet(class CConnection *conn, CDB_Result *rs)
Definition: rs_impl.cpp:58
virtual CNcbiOstream & GetBlobOStream(size_t blob_size, TBlobOStreamFlags flags, size_t buf_size)
Get Blob output stream.
Definition: rs_impl.cpp:348
int m_column
Definition: rs_impl.hpp:152
void x_CacheItems(int last_num)
Definition: rs_impl.cpp:253
CxBlobReader * m_rd
Definition: rs_impl.hpp:156
virtual ~CResultSet()
Definition: rs_impl.cpp:117
virtual void Action(const CDbapiEvent &e)
Definition: rs_impl.cpp:419
virtual bool WasNull()
Determine if last column was NULL.
Definition: rs_impl.cpp:297
virtual const IResultSetMetaData * GetMetaData(EOwnership ownership)
Get Metadata.
Definition: rs_impl.cpp:164
CResultSetMetaData * m_metaData
Definition: rs_impl.hpp:148
virtual unsigned int GetTotalColumns()
Get total columns.
Definition: rs_impl.cpp:309
virtual IReader * GetBlobReader()
Get a Blob Reader.
Definition: rs_impl.cpp:340
CVariant –.
Definition: variant.hpp:99
Writer-based output stream.
Definition: rwstream.hpp:171
A very basic data-read interface.
IResultSetMetaData –.
Definition: dbapi.hpp:114
The NCBI C++ standard methods for dealing with std::string.
static uch flags
#define NCBI_DBAPI_THROW(message)
Definition: dbexception.hpp:55
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static int type
Definition: getdata.c:31
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
#define NULL
Definition: ncbistd.hpp:225
int TBlobOStreamFlags
Definition: dbapi.hpp:103
EAllowLog
EDataSource –.
Definition: dbapi.hpp:78
virtual CNcbiOstream & GetBlobOStream(size_t blob_size, TBlobOStreamFlags flags=0, size_t buf_size=0)=0
Get Blob output stream.
bool IsPositional(void) const
Definition: interfaces.hpp:115
unsigned int GetPosition(void) const
Definition: interfaces.hpp:119
EDB_ResType
EDB_ResType::
Definition: interfaces.hpp:386
const string & GetName(void) const
Definition: interfaces.hpp:129
@ eDB_StatusResult
Definition: interfaces.hpp:390
virtual EDB_ResType ResultType() const
Get type of the result.
Definition: public.cpp:609
virtual size_t ItemMaxSize(unsigned int item_num) const
Get size (in bytes) of a result item.
Definition: public.cpp:643
virtual EDB_Type ItemDataType(unsigned int item_num) const
Get datatype of a result item.
Definition: public.cpp:649
virtual int CurrentItemNo() const
Return current item number we can retrieve (0,1,...)
Definition: public.cpp:666
virtual size_t ReadItem(void *buffer, size_t buffer_size, bool *is_null=0)
Read a result item body (for BLOB columns, mostly).
Definition: public.cpp:684
virtual CDB_Object * GetItem(CDB_Object *item_buf=0, EGetItem policy=eAppendLOB)
Get a result item (you can use either GetItem or ReadItem).
Definition: public.cpp:678
virtual const char * ItemName(unsigned int item_num) const
Get name of a result item.
Definition: public.cpp:630
virtual unsigned int NofItems() const
Get # of items (columns) in the result.
Definition: public.cpp:623
virtual I_BlobDescriptor * GetBlobDescriptor()
Get a descriptor for a BLOB column (for SendData).
Definition: public.cpp:690
virtual bool Fetch()
Fetch next row.
Definition: public.cpp:655
static bool IsBlobType(EDB_Type db_type)
Definition: types.hpp:320
EDB_Type
Definition: types.hpp:52
@ eDB_Char
Definition: types.hpp:58
@ eDB_LongChar
Definition: types.hpp:70
@ eDB_Binary
Definition: types.hpp:60
@ eDB_LongBinary
Definition: types.hpp:71
CDB_Object * GetNonNullData() const
Definition: variant.cpp:456
static CVariant LongChar(const char *p, size_t len=0)
Definition: variant.cpp:135
static CVariant LongBinary(size_t maxSize, const void *p, size_t len)
Definition: variant.cpp:181
static CVariant Binary(size_t size, const void *p, size_t len)
Definition: variant.cpp:196
static CVariant Char(size_t size, const char *p)
Definition: variant.cpp:171
void SetBlobDescriptor(I_BlobDescriptor *descr)
Definition: variant.hpp:295
#define _TRACE(message)
Definition: ncbidbg.hpp:122
#define NCBI_CATCH_ALL_X(err_subcode, message)
Definition: ncbiexpt.hpp:619
void destroy(P pT)
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
#define NcbiCerr
Definition: ncbistre.hpp:544
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5086
static int Compare(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Compare of a substring with another string.
Definition: ncbistr.hpp:5299
CTime Truncate(const CTime &t)
Definition: ncbitime.hpp:2194
enum ENcbiOwnership EOwnership
Ownership relations between objects.
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
char * buf
int i
const struct ncbi::grid::netcache::search::fields::SIZE size
Definition: type.c:6
#define _ASSERT
Modified on Wed Sep 04 15:01:25 2024 by modify_doxy.py rev. 669887