Loading...
Searching...
No Matches
Utils.h
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/Utils.h
22
23 \brief Utility functions for PostgreSQL.
24*/
25
26#ifndef __TERRALIB_POSTGIS_INTERNAL_UTILS_H
27#define __TERRALIB_POSTGIS_INTERNAL_UTILS_H
28
29// TerraLib
30#include "../common/ByteSwapUtils.h"
31#include "../common/Globals.h"
32#include "../common/StringUtils.h"
33#include "../dataaccess/Enums.h"
34#include "../datatype/ArrayProperty.h"
35#include "../datatype/Date.h"
36#include "../datatype/DateTimeProperty.h"
37#include "../datatype/NumericProperty.h"
38#include "../datatype/SimpleProperty.h"
39#include "../datatype/StringProperty.h"
40#include "../datatype/TimeDuration.h"
41#include "../datatype/TimeInstant.h"
42#include "../datatype/TimeInstantTZ.h"
43#include "../geometry/Envelope.h"
44#include "../geometry/Geometry.h"
45#include "../geometry/GeometryProperty.h"
46#include "../raster/RasterProperty.h"
47#include "Config.h"
48
49// STL
50#include <cstdlib>
51#include <cstring>
52#include <string>
53#include <vector>
54
55#include <boost/date_time/time_zone_base.hpp>
56
57// Forward declaration for libpq
58extern "C"
59{
60 struct pg_conn;
61 typedef struct pg_conn PGconn;
62
63 struct pg_result;
64 typedef struct pg_result PGresult;
65}
66
67namespace te
68{
69 // Forward declarations
70 namespace core { class URI; }
71
72 namespace da
73 {
74 class DataSet;
75 class DataSetType;
76 }
77
78 namespace pgis
79 {
80 /*!
81 \brief It returns the geometry names as usual for PostGIS.
82
83 \param t The TerraLib geometry type.
84
85 \return The geometry names as usual for PostGIS.
86 */
87 const std::string& GetGeometryName(te::gm::GeomType t);
88
89 /*!
90 \brief It writes the PostgreSQL column definition to the output string.
91
92 \param s The string to output the column definition.
93 \param p The TerraLib propoerty type.
94
95 \return It returns true if the property type is an autonumber.
96
97 \exception Exception It throws an exception if the data type is not mapped to the PostgreSQL type system.
98 */
99 bool SetColumnDef(std::string& s, const te::dt::Property* p, bool justDataType = false);
100
101 /*!
102 \brief It converts the PostgreSQL foreign key modifier to a TerraLib data type.
103
104 <ul>
105 <li>a: NO_ACTION</li>
106 <li>r: RESTRICT</li>
107 <li>c: CASCADE</li>
108 <li>n: SET_NULL</li>
109 <li>d: SET_DEFAULT</li>
110 </ul>
111
112 \param a PostgreSQL foreign key modifier type.
113
114 \retun The equivalent TerraLib foreign key modifier type.
115 */
117 {
118 switch(a)
119 {
120 case 'a' : return te::da::NO_ACTION;
121 case 'r' : return te::da::RESTRICT;
122 case 'c' : return te::da::CASCADE;
123 case 'n' : return te::da::SET_NULL;
124 case 'd' : return te::da::SET_DEFAULT;
125 }
126
127 return te::da::NO_ACTION;
128 }
129
130 /*!
131 \brief It converts the PostgreSQL index string to a TerraLib index type.
132
133 <ul>
134 <li>btree: BTreeType</li>
135 <li>gist: RTreeType</li>
136 <li>gin: BTreeType</li>
137 <li>hash: HashType</li>
138 </ul>
139
140 \param t PostgreSQL index name (A NULL terminated string).
141
142 \retun The equivalent TerraLib foreign key modifier type.
143 */
144 inline te::da::IndexType GetIndexType(const char* t)
145 {
146 if(strcmp(t, "btree") == 0)
147 {
148 return te::da::B_TREE_TYPE;
149 }
150 else if(strcmp(t, "gist") == 0)
151 {
152 return te::da::R_TREE_TYPE;
153 }
154 else if(strcmp(t, "gin") == 0)
155 {
156 return te::da::B_TREE_TYPE;
157 }
158 else //if(strcmp(t, "hash") == 0)
159 {
160 return te::da::HASH_TYPE;
161 }
162 }
163
164 /*!
165 \brief It converts the pgType to a valid TerraLib data type.
166
167 \param cols An array with column numbers.
168 \param dt The DataSetType to look for the property.
169
170 \return The next.
171 */
172 inline te::gm::Envelope* GetEnvelope(const char* str)
173 {
174 std::string enve(str);
175 size_t st = enve.find(",");
176 if(st != std::string::npos)
177 enve.replace(st, 1, ";");
178 double dval = atof("1,2");
179 if(dval == 1.2) // if decimal separator is ','
180 {
181 st = enve.find(".");
182 while(st != std::string::npos)
183 {
184 enve.replace(st, 1, ",");
185 st = enve.find(".");
186 }
187 }
188 const char* enveStr = enve.c_str();
189
191
192 enveStr += 4;
193 mbr->m_llx = atof(enveStr);
194
195 while(*enveStr != ' ')
196 ++enveStr;
197
198 ++enveStr;
199
200 mbr->m_lly = atof(enveStr);
201
202 while(*enveStr != ';')
203 ++enveStr;
204
205 ++enveStr;
206
207 mbr->m_urx = atof(enveStr);
208
209 while(*enveStr != ' ')
210 ++enveStr;
211
212 ++enveStr;
213
214 mbr->m_ury = atof(enveStr);
215
216 return mbr;
217 }
218
219 /*!
220 \brief It converts the envelope into a PostGIS BOX3D.
221
222 \param e The envelope to be converted.
223 \param srid The envelope coordinates SRS.
224 \param output The string to output the result.
225
226 \todo Toda chamada de rotinas de conversao de double para string deveria dizer a precisao!
227 */
228 inline void Convert2PostGIS(const te::gm::Envelope* e, int srid, std::string& output)
229 {
230 output += "ST_MakeEnvelope(";
231 output += te::common::Convert2String(e->m_llx, 15);
232 output += ", ";
233 output += te::common::Convert2String(e->m_lly, 15);
234 output += ", ";
235 output += te::common::Convert2String(e->m_urx, 15);
236 output += ", ";
237 output += te::common::Convert2String(e->m_ury, 15);
238 output += ", ";
239 output += te::common::Convert2String(srid);
240 output += ")";
241 }
242
243 /*!
244 \brief It converts the geometry into a PostGIS geometry.
245
246 \param conn The connection to be used with bytearray.
247 \param g The geometry to be converted.
248 \param output The string to output the result.
249 */
250 void Convert2PostGIS(PGconn* conn, const te::gm::Geometry* g, std::string& output);
251
252 /*!
253 \brief It escapes a string for use within an SQL command.
254
255 \param conn The connection to be used with bytearray.
256 \param s The string to be scapaded.
257 \param output The string to output the result.
258 */
259 void ScapeString(PGconn* conn, const std::string& s, std::string& output);
260
261 /*!
262 \brief It returns a julian date (in seconds) from a gregorian date.
263
264 It returns a julian date (in seconds) from a gregorian date.
265 Internally, postgresql stores julian dates.
266
267 \param y A year of a gregorian date.
268 \param m A month of a gregorian date.
269 \param d A day of a gregorian date.
270
271 \return a julian date in seconds from the informed gregorian date.
272 */
273 inline int Date2Julian(int y, int m, const int d)
274 {
275 int julian = 0;
276 int century = 0;
277
278 if(m > 2)
279 {
280 m += 1;
281 y += 4800;
282 }
283 else
284 {
285 m += 13;
286 y += 4799;
287 }
288
289 century = y / 100;
290 julian = y * 365 - 32167;
291 julian += y / 4 - century + century / 4;
292 julian += 7834 * m / 256 + d;
293
294 return julian;
295 }
296
297 /*!
298 \brief It returns a gregorian date from a julian date (in seconds).
299
300 It returns a gregorian date from a julian date (in seconds).
301
302 \param jd A julian date in seconds (INPUT).
303 \param year The year of a gregorian date that will be filled by this function (OUTPUT).
304 \param month The month of a gregorian date that will be filled by this function (OUTPUT).
305 \param day The day of a gregorian date that will be filled by this function (OUTPUT).
306 */
307 inline void Julian2Date(const int jd, int* year, int* month, int* day)
308 {
309 unsigned int julian = 0;
310 unsigned int quad = 0;
311 unsigned int extra = 0;
312 int y = 0;
313
314 julian = jd;
315 julian += 32044;
316 quad = julian / 146097;
317 extra = (julian - quad * 146097) * 4 + 3;
318 julian += 60 + quad * 3 + extra / 146097;
319 quad = julian / 1461;
320 julian -= quad * 1461;
321 y = julian * 4 / 1461;
322 julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366)) + 123;
323 y += quad * 4;
324 *year = y - 4800;
325 quad = julian * 2141 / 65536;
326 *day = julian - 7834 * quad / 256;
327 *month = (quad + 10) % 12 + 1;
328
329 return;
330 }
331
332 /*!
333 \brief It returns a DateTime type from a date loaded by PostgreSQL.
334
335 It returns a DateTime type from a date loaded by PostgreSQL. Internelly,
336 PostgreSQL stores julian dates in 4 bytes, so this function has to convert it
337 to gregorian date. Besides that, PostgreSQL stores date as seconds before
338 or after midnight 2000-01-01. Therefore, this function has to sum the number
339 of seconds (2451545 seconds) between 01-01-01 00:00:00 and 01-01-2000 00:00:00
340 to the date.
341
342 \param dDate A julian date in seconds loaded by PostgreSQL.
343
344 \param return A gregorian date from the input julian date.
345 */
346 inline te::dt::DateTime* Internal2Date(const long dDate)
347 {
348 int year, month, day;
349 //2451545: number of seconds between 01-01-01 00:00:00 and 01-01-2000 00:00:00
350 Julian2Date(dDate + 2451545, &year, &month, &day);
351 te::dt::DateTime* result = new te::dt::Date(static_cast<unsigned short>(year), static_cast<unsigned short>(month), static_cast<unsigned short>(day));
352 return result;
353 }
354
355 /*!
356 \brief It returns a DateTime type from a time loaded by PostgreSQL.
357
358 It returns a DateTime type from a time loaded by PostgreSQL. Internelly,
359 PostgreSQL stores time as seconds.
360
361 \param tval The amount of seconds loaded by PostgreSQL.
362
363 \param return A time (hour, minute, second) from the input amount of seconds.
364 */
365 inline te::dt::DateTime* Internal2Time(boost::int64_t tval)
366 {
367 int hour = (int)(tval / 3600000000UL);
368 boost::int64_t timeval = tval - hour * (boost::int64_t)3600000000UL;
369 int min = (int)(timeval / 60000000);
370 timeval -= min * (boost::int64_t)60000000;
371 int sec = (int)(timeval / 1000000);
372 timeval -= sec * (boost::int64_t)1000000;
373 int fsec = (int) timeval;
374
375 boost::posix_time::time_duration td(hour, min, sec, fsec);
376 te::dt::DateTime* result = new te::dt::TimeDuration(td);
377 return result;
378 }
379
380 inline te::dt::DateTime* Internal2TimeTZ(boost::int64_t tval, int z)
381 {
382 int hour = (int)(tval / 3600000000UL);
383 boost::int64_t timeval = tval - hour * (boost::int64_t)3600000000UL;
384 int min = (int)(timeval / 60000000);
385 timeval -= min * (boost::int64_t)60000000;
386 int sec = (int)(timeval / 1000000);
387 timeval -= sec * (boost::int64_t)1000000;
388 int fsec = (int) timeval;
389
390 boost::posix_time::time_duration td(hour, min, sec, fsec);
391 char buf[10];
392 sprintf(buf, "%d", z);
393 std::string sz = "OFF";
394 if(z >= 0)
395 sz += "+";
396 sz += buf;
397 boost::local_time::time_zone_ptr zp(new boost::local_time::posix_time_zone(sz));
398
399 boost::posix_time::ptime pt(boost::gregorian::date(2000, 01, 01), td);
400 boost::local_time::local_date_time tz(pt, zp);
402
403 return result;
404 }
405
406 /*!
407 \brief It returns a DateTime type from a timestamp loaded by PostgreSQL.
408
409 It returns a DateTime type from a timestamp loaded by PostgreSQL. Internelly,
410 PostgreSQL stores timestamp as seconds before or after midnight 2000-01-01.
411
412 \param ival The timestamp, in seconds, loaded by PostgreSQL.
413
414 \param return A time instant from the input timestamp.
415 */
416 inline te::dt::DateTime* Internal2TimeStamp(boost::int64_t ival)
417 {
418 boost::int64_t dateval;
419 boost::int64_t timeval = ival;
420
421 //1 day has 86400 seconds (* 1000000)
422 dateval = timeval / 86400000000LL;
423 if(dateval != 0)
424 timeval -= dateval * 86400000000LL;
425
426 if (timeval < 0)
427 {
428 timeval += 86400000000LL;
429 dateval -= 1;
430 }
431
432 te::dt::DateTime* aux1 = Internal2Date((long)dateval);
433 te::dt::DateTime* aux2 = Internal2Time(timeval);
434 te::dt::DateTime* result = new te::dt::TimeInstant(*static_cast<te::dt::Date*>(aux1), *static_cast<te::dt::TimeDuration*>(aux2));
435 delete aux1;
436 delete aux2;
437 return result;
438 }
439
440 inline te::dt::DateTime* Internal2TimeStampTZ(boost::int64_t ival, int z)
441 {
442 boost::int64_t dateval;
443 boost::int64_t timeval = ival;
444
445 //1 day has 86400 seconds (* 1000000)
446 dateval = timeval / 86400000000LL;
447 if(dateval != 0)
448 timeval -= dateval * 86400000000LL;
449
450 if (timeval < 0)
451 {
452 timeval += 86400000000LL;
453 dateval -= 1;
454 }
455
456 te::dt::Date* aux1 = static_cast<te::dt::Date*>(Internal2Date((long)dateval));
457 te::dt::TimeInstantTZ* aux2 = static_cast<te::dt::TimeInstantTZ*>(Internal2TimeTZ(timeval, z));
458
459 boost::local_time::local_date_time tz(aux1->getDate(), aux2->getTimeInstantTZ().local_time().time_of_day(), aux2->getTimeInstantTZ().zone(), true);
460
462 delete aux1;
463 delete aux2;
464 return result;
465 }
466
467
468 /*!
469 \brief It creates a PropertyType from a PostgreSQL attribute description.
470
471 \param attNum The column number (a number in the range [1, num-columns]).
472 \param attName The column name.
473 \param attType The column type
474 \param attLen The column size (depends on column type).
475 \param attNotNull If the column is not null.
476 \param fmt Column formats: Numeric(20, 30), VARCHAR(30), CHAR(10).
477 \param attHasDefault True if the column has a default value.
478 \param attDefValue The default value expression if attHasDefValue is true otherwise this has no meaning.
479 \param pgisGeomTypeOid The oid of PostGIS geometry type.
480
481 \return The TerraLib equivalent datatype.
482
483 \note The caller of this function will take the ownership of the returned PropertyType.
484 \note This method is valid just for types different from Array. For array types, see the method below (Convert2TerraLib) where the dimension info must be available.
485 */
486 inline te::dt::Property* Convert2TerraLib(unsigned int attNum, const char* attName, unsigned int attType,
487 bool attNotNull, const char* fmt,
488 bool attHasDefault, const char* attDefValue,
489 unsigned int pgisGeomTypeOid,
490 unsigned int pgisRasterTypeOid)
491 {
492 te::dt::Property* p = nullptr;
493 //te::dt::SimpleProperty* simpleP = nullptr;
494
495 std::string* defaultValue = (attHasDefault ? new std::string(attDefValue) : nullptr);
496 std::string name = std::string(attName);
497
498 if(attType == pgisGeomTypeOid)
499 return new te::gm::GeometryProperty(name, attNotNull, defaultValue, attNum);
500 else if(attType == pgisRasterTypeOid)
501 return new te::rst::RasterProperty(name, attNotNull, attNum);
502
503 switch(attType)
504 {
505 case PG_INT2_TYPE:
506 p = new te::dt::SimpleProperty(name, te::dt::INT16_TYPE, attNotNull, defaultValue, attNum);
507 break;
508
509 case PG_INT4_TYPE:
510 p = new te::dt::SimpleProperty(name, te::dt::INT32_TYPE, attNotNull, defaultValue, attNum);
511
512 if (defaultValue != 0 && defaultValue->find("nextval(") == 0)
513 {
514 te::dt::SimpleProperty* simpleP = dynamic_cast<te::dt::SimpleProperty*>(p);
515 simpleP->setAutoNumber(true);
516 }
517 break;
518
519 case PG_INT8_TYPE:
520 p = new te::dt::SimpleProperty(name, te::dt::INT64_TYPE, attNotNull, defaultValue, attNum);
521
522 if(defaultValue != 0 && defaultValue->find("nextval(") == 0)
523 {
524 te::dt::SimpleProperty* simpleP = dynamic_cast<te::dt::SimpleProperty*>(p);
525 simpleP->setAutoNumber(true);
526 }
527 break;
528
529 case PG_OID_TYPE:
530 p = new te::dt::SimpleProperty(name, te::dt::INT32_TYPE, attNotNull, defaultValue, attNum);
531 break;
532
533 case PG_FLOAT8_TYPE:
534 p = new te::dt::SimpleProperty(name, te::dt::DOUBLE_TYPE, attNotNull, defaultValue, attNum);
535 break;
536
537 case PG_NUMERIC_TYPE:
538 {
539 unsigned int precision = (fmt && (*(fmt + 7) != '\0') ? atoi(fmt + 8) : 0);
540 const char* sprecision = fmt ? strstr(fmt,",") : 0;
541 unsigned int scale = (sprecision ? atoi(sprecision + 1) : 0);
542
543 p = new te::dt::NumericProperty(name, precision, scale, attNotNull, defaultValue, attNum);
544 }
545 break;
546
547 case PG_VARCHAR_TYPE:
548 {
549 unsigned int size = fmt ? atoi(fmt + 18) : 0;
550
551 p = new te::dt::StringProperty(name, te::dt::VAR_STRING, size, attNotNull, defaultValue, attNum);
552 }
553 break;
554
555 case PG_TEXT_TYPE:
556 p = new te::dt::StringProperty(name, te::dt::STRING, 0, attNotNull, defaultValue, attNum);
557 break;
558
559 case PG_DATE_TYPE:
560 p = new te::dt::DateTimeProperty(name, te::dt::DATE, 0, attNotNull, defaultValue, attNum);
561 break;
562
563 case PG_TIME_TYPE:
564 p = new te::dt::DateTimeProperty(name, te::dt::TIME_DURATION, 0, attNotNull, defaultValue, attNum);
565 break;
566
567 case PG_TIMETZ_TYPE:
570 p = new te::dt::DateTimeProperty(name, te::dt::TIME_INSTANT, 0, attNotNull, defaultValue, attNum);
571 break;
572
573 case PG_BOOL_TYPE:
574 p = new te::dt::SimpleProperty(name, te::dt::BOOLEAN_TYPE, attNotNull, defaultValue, attNum);
575 break;
576
577 case PG_BYTEA_TYPE:
578 p = new te::dt::SimpleProperty(name, te::dt::BYTE_ARRAY_TYPE, attNotNull, defaultValue, attNum);
579 break;
580
581 case PG_FLOAT4_TYPE:
582 p = new te::dt::SimpleProperty(name, te::dt::FLOAT_TYPE, attNotNull, defaultValue, attNum);
583 break;
584
586 case PG_NAME_TYPE:
587 {
588 unsigned int size = (fmt && (*(fmt + 9) != '\0') ? atoi(fmt + 10) : 0);
589
590 p = new te::dt::StringProperty(name, te::dt::FIXED_STRING, size, attNotNull, defaultValue, attNum);
591 }
592 break;
593
594 case PG_CHAR_TYPE:
595 p = new te::dt::SimpleProperty(name, te::dt::CHAR_TYPE, attNotNull, defaultValue, attNum);
596 break;
597
598 default:
599 p = new te::dt::SimpleProperty(name, te::dt::UNKNOWN_TYPE, attNotNull, defaultValue, attNum);
600 }
601
602 return p;
603 }
604
605 /*!
606 \brief It creates a PropertyType from a PostgreSQL attribute description.
607
608 \param attNum The column number.
609 \param attName The column name.
610 \param attType The column type.
611 \param attNotNull If the column is not null.
612 \param fmt Column formats: Numeric(20, 30), VARCHAR(30), CHAR(10).
613 \param attHasDefault True, if the column has a default value.
614 \param attDefValue The default value expression, if attHasDefValue is true; otherwise, it has no meaning.
615 \param ndims If different of 0, it indicates an array type.
616 \param pgisGeomTypeOid The oid of the PostGIS geometry type.
617
618 \return The TerraLib equivalent PropertyType.
619
620 \note The caller of this method will take the ownership of the returned PropertyType.
621 \note This method may be used for array types also.
622 */
623 inline te::dt::Property* Convert2TerraLib(unsigned int attNum, const char* attName, unsigned int attType,
624 bool attNotNull, const char* fmt,
625 bool attHasDefault, const char* attDefValue,
626 int ndims, unsigned int pgisGeomTypeOid,
627 unsigned int pgisRasterTypeOid)
628 {
629 if(ndims == 0)
630 return Convert2TerraLib(attNum, attName, attType, attNotNull, fmt,
631 attHasDefault, attDefValue,
632 pgisGeomTypeOid, pgisRasterTypeOid);
633
634 std::string* defaultValue = (attHasDefault ? new std::string(attDefValue) : 0);
635 std::string name = std::string(attName);
636
637 te::dt::ArrayProperty* arrayElementProperty = 0;
638
639 for(int i = 0; i < ndims - 1; ++i)
640 arrayElementProperty = new te::dt::ArrayProperty(std::string(), arrayElementProperty);
641
642 std::unique_ptr<te::dt::ArrayProperty> at(new te::dt::ArrayProperty(name, arrayElementProperty, attNotNull, defaultValue, attNum));
643
644 switch(attType)
645 {
647 {
648 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_BOOL_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
649 if(arrayElementProperty)
650 arrayElementProperty->setElementType(p);
651 else
652 at->setElementType(p);
653 break;
654 }
655
657 {
658 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_BYTEA_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
659 if(arrayElementProperty)
660 arrayElementProperty->setElementType(p);
661 else
662 at->setElementType(p);
663 break;
664 }
665
667 {
668 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_CHAR_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
669 if(arrayElementProperty)
670 arrayElementProperty->setElementType(p);
671 else
672 at->setElementType(p);
673 break;
674 }
675
677 {
678 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_INT8_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
679 if(arrayElementProperty)
680 arrayElementProperty->setElementType(p);
681 else
682 at->setElementType(p);
683 break;
684 }
685
689 {
690 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_INT2_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
691 if(arrayElementProperty)
692 arrayElementProperty->setElementType(p);
693 else
694 at->setElementType(p);
695 break;
696 }
697
701 {
702 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_INT4_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
703 if(arrayElementProperty)
704 arrayElementProperty->setElementType(p);
705 else
706 at->setElementType(p);
707 break;
708 }
709
711 {
712 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_TEXT_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
713 if(arrayElementProperty)
714 arrayElementProperty->setElementType(p);
715 else
716 at->setElementType(p);
717 break;
718 }
719
721 {
722 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_FLOAT4_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
723 if(arrayElementProperty)
724 arrayElementProperty->setElementType(p);
725 else
726 at->setElementType(p);
727 break;
728 }
729
731 {
732 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_FLOAT8_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
733 if(arrayElementProperty)
734 arrayElementProperty->setElementType(p);
735 else
736 at->setElementType(p);
737 break;
738 }
739
742 {
743 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_CHARACTER_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
744 if(arrayElementProperty)
745 arrayElementProperty->setElementType(p);
746 else
747 at->setElementType(p);
748 break;
749 }
750
752 {
753 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_VARCHAR_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
754 if(arrayElementProperty)
755 arrayElementProperty->setElementType(p);
756 else
757 at->setElementType(p);
758 break;
759 }
760
762 {
763 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_DATE_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
764 if(arrayElementProperty)
765 arrayElementProperty->setElementType(p);
766 else
767 at->setElementType(p);
768 break;
769 }
770
772 {
773 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_TIME_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
774 if(arrayElementProperty)
775 arrayElementProperty->setElementType(p);
776 else
777 at->setElementType(p);
778 break;
779 }
780
782 {
783 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_TIMETZ_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
784 if(arrayElementProperty)
785 arrayElementProperty->setElementType(p);
786 else
787 at->setElementType(p);
788 break;
789 }
790
792 {
793 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_TIMESTAMP_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
794 if(arrayElementProperty)
795 arrayElementProperty->setElementType(p);
796 else
797 at->setElementType(p);
798 break;
799 }
800
802 {
803 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_TIMESTAMPTZ_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
804 if(arrayElementProperty)
805 arrayElementProperty->setElementType(p);
806 else
807 at->setElementType(p);
808 break;
809 }
810
812 {
813 te::dt::Property* p = Convert2TerraLib(attNum, attName, PG_NUMERIC_TYPE, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
814 if(arrayElementProperty)
815 arrayElementProperty->setElementType(p);
816 else
817 at->setElementType(p);
818 break;
819 }
820
821 default:
822 return Convert2TerraLib(attNum, attName, attType, attNotNull, fmt, attHasDefault, attDefValue, pgisGeomTypeOid, pgisRasterTypeOid);
823 }
824
825 return at.release();
826 }
827
828 /*!
829 \brief It converts the spatial relationship to PostGIS dialect.
830
831 \param rel The spatial relationship.
832
833 \return The PostGIS relationship name.
834 */
836 {
837 switch(rel)
838 {
840 return "ST_Intersects";
841
842 case te::gm::DISJOINT:
843 return "ST_Disjoint";
844
845 case te::gm::TOUCHES:
846 return "ST_Touches";
847
848 case te::gm::OVERLAPS:
849 return "ST_Overlaps";
850
851 case te::gm::CROSSES:
852 return "ST_Crosses";
853
854 case te::gm::WITHIN:
855 return "ST_Within";
856
857 case te::gm::CONTAINS:
858 return "ST_Contains";
859
860 case te::gm::COVERS:
861 return "ST_Covers";
862
864 return "ST_CoveredBy";
865
866 case te::gm::EQUALS:
867 return "ST_Equals";
868
869 default:
870 return "";
871 }
872 }
873
874 /*!
875 \brief It converts the spatial relationship to PostGIS dialect.
876
877 \param rel The spatial relationship.
878
879 \return The PostGIS relationship name.
880 */
882 {
883 switch(rel)
884 {
886 return " && ";
887
888 case te::gm::OVERLAPS:
889 return " && ";
890
891 case te::gm::WITHIN:
892 return " @ ";
893
894 case te::gm::CONTAINS:
895 return " ~ ";
896
897 case te::gm::COVERS:
898 return " ~ ";
899
901 return " @ ";
902
903 case te::gm::EQUALS:
904 return " = ";
905
906 default:
907 return "";
908 }
909 }
910
911 /*!
912 \brief It creates a data set type from a PostGIS internal result.
913
914 \param result A PostGIS internal result.
915 \param pgisGeomTypeOid The oid of PostGIS geometry type.
916
917 \return The data set type created.
918 */
920 unsigned int pgisGeomTypeOid,
921 unsigned int pgisRasterTypeOid,
922 std::vector<int>& teTypes);
923
924 /*!
925 \brief It converts the PostGIS geometry type to a pure OGC WKB code.
926
927 This function will turn off the PostGIS flags and will turn on
928 the right bits for OGC WKB type.
929
930 \param gType A value that can have some flags set by PostGIS.
931 */
932 inline void Convert2OGCWKBType(unsigned int& gType)
933 {
934 if(gType & 0xF0000000) // Is PostGIS?
935 {
936 if((gType & TE_EWKB_ZM_OFFSET) == 0xC0000000) // z and m is on
937 {
938 gType = (gType & 0x0FFFFFFF) | 0xBB8;
939 }
940 else if(gType & TE_EWKB_Z_OFFSET)
941 {
942 gType = (gType & 0x0FFFFFFF) | 0x3E8;
943 }
944 else if(gType & TE_EWKB_M_OFFSET)
945 {
946 gType = (gType & 0x0FFFFFFF) | 0x7D0;
947 }
948 else
949 {
950 gType = (gType & 0x0FFFFFFF);
951 }
952 }
953 }
954
955 std::string MakeConnectionStr(const te::core::URI& connInfo);
956
957 void SplitTableName(const std::string& fullName,
958 const std::string* defaultSchema,
959 std::string& schemaName,
960 std::string& tableName);
961
962 inline void Convert2PostGISWKBType(unsigned int& gType)
963 {
964 if((gType & 0xF00) == 0xB00) // it is zm
965 {
966 gType -= 3000;
967 gType |= TE_EWKB_ZM_OFFSET;
968 }
969 else if((gType & 0x0F00) == 0x300)
970 {
971 gType -= 1000;
972 gType |= TE_EWKB_Z_OFFSET;
973 }
974 else if((gType & 0xF00) == 0x700)
975 {
976 gType -= 2000;
977 gType |= TE_EWKB_M_OFFSET;
978 }
979 }
980
981 /*!
982 \brief Given a list of properties it creates an AND connected expression with bindable parameters ($n).
983
984 \param itBegin The start property.
985 \param itEnd The mark of end of properties.
986
987 \return An AND connected expression with bindable parameters ($n) that can be used in WHERE expressions.
988 */
989 std::string GetBindableWhereSQL(const std::vector<te::dt::Property*>& properties, const std::size_t offset = 0);
990
991 std::string GetSQLBindValues(std::size_t nproperties);
992
993 /*!
994 \brief Given a list of properties it constructs a string with bindable parameters that can be used inside an update query.
995
996 \param properties A vector with property names that will be used to create the expression.
997
998 \return A comma (',') connected expression with bindable parameters ($1) that can be used in an UPDATE query.
999 */
1000 std::string GetBindableUpdateSQL(const std::vector<te::dt::Property*>& properties);
1001
1002 std::string GetSQLValues(const te::da::DataSetType* dt, te::da::DataSet* d, PGconn *conn);
1003
1004 std::string GetSQLValue(const te::dt::Property* p, std::size_t propertyPos, te::da::DataSet* d, PGconn *conn);
1005
1007
1008 } // end namespace pgis
1009} // end namespace te
1010
1011#endif // __TERRALIB_POSTGIS_INTERNAL_UTILS_H
A class to store the proxy information that must be used to access data located in URIs.
Definition: URI.h:50
A class that models the description of a dataset.
Definition: DataSetType.h:73
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:114
The type for variable-length multidimensional arrays.
Definition: ArrayProperty.h:46
void setElementType(Property *t)
It sets the type of array elements.
The type for date and time types: date, date period, date duration, time duration,...
A base class for date data types.
Definition: Date.h:66
const boost::gregorian::date & getDate() const
It returns the internal boost date type.
The type for arbitrary precison numbers, like numeric(p, q).
It models a property definition.
Definition: Property.h:60
An atomic property like an integer or double.
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
A class to represent time duration with nano-second/micro-second resolution.
Definition: TimeDuration.h:52
A class to represent time instant with time zone.
Definition: TimeInstantTZ.h:57
const boost::local_time::local_date_time & getTimeInstantTZ() const
It returns the boost time instant with time zone type.
Definition: TimeInstantTZ.h:72
A class to represent time instant.
Definition: TimeInstant.h:56
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:52
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
Geometric property.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:78
Raster property.
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:56
IndexType
Index type.
Definition: Enums.h:108
@ B_TREE_TYPE
Definition: Enums.h:109
@ R_TREE_TYPE
Definition: Enums.h:110
@ HASH_TYPE
Definition: Enums.h:112
FKActionType
Type of action performed on the foreign key data.
Definition: Enums.h:94
@ SET_NULL
Definition: Enums.h:98
@ CASCADE
Definition: Enums.h:97
@ SET_DEFAULT
Definition: Enums.h:99
@ RESTRICT
Definition: Enums.h:96
@ NO_ACTION
Definition: Enums.h:95
@ VAR_STRING
Definition: Enums.h:174
@ FIXED_STRING
Definition: Enums.h:173
@ STRING
Definition: Enums.h:175
@ DOUBLE_TYPE
Definition: Enums.h:198
@ FLOAT_TYPE
Definition: Enums.h:197
@ UNKNOWN_TYPE
Definition: Enums.h:185
@ INT16_TYPE
Definition: Enums.h:190
@ CHAR_TYPE
Definition: Enums.h:188
@ BYTE_ARRAY_TYPE
Definition: Enums.h:201
@ INT64_TYPE
Definition: Enums.h:194
@ BOOLEAN_TYPE
Definition: Enums.h:196
@ INT32_TYPE
Definition: Enums.h:192
@ DATE
Definition: Enums.h:47
@ TIME_DURATION
Definition: Enums.h:50
@ TIME_INSTANT
Definition: Enums.h:51
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:42
SpatialRelation
Spatial relations between geometric objects.
Definition: Enums.h:128
@ COVEREDBY
Definition: Enums.h:138
@ OVERLAPS
Definition: Enums.h:133
@ INTERSECTS
Definition: Enums.h:130
@ DISJOINT
Definition: Enums.h:131
@ WITHIN
Definition: Enums.h:135
@ CROSSES
Definition: Enums.h:134
@ TOUCHES
Definition: Enums.h:132
@ EQUALS
Definition: Enums.h:139
@ COVERS
Definition: Enums.h:137
@ CONTAINS
Definition: Enums.h:136
std::string GetBindableUpdateSQL(const std::vector< te::dt::Property * > &properties)
Given a list of properties it constructs a string with bindable parameters that can be used inside an...
void Convert2PostGIS(const te::gm::Envelope *e, int srid, std::string &output)
It converts the envelope into a PostGIS BOX3D.
Definition: Utils.h:228
std::string GetLoadDataRow(const te::da::DataSetType *dt, te::da::DataSet *d, PGconn *conn)
std::string GetSQLValues(const te::da::DataSetType *dt, te::da::DataSet *d, PGconn *conn)
te::dt::DateTime * Internal2TimeStampTZ(boost::int64_t ival, int z)
Definition: Utils.h:440
void Convert2PostGISWKBType(unsigned int &gType)
Definition: Utils.h:962
std::string GetSQLBindValues(std::size_t nproperties)
void SplitTableName(const std::string &fullName, const std::string *defaultSchema, std::string &schemaName, std::string &tableName)
std::string MakeConnectionStr(const te::core::URI &connInfo)
te::da::IndexType GetIndexType(const char *t)
It converts the PostgreSQL index string to a TerraLib index type.
Definition: Utils.h:144
te::dt::Property * Convert2TerraLib(unsigned int attNum, const char *attName, unsigned int attType, bool attNotNull, const char *fmt, bool attHasDefault, const char *attDefValue, unsigned int pgisGeomTypeOid, unsigned int pgisRasterTypeOid)
It creates a PropertyType from a PostgreSQL attribute description.
Definition: Utils.h:486
const std::string & GetGeometryName(te::gm::GeomType t)
It returns the geometry names as usual for PostGIS.
te::dt::DateTime * Internal2Time(boost::int64_t tval)
It returns a DateTime type from a time loaded by PostgreSQL.
Definition: Utils.h:365
te::dt::DateTime * Internal2Date(const long dDate)
It returns a DateTime type from a date loaded by PostgreSQL.
Definition: Utils.h:346
te::dt::DateTime * Internal2TimeTZ(boost::int64_t tval, int z)
Definition: Utils.h:380
std::string GetBindableWhereSQL(const std::vector< te::dt::Property * > &properties, const std::size_t offset=0)
Given a list of properties it creates an AND connected expression with bindable parameters ($n).
bool SetColumnDef(std::string &s, const te::dt::Property *p, bool justDataType=false)
It writes the PostgreSQL column definition to the output string.
std::string GetBoxSpatialRelation(te::gm::SpatialRelation rel)
It converts the spatial relationship to PostGIS dialect.
Definition: Utils.h:881
int Date2Julian(int y, int m, const int d)
It returns a julian date (in seconds) from a gregorian date.
Definition: Utils.h:273
te::gm::Envelope * GetEnvelope(const char *str)
It converts the pgType to a valid TerraLib data type.
Definition: Utils.h:172
te::dt::DateTime * Internal2TimeStamp(boost::int64_t ival)
It returns a DateTime type from a timestamp loaded by PostgreSQL.
Definition: Utils.h:416
std::string GetSQLValue(const te::dt::Property *p, std::size_t propertyPos, te::da::DataSet *d, PGconn *conn)
void Julian2Date(const int jd, int *year, int *month, int *day)
It returns a gregorian date from a julian date (in seconds).
Definition: Utils.h:307
te::da::FKActionType GetAction(char a)
It converts the PostgreSQL foreign key modifier to a TerraLib data type.
Definition: Utils.h:116
std::string GetSpatialRelation(te::gm::SpatialRelation rel)
It converts the spatial relationship to PostGIS dialect.
Definition: Utils.h:835
void Convert2OGCWKBType(unsigned int &gType)
It converts the PostGIS geometry type to a pure OGC WKB code.
Definition: Utils.h:932
void ScapeString(PGconn *conn, const std::string &s, std::string &output)
It escapes a string for use within an SQL command.
TerraLib.
struct pg_conn PGconn
Definition: Connection.h:45
struct pg_result PGresult
Definition: Connection.h:48
#define PG_INT2_TYPE
Definition: Config.h:114
#define PG_FLOAT8_ARRAY_TYPE
Definition: Config.h:141
#define PG_TEXT_ARRAY_TYPE
Definition: Config.h:137
#define PG_BOOL_TYPE
Definition: Config.h:109
#define PG_OID_VECTOR_TYPE
Definition: Config.h:139
#define PG_NAME_TYPE
Definition: Config.h:112
#define PG_BYTEA_ARRAY_TYPE
Definition: Config.h:130
#define PG_VARCHAR_ARRAY_TYPE
Definition: Config.h:143
#define PG_INT4_ARRAY_TYPE
Definition: Config.h:136
#define PG_CHARACTER_ARRAY_TYPE
Definition: Config.h:142
#define PG_FLOAT4_ARRAY_TYPE
Definition: Config.h:140
#define TE_EWKB_Z_OFFSET
Definition: Config.h:159
#define PG_INT2_VECTOR_TYPE
Definition: Config.h:115
#define PG_TIMESTAMPTZ_ARRAY_TYPE
Definition: Config.h:148
#define PG_DATE_ARRAY_TYPE
Definition: Config.h:144
#define PG_DATE_TYPE
Definition: Config.h:123
#define PG_FLOAT4_TYPE
Definition: Config.h:119
#define PG_TIMESTAMPTZ_TYPE
Definition: Config.h:127
#define PG_TIME_ARRAY_TYPE
Definition: Config.h:145
#define PG_INT4_TYPE
Definition: Config.h:116
#define PG_VARCHAR_TYPE
Definition: Config.h:122
#define PG_CHAR_TYPE
Definition: Config.h:111
#define PG_TIME_TYPE
Definition: Config.h:124
#define PG_TIMESTAMP_ARRAY_TYPE
Definition: Config.h:147
#define PG_NUMERIC_TYPE
Definition: Config.h:128
#define PG_NUMERIC_ARRAY_TYPE
Definition: Config.h:149
#define PG_INT2_ARRAY_TYPE
Definition: Config.h:134
#define PG_INT8_TYPE
Definition: Config.h:113
#define PG_TIMESTAMP_TYPE
Definition: Config.h:126
#define PG_TIMETZ_TYPE
Definition: Config.h:125
#define PG_OID_TYPE
Definition: Config.h:118
#define PG_FLOAT8_TYPE
Definition: Config.h:120
#define PG_BYTEA_TYPE
Definition: Config.h:110
#define PG_BOOL_ARRAY_TYPE
Definition: Config.h:129
#define TE_EWKB_M_OFFSET
Definition: Config.h:160
#define PG_INT8_ARRAY_TYPE
Definition: Config.h:133
#define PG_OID_ARRAY_TYPE
Definition: Config.h:138
#define TE_EWKB_ZM_OFFSET
Definition: Config.h:158
#define PG_NAME_ARRAY_TYPE
Definition: Config.h:132
#define PG__INT2_VECTOR_TYPE
Definition: Config.h:135
#define PG_CHARACTER_TYPE
Definition: Config.h:121
#define PG_CHAR_ARRAY_TYPE
Definition: Config.h:131
#define PG_TIMETZ_ARRAY_TYPE
Definition: Config.h:146
#define PG_TEXT_TYPE
Definition: Config.h:117
Proxy configuration file for TerraView (see terraview_config.h).