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.