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