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" 52 #include <boost/dynamic_bitset.hpp> 77 template<
class T,
class ALIGN>
inline void GetArray(
int i,
int j,
PGresult* result, std::vector<T>& a)
79 char* value = PQgetvalue(result, i, j);
81 int ndim = *
reinterpret_cast<int*
>(value);
84 int dataoffset = *
reinterpret_cast<int*
>(value);
87 unsigned int elemtype = *
reinterpret_cast<unsigned int*
>(value);
88 value +=
sizeof(
unsigned int);
90 int dimension = *
reinterpret_cast<int*
>(value);
93 int lowerbnds = *
reinterpret_cast<int*
>(value);
94 value += (2 *
sizeof(
int));
104 a.reserve(dimension);
106 for(
int k = 0; k < dimension; ++k)
108 T v = *
reinterpret_cast<T*
>(value);
111 value +=
sizeof(ALIGN);
116 a.reserve(dimension);
118 for(
int k = 0; k < dimension; ++k)
120 T v = *
reinterpret_cast<T*
>(value);
122 value +=
sizeof(ALIGN);
131 const std::vector<int>& ptypes,
137 m_timeIsInteger(timeIsInteger)
159 return static_cast<size_t>(PQnfields(
m_result));
169 return PQfname(
m_result, static_cast<int>(i));
189 return static_cast<size_t>(
m_size);
197 throw Exception(
TE_TR(
"This driver only supports the getExtent method over a geometry column!"));
204 std::unique_ptr<te::gm::Geometry> geom(
getGeometry(i));
213 return std::unique_ptr<te::gm::Envelope>(mbr);
252 m_i =
static_cast<int>(i);
283 char cval = *(PQgetvalue(
m_result,
m_i, static_cast<int>(i)));
289 unsigned char cval = *(
reinterpret_cast<unsigned char*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
295 short int ival = *(
reinterpret_cast<short int*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
297 #if TE_MACHINE_BYTE_ORDER == TE_NDR 306 int ival = *
reinterpret_cast<int*
>((PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
308 #if TE_MACHINE_BYTE_ORDER == TE_NDR 312 return static_cast<boost::int32_t
>(ival);
317 long long int ival = *(
reinterpret_cast<long long int*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
319 #if TE_MACHINE_BYTE_ORDER == TE_NDR 328 char bval = *(PQgetvalue(
m_result,
m_i, static_cast<int>(i)));
334 float fval = *(
reinterpret_cast<float*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
336 #if TE_MACHINE_BYTE_ORDER == TE_NDR 345 double dval = *(
reinterpret_cast<double*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i))));
347 #if TE_MACHINE_BYTE_ORDER == TE_NDR 356 char* val = PQgetvalue(
m_result,
m_i, static_cast<int>(i));
360 unsigned short totalGroups;
362 totalGroups = *(
reinterpret_cast<unsigned short*
>(val));
364 #if TE_MACHINE_BYTE_ORDER == TE_NDR 372 unsigned short decimalGroups;
374 decimalGroups = *(
reinterpret_cast<unsigned short*
>(val+2));
376 #if TE_MACHINE_BYTE_ORDER == TE_NDR 382 decimalGroups = totalGroups - decimalGroups;
387 sign = *(
reinterpret_cast<unsigned short*
>(val+4));
389 #if TE_MACHINE_BYTE_ORDER == TE_NDR 393 if(!(sign == 0 || sign == 0x4000))
404 unsigned short ii = 0;
406 while(ii < ((totalGroups - decimalGroups) * 2))
408 n = *(
reinterpret_cast<unsigned short*
>(val + ii + 8));
410 #if TE_MACHINE_BYTE_ORDER == TE_NDR 415 if(intVal.empty() ==
false)
435 if(decimalGroups == 0)
439 while(ii < (totalGroups * 2))
441 n = *(
reinterpret_cast<unsigned short*
>(val + ii + 8));
443 #if TE_MACHINE_BYTE_ORDER == TE_NDR 449 while (newVal.length() < 4)
450 newVal =
"0" + newVal;
457 while(!(decVal.empty()) && (decVal[decVal.length() - 1] ==
'0'))
458 decVal.erase(decVal.length() - 1);
461 return intVal +
"." + decVal;
466 std::string value(PQgetvalue(
m_result,
m_i, static_cast<int>(i)));
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);
486 return std::unique_ptr<te::rst::Raster>(
nullptr);
491 Oid tid = PQftype(
m_result, static_cast<int>(i));
492 boost::int64_t ival = 0;
507 ival =
static_cast<boost::int64_t
>(dval * 1000000);
510 return std::unique_ptr<te::dt::DateTime>(
Internal2Time(ival));
517 return std::unique_ptr<te::dt::DateTime>(
Internal2Date(static_cast<long>(ival)));
527 ival =
static_cast<boost::int64_t
>(dval * 1000000);
542 char* c =
reinterpret_cast<char*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i)));
543 dval = *(
reinterpret_cast<double*
>(c));
545 iz = *
reinterpret_cast<int*
>(c);
547 #if TE_MACHINE_BYTE_ORDER == TE_NDR 552 ival =
static_cast<boost::int64_t
>(dval * 1000000);
571 char* c =
reinterpret_cast<char*
>(PQgetvalue(
m_result,
m_i, static_cast<int>(i)));
572 dval = *(
reinterpret_cast<double*
>(c));
574 iz = *
reinterpret_cast<int*
>(c);
576 #if TE_MACHINE_BYTE_ORDER == TE_NDR 581 ival =
static_cast<boost::int64_t
>(dval * 1000000);
592 throw Exception(
TE_TR(
"This type is not supported by TerraLib!"));
598 char* value = PQgetvalue(
m_result,
m_i, static_cast<int>(i));
600 int ndim = *
reinterpret_cast<int*
>(value);
601 value +=
sizeof(
int);
603 #if TE_MACHINE_BYTE_ORDER == TE_NDR 607 int dataoffset = *
reinterpret_cast<int*
>(value);
608 value +=
sizeof(
int);
610 #if TE_MACHINE_BYTE_ORDER == TE_NDR 614 unsigned int elemtype = *
reinterpret_cast<unsigned int*
>(value);
615 value +=
sizeof(
unsigned int);
617 #if TE_MACHINE_BYTE_ORDER == TE_NDR 621 int* dimensions =
reinterpret_cast<int*
>(value);
622 value +=
static_cast<size_t>(ndim) *
sizeof(
int);
624 int* lowerbounds =
reinterpret_cast<int*
>(value);
625 value +=
static_cast<size_t>(ndim) *
sizeof(
int);
627 uint32_t* null_bitmap =
reinterpret_cast<uint32_t*
>(value);
629 boost::dynamic_bitset<size_t> mask;
633 int nmasks = (dataoffset + 3) / 4;
635 mask.resize(static_cast<size_t>(nmasks * 8 *
sizeof(uint32_t)));
639 for(
int i = 0; i != nmasks; ++i)
641 value +=
sizeof(uint32_t);
643 uint32_t umask = null_bitmap[i];
645 #if TE_MACHINE_BYTE_ORDER == TE_NDR 649 for(
int j = 0; j != 32; ++j)
651 mask[pos] =
static_cast<unsigned long>(((umask >> j) & 1) == 0);
658 value +=
sizeof(uint32_t);
669 std::vector<std::size_t> pos(static_cast<size_t>(ndim), 0);
671 for(
int d = 0;
d != ndim; ++
d)
673 int d_size = dimensions[
d];
675 #if TE_MACHINE_BYTE_ORDER == TE_NDR 678 int d_lower_boundary = lowerbounds[
d];
680 #if TE_MACHINE_BYTE_ORDER == TE_NDR 684 for(i = 0; i !=
static_cast<size_t>(d_size); ++i)
686 if((dataoffset != 0) && (!mask[i]))
688 arr->insert(
nullptr, pos);
694 int text_size = *
reinterpret_cast<int*
>(value);
696 #if TE_MACHINE_BYTE_ORDER == TE_NDR 699 value +=
sizeof(
int);
707 return std::unique_ptr<te::dt::Array>(arr.release());
714 std::vector<std::size_t> pos(static_cast<size_t>(ndim), 0);
716 for(
int d = 0;
d != ndim; ++
d)
718 int d_size = dimensions[
d];
720 #if TE_MACHINE_BYTE_ORDER == TE_NDR 723 int d_lower_boundary = lowerbounds[
d];
725 #if TE_MACHINE_BYTE_ORDER == TE_NDR 729 for(i = 0; i !=
static_cast<size_t>(d_size); ++i)
731 if((dataoffset != 0) && (!mask[i]))
733 arr->insert(
nullptr, pos);
739 double val = *
reinterpret_cast<double*
>(value);
741 #if TE_MACHINE_BYTE_ORDER == TE_NDR 747 value +=
sizeof(double);
751 return std::unique_ptr<te::dt::Array>(arr.release());
758 std::vector<std::size_t> pos(static_cast<size_t>(ndim), 0);
760 for(
int d = 0;
d != ndim; ++
d)
762 int d_size = dimensions[
d];
764 #if TE_MACHINE_BYTE_ORDER == TE_NDR 767 int d_lower_boundary = lowerbounds[
d];
769 #if TE_MACHINE_BYTE_ORDER == TE_NDR 773 for(i = 0; i !=
static_cast<size_t>(d_size); ++i)
775 if((dataoffset != 0) && (!mask[i]))
777 arr->insert(
nullptr, pos);
783 boost::uint16_t val = *
reinterpret_cast<boost::uint16_t*
>(value);
785 #if TE_MACHINE_BYTE_ORDER == TE_NDR 789 arr->insert(
new te::dt::Int16(static_cast<int16_t>(val)), pos);
791 value +=
sizeof(uint16_t);
792 value +=
sizeof(
int);
796 return std::unique_ptr<te::dt::Array>(arr.release());
800 throw Exception(
TE_TR(
"The array element type is not supported yet!"));
835 return PQgetisnull(
m_result,
m_i, static_cast<int>(i)) == 1;
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.
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
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).
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.
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).
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.
std::unique_ptr< te::dt::Array > getArray(std::size_t i) const
Method for retrieving an array.
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...
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.
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.
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).
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).
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
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.
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.
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.