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"
50 #include <boost/dynamic_bitset.hpp>
75 template<
class T,
class ALIGN>
inline void GetArray(
int i,
int j,
PGresult* result, std::vector<T>& a)
77 char* value = PQgetvalue(result, i, j);
79 int ndim = *((
int*)value);
82 int dataoffset = *((
int*)value);
85 unsigned int elemtype = *((
unsigned int*)value);
86 value +=
sizeof(
unsigned int);
88 int dimension = *((
int*)value);
91 int lowerbnds = *((
int*)value);
92 value += (2 *
sizeof(int));
102 a.reserve(dimension);
104 for(
int k = 0; k < dimension; ++k)
109 value +=
sizeof(ALIGN);
114 a.reserve(dimension);
116 for(
int k = 0; k < dimension; ++k)
120 value +=
sizeof(ALIGN);
129 const std::vector<int>& ptypes,
135 m_timeIsInteger(timeIsInteger)
157 return PQnfields(m_result);
167 return PQfname(m_result, i);
172 throw Exception(
TR_PGIS(
"Not implemented yet!"));
177 return (m_size == 0);
195 throw Exception(
TR_PGIS(
"This driver only supports the getExtent method over a geometry column!"));
202 std::auto_ptr<te::gm::Geometry> geom(getGeometry(i));
203 m_mbr->Union(*(geom->getMBR()));
211 return std::auto_ptr<te::gm::Envelope>(mbr);
217 return (m_i < m_size);
235 return (m_i < m_size);
246 m_i =
static_cast<int>(i);
247 return (m_i < m_size);
262 return m_i == (m_size - 1);
267 return m_i >= m_size;
272 char cval = *(PQgetvalue(m_result, m_i, i));
278 unsigned char cval = *(PQgetvalue(m_result, m_i, i));
284 short int ival = *((
short int*)(PQgetvalue(m_result, m_i, i)));
286 #if TE_MACHINE_BYTE_ORDER == TE_NDR
295 int ival = *((
int*)(PQgetvalue(m_result, m_i, i)));
297 #if TE_MACHINE_BYTE_ORDER == TE_NDR
306 long long int ival = *((
long long int*)(PQgetvalue(m_result, m_i, i)));
308 #if TE_MACHINE_BYTE_ORDER == TE_NDR
317 char bval = *(PQgetvalue(m_result, m_i, i));
323 float fval = *((
float*)(PQgetvalue(m_result, m_i, i)));
325 #if TE_MACHINE_BYTE_ORDER == TE_NDR
334 double dval = *((
double*)(PQgetvalue(m_result, m_i, i)));
336 #if TE_MACHINE_BYTE_ORDER == TE_NDR
345 char* val = PQgetvalue(m_result, m_i, i);
349 unsigned short totalGroups;
351 totalGroups = *((
unsigned short*)val);
353 #if TE_MACHINE_BYTE_ORDER == TE_NDR
361 unsigned short decimalGroups;
363 decimalGroups = *((
unsigned short*)(val+2));
365 #if TE_MACHINE_BYTE_ORDER == TE_NDR
371 decimalGroups = totalGroups - decimalGroups;
376 sign = *((
unsigned short*)(val+4));
378 #if TE_MACHINE_BYTE_ORDER == TE_NDR
382 if(!(sign == 0 || sign == 0x4000))
395 while(ii < ((totalGroups - decimalGroups) * 2))
397 n = *((
unsigned short*)(val + ii + 8));
399 #if TE_MACHINE_BYTE_ORDER == TE_NDR
414 if(decimalGroups == 0)
418 while(ii < (totalGroups * 2))
420 n = *((
unsigned short*)(val + ii + 8));
422 #if TE_MACHINE_BYTE_ORDER == TE_NDR
428 while (newVal.length() < 4)
429 newVal =
"0" + newVal;
436 while((decVal.empty() ==
false) && (decVal[decVal.length() - 1] ==
'0'))
437 decVal.erase(decVal.length() - 1);
440 return intVal +
"." + decVal;
445 std::string value(PQgetvalue(m_result, m_i, i));
451 int size = PQgetlength(m_result, m_i, i);
454 b->
copy(PQgetvalue(m_result, m_i, i), size);
455 return std::auto_ptr<te::dt::ByteArray>(b);
460 return std::auto_ptr<te::gm::Geometry>(
EWKBReader::read(PQgetvalue(m_result, m_i, i)));
465 return std::auto_ptr<te::rst::Raster>(0);
470 Oid tid = PQftype(m_result, i);
471 boost::int64_t ival = 0;
487 ival = (boost::int64_t)(dval * 1000000);
495 char* val = PQgetvalue(m_result, m_i, i);
496 lval = *((
long int*)val);
498 #if TE_MACHINE_BYTE_ORDER == TE_NDR
512 ival = (boost::int64_t)(dval * 1000000);
524 char* c = (
char*)PQgetvalue(m_result, m_i, i);
525 dval = *((
double*)c);
527 #if TE_MACHINE_BYTE_ORDER == TE_NDR
531 ival = (boost::int64_t)(dval * 1000000);
544 char* c = (
char*)PQgetvalue(m_result, m_i, i);
545 dval = *((
double*)c);
549 #if TE_MACHINE_BYTE_ORDER == TE_NDR
554 ival = (boost::int64_t)(dval * 1000000);
565 throw Exception(
TR_PGIS(
"This type is not supported by TerraLib!"));
571 char* value = PQgetvalue(m_result, m_i, i);
573 int ndim = *((
int*)value);
574 value +=
sizeof(int);
576 #if TE_MACHINE_BYTE_ORDER == TE_NDR
580 int dataoffset = *((
int*)value);
581 value +=
sizeof(int);
583 #if TE_MACHINE_BYTE_ORDER == TE_NDR
587 unsigned int elemtype = *((
unsigned int*)value);
588 value +=
sizeof(
unsigned int);
590 #if TE_MACHINE_BYTE_ORDER == TE_NDR
594 int* dimensions = (
int*)value;
595 value += ndim *
sizeof(int);
597 int* lowerbounds = (
int*)value;
598 value += ndim *
sizeof(int);
600 uint32_t* null_bitmap = (
unsigned int*)value;
602 boost::dynamic_bitset<> mask;
606 int nmasks = (dataoffset + 3) / 4;
608 mask.resize(nmasks * 8 *
sizeof(uint32_t));
612 for(
int i = 0; i != nmasks; ++i)
614 value +=
sizeof(uint32_t);
616 uint32_t umask = null_bitmap[i];
618 #if TE_MACHINE_BYTE_ORDER == TE_NDR
622 for(
int j = 0; j != 32; ++j)
624 mask[pos] = ((umask >> j) & 1) == 0;
631 value +=
sizeof(uint32_t);
642 std::vector<std::size_t> pos(ndim, 0);
644 for(
int d = 0; d != ndim; ++d)
646 int d_size = dimensions[d];
648 #if TE_MACHINE_BYTE_ORDER == TE_NDR
651 int d_lower_boundary = lowerbounds[d];
653 #if TE_MACHINE_BYTE_ORDER == TE_NDR
657 for(i = 0; i != d_size; ++i)
659 if((dataoffset != 0) && (mask[i] ==
false))
667 int text_size = *(
int*)value;
669 #if TE_MACHINE_BYTE_ORDER == TE_NDR
672 value +=
sizeof(int);
680 return std::auto_ptr<te::dt::Array>(arr.release());
688 std::vector<std::size_t> pos(ndim, 0);
690 for(
int d = 0; d != ndim; ++d)
692 int d_size = dimensions[d];
694 #if TE_MACHINE_BYTE_ORDER == TE_NDR
697 int d_lower_boundary = lowerbounds[d];
699 #if TE_MACHINE_BYTE_ORDER == TE_NDR
703 for(i = 0; i != d_size; ++i)
705 if((dataoffset != 0) && (mask[i] ==
false))
713 double val = *(
double*)value;
715 #if TE_MACHINE_BYTE_ORDER == TE_NDR
721 value +=
sizeof(double);
725 return std::auto_ptr<te::dt::Array>(arr.release());
733 std::vector<std::size_t> pos(ndim, 0);
735 for(
int d = 0; d != ndim; ++d)
737 int d_size = dimensions[d];
739 #if TE_MACHINE_BYTE_ORDER == TE_NDR
742 int d_lower_boundary = lowerbounds[d];
744 #if TE_MACHINE_BYTE_ORDER == TE_NDR
748 for(i = 0; i != d_size; ++i)
750 if((dataoffset != 0) && (mask[i] ==
false))
758 boost::uint16_t val = *(boost::uint16_t*)value;
760 #if TE_MACHINE_BYTE_ORDER == TE_NDR
766 value +=
sizeof(uint32_t);
770 return std::auto_ptr<te::dt::Array>(arr.release());
775 throw Exception(
TR_PGIS(
"The array element type is not supported yet!"));
810 return PQgetisnull(m_result, m_i, i) == 1;
PGresult * m_result
The internal buffer with the result query.
te::dt::DateTime * Internal2TimeStamp(boost::int64_t ival)
It returns a DateTime type from a timestamp loaded by PostgreSQL.
~DataSet()
The destructor will clear the internal PGresult.
bool moveFirst()
It moves the internal pointer to the first item in the collection.
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
bool movePrevious()
It moves the internal pointer to the previous item of the collection.
#define PG_TIMESTAMP_TYPE
std::string getNumeric(std::size_t i) const
Method for retrieving a numeric attribute value.
std::auto_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const
Method for retrieving a byte array.
A class that implements a connection pool for PostGIS.
bool moveNext()
It moves the internal pointer to the next item of the collection.
te::dt::DateTime * Internal2Date(const long dDate)
It returns a DateTime type from a date loaded by PostgreSQL.
DataSet()
Default constructor.
bool move(std::size_t i)
It moves the dataset internal pointer to a given position.
te::common::TraverseType getTraverseType() const
It returns the traverse type associated to the dataset.
A template for atomic data types (integers, floats, strings and others).
bool isConnected() const
It returns true if the dataset is connected and false if it is disconnected. A dataset can be connect...
void GetArray(int i, int j, PGresult *result, std::vector< T > &a)
It retrieves information from an unidimensional array.
An utility class for reading a PostGIS EWKB.
bool getBool(std::size_t i) const
Method for retrieving a boolean attribute value.
bool isAtEnd() const
It tells if the dataset internal pointer is on the last element of the collection.
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).
AccessPolicy
Supported data access policies (can be used as bitfield).
#define TR_PGIS(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
void SwapBytes(T &v)
It swaps the bytes in local.
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
std::string getString(std::size_t i) const
Method for retrieving a string value attribute.
boost::int64_t getInt64(std::size_t i) const
Method for retrieving a 64-bit integer attribute value (8 bytes long).
std::string getPropertyName(std::size_t i) const
It returns the property name at position pos.
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
std::auto_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
static te::gm::Geometry * read(const char *ewkb)
It returns a valid geometry from a given EWKB.
bool moveLast()
It sets the dataset internal pointer to the last item in the collection.
bool isAfterEnd() const
It tells if the dataset internal pointer is on the sentinel position after the last element of the co...
std::auto_ptr< te::dt::DateTime > getDateTime(std::size_t i) const
Method for retrieving a date and time attribute value.
bool isEmpty() const
It returns true if the collection is empty.
#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.
std::size_t size() const
It returns the collection size, if it is known.
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
bool isAtBegin() const
It tells if the dataset internal pointer is on the first element of the collection or not...
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
TraverseType
A dataset can be traversed in two ways:
struct pg_result PGresult
std::auto_ptr< te::rst::Raster > getRaster(std::size_t i) const
Method for retrieving a raster attribute value.
std::auto_ptr< te::gm::Envelope > getExtent(std::size_t i)
It computes the bounding rectangle for a spatial property of the dataset.
float getFloat(std::size_t i) const
Method for retrieving a float attribute value.
void copy(char *data, std::size_t size)
It copies the data from the given pointer to the byte array.
std::string getDatasetNameOfProperty(std::size_t i) const
It returns the underlying dataset name of the property at position pos.
int m_size
The number of datasets in the collection.
boost::int16_t getInt16(std::size_t i) const
Method for retrieving a 16-bit integer attribute value (2 bytes long).
bool isNull(std::size_t i) const
It checks if the attribute value is NULL.
std::size_t getNumProperties() const
It returns the number of properties that composes an item of the dataset.
te::common::AccessPolicy getAccessPolicy() const
It returns the read and write permission associated to the dataset.
double getDouble(const std::string &value, std::vector< std::string > &sVector)
#define PG_TIMESTAMPTZ_TYPE
Utility functions for PostgreSQL.
int getPropertyDataType(std::size_t i) const
It returns the underlying data type of the property at position pos.
bool isBeforeBegin() const
It tells if the dataset internal pointer is in a position before the first element of the collection ...
The type for variable-length multidimensional arrays.
An Envelope defines a 2D rectangular region.
A class for representing binary data.
te::dt::DateTime * Internal2TimeTZ(boost::int64_t tval, int z)
unsigned char getUChar(std::size_t i) const
Method for retrieving an unsigned character attribute value (1 byte long).
Implementation of the data source for the PostGIS driver.