All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2009-2013 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/sqlite/Utils.cpp
22 
23  \brief Utility functions for the TerraLib SQLite Data Access driver.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../common/Translator.h"
29 #include "../dataaccess/Exception.h"
30 #include "../datatype/ByteArray.h"
31 #include "../datatype/DateTimeProperty.h"
32 #include "../datatype/Enums.h"
33 #include "../datatype/NumericProperty.h"
34 #include "../datatype/Property.h"
35 #include "../datatype/SimpleProperty.h"
36 #include "../datatype/StringProperty.h"
37 #include "../geometry/Envelope.h"
38 #include "../geometry/Geometry.h"
39 #include "../geometry/GeometryProperty.h"
40 #include "Config.h"
41 #include "DataSource.h"
42 #include "Utils.h"
43 
44 // STL
45 #include <cassert>
46 #include <cstring>
47 #include <fstream>
48 #include <memory>
49 
50 // Boost
51 #include <boost/algorithm/string/case_conv.hpp>
52 #include <boost/format.hpp>
53 #include <boost/lexical_cast.hpp>
54 
55 // SQLite
56 #include <sqlite3.h>
57 
58 #ifdef TE_ENABLE_SPATIALITE
59 // SpatiaLite
60 #include <spatialite/gaiageo.h>
61 #endif
62 
63 int te::sqlite::GetConnectionFlags(const std::map<std::string, std::string>& connInfo)
64 {
65  int flags = 0;
66 
67  if((connInfo.find("SQLITE_OPEN_NOMUTEX") != connInfo.end()) &&
68  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_NOMUTEX")->second) == "TRUE"))
69  flags |= SQLITE_OPEN_NOMUTEX;
70 
71  if((connInfo.find("SQLITE_OPEN_FULLMUTEX") != connInfo.end()) &&
72  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_FULLMUTEX")->second) == "TRUE"))
73  flags |= SQLITE_OPEN_FULLMUTEX;
74 
75  if((connInfo.find("SQLITE_OPEN_SHAREDCACHE") != connInfo.end()) &&
76  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_SHAREDCACHE")->second) == "TRUE"))
77  flags |= SQLITE_OPEN_SHAREDCACHE;
78 
79  if((connInfo.find("SQLITE_OPEN_PRIVATECACHE") != connInfo.end()) &&
80  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_PRIVATECACHE")->second) == "TRUE"))
81  flags |= SQLITE_OPEN_PRIVATECACHE;
82 
83  if((connInfo.find("SQLITE_OPEN_READWRITE") != connInfo.end()) &&
84  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_READWRITE")->second) == "TRUE"))
85  flags |= SQLITE_OPEN_READWRITE;
86  else if((connInfo.find("SQLITE_OPEN_READONLY") != connInfo.end()) &&
87  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_READONLY")->second) == "TRUE"))
88  flags |= SQLITE_OPEN_READONLY;
89 
90  if((connInfo.find("SQLITE_OPEN_CREATE") != connInfo.end()) &&
91  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_CREATE")->second) == "TRUE"))
92  flags |= SQLITE_OPEN_CREATE;
93 
94  if((connInfo.find("SQLITE_OPEN_URI") != connInfo.end()) &&
95  (boost::to_upper_copy(connInfo.find("SQLITE_OPEN_URI")->second) == "TRUE"))
96  flags |= SQLITE_OPEN_CREATE;
97 
98  return flags;
99 }
100 
101 bool te::sqlite::Exists(const std::map<std::string, std::string>& dbInfo)
102 {
103  int flags = GetConnectionFlags(dbInfo);
104 
105  if(flags == 0)
106  flags = SQLITE_OPEN_READONLY;
107 
108  flags &= 0xFFFFFFFB;
109 
110  std::string fileName;
111 
112  {
113  std::map<std::string, std::string>::const_iterator it = dbInfo.find("SQLITE_FILE");
114 
115  if(it != dbInfo.end())
116  fileName = it->second;
117  else
118  throw te::da::Exception(TR_COMMON("To check the existence of an SQLite database you must inform its file name or URI!"));
119  }
120 
121  std::string vfs;
122 
123  {
124  std::map<std::string, std::string>::const_iterator it = dbInfo.find("SQLITE_VFS");
125 
126  if(it != dbInfo.end())
127  vfs = it->second;
128  }
129 
130  sqlite3* db = 0;
131 
132  int ret = sqlite3_open_v2(fileName.c_str(), &db, flags, vfs.empty() ? 0 : vfs.c_str());
133 
134  sqlite3_close(db);
135 
136  return (ret == SQLITE_OK);
137 }
138 
139 void te::sqlite::ExecuteScript(sqlite3* db, const char* fileName)
140 {
141  std::ifstream istr;
142 
143  istr.open(fileName, std::ios_base::in);
144 
145  if(!istr.is_open())
146  throw te::da::Exception((boost::format(TR_COMMON("Could not open file: %1%.")) % fileName).str());
147 
148  try
149  {
150  PerformCommands(db, istr);
151  }
152  catch(...)
153  {
154  istr.close();
155  throw;
156  }
157 
158  istr.close();
159 }
160 
161 void te::sqlite::PerformCommands(sqlite3* db, std::istream& istr)
162 {
163  char* buff = (char*)malloc(TE_SQLITE_BUFFER_SCRIPT_SIZE);
164  char* sql = (char*)malloc(TE_SQLITE_BUFFER_SCRIPT_SIZE);
165  size_t buffsize = TE_SQLITE_BUFFER_SCRIPT_SIZE;
166  size_t sqlSize = TE_SQLITE_BUFFER_SCRIPT_SIZE;
167  size_t offset = 0;
168  size_t priorOffset = 0;
169 
170  while(!istr.eof())
171  {
172  std::streamsize readbytes = ReadLine(istr, &buff, buffsize);
173 
174  if(readbytes == 0)
175  break;
176 
177  if(IsAllWhitespace(buff))
178  continue;
179 
180  if(IsCommandTerminator(buff) && IsComplete(&sql, offset, sqlSize))
181  memcpy(buff, ";", 2);
182 
183  std::size_t lineLen = strlen(buff);
184 
185  if((lineLen + 2) > (sqlSize - offset))
186  {
187  sql = (char*)realloc(sql, sqlSize + buffsize);
188  sqlSize = sqlSize + buffsize;
189  }
190 
191  if(offset != 0)
192  sql[offset++] = '\n';
193 
194  memcpy(&sql[offset], buff, lineLen + 1);
195  priorOffset = offset;
196  offset += lineLen;
197 
198  if(offset && ContainsSemicolon(sql + priorOffset, lineLen) && sqlite3_complete(sql))
199  {
200  try
201  {
202  PerformCommands(db, sql);
203  priorOffset = offset = 0;
204  }
205  catch(...)
206  {
207  free(buff);
208  free(sql);
209 
210  throw;
211  }
212  }
213  }
214 
215  if(offset && !IsAllWhitespace(sql))
216  {
217  boost::format errmsg(TR_COMMON("Error! incomplete SQL: %1%"));
218 
219  errmsg = errmsg % sql;
220 
221  free(buff);
222  free(sql);
223 
224  throw te::da::Exception(errmsg.str());
225  }
226 
227 
228  free(buff);
229  free(sql);
230 }
231 
232 void te::sqlite::PerformCommands(sqlite3* db, const char* sql)
233 {
234  sqlite3_stmt *pStmt = 0;
235  int rc = SQLITE_OK;
236  const char* sqlLeftOver = 0;
237 
238  while(sql[0] != '\0' && rc == SQLITE_OK)
239  {
240  rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, &sqlLeftOver);
241 
242  if(rc != SQLITE_OK)
243  throw te::da::Exception((boost::format(TR_COMMON("Error preparing the SQL statement. The follwoing error has occurried: %1%.")) % sqlite3_errmsg(db)).str());
244 
245  if(pStmt == 0)
246  {
247  sql = sqlLeftOver;
248 
249  while(isspace(sql[0]))
250  ++sql;
251 
252  continue;
253  }
254 
255  rc = sqlite3_step(pStmt);
256 
257  sqlite3_finalize(pStmt);
258 
259  if(rc != SQLITE_ROW && rc != SQLITE_OK && rc != SQLITE_DONE)
260  {
261  std::string errmsg = TR_COMMON("Error processing the SQL statement. The follwoing error has occurried: ");
262  errmsg += sqlite3_errmsg(db);
263  errmsg += ".";
264 
265  throw te::common::Exception(errmsg);
266  }
267 
268  sql = sqlLeftOver;
269 
270  while(isspace(sql[0]))
271  ++sql;
272 
273  rc = SQLITE_OK;
274  }
275 }
276 
277 std::streamsize te::sqlite::ReadLine(std::istream& istr, char** pbuff, std::size_t& buffsize)
278 {
279  std::streamsize readbytes = 0;
280 
281  char* buff = *pbuff;
282 
283  do
284  {
285  istr.getline(buff + readbytes, static_cast<std::streamsize>(buffsize - readbytes));
286 
287  if(istr.flags() & std::ios::failbit)
288  {
289  buffsize += TE_SQLITE_BUFFER_SCRIPT_SIZE;
290  buff = (char*)realloc(buff, buffsize);
291  *pbuff = buff;
292  readbytes += istr.gcount();
293  }
294  else
295  {
296  readbytes = istr.gcount();
297  break;
298  }
299  }while(true);
300 
301  return readbytes;
302 }
303 
304 bool te::sqlite::IsAllWhitespace(const char* sqlLine)
305 {
306  for(; *sqlLine; ++sqlLine)
307  {
308  if(isspace(*(unsigned char*)sqlLine))
309  continue;
310 
311  if((*sqlLine == '/') && (sqlLine[1] == '*'))
312  {
313  sqlLine += 2;
314 
315  while(*sqlLine && ((*sqlLine != '*') || (sqlLine[1] != '/')))
316  ++sqlLine;
317 
318  if(*sqlLine == 0)
319  return false;
320 
321  ++sqlLine;
322 
323  continue;
324  }
325 
326  if((*sqlLine == '-') && (sqlLine[1] == '-'))
327  {
328  sqlLine += 2;
329 
330  while(*sqlLine && (*sqlLine != '\n'))
331  ++sqlLine;
332 
333  if(*sqlLine == 0)
334  return true;
335 
336  continue;
337  }
338 
339  return false;
340  }
341 
342  return true;
343 }
344 
345 bool te::sqlite::IsCommandTerminator(const char* sqlLine)
346 {
347  while(isspace(*(unsigned char*)sqlLine))
348  ++sqlLine;
349 
350  if((sqlLine[0] == '/') && IsAllWhitespace(&sqlLine[1]))
351  return true;
352 
353  if(tolower((sqlLine[0]) == 'g') && (tolower(sqlLine[1]) == 'o') && IsAllWhitespace(&sqlLine[2]))
354  return true;
355 
356  return false;
357 }
358 
359 bool te::sqlite::ContainsSemicolon(const char* sql, std::size_t nbytes)
360 {
361  for(std::size_t i = 0; i < nbytes; ++i)
362  if(sql[i] == ';')
363  return true;
364 
365  return false;
366 }
367 
368 bool te::sqlite::IsComplete(char** sql, size_t len, std::size_t& buffsize)
369 {
370  char* psql = *sql;
371 
372  if(len == 0)
373  return true;
374 
375  if(len + 2 > buffsize)
376  {
377  buffsize += TE_SQLITE_BUFFER_SCRIPT_SIZE;
378  psql = (char*)realloc(psql, buffsize);
379  *sql = psql;
380  }
381 
382  psql[len] = ';';
383  psql[len + 1] = 0;
384 
385  int rc = sqlite3_complete(psql);
386 
387  psql[len] = '\0';
388 
389  return rc != 0;
390 }
391 
392 void te::sqlite::GetHiddenTables(const te::da::DataSource* ds, std::vector<std::string>& tables)
393 {
394  const std::map<std::string, std::string>& connInfo = ds->getConnectionInfo();
395 
396  std::map<std::string, std::string>::const_iterator it = connInfo.find("SQLITE_HIDE_SPATIAL_METADATA_TABLES");
397  std::map<std::string, std::string>::const_iterator itend = connInfo.end();
398 
399  if((it != itend) && (te::common::Convert2UCase(it->second) == "TRUE"))
400  {
401  tables.push_back("SpatialIndex");
402  tables.push_back("geom_cols_ref_sys");
403  tables.push_back("geometry_columns");
404  tables.push_back("geometry_columns_auth");
405  tables.push_back("geometry_columns_field_infos");
406  tables.push_back("geometry_columns_statistics");
407  tables.push_back("geometry_columns_time");
408  tables.push_back("spatial_ref_sys");
409  tables.push_back("spatialite_history");
410  tables.push_back("sql_statements_log");
411  tables.push_back("vector_layers");
412  tables.push_back("vector_layers_auth");
413  tables.push_back("vector_layers_field_infos");
414  tables.push_back("vector_layers_statistics");
415  tables.push_back("views_geometry_columns");
416  tables.push_back("views_geometry_columns_auth");
417  tables.push_back("views_geometry_columns_field_infos");
418  tables.push_back("views_geometry_columns_statistics");
419  tables.push_back("virts_geometry_columns");
420  tables.push_back("virts_geometry_columns_auth");
421  tables.push_back("virts_geometry_columns_field_infos");
422  tables.push_back("virts_geometry_columns_statistics");
423  }
424 
425  it = connInfo.find("SQLITE_HIDE_TABLES");
426 
427  if((it != itend) && (it->second.empty() == false))
428  te::common::Tokenize(it->second, tables, ",");
429 
430  return;
431 }
432 
434 {
435  te::da::DataSetType* dt = new te::da::DataSetType("", 0);
436 
437  const int ncols = sqlite3_column_count(pStmt);
438 
439  for(int i = 0; i < ncols; ++i)
440  {
441  const char* t = sqlite3_column_decltype(pStmt, i);
442  const char* name = sqlite3_column_name(pStmt, i);
443 
444  te::dt::Property* p = Convert2TerraLib(i, name, t != 0 ? t : "", false);
445 
446  dt->add(p);
447  }
448 
449  return dt;
450 }
451 
453  const std::string& colName,
454  const std::string& colType,
455  bool required,
456  std::string* defaultValue)
457 {
458  te::dt::Property* p = 0;
459 
460  std::string uColType = te::common::Convert2UCase(colType);
461 
462  if((uColType == "INT") ||
463  (uColType == "INTEGER") ||
464  (uColType == "TINYINT") ||
465  (uColType == "SMALLINT") ||
466  (uColType == "MEDIUMINT") ||
467  (uColType == "BIGINT") ||
468  (uColType == "UNSIGNED BIG INT") ||
469  (uColType == "INT2") ||
470  (uColType == "INT8"))
471  {
472  p = new te::dt::SimpleProperty(colName, te::dt::INT64_TYPE, required, defaultValue, colId);
473  }
474  else if((uColType == "FLOAT") ||
475  (uColType == "DOUBLE") ||
476  (uColType == "REAL") ||
477  (uColType == "DOUBLE PRECISION"))
478  {
479  p = new te::dt::SimpleProperty(colName, te::dt::DOUBLE_TYPE, required, defaultValue, colId);
480  }
481  else if((uColType == "NUMERIC") ||
482  (uColType.substr(0, 7) == "DECIMAL"))
483  {
484  p = new te::dt::NumericProperty(colName, 0, 0, required, defaultValue, colId);
485  }
486  else if((uColType == "TEXT") ||
487  (uColType == "CLOB") ||
488  (uColType.substr(0, 4) == "CHAR") ||
489  (uColType.substr(0, 7) == "VARCHAR"))
490  {
491  p = new te::dt::StringProperty(colName, te::dt::STRING, 0, required, defaultValue, colId);
492  }
493  else if(uColType == "BLOB")
494  {
495  p = new te::dt::SimpleProperty(colName, te::dt::BYTE_ARRAY_TYPE, required, defaultValue, colId);
496  }
497  else if(te::gm::Geometry::isGeomType(uColType))
498  {
499  p = new te::gm::GeometryProperty(colName, -1, te::gm::GeometryType, required, defaultValue, colId, 0);
500  }
501  else if(uColType == "DATE")
502  {
503  p = new te::dt::DateTimeProperty(colName, te::dt::DATE, te::dt::UNKNOWN, required, defaultValue, colId);
504  }
505  else if(uColType == "DATETIME")
506  {
507  p = new te::dt::DateTimeProperty(colName, te::dt::TIME_INSTANT, te::dt::UNKNOWN, required, defaultValue, colId);
508  }
509  else if((uColType == "BOOL") ||
510  (uColType == "BOOLEAN"))
511  {
512  p = new te::dt::SimpleProperty(colName, te::dt::BOOLEAN_TYPE, required, defaultValue, colId);
513  }
514  else// if(uColType == "NULL")
515  {
516  p = new te::dt::SimpleProperty(colName, te::dt::UNKNOWN_TYPE, required, defaultValue, colId);
517  }
518 
519  return p;
520 }
521 
522 int te::sqlite::Convert2TerraLibCategory(const std::string& category)
523 {
524  if(category == "table")
525  return te::da::TABLE_TYPE;
526  else if(category == "view")
527  return te::da::VIEW_TYPE;
528  else if(category == "index")
529  return te::da::INDEX_TYPE;
530  else if(category == "trigger")
531  return te::da::TRIGGER_TYPE;
532  else
534 }
535 
537 {
538  std::string filter;
539 
540  switch(r)
541  {
542  case te::gm::INTERSECTS :
543  case te::gm::TOUCHES :
544  case te::gm::OVERLAPS :
545  case te::gm::CROSSES :
546  case te::gm::EQUALS :
547  filter = "RTreeIntersects(";
548  break;
549 
550  case te::gm::WITHIN :
551  filter = "RTreeWithin(";
552  break;
553 
554  case te::gm::CONTAINS :
555  filter = "RTreeContains(";
556  break;
557 
558  default:
559  throw te::common::Exception(TR_COMMON("Invalid rectangle relation for SQLite driver!"));
560  }
561 
562  filter += boost::lexical_cast<std::string>(e->m_llx);
563  filter += ", ";
564  filter += boost::lexical_cast<std::string>(e->m_lly);
565  filter += ", ";
566  filter += boost::lexical_cast<std::string>(e->m_urx);
567  filter += ", ";
568  filter += boost::lexical_cast<std::string>(e->m_ury);
569  filter += ")";
570 
571  return filter;
572 }
573 
574 std::string te::sqlite::GetBindableSpatialRelation(const std::string& colName, const te::gm::SpatialRelation r)
575 {
576  std::string filter;
577 
578  switch(r)
579  {
580  case te::gm::INTERSECTS :
581  filter = "Intersects(";
582  break;
583 
584  case te::gm::WITHIN :
585  filter = "Within(";
586  break;
587 
588  case te::gm::CONTAINS :
589  filter = "Contains(";
590  break;
591 
592  case te::gm::TOUCHES :
593  filter = "Touches(";
594  break;
595 
596  case te::gm::EQUALS :
597  filter = "Equals(";
598  break;
599 
600  case te::gm::OVERLAPS :
601  filter = "Overlaps(";
602  break;
603 
604  case te::gm::CROSSES :
605  filter = "Crosses(";
606  break;
607 
608  case te::gm::DISJOINT :
609  filter = "Disjoint(";
610  break;
611 
612  default:
613  throw te::common::Exception(TR_COMMON("Invalid rectangle relation for SQLite driver!"));
614  }
615 
616  filter += colName;
617 
618  filter += ", ?)";
619 
620  return filter;
621 }
622 
623 void te::sqlite::Convert2SpatiaLiteGeom(const te::gm::GeomType t, std::string& geomType, std::string& dimension)
624 {
625  switch(t)
626  {
627  case te::gm::PointType :
628  geomType = "POINT";
629  break;
630 
631  case te::gm::PointZType :
632  geomType = "POINTZ";
633  break;
634 
635  case te::gm::PointMType :
636  geomType = "POINTM";
637  break;
638 
639  case te::gm::PointZMType :
640  geomType = "POINTZM";
641  break;
642 
644  geomType = "LINESTRING";
645  break;
646 
648  geomType = "LINESTRINGZ";
649  break;
650 
652  geomType = "LINESTRINGM";
653  break;
654 
656  geomType = "LINESTRINGZM";
657  break;
658 
659  case te::gm::PolygonType :
660  geomType = "POLYGON";
661  break;
662 
663  case te::gm::PolygonZType :
664  geomType = "POLYGONZ";
665  break;
666 
667  case te::gm::PolygonMType :
668  geomType = "POLYGONM";
669  break;
670 
671  case te::gm::PolygonZMType :
672  geomType = "POLYGONZM";
673  break;
674 
676  geomType = "MULTIPOINT";
677  break;
678 
680  geomType = "MULTIPOINTZ";
681  break;
682 
684  geomType = "MULTIPOINTM";
685  break;
686 
688  geomType = "MULTIPOINTZM";
689  break;
690 
692  geomType = "MULTILINESTRING";
693  break;
694 
696  geomType = "MULTILINESTRINGZ";
697  break;
698 
700  geomType = "MULTILINESTRINGM";
701  break;
702 
704  geomType = "MULTILINESTRINGZM";
705  break;
706 
708  geomType = "MULTIPOLYGON";
709  break;
710 
712  geomType = "MULTIPOLYGONZ";
713  break;
714 
716  geomType = "MULTIPOLYGONM";
717  break;
718 
720  geomType = "MULTIPOLYGONZM";
721  break;
722 
724  geomType = "GEOMETRYCOLLECTION";
725  break;
726 
728  geomType = "GEOMETRYCOLLECTIONZ";
729  break;
730 
732  geomType = "GEOMETRYCOLLECTIONM";
733  break;
734 
736  geomType = "GEOMETRYCOLLECTIONZM";
737  break;
738 
739  case te::gm::GeometryType :
740  geomType = "GEOMETRY";
741  break;
742 
743  case te::gm::GeometryZType :
744  geomType = "GEOMETRYZ";
745  break;
746 
747  case te::gm::GeometryMType :
748  geomType = "GEOMETRYM";
749  break;
750 
752  geomType = "GEOMETRYZM";
753  break;
754 
755  default:
756  throw te::common::Exception(TR_COMMON("This geometric type is not supported by SpatiaLite!"));
757  }
758 
759  if((t & 0xF00) == 0xB00) // it is zm
760  dimension = "XYZM";
761  else if((t & 0x0F00) == 0x300) // it is z
762  dimension = "XYZ";
763  else if((t & 0xF00) == 0x700) // it is m
764  dimension = "XYM";
765  else
766  dimension = "XY";
767 }
768 
770 {
771  std::string sql;
772 
773  switch(p->getType())
774  {
775  case te::dt::CHAR_TYPE :
776  case te::dt::UCHAR_TYPE :
777  case te::dt::INT16_TYPE :
778  case te::dt::INT32_TYPE :
779  case te::dt::INT64_TYPE :
780  sql = "INTEGER";
781  break;
782 
783  case te::dt::FLOAT_TYPE :
784  case te::dt::DOUBLE_TYPE :
785  sql = "REAL";
786  break;
787 
788  case te::dt::STRING_TYPE :
789  sql = "TEXT";
790  break;
791 
792  case te::dt::NUMERIC_TYPE :
793  sql = "NUMERIC";
794  break;
795 
797  sql = "BLOB";
798  break;
799 
800  case te::dt::DATETIME_TYPE :
801  sql = static_cast<const te::dt::DateTimeProperty*>(p)->getSubType() == te::dt::TIME_INSTANT ? "DATETIME" : "DATE";
802  break;
803 
804  case te::dt::GEOMETRY_TYPE :
805  {
806  const te::gm::GeometryProperty* gp = static_cast<const te::gm::GeometryProperty*>(p);
807 
808  std::string gtype;
809  std::string cdim;
810 
811  Convert2SpatiaLiteGeom(gp->getGeometryType(), gtype, cdim);
812 
813  sql = gtype;
814  }
815  break;
816 
817  default:
818  throw te::common::Exception((boost::format(TR_COMMON("The TerraLib data type %1% can not be converted to SQLite type system!")) % p->getType()).str());
819  }
820 
821  return sql;
822 }
823 
824 te::da::FKActionType te::sqlite::GetAction(const std::string& action)
825 {
826  if(action == "NO ACTION")
827  {
828  return te::da::NO_ACTION;
829  }
830  else if(action == "RESTRICT")
831  {
832  return te::da::RESTRICT;
833  }
834  else if(action == "CASCADE")
835  {
836  return te::da::CASCADE;
837  }
838  else if(action == "SET NULL")
839  {
840  return te::da::SET_NULL;
841  }
842  else //if(action == "SET DEFAULT")
843  {
844  return te::da::SET_DEFAULT;
845  }
846 }
847 
849 {
850  std::string sql = p->getName();
851 
852  sql += " ";
853 
854  sql += GetSQLType(p);
855 
856  const te::dt::SimpleProperty* sp = static_cast<const te::dt::SimpleProperty*>(p);
857 
858  if(sp->isRequired())
859  sql += " NOT NULL";
860 
861  if(p->getParent())
862  {
863  const te::da::DataSetType* dt = static_cast<const te::da::DataSetType*>(p->getParent());
864 
865  if(dt->getPrimaryKey() && (dt->getPrimaryKey()->getProperties().size() == 1) && dt->getPrimaryKey()->has(p))
866  {
867  sql += " PRIMARY KEY";
868  }
869  }
870 
871  return sql;
872 }
873 
875 {
876  std::string valueNames("(");
877 
878  const std::size_t np = dataset->getNumProperties();
879 
880  for(std::size_t i = 0; i != np; ++i)
881  {
882  if(i != 0)
883  valueNames += ",";
884 
885  valueNames += "?";
886  }
887 
888  valueNames += ")";
889 
890  return valueNames;
891 }
892 
std::streamsize ReadLine(std::istream &istr, char **pbuff, std::size_t &buffsize)
Definition: Utils.cpp:277
bool isRequired() const
It returns true if the attribute is required, otherwise it returns false.
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
FKActionType
Type of action performed on the foreign key data.
Definition: Enums.h:93
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
An atomic property like an integer or double.
The type for date and time types: date, date period, date duration, time duration, time instant, time period, time instant with time zone or time period with time zone.
void Convert2SpatiaLiteGeom(const te::gm::GeomType t, std::string &geomType, std::string &dimension)
Definition: Utils.cpp:623
The type for string types: FIXED_STRING, VAR_STRING or STRING.
te::da::FKActionType GetAction(const std::string &action)
Definition: Utils.cpp:824
Implements the DataSource class for the SQLite Data Access Driver.
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
void add(Constraint *c)
It adds a new constraint.
SpatialRelation
Spatial relations between geometric objects.
Definition: Enums.h:122
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
Definition: PrimaryKey.h:109
static bool isGeomType(const std::string &stype)
It tells if the given string is a geometry data type.
Definition: Geometry.cpp:553
void PerformCommands(sqlite3 *db, std::istream &istr)
Definition: Utils.cpp:161
int Convert2TerraLibCategory(const std::string &category)
Definition: Utils.cpp:522
void ExecuteScript(sqlite3 *db, const char *fileName)
Definition: Utils.cpp:139
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
bool Exists(const std::map< std::string, std::string > &dbInfo)
Definition: Utils.cpp:101
bool IsAllWhitespace(const char *sqlLine)
Definition: Utils.cpp:304
bool IsCommandTerminator(const char *sqlLine)
Definition: Utils.cpp:345
virtual const std::map< std::string, std::string > & getConnectionInfo() const =0
It returns the set of parameters used to set up the access channel to the underlying repository...
std::string Convert2SQLCreate(const te::dt::Property *p)
Definition: Utils.cpp:848
std::string GetBindableSpatialRelation(const std::string &colName, const te::gm::SpatialRelation r)
Definition: Utils.cpp:574
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
Property * getParent() const
It returns the parent of this property, or NULL, if it doesn&#39;t have one.
Definition: Property.h:150
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
Utility functions for the TerraLib SQLite Data Access driver.
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:216
#define TR_COMMON(message)
It marks a string in order to get translated. This is the mark used in the Common module of TerraLib...
Definition: Config.h:173
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:116
te::da::DataSetType * Convert2TerraLib(sqlite3_stmt *pStmt)
Definition: Utils.cpp:433
A class that models the description of a dataset.
Definition: DataSetType.h:72
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
Definition: Utils.cpp:54
void GetHiddenTables(const te::da::DataSource *ds, std::vector< std::string > &tables)
Definition: Utils.cpp:392
#define TE_SQLITE_BUFFER_SCRIPT_SIZE
This is the default buffer size allocated when reading an SQL script (Warning: this must be a value g...
Definition: Config.h:36
std::string GetRtreeFilter(const te::gm::Envelope *e, const te::gm::SpatialRelation r)
Definition: Utils.cpp:536
Configuration flags for the SQLite Data Access driver.
It models a property definition.
Definition: Property.h:59
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
bool ContainsSemicolon(const char *sql, std::size_t nbytes)
Definition: Utils.cpp:359
int GetConnectionFlags(const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:63
The type for arbitrary precison numbers, like numeric(p, q).
int getType() const
It returns the property data type.
Definition: Property.h:143
struct sqlite3 sqlite3
bool has(const te::dt::Property *p) const
It verifies if Property is associated to the primary key.
Definition: PrimaryKey.cpp:66
std::string GetSQLType(const te::dt::Property *p)
Definition: Utils.cpp:769
PrimaryKey * getPrimaryKey() const
It returns the primary key associated to the dataset type.
Definition: DataSetType.h:214
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
Geometric property.
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
bool IsComplete(char **sql, size_t len, std::size_t &buffsize)
Definition: Utils.cpp:368
struct sqlite3_stmt sqlite3_stmt
Definition: FwDataSet.h:35
std::string GetSQLBindValues(const te::da::DataSet *dataset)
Definition: Utils.cpp:874