All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataSet.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/ado/DataSet.cpp
22 
23  \brief DataSet class implementation for Microsoft Access driver.
24 */
25 
26 // TerraLib
27 #include "../common/ByteSwapUtils.h"
28 #include "../common/Globals.h"
29 #include "../common/StringUtils.h"
30 #include "../common/Translator.h"
31 #include "../dataaccess/dataset/DataSetType.h"
32 #include "../datatype/Array.h"
33 #include "../datatype/ByteArray.h"
34 #include "../datatype/DateTimeProperty.h"
35 #include "../datatype/SimpleData.h"
36 #include "../datatype/TimeInstant.h"
37 #include "../geometry/Envelope.h"
38 #include "../geometry/Geometry.h"
39 #include "../geometry/WKBReader.h"
40 #include "Connection.h"
41 #include "DataSet.h"
42 #include "DataSource.h"
43 #include "Exception.h"
44 #include "Transactor.h"
45 #include "Utils.h"
46 
47 // STL
48 #include <memory>
49 
50 // Boost
51 #include <boost/dynamic_bitset.hpp>
52 #include <boost/lexical_cast.hpp>
53 
54 inline void TESTHR( HRESULT hr )
55 {
56  if( FAILED(hr) ) _com_issue_error( hr );
57 }
58 
59 te::ado::DataSet::DataSet(Transactor* t, _RecordsetPtr result)
60  : m_result(result),
61  m_t(t),
62  m_i(-1),
63  m_size(-1),
64  m_ncols(-1)
65 {
66  m_size = m_result->GetRecordCount();
67 
68  m_ncols = m_result->GetFields()->GetCount();
69 
70 // convert data types from ADO to TerraLib
71  FieldsPtr fields = m_result->GetFields();
72 
73  for(int i = 0; i != m_ncols; ++i)
74  {
75  FieldPtr field = fields->GetItem((long)i);
76 
77  std::string columnName = field->GetName();
78 
79  m_colNames.push_back(columnName);
80 
81  int terralib_data_type = te::ado::Convert2Terralib(field->GetType());
82 
83 // if it is a byte array it may be a geometric column!
84  if(terralib_data_type == te::dt::BYTE_ARRAY_TYPE)
85  {
86  std::string tableName = (LPCSTR)(_bstr_t)field->GetProperties()->GetItem("BASETABLENAME")->GetValue();
87 
88  bool is_geom = m_t->getAdoDataSource()->isGeometryColumn(tableName, columnName);
89 
90  if(is_geom)
92  else
93  m_datatypes.push_back(terralib_data_type);
94  }
95  else
96  {
97  m_datatypes.push_back(terralib_data_type);
98  }
99  }
100 }
101 
103 {
104  m_result->Close();
105 }
106 
108 {
109  return te::common::RANDOM;
110 }
111 
113 {
114  return te::common::RAccess;
115 }
116 
117 std::auto_ptr<te::gm::Envelope> te::ado::DataSet::getExtent(std::size_t /*i*/)
118 {
119  throw Exception(TR_ADO("Method getExtent: not implemented yet!"));
120 }
121 
123 {
124  return m_ncols;
125 }
126 
128 {
129  return m_datatypes[i];
130 }
131 
132 std::string te::ado::DataSet::getPropertyName(std::size_t i) const
133 {
134  return m_colNames[i];
135 }
136 
137 std::string te::ado::DataSet::getDatasetNameOfProperty(std::size_t /*i*/) const
138 {
139  throw Exception(TR_ADO("Method getDatasetNameOfProperty: not implemented yet!"));
140 }
141 
143 {
144  return (m_size == 0);
145 }
146 
148 {
149  return true;
150 }
151 
152 std::size_t te::ado::DataSet::size() const
153 {
154  return m_size;
155 }
156 
158 {
159  if(m_i != -1)
160  TESTHR(m_result->MoveNext());
161 
162  ++m_i;
163  bool teste = (m_i < m_size);
164  return (m_i < m_size);
165 }
166 
168 {
169  if(m_i != m_size)
170  m_result->MovePrevious();
171 
172  --m_i;
173  return (m_i > -1);
174 }
175 
177 {
178  if(m_result->BOF != 0)
179  return true;
180 
181  TESTHR(m_result->MoveFirst());
182  m_i = -1;
183 
184  return m_size != 0;
185 }
186 
188 {
189  m_result->MoveFirst();
190  m_i = 0;
191  return m_size != 0;
192 }
193 
195 {
196  TESTHR(m_result->MoveLast());
197  m_i = m_size - 1;
198  return (m_i < m_size);
199 }
200 
201 bool te::ado::DataSet::move(std::size_t i)
202 {
203  if(i == 0)
204  return moveFirst();
205 
206  if(m_i == i)
207  return true;
208 
209  long p = static_cast<long>(i-m_i);
210 
211  TESTHR(m_result->Move(p));
212 
213  m_i += p;
214  return (m_i < m_size);
215 }
216 
218 {
219  return m_i == 0;
220 }
221 
223 {
224  return m_i < 0;
225 }
226 
228 {
229  return m_i == (m_size - 1);
230 }
231 
233 {
234  return m_i >= m_size;
235 }
236 
237 char te::ado::DataSet::getChar(std::size_t i) const
238 {
239  _variant_t vtIndex;
240  vtIndex.vt = VT_I4;
241  vtIndex.lVal = i;
242 
243  char ival;
244 
245  try
246  {
247  ival = (char)m_result->GetFields()->GetItem(vtIndex)->GetValue();
248  }
249  catch(_com_error& e)
250  {
251  throw Exception(TR_ADO(e.Description()));
252  }
253 
254  return ival;
255 }
256 
257 unsigned char te::ado::DataSet::getUChar(std::size_t i) const
258 {
259  return (unsigned char)getChar(i);
260 }
261 
262 boost::int16_t te::ado::DataSet::getInt16(std::size_t i) const
263 {
264  _variant_t vtIndex;
265  vtIndex.vt = VT_I4;
266  vtIndex.lVal = i;
267 
268  int16_t ival;
269 
270  try
271  {
272  ival = (int16_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
273  }
274  catch(_com_error& e)
275  {
276  throw Exception(TR_ADO(e.Description()));
277  }
278 
279  return ival;
280 }
281 
282 boost::int32_t te::ado::DataSet::getInt32(std::size_t i) const
283 {
284  _variant_t vtIndex;
285  vtIndex.vt = VT_I4;
286  vtIndex.lVal = i;
287 
288  int32_t ival;
289 
290  try
291  {
292  ival = (int32_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
293  }
294  catch(_com_error& e)
295  {
296  throw Exception(TR_ADO(e.Description()));
297  }
298 
299  return ival;
300 }
301 
302 boost::int64_t te::ado::DataSet::getInt64(std::size_t i) const
303 {
304  _variant_t vtIndex;
305  vtIndex.vt = VT_I4;
306  vtIndex.lVal = i;
307 
308  int64_t ival;
309 
310  try
311  {
312  ival = (int64_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
313  }
314  catch(_com_error& e)
315  {
316  throw Exception(TR_ADO(e.Description()));
317  }
318 
319  return ival;
320 }
321 
322 bool te::ado::DataSet::getBool(std::size_t i) const
323 {
324  _variant_t vtIndex;
325  vtIndex.vt = VT_I4;
326  vtIndex.lVal = i;
327 
328  bool ival;
329 
330  try
331  {
332  ival = (bool)m_result->GetFields()->GetItem(vtIndex)->GetValue();
333  }
334  catch(_com_error& e)
335  {
336  throw Exception(TR_ADO(e.Description()));
337  }
338 
339  return ival;
340 }
341 
342 float te::ado::DataSet::getFloat(std::size_t i) const
343 {
344  float value;
345 
346  _variant_t vtIndex;
347  vtIndex.vt = VT_I4;
348  vtIndex.lVal = i;
349 
350  try
351  {
352  value = (float)m_result->GetFields()->GetItem(vtIndex)->GetValue();
353  }
354  catch(_com_error& e)
355  {
356  throw Exception(TR_ADO(e.Description()));
357  }
358 
359  return value;
360 }
361 
362 double te::ado::DataSet::getDouble(std::size_t i) const
363 {
364  double value;
365 
366  _variant_t vtIndex;
367  vtIndex.vt = VT_I4;
368  vtIndex.lVal = i;
369 
370  try
371  {
372  value = (double)m_result->GetFields()->GetItem(vtIndex)->GetValue();
373  }
374  catch(_com_error& e)
375  {
376  throw Exception(TR_ADO(e.Description()));
377  }
378 
379  return value;
380 }
381 
382 std::string te::ado::DataSet::getNumeric(std::size_t /*i*/) const
383 {
384  throw Exception(TR_ADO("Method getNumeric: not implemented yet!"));
385 }
386 
387 std::string te::ado::DataSet::getString(std::size_t i) const
388 {
389  _variant_t vtIndex;
390  vtIndex.vt = VT_I4;
391  vtIndex.lVal = i;
392 
393  std::string ival;
394 
395  try
396  {
397  ival = (LPCSTR)(_bstr_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
398  }
399  catch(_com_error& e)
400  {
401  throw Exception(TR_ADO(e.Description()));
402  }
403 
404  return ival;
405 }
406 
407 std::auto_ptr<te::dt::ByteArray> te::ado::DataSet::getByteArray(std::size_t i) const
408 {
409  _variant_t vtIndex;
410  vtIndex.vt = VT_I4;
411  vtIndex.lVal = i;
412 
413  _variant_t varBLOB;
414  char *cdata = 0;
415  long size;
416  char* data;
417 
418  try
419  {
420  ::Field15Ptr field;
421 
422  if(m_result->MoveNext() == S_OK)
423  m_result->MovePrevious();
424  else if(m_result->MovePrevious() == S_OK)
425  m_result->MoveNext();
426  else
427  {
428  _RecordsetPtr copy = m_result->Clone(adLockReadOnly);
429 
430  field = copy->GetFields()->GetItem(vtIndex);
431  }
432 
433  field = m_result->GetFields()->GetItem(vtIndex);
434 
435  size = field->ActualSize;
436  if(size > 0)
437  {
438  VariantInit(&varBLOB);
439 
440  varBLOB = field->GetChunk(size);
441 
442  if(varBLOB.vt == (VT_ARRAY | VT_UI1))
443  {
444  SafeArrayAccessData(varBLOB.parray,(void **)&cdata);
445  data = new char[size];
446  memcpy(data, cdata, size);
447  SafeArrayUnaccessData(varBLOB.parray);
448  }
449  }
450  }
451  catch(_com_error& e)
452  {
453  throw Exception(TR_ADO(e.Description()));
454  }
455 
456  return std::auto_ptr<te::dt::ByteArray>(new te::dt::ByteArray(data, size));
457 }
458 
459 std::auto_ptr<te::gm::Geometry> te::ado::DataSet::getGeometry(std::size_t i) const
460 {
461  std::auto_ptr<te::dt::ByteArray> ba(getByteArray(i));
462 
463  std::auto_ptr<te::gm::Geometry> geom(te::gm::WKBReader::read(ba->getData()));
464 
465  std::size_t wkb_size = geom->getWkbSize();
466 
467  if(ba->bytesUsed() - wkb_size >= 4)
468  geom->setSRID(*((int*)(ba->getData() + wkb_size)));
469 
470  return geom;
471 }
472 
473 std::auto_ptr<te::rst::Raster> te::ado::DataSet::getRaster(std::size_t /*i*/) const
474 {
475  throw Exception(TR_ADO("Method getRaster: not implemented yet!"));
476 }
477 
478 std::auto_ptr<te::dt::DateTime> te::ado::DataSet::getDateTime(std::size_t i) const
479 {
480  _variant_t vtIndex;
481  _variant_t value;
482 
483  vtIndex.vt = VT_I4;
484  vtIndex.lVal = i;
485 
486  te::dt::DateTime* dateTime = 0;
487 
488  std::string strDate;
489  try
490  {
491  value = m_result->GetFields()->GetItem(vtIndex)->Value;
492  }
493  catch(_com_error &e)
494  {
495  throw Exception(TR_ADO(e.Description()));
496  }
497 
498  if(value.vt == VT_NULL)
499  return std::auto_ptr<te::dt::DateTime>(0);
500 
501  strDate = (LPCSTR)(_bstr_t)value;
502 
503  // Getting system format
504  std::string indAM;
505  std::string indPM;
506  std::string sepD;
507  std::string sepT;
508 
509  std::string mask = te::ado::GetSystemDateTimeFormat(indAM, indPM, sepD, sepT);
510 
511  std::auto_ptr<te::dt::DateTime> result = te::ado::GetDateTime(strDate, mask, sepD, sepT);
512 
513  return result;
514 }
515 
516 std::auto_ptr<te::dt::Array> te::ado::DataSet::getArray(std::size_t /*i*/) const
517 {
518  throw Exception(TR_ADO("Method getArray: not implemented yet!"));
519 }
520 
521 bool te::ado::DataSet::isNull(std::size_t i) const
522 {
523  _variant_t value;
524 
525  std::string propertyName = getPropertyName(i);
526 
527  try
528  {
529  value = m_result->GetFields()->GetItem(static_cast<long>(i))->GetValue();
530  }
531 
532  catch(_com_error& e)
533  {
534  throw Exception(TR_ADO(e.Description()));
535  }
536 
537  if(value.vt == VT_NULL)
538  return true;
539 
540  return false;
541 }
bool isNull(std::size_t i) const
It checks if the attribute value is NULL.
Definition: DataSet.cpp:521
int Convert2Terralib(ADOX::DataTypeEnum adoType)
Bind ADOX Type to TerraLib Type.
Definition: Utils.cpp:202
The transactor class for the Microsoft Access driver.
Definition: Transactor.h:62
bool isEmpty() const
It returns true if the collection is empty.
Definition: DataSet.cpp:142
Utility functions for ADO.
te::common::TraverseType getTraverseType() const
It returns the traverse type associated to the dataset.
Definition: DataSet.cpp:107
bool isAfterEnd() const
It tells if the dataset internal pointer is on the sentinel position after the last element of the co...
Definition: DataSet.cpp:232
DataSet class implementation for Microsoft Access driver.
te::common::AccessPolicy getAccessPolicy() const
It returns the read and write permission associated to the dataset.
Definition: DataSet.cpp:112
bool getBool(std::size_t i) const
Method for retrieving a boolean attribute value.
Definition: DataSet.cpp:322
int m_size
The number of datasets in the collection.
Definition: DataSet.h:150
boost::int16_t getInt16(std::size_t i) const
Method for retrieving a 16-bit integer attribute value (2 bytes long).
Definition: DataSet.cpp:262
std::string getPropertyName(std::size_t i) const
It returns the property name at position pos.
Definition: DataSet.cpp:132
DataSet()
Default constructor.
Definition: DataSet.h:116
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
Definition: DataSet.cpp:387
static Geometry * read(const char *wkb)
It returns a valid geometry from a given WKB.
Definition: WKBReader.cpp:50
std::auto_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
Definition: DataSet.cpp:407
boost::int64_t getInt64(std::size_t i) const
Method for retrieving a 64-bit integer attribute value (8 bytes long).
Definition: DataSet.cpp:302
std::auto_ptr< te::rst::Raster > getRaster(std::size_t i) const
Method for retrieving a raster attribute value.
Definition: DataSet.cpp:473
std::vector< std::string > m_colNames
A vector of columns names.
Definition: DataSet.h:148
char getChar(std::size_t i) const
Method for retrieving a signed character attribute value (1 byte long).
Definition: DataSet.cpp:237
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
Definition: DataSet.cpp:222
A class that implements a connection to a ADO database.
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
Definition: DataSet.cpp:342
~DataSet()
The destructor will clear the internal ADO _RecordsetPtr.
Definition: DataSet.cpp:102
AccessPolicy
Supported data access policies (can be used as bitfield).
Definition: Enums.h:40
bool isGeometryColumn(const std::string &datasetName, const std::string &colName) const
Definition: DataSource.cpp:152
bool isConnected() const
It returns true if the dataset is connected and false if it is disconnected. A dataset can be connect...
Definition: DataSet.cpp:147
DataSourceTransactor class implementation for Microsoft Access driver.
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
Definition: DataSet.cpp:201
bool isAtEnd() const
It tells if the dataset internal pointer is on the last element of the collection.
Definition: DataSet.cpp:227
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
Definition: DataSet.cpp:459
std::auto_ptr< te::gm::Envelope > getExtent(std::size_t i)
It computes the bounding rectangle for a spatial property of the dataset.
Definition: DataSet.cpp:117
Implementation of the data source class for the ADO driver.
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
Definition: DataSet.cpp:194
std::string GetSystemDateTimeFormat(std::string &indAM, std::string &indPM, std::string &sepD, std::string &sepT)
It gets the system Date and Time format.
Definition: Utils.cpp:897
TraverseType
A dataset can be traversed in two ways:
Definition: Enums.h:53
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
Definition: DataSet.cpp:362
std::vector< int > m_datatypes
A vector of data types.
Definition: DataSet.h:147
std::string getDatasetNameOfProperty(std::size_t i) const
It returns the underlying dataset name of the property at position pos.
Definition: DataSet.cpp:137
std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
Definition: DataSet.cpp:478
_RecordsetPtr m_result
The internal buffer with the result query.
Definition: DataSet.h:145
DataSource * getAdoDataSource() const
Definition: Transactor.h:329
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
Definition: DataSet.cpp:282
bool moveFirst()
It moves the internal pointer to the first item in the collection.
Definition: DataSet.cpp:187
std::size_t getNumProperties() const
It returns the number of properties that composes an item of the dataset.
Definition: DataSet.cpp:122
void TESTHR(HRESULT hr)
Definition: Connection.cpp:38
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
Definition: DataSet.cpp:217
unsigned char getUChar(std::size_t i) const
Method for retrieving an unsigned character attribute value (1 byte long).
Definition: DataSet.cpp:257
A class for representing binary data.
Definition: ByteArray.h:51
std::auto_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
Definition: DataSet.cpp:516
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:157
int getPropertyDataType(std::size_t i) const
It returns the underlying data type of the property at position pos.
Definition: DataSet.cpp:127
An exception class for ADO.
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
Definition: DataSet.cpp:167
Transactor * m_t
The DataSet Transactor.
Definition: DataSet.h:146
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
Definition: DataSet.cpp:176
std::size_t size() const
It returns the collection size, if it is known.
Definition: DataSet.cpp:152
std::auto_ptr< te::dt::DateTime > GetDateTime(std::string &value, std::string &mask, std::string &sepD, std::string &sepT)
It gets the DateTime TerraLib 5 from string.
Definition: Utils.cpp:1066
int m_ncols
The number of properties in the collection.
Definition: DataSet.h:151
std::string getNumeric(std::size_t i) const
Method for retrieving a numeric attribute value.
Definition: DataSet.cpp:382
#define TR_ADO(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
Definition: Config.h:126