All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Utils.cpp
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/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 
Configuration flags for the SQLite Data Access driver.
std::string GetRtreeFilter(const te::gm::Envelope *e, const te::gm::SpatialRelation r)
Definition: Utils.cpp:536
Geometric property.
void Convert2SpatiaLiteGeom(const te::gm::GeomType t, std::string &geomType, std::string &dimension)
Definition: Utils.cpp:623
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
struct sqlite3 sqlite3
An atomic property like an integer or double.
A class that models the description of a dataset.
Definition: DataSetType.h:72
FKActionType
Type of action performed on the foreign key data.
Definition: Enums.h:93
void GetHiddenTables(const te::da::DataSource *ds, std::vector< std::string > &tables)
Definition: Utils.cpp:392
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
PrimaryKey * getPrimaryKey() const
It returns the primary key associated to the dataset type.
Definition: DataSetType.h:214
bool has(const te::dt::Property *p) const
It verifies if Property is associated to the primary key.
Definition: PrimaryKey.cpp:66
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
SpatialRelation
Spatial relations between geometric objects.
Definition: Enums.h:122
std::string Convert2SQLCreate(const te::dt::Property *p)
Definition: Utils.cpp:848
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:118
It models a property definition.
Definition: Property.h:59
bool IsCommandTerminator(const char *sqlLine)
Definition: Utils.cpp:345
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
Definition: PrimaryKey.h:109
bool IsComplete(char **sql, size_t len, std::size_t &buffsize)
Definition: Utils.cpp:368
The type for arbitrary precison numbers, like numeric(p, q).
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
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
#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
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
Definition: Utils.cpp:55
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
bool IsAllWhitespace(const char *sqlLine)
Definition: Utils.cpp:304
std::string GetSQLType(const te::dt::Property *p)
Definition: Utils.cpp:769
void PerformCommands(sqlite3 *db, std::istream &istr)
Definition: Utils.cpp:161
bool isRequired() const
It returns true if the attribute is required, otherwise it returns false.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
Property * getParent() const
It returns the parent of this property, or NULL, if it doesn't have one.
Definition: Property.h:168
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
Utility functions for the TerraLib SQLite Data Access driver.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
std::string GetBindableSpatialRelation(const std::string &colName, const te::gm::SpatialRelation r)
Definition: Utils.cpp:574
int getType() const
It returns the property data type.
Definition: Property.h:161
void add(Constraint *c)
It adds a new constraint.
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
std::streamsize ReadLine(std::istream &istr, char **pbuff, std::size_t &buffsize)
Definition: Utils.cpp:277
static bool isGeomType(const std::string &stype)
It tells if the given string is a geometry data type.
Definition: Geometry.cpp:643
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
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.
Implements the DataSource class for the SQLite Data Access Driver.
void ExecuteScript(sqlite3 *db, const char *fileName)
Definition: Utils.cpp:139
struct sqlite3_stmt sqlite3_stmt
Definition: FwDataSet.h:35
std::string GetSQLBindValues(const te::da::DataSet *dataset)
Definition: Utils.cpp:874
bool ContainsSemicolon(const char *sql, std::size_t nbytes)
Definition: Utils.cpp:359
bool Exists(const std::map< std::string, std::string > &dbInfo)
Definition: Utils.cpp:101
te::da::DataSetType * Convert2TerraLib(sqlite3_stmt *pStmt)
Definition: Utils.cpp:433
te::da::FKActionType GetAction(const std::string &action)
Definition: Utils.cpp:824
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...
int Convert2TerraLibCategory(const std::string &category)
Definition: Utils.cpp:522
const std::string & getName() const
It returns the property name.
Definition: Property.h:127
int GetConnectionFlags(const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:63