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