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/postgis/DataSet.cpp
22 
23  \brief Implementation of a dataset for the PostGIS 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/DateTime.h"
35 #include "../datatype/SimpleData.h"
36 #include "../geometry/Geometry.h"
37 #include "Connection.h"
38 #include "ConnectionPool.h"
39 //#include "CatalogLoader.h"
40 #include "DataSet.h"
41 #include "DataSource.h"
42 #include "EWKBReader.h"
43 #include "Exception.h"
44 #include "Utils.h"
45 
46 // STL
47 #include <memory>
48 
49 // Boost
50 #include <boost/dynamic_bitset.hpp>
51 
52 // libpq
53 #include <libpq-fe.h>
54 
55 namespace te
56 {
57  namespace pgis
58  {
59  /*!
60  \brief It retrieves information from an unidimensional array.
61 
62  Requirements on types:
63  <ul>
64  <li>T: the type of basic elements of the array.</li>
65  <li>ALIGN: the size in bytes of pointer alignment for the type T.</li>
66  </ul>
67 
68  \param i The row.
69  \param j The column.
70  \param result The result to extract the array.
71  \param a The output vector.
72 
73  \warning Don't call this method for multidimensional arrays!
74  */
75  template<class T, class ALIGN> inline void GetArray(int i, int j, PGresult* result, std::vector<T>& a)
76  {
77  char* value = PQgetvalue(result, i, j);
78 
79  int ndim = *((int*)value);
80  value += sizeof(int);
81 
82  int dataoffset = *((int*)value);
83  value += sizeof(int);
84 
85  unsigned int elemtype = *((unsigned int*)value);
86  value += sizeof(unsigned int);
87 
88  int dimension = *((int*)value);
89  value += sizeof(int);
90 
91  int lowerbnds = *((int*)value);
92  value += (2 * sizeof(int)); //jump null-bitmap field
93 
95  {
97  te::common::SwapBytes(dataoffset);
98  te::common::SwapBytes(elemtype);
99  te::common::SwapBytes(dimension);
100  te::common::SwapBytes(lowerbnds);
101 
102  a.reserve(dimension);
103 
104  for(int k = 0; k < dimension; ++k)
105  {
106  T v = *((T*)value);
108  a.push_back(v);
109  value += sizeof(ALIGN);
110  }
111  }
112  else
113  {
114  a.reserve(dimension);
115 
116  for(int k = 0; k < dimension; ++k)
117  {
118  T v = *((T*)value);
119  a.push_back(v);
120  value += sizeof(ALIGN);
121  }
122  }
123  }
124 
125  } // end namespace pgis
126 } // end namespace te
127 
129  const std::vector<int>& ptypes,
130  bool timeIsInteger)
131  : m_i(-1),
132  m_result(result),
133  m_ptypes(ptypes),
134  m_mbr(0),
135  m_timeIsInteger(timeIsInteger)
136 {
137  m_size = PQntuples(m_result);
138 }
139 
141 {
142  PQclear(m_result);
143 }
144 
146 {
147  return te::common::RANDOM;
148 }
149 
151 {
152  return te::common::RAccess;
153 }
154 
156 {
157  return PQnfields(m_result);
158 }
159 
161 {
162  return m_ptypes[i];
163 }
164 
165 std::string te::pgis::DataSet::getPropertyName(std::size_t i) const
166 {
167  return PQfname(m_result, i);
168 }
169 
170 std::string te::pgis::DataSet::getDatasetNameOfProperty(std::size_t i) const
171 {
172  throw Exception(TR_PGIS("Not implemented yet!"));
173 }
174 
176 {
177  return (m_size == 0);
178 }
179 
181 {
182  return false;
183 }
184 
185 std::size_t te::pgis::DataSet::size() const
186 {
187  return m_size;
188 }
189 
190 std::auto_ptr<te::gm::Envelope> te::pgis::DataSet::getExtent(std::size_t i)
191 {
192  if(!m_mbr)
193  {
194  if(m_ptypes[i] != te::dt::GEOMETRY_TYPE)
195  throw Exception(TR_PGIS("This driver only supports the getExtent method over a geometry column!"));
196 
197  m_mbr = new te::gm::Envelope;
198 
199  m_i = -1;
200  while(moveNext())
201  {
202  std::auto_ptr<te::gm::Geometry> geom(getGeometry(i));
203  m_mbr->Union(*(geom->getMBR()));
204  }
205  }
206 
207  m_i = -1;
208 
209  te::gm::Envelope* mbr = new te::gm::Envelope(*m_mbr);
210 
211  return std::auto_ptr<te::gm::Envelope>(mbr);
212 }
213 
215 {
216  ++m_i;
217  return (m_i < m_size);
218 }
219 
221 {
222  --m_i;
223  return (m_i > -1);
224 }
225 
227 {
228  m_i = 0;
229  return m_size != 0;
230 }
231 
233 {
234  m_i = m_size - 1;
235  return (m_i < m_size);
236 }
237 
239 {
240  m_i = -1;
241  return m_size != 0;;
242 }
243 
244 bool te::pgis::DataSet::move(std::size_t i)
245 {
246  m_i = static_cast<int>(i);
247  return (m_i < m_size);
248 }
249 
251 {
252  return m_i == 0;
253 }
254 
256 {
257  return m_i < 0;
258 }
259 
261 {
262  return m_i == (m_size - 1);
263 }
264 
266 {
267  return m_i >= m_size;
268 }
269 
270 char te::pgis::DataSet::getChar(std::size_t i) const
271 {
272  char cval = *(PQgetvalue(m_result, m_i, i));
273  return cval;
274 }
275 
276 unsigned char te::pgis::DataSet::getUChar(std::size_t i) const
277 {
278  unsigned char cval = *(PQgetvalue(m_result, m_i, i));
279  return cval;
280 }
281 
282 boost::int16_t te::pgis::DataSet::getInt16(std::size_t i) const
283 {
284  short int ival = *((short int*)(PQgetvalue(m_result, m_i, i)));
285 
286 #if TE_MACHINE_BYTE_ORDER == TE_NDR
287  te::common::SwapBytes(ival);
288 #endif
289 
290  return ival;
291 }
292 
293 boost::int32_t te::pgis::DataSet::getInt32(std::size_t i) const
294 {
295  int ival = *((int*)(PQgetvalue(m_result, m_i, i)));
296 
297 #if TE_MACHINE_BYTE_ORDER == TE_NDR
298  te::common::SwapBytes(ival);
299 #endif
300 
301  return ival;
302 }
303 
304 boost::int64_t te::pgis::DataSet::getInt64(std::size_t i) const
305 {
306  long long int ival = *((long long int*)(PQgetvalue(m_result, m_i, i)));
307 
308 #if TE_MACHINE_BYTE_ORDER == TE_NDR
309  te::common::SwapBytes(ival);
310 #endif
311 
312  return ival;
313 }
314 
315 bool te::pgis::DataSet::getBool(std::size_t i) const
316 {
317  char bval = *(PQgetvalue(m_result, m_i, i));
318  return bval != 0;
319 }
320 
321 float te::pgis::DataSet::getFloat(std::size_t i) const
322 {
323  float fval = *((float*)(PQgetvalue(m_result, m_i, i)));
324 
325 #if TE_MACHINE_BYTE_ORDER == TE_NDR
326  te::common::SwapBytes(fval);
327 #endif
328 
329  return fval;
330 }
331 
332 double te::pgis::DataSet::getDouble(std::size_t i) const
333 {
334  double dval = *((double*)(PQgetvalue(m_result, m_i, i)));
335 
336 #if TE_MACHINE_BYTE_ORDER == TE_NDR
337  te::common::SwapBytes(dval);
338 #endif
339 
340  return dval;
341 }
342 
343 std::string te::pgis::DataSet::getNumeric(std::size_t i) const
344 {
345  char* val = PQgetvalue(m_result, m_i, i);
346 
347 // get number of groups of 2 bytes used to represent the numeric number
348 // each 2 bytes represents 4 digits (ex: 2345678.87654 needs 4 groups. 2 to integer and 2 to decimals)
349  unsigned short totalGroups; // total number of groups
350 
351  totalGroups = *((unsigned short*)val);
352 
353 #if TE_MACHINE_BYTE_ORDER == TE_NDR
354  te::common::SwapBytes(totalGroups);
355 #endif
356 
357  if(totalGroups == 0)
358  return "0";
359 
360 // get number of groups of 2 bytes used to represent the decimal part of the number
361  unsigned short decimalGroups; // total number of groups
362 
363  decimalGroups = *((unsigned short*)(val+2));
364 
365 #if TE_MACHINE_BYTE_ORDER == TE_NDR
366  te::common::SwapBytes(decimalGroups);
367 #endif
368 
369  ++decimalGroups;
370 
371  decimalGroups = totalGroups - decimalGroups;
372 
373 // get sign of the number
374  unsigned short sign; // sign of the number (positive: sign = 0, negative: sign = 0x4000)
375 
376  sign = *((unsigned short*)(val+4));
377 
378 #if TE_MACHINE_BYTE_ORDER == TE_NDR
379  te::common::SwapBytes(sign);
380 #endif
381 
382  if(!(sign == 0 || sign == 0x4000))
383  return "";
384 
385  std::string intVal;
386 
387  if(sign != 0)
388  intVal = "-";
389 
390 //get integer part
391  unsigned short n;
392 
393  short ii = 0;
394 
395  while(ii < ((totalGroups - decimalGroups) * 2))
396  {
397  n = *((unsigned short*)(val + ii + 8));
398 
399 #if TE_MACHINE_BYTE_ORDER == TE_NDR
401 #endif
402 
403  intVal += te::common::Convert2String(n);
404 
405  ii += 2;
406  }
407 
408  if(ii == 0)
409  intVal += "0";
410 
411 //get decimal part
412  std::string decVal;
413 
414  if(decimalGroups == 0)
415  decVal = "0";
416  else
417  {
418  while(ii < (totalGroups * 2))
419  {
420  n = *((unsigned short*)(val + ii + 8));
421 
422 #if TE_MACHINE_BYTE_ORDER == TE_NDR
424 #endif
425 
426  std::string newVal = te::common::Convert2String(n);
427 
428  while (newVal.length() < 4) //fill with zeros (ex: .0700 was "700")
429  newVal = "0" + newVal;
430 
431  decVal += newVal;
432 
433  ii += 2;
434  }
435 
436  while((decVal.empty() == false) && (decVal[decVal.length() - 1] == '0'))
437  decVal.erase(decVal.length() - 1);
438  }
439 
440  return intVal + "." + decVal;
441 }
442 
443 std::string te::pgis::DataSet::getString(std::size_t i) const
444 {
445  std::string value(PQgetvalue(m_result, m_i, i));
446  return value;
447 }
448 
449 std::auto_ptr<te::dt::ByteArray> te::pgis::DataSet::getByteArray(std::size_t i) const
450 {
451  int size = PQgetlength(m_result, m_i, i);
452 
453  te::dt::ByteArray* b = new te::dt::ByteArray(size);
454  b->copy(PQgetvalue(m_result, m_i, i), size);
455  return std::auto_ptr<te::dt::ByteArray>(b);
456 }
457 
458 std::auto_ptr<te::gm::Geometry> te::pgis::DataSet::getGeometry(std::size_t i) const
459 {
460  return std::auto_ptr<te::gm::Geometry>(EWKBReader::read(PQgetvalue(m_result, m_i, i)));
461 }
462 
463 std::auto_ptr<te::rst::Raster> te::pgis::DataSet::getRaster(std::size_t /*i*/) const
464 {
465  return std::auto_ptr<te::rst::Raster>(0);
466 }
467 
468 std::auto_ptr<te::dt::DateTime> te::pgis::DataSet::getDateTime(std::size_t i) const
469 {
470  Oid tid = PQftype(m_result, i);
471  boost::int64_t ival = 0;
472  int iz;
473  double dval;
474  long int lval;
475 
476  switch(tid)
477  {
478  case PG_TIME_TYPE:
479  {
480  if(m_timeIsInteger)
481  {
482  ival = getInt64(i);
483  }
484  else
485  {
486  dval = getDouble(i);
487  ival = (boost::int64_t)(dval * 1000000);
488  }
489 
490  return std::auto_ptr<te::dt::DateTime>(Internal2Time(ival));
491  }
492 
493  case PG_DATE_TYPE:
494  {
495  char* val = PQgetvalue(m_result, m_i, i);
496  lval = *((long int*)val);
497 
498 #if TE_MACHINE_BYTE_ORDER == TE_NDR
499  te::common::SwapBytes(lval);
500 #endif
501 
502  return std::auto_ptr<te::dt::DateTime>(Internal2Date(lval));
503  }
504 
505  case PG_TIMESTAMP_TYPE:
506  {
507  if(m_timeIsInteger)
508  ival = getInt64(i);
509  else
510  {
511  dval = getDouble(i);
512  ival = (boost::int64_t)(dval * 1000000);
513  }
514 
515  return std::auto_ptr<te::dt::DateTime>(Internal2TimeStamp(ival));
516  }
517 
518  case PG_TIMESTAMPTZ_TYPE:
519  {
520  if(m_timeIsInteger)
521  ival = getInt64(i);
522  else
523  {
524  char* c = (char*)PQgetvalue(m_result, m_i, i);
525  dval = *((double*)c);
526 
527  #if TE_MACHINE_BYTE_ORDER == TE_NDR
528  te::common::SwapBytes(dval);
529  #endif
530 
531  ival = (boost::int64_t)(dval * 1000000);
532  }
533  return std::auto_ptr<te::dt::DateTime>(Internal2TimeStamp(ival));
534  }
535  case PG_TIMETZ_TYPE:
536  {
537  if(m_timeIsInteger)
538  {
539  ival = getInt64(i);
540  iz = 0;
541  }
542  else
543  {
544  char* c = (char*)PQgetvalue(m_result, m_i, i);
545  dval = *((double*)c);
546  c += 8;
547  iz = *((int*)c);
548 
549  #if TE_MACHINE_BYTE_ORDER == TE_NDR
550  te::common::SwapBytes(dval);
552  #endif
553 
554  ival = (boost::int64_t)(dval * 1000000);
555  }
556  iz /= 3600;
557  if(iz < -12)
558  iz = -12;
559  if(iz > 14)
560  iz = 14;
561  return std::auto_ptr<te::dt::DateTime>(Internal2TimeTZ(ival, iz));
562  }
563 
564  default:
565  throw Exception(TR_PGIS("This type is not supported by TerraLib!"));
566  }
567 }
568 
569 std::auto_ptr<te::dt::Array> te::pgis::DataSet::getArray(std::size_t i) const
570 {
571  char* value = PQgetvalue(m_result, m_i, i);
572 
573  int ndim = *((int*)value);
574  value += sizeof(int);
575 
576 #if TE_MACHINE_BYTE_ORDER == TE_NDR
577  te::common::SwapBytes(ndim);
578 #endif
579 
580  int dataoffset = *((int*)value);
581  value += sizeof(int);
582 
583 #if TE_MACHINE_BYTE_ORDER == TE_NDR
584  te::common::SwapBytes(dataoffset);
585 #endif
586 
587  unsigned int elemtype = *((unsigned int*)value);
588  value += sizeof(unsigned int);
589 
590 #if TE_MACHINE_BYTE_ORDER == TE_NDR
591  te::common::SwapBytes(elemtype);
592 #endif
593 
594  int* dimensions = (int*)value;
595  value += ndim * sizeof(int);
596 
597  int* lowerbounds = (int*)value;
598  value += ndim * sizeof(int);
599 
600  uint32_t* null_bitmap = (unsigned int*)value;
601 
602  boost::dynamic_bitset<> mask;
603 
604  if(dataoffset != 0)
605  {
606  int nmasks = (dataoffset + 3) / 4;
607 
608  mask.resize(nmasks * 8 * sizeof(uint32_t));
609 
610  int pos = 0;
611 
612  for(int i = 0; i != nmasks; ++i)
613  {
614  value += sizeof(uint32_t);
615 
616  uint32_t umask = null_bitmap[i];
617 
618 #if TE_MACHINE_BYTE_ORDER == TE_NDR
619  te::common::SwapBytes(umask);
620 #endif
621 
622  for(int j = 0; j != 32; ++j)
623  {
624  mask[pos] = ((umask >> j) & 1) == 0;
625  ++pos;
626  }
627  }
628  }
629  else
630  {
631  value += sizeof(uint32_t);
632  }
633 
634  switch(elemtype)
635  {
636  case PG_TEXT_TYPE:
637  case PG_VARCHAR_TYPE:
638  case PG_NAME_TYPE:
639  {
640  std::auto_ptr<te::dt::Array> arr(new te::dt::Array(ndim, te::dt::STRING_TYPE));
641 
642  std::vector<std::size_t> pos(ndim, 0);
643 
644  for(int d = 0; d != ndim; ++d)
645  {
646  int d_size = dimensions[d];
647 
648 #if TE_MACHINE_BYTE_ORDER == TE_NDR
649  te::common::SwapBytes(d_size);
650 #endif
651  int d_lower_boundary = lowerbounds[d];
652 
653 #if TE_MACHINE_BYTE_ORDER == TE_NDR
654  te::common::SwapBytes(d_lower_boundary);
655 #endif
656 
657  for(i = 0; i != d_size; ++i)
658  {
659  if((dataoffset != 0) && (mask[i] == false))
660  {
661  arr->insert(0, pos);
662  continue;
663  }
664 
665  pos[d] = i;
666 
667  int text_size = *(int*)value;
668 
669 #if TE_MACHINE_BYTE_ORDER == TE_NDR
670  te::common::SwapBytes(text_size);
671 #endif
672  value += sizeof(int);
673 
674  arr->insert(new te::dt::String(value), pos);
675 
676  value += text_size;
677  }
678  }
679 
680  return std::auto_ptr<te::dt::Array>(arr.release());
681  }
682  break;
683 
684  case PG_FLOAT8_TYPE:
685  {
686  std::auto_ptr<te::dt::Array> arr(new te::dt::Array(ndim, te::dt::DOUBLE_TYPE));
687 
688  std::vector<std::size_t> pos(ndim, 0);
689 
690  for(int d = 0; d != ndim; ++d)
691  {
692  int d_size = dimensions[d];
693 
694 #if TE_MACHINE_BYTE_ORDER == TE_NDR
695  te::common::SwapBytes(d_size);
696 #endif
697  int d_lower_boundary = lowerbounds[d];
698 
699 #if TE_MACHINE_BYTE_ORDER == TE_NDR
700  te::common::SwapBytes(d_lower_boundary);
701 #endif
702 
703  for(i = 0; i != d_size; ++i)
704  {
705  if((dataoffset != 0) && (mask[i] == false))
706  {
707  arr->insert(0, pos);
708  continue;
709  }
710 
711  pos[d] = i;
712 
713  double val = *(double*)value;
714 
715 #if TE_MACHINE_BYTE_ORDER == TE_NDR
717 #endif
718 
719  arr->insert(new te::dt::Double(val), pos);
720 
721  value += sizeof(double);
722  }
723  }
724 
725  return std::auto_ptr<te::dt::Array>(arr.release());
726  }
727  break;
728 
729  case PG_INT2_TYPE:
730  {
731  std::auto_ptr<te::dt::Array> arr(new te::dt::Array(ndim, te::dt::INT16_TYPE));
732 
733  std::vector<std::size_t> pos(ndim, 0);
734 
735  for(int d = 0; d != ndim; ++d)
736  {
737  int d_size = dimensions[d];
738 
739 #if TE_MACHINE_BYTE_ORDER == TE_NDR
740  te::common::SwapBytes(d_size);
741 #endif
742  int d_lower_boundary = lowerbounds[d];
743 
744 #if TE_MACHINE_BYTE_ORDER == TE_NDR
745  te::common::SwapBytes(d_lower_boundary);
746 #endif
747 
748  for(i = 0; i != d_size; ++i)
749  {
750  if((dataoffset != 0) && (mask[i] == false))
751  {
752  arr->insert(0, pos);
753  continue;
754  }
755 
756  pos[d] = i;
757 
758  boost::uint16_t val = *(boost::uint16_t*)value;
759 
760 #if TE_MACHINE_BYTE_ORDER == TE_NDR
762 #endif
763 
764  arr->insert(new te::dt::Int16(val), pos);
765 
766  value += sizeof(uint32_t);
767  }
768  }
769 
770  return std::auto_ptr<te::dt::Array>(arr.release());
771  }
772  break;
773 
774  default:
775  throw Exception(TR_PGIS("The array element type is not supported yet!"));
776  }
777 
778  // {
779  // te::common::SwapBytes(ndim);
780  // te::common::SwapBytes(dataoffset);
781  // te::common::SwapBytes(elemtype);
782  // te::common::SwapBytes(dimension);
783  // te::common::SwapBytes(lowerbnds);
784 
785  // a.reserve(dimension);
786 
787  // for(int k = 0; k < dimension; ++k)
788  // {
789  // T v = *((T*)value);
790  // te::common::SwapBytes(v);
791  // a.push_back(v);
792  // value += sizeof(ALIGN);
793  // }
794  // }
795  // else
796  // {
797  // a.reserve(dimension);
798 
799  // for(int k = 0; k < dimension; ++k)
800  // {
801  // T v = *((T*)value);
802  // a.push_back(v);
803  // value += sizeof(ALIGN);
804  // }
805  // }
806 }
807 
808 bool te::pgis::DataSet::isNull(std::size_t i) const
809 {
810  return PQgetisnull(m_result, m_i, i) == 1;
811 }
PGresult * m_result
The internal buffer with the result query.
Definition: DataSet.h:167
te::dt::DateTime * Internal2TimeStamp(boost::int64_t ival)
It returns a DateTime type from a timestamp loaded by PostgreSQL.
Definition: Utils.h:413
~DataSet()
The destructor will clear the internal PGresult.
Definition: DataSet.cpp:140
bool moveFirst()
It moves the internal pointer to the first item in the collection.
Definition: DataSet.cpp:226
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
Definition: DataSet.cpp:238
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
Definition: DataSet.cpp:220
#define PG_TIMESTAMP_TYPE
Definition: Config.h:117
std::string getNumeric(std::size_t i) const
Method for retrieving a numeric attribute value.
Definition: DataSet.cpp:343
std::auto_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
Definition: DataSet.cpp:449
A class that implements a connection pool for PostGIS.
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:214
te::dt::DateTime * Internal2Date(const long dDate)
It returns a DateTime type from a date loaded by PostgreSQL.
Definition: Utils.h:343
DataSet()
Default constructor.
Definition: DataSet.h:116
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
Definition: DataSet.cpp:244
te::common::TraverseType getTraverseType() const
It returns the traverse type associated to the dataset.
Definition: DataSet.cpp:145
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
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:180
void GetArray(int i, int j, PGresult *result, std::vector< T > &a)
It retrieves information from an unidimensional array.
Definition: DataSet.cpp:75
An utility class for reading a PostGIS EWKB.
bool getBool(std::size_t i) const
Method for retrieving a boolean attribute value.
Definition: DataSet.cpp:315
bool isAtEnd() const
It tells if the dataset internal pointer is on the last element of the collection.
Definition: DataSet.cpp:260
Implementation of a dataset for the PostGIS driver.
An exception class for the PostGIS driver.
char getChar(std::size_t i) const
Method for retrieving a signed character attribute value (1 byte long).
Definition: DataSet.cpp:270
AccessPolicy
Supported data access policies (can be used as bitfield).
Definition: Enums.h:40
#define TR_PGIS(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
Definition: Config.h:168
#define PG_VARCHAR_TYPE
Definition: Config.h:113
void SwapBytes(T &v)
It swaps the bytes in local.
#define PG_FLOAT8_TYPE
Definition: Config.h:111
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
Definition: DataSet.cpp:332
#define PG_TIME_TYPE
Definition: Config.h:115
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
Definition: DataSet.cpp:443
boost::int64_t getInt64(std::size_t i) const
Method for retrieving a 64-bit integer attribute value (8 bytes long).
Definition: DataSet.cpp:304
std::string getPropertyName(std::size_t i) const
It returns the property name at position pos.
Definition: DataSet.cpp:165
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
Definition: Globals.h:55
std::auto_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
Definition: DataSet.cpp:569
static te::gm::Geometry * read(const char *ewkb)
It returns a valid geometry from a given EWKB.
Definition: EWKBReader.cpp:134
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
Definition: DataSet.cpp:232
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:265
std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
Definition: DataSet.cpp:468
bool isEmpty() const
It returns true if the collection is empty.
Definition: DataSet.cpp:175
#define TE_NDR
Macro for little endian (machine byte order).
A class that implements a connection to a PostgreSQL database.
te::dt::DateTime * Internal2Time(boost::int64_t tval)
It returns a DateTime type from a time loaded by PostgreSQL.
Definition: Utils.h:362
#define PG_TIMETZ_TYPE
Definition: Config.h:116
std::size_t size() const
It returns the collection size, if it is known.
Definition: DataSet.cpp:185
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
Definition: DataSet.cpp:293
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
Definition: DataSet.cpp:458
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
Definition: DataSet.cpp:250
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:51
TraverseType
A dataset can be traversed in two ways:
Definition: Enums.h:53
struct pg_result PGresult
Definition: Connection.h:48
std::auto_ptr< te::rst::Raster > getRaster(std::size_t i) const
Method for retrieving a raster attribute value.
Definition: DataSet.cpp:463
#define PG_INT2_TYPE
Definition: Config.h:105
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:190
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
Definition: DataSet.cpp:321
void copy(char *data, std::size_t size)
It copies the data from the given pointer to the byte array.
Definition: ByteArray.cpp:128
std::string getDatasetNameOfProperty(std::size_t i) const
It returns the underlying dataset name of the property at position pos.
Definition: DataSet.cpp:170
int m_size
The number of datasets in the collection.
Definition: DataSet.h:166
boost::int16_t getInt16(std::size_t i) const
Method for retrieving a 16-bit integer attribute value (2 bytes long).
Definition: DataSet.cpp:282
bool isNull(std::size_t i) const
It checks if the attribute value is NULL.
Definition: DataSet.cpp:808
std::size_t getNumProperties() const
It returns the number of properties that composes an item of the dataset.
Definition: DataSet.cpp:155
te::common::AccessPolicy getAccessPolicy() const
It returns the read and write permission associated to the dataset.
Definition: DataSet.cpp:150
double getDouble(const std::string &value, std::vector< std::string > &sVector)
Definition: Utils.cpp:54
#define PG_TIMESTAMPTZ_TYPE
Definition: Config.h:118
Utility functions for PostgreSQL.
int getPropertyDataType(std::size_t i) const
It returns the underlying data type of the property at position pos.
Definition: DataSet.cpp:160
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
Definition: DataSet.cpp:255
#define PG_TEXT_TYPE
Definition: Config.h:108
The type for variable-length multidimensional arrays.
Definition: Array.h:59
#define PG_DATE_TYPE
Definition: Config.h:114
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
A class for representing binary data.
Definition: ByteArray.h:51
te::dt::DateTime * Internal2TimeTZ(boost::int64_t tval, int z)
Definition: Utils.h:377
#define PG_NAME_TYPE
Definition: Config.h:103
unsigned char getUChar(std::size_t i) const
Method for retrieving an unsigned character attribute value (1 byte long).
Definition: DataSet.cpp:276
Implementation of the data source for the PostGIS driver.