All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  bool teste = (m_i < m_size);
170  return (m_i < m_size);
171 }
172 
174 {
175  if(m_i != m_size)
176  m_result->MovePrevious();
177 
178  --m_i;
179  return (m_i > -1);
180 }
181 
183 {
184  if(m_result->BOF != 0)
185  return true;
186 
187  TESTHR(m_result->MoveFirst());
188  m_i = -1;
189 
190  return m_size != 0;
191 }
192 
194 {
195  m_result->MoveFirst();
196  m_i = 0;
197  return m_size != 0;
198 }
199 
201 {
202  TESTHR(m_result->MoveLast());
203  m_i = m_size - 1;
204  return (m_i < m_size);
205 }
206 
207 bool te::ado::DataSet::move(std::size_t i)
208 {
209  if(i == 0)
210  return moveFirst();
211 
212  if(m_i == i)
213  return true;
214 
215  long p = static_cast<long>(i-m_i);
216 
217  TESTHR(m_result->Move(p));
218 
219  m_i += p;
220  return (m_i < m_size);
221 }
222 
224 {
225  return m_i == 0;
226 }
227 
229 {
230  return m_i < 0;
231 }
232 
234 {
235  return m_i == (m_size - 1);
236 }
237 
239 {
240  return m_i >= m_size;
241 }
242 
243 char te::ado::DataSet::getChar(std::size_t i) const
244 {
245  _variant_t vtIndex;
246  vtIndex.vt = VT_I4;
247  vtIndex.lVal = i;
248 
249  char ival;
250 
251  try
252  {
253  ival = (char)m_result->GetFields()->GetItem(vtIndex)->GetValue();
254  }
255  catch(_com_error& e)
256  {
257  throw te::common::Exception((LPCSTR)e.ErrorMessage());
258  }
259 
260  return ival;
261 }
262 
263 unsigned char te::ado::DataSet::getUChar(std::size_t i) const
264 {
265  return (unsigned char)getChar(i);
266 }
267 
268 boost::int16_t te::ado::DataSet::getInt16(std::size_t i) const
269 {
270  _variant_t vtIndex;
271  vtIndex.vt = VT_I4;
272  vtIndex.lVal = i;
273 
274  int16_t ival;
275 
276  try
277  {
278  ival = (int16_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
279  }
280  catch(_com_error& e)
281  {
282  throw te::common::Exception((LPCSTR)e.ErrorMessage());
283  }
284 
285  return ival;
286 }
287 
288 boost::int32_t te::ado::DataSet::getInt32(std::size_t i) const
289 {
290  _variant_t vtIndex;
291  vtIndex.vt = VT_I4;
292  vtIndex.lVal = i;
293 
294  int32_t ival;
295 
296  try
297  {
298  ival = (int32_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
299  }
300  catch(_com_error& e)
301  {
302  throw te::common::Exception((LPCSTR)e.ErrorMessage());
303  }
304 
305  return ival;
306 }
307 
308 boost::int64_t te::ado::DataSet::getInt64(std::size_t i) const
309 {
310  _variant_t vtIndex;
311  vtIndex.vt = VT_I4;
312  vtIndex.lVal = i;
313 
314  int64_t ival;
315 
316  try
317  {
318  ival = (int64_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
319  }
320  catch(_com_error& e)
321  {
322  throw te::common::Exception((LPCSTR)e.ErrorMessage());
323  }
324 
325  return ival;
326 }
327 
328 bool te::ado::DataSet::getBool(std::size_t i) const
329 {
330  _variant_t vtIndex;
331  vtIndex.vt = VT_I4;
332  vtIndex.lVal = i;
333 
334  bool ival;
335 
336  try
337  {
338  ival = (bool)m_result->GetFields()->GetItem(vtIndex)->GetValue();
339  }
340  catch(_com_error& e)
341  {
342  throw te::common::Exception((LPCSTR)e.ErrorMessage());
343  }
344 
345  return ival;
346 }
347 
348 float te::ado::DataSet::getFloat(std::size_t i) const
349 {
350  float value;
351 
352  _variant_t vtIndex;
353  vtIndex.vt = VT_I4;
354  vtIndex.lVal = i;
355 
356  try
357  {
358  value = (float)m_result->GetFields()->GetItem(vtIndex)->GetValue();
359  }
360  catch(_com_error& e)
361  {
362  throw te::common::Exception((LPCSTR)e.ErrorMessage());
363  }
364 
365  return value;
366 }
367 
368 double te::ado::DataSet::getDouble(std::size_t i) const
369 {
370  double value;
371 
372  _variant_t vtIndex;
373  vtIndex.vt = VT_I4;
374  vtIndex.lVal = i;
375 
376  try
377  {
378  value = (double)m_result->GetFields()->GetItem(vtIndex)->GetValue();
379  }
380  catch(_com_error& e)
381  {
382  throw te::common::Exception((LPCSTR)e.ErrorMessage());
383  }
384 
385  return value;
386 }
387 
388 std::string te::ado::DataSet::getNumeric(std::size_t /*i*/) const
389 {
390  throw te::common::Exception(TE_TR("Method getNumeric: not implemented yet!"));
391 }
392 
393 std::string te::ado::DataSet::getString(std::size_t i) const
394 {
395  _variant_t vtIndex;
396  vtIndex.vt = VT_I4;
397  vtIndex.lVal = i;
398 
399  std::string ival;
400 
401  try
402  {
403  ival = (LPCSTR)(_bstr_t)m_result->GetFields()->GetItem(vtIndex)->GetValue();
404  }
405  catch(_com_error& e)
406  {
407  throw te::common::Exception((LPCSTR)e.ErrorMessage());
408  }
409 
410  return ival;
411 }
412 
413 std::auto_ptr<te::dt::ByteArray> te::ado::DataSet::getByteArray(std::size_t i) const
414 {
415  _variant_t vtIndex;
416  vtIndex.vt = VT_I4;
417  vtIndex.lVal = i;
418 
419  _variant_t varBLOB;
420  char *cdata = 0;
421  long size;
422  char* data;
423 
424  try
425  {
426  ::Field15Ptr field;
427 
428  if(m_result->MoveNext() == S_OK)
429  m_result->MovePrevious();
430  else if(m_result->MovePrevious() == S_OK)
431  m_result->MoveNext();
432  else
433  {
434  _RecordsetPtr copy = m_result->Clone(adLockReadOnly);
435 
436  field = copy->GetFields()->GetItem(vtIndex);
437  }
438 
439  field = m_result->GetFields()->GetItem(vtIndex);
440 
441  size = field->ActualSize;
442  if(size > 0)
443  {
444  VariantInit(&varBLOB);
445 
446  varBLOB = field->GetChunk(size);
447 
448  if(varBLOB.vt == (VT_ARRAY | VT_UI1))
449  {
450  SafeArrayAccessData(varBLOB.parray,(void **)&cdata);
451  data = new char[size];
452  memcpy(data, cdata, size);
453  SafeArrayUnaccessData(varBLOB.parray);
454  }
455  }
456  }
457  catch(_com_error& e)
458  {
459  throw te::common::Exception((LPCSTR)e.ErrorMessage());
460  }
461 
462  return std::auto_ptr<te::dt::ByteArray>(new te::dt::ByteArray(data, size));
463 }
464 
465 std::auto_ptr<te::gm::Geometry> te::ado::DataSet::getGeometry(std::size_t i) const
466 {
467  std::auto_ptr<te::dt::ByteArray> ba(getByteArray(i));
468 
469  std::auto_ptr<te::gm::Geometry> geom(te::gm::WKBReader::read(ba->getData()));
470 
471  std::size_t wkb_size = geom->getWkbSize();
472 
473  if(ba->bytesUsed() - wkb_size >= 4)
474  geom->setSRID(*((int*)(ba->getData() + wkb_size)));
475 
476  return geom;
477 }
478 
479 std::auto_ptr<te::rst::Raster> te::ado::DataSet::getRaster(std::size_t /*i*/) const
480 {
481  throw te::common::Exception(TE_TR("Method getRaster: not implemented yet!"));
482 }
483 
484 std::auto_ptr<te::dt::DateTime> te::ado::DataSet::getDateTime(std::size_t i) const
485 {
486  _variant_t vtIndex;
487  _variant_t value;
488 
489  vtIndex.vt = VT_I4;
490  vtIndex.lVal = i;
491 
492  te::dt::DateTime* dateTime = 0;
493 
494  std::string strDate;
495  try
496  {
497  value = m_result->GetFields()->GetItem(vtIndex)->Value;
498  }
499  catch(_com_error &e)
500  {
501  throw te::common::Exception((LPCSTR)e.ErrorMessage());
502  }
503 
504  if(value.vt == VT_NULL)
505  return std::auto_ptr<te::dt::DateTime>(0);
506 
507  strDate = (LPCSTR)(_bstr_t)value;
508 
509  // Getting system format
510  std::string indAM;
511  std::string indPM;
512  std::string sepD;
513  std::string sepT;
514 
515  std::string mask = te::ado::GetSystemDateTimeFormat(indAM, indPM, sepD, sepT);
516 
517  std::auto_ptr<te::dt::DateTime> result = te::ado::GetDateTime(strDate, mask, sepD, sepT);
518 
519  return result;
520 }
521 
522 std::auto_ptr<te::dt::Array> te::ado::DataSet::getArray(std::size_t /*i*/) const
523 {
524  throw te::common::Exception(TE_TR("Method getArray: not implemented yet!"));
525 }
526 
527 bool te::ado::DataSet::isNull(std::size_t i) const
528 {
529  _variant_t value;
530 
531  std::string propertyName = getPropertyName(i);
532 
533  try
534  {
535  value = m_result->GetFields()->GetItem(static_cast<long>(i))->GetValue();
536  }
537 
538  catch(_com_error& e)
539  {
540  throw te::common::Exception((LPCSTR)e.ErrorMessage());
541  }
542 
543  if(value.vt == VT_NULL)
544  return true;
545 
546  return false;
547 }
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:193
int Convert2Terralib(ADOX::DataTypeEnum adoType)
Bind ADOX Type to TerraLib Type.
Definition: Utils.cpp:236
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
Definition: DataSet.cpp:207
DataSet()
Default constructor.
Definition: DataSet.h:117
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
Definition: DataSet.cpp:368
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
Definition: DataSet.cpp:173
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:182
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
Definition: DataSet.cpp:348
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:931
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
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:238
std::auto_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
Definition: DataSet.cpp:522
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:268
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:328
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:388
std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
Definition: DataSet.cpp:484
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:263
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:479
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:243
std::auto_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
Definition: DataSet.cpp:413
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:139
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
Definition: DataSet.cpp:200
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
Definition: DataSet.cpp:393
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
Definition: DataSet.cpp:228
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:308
_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:527
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:288
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
Definition: DataSet.cpp:223
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
Definition: DataSet.cpp:465
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:1100
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:233