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"
51 #include <boost/algorithm/string/case_conv.hpp>
52 #include <boost/format.hpp>
53 #include <boost/lexical_cast.hpp>
58 #ifdef TE_ENABLE_SPATIALITE
60 #include <spatialite/gaiageo.h>
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;
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;
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;
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;
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;
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;
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;
106 flags = SQLITE_OPEN_READONLY;
110 std::string fileName;
113 std::map<std::string, std::string>::const_iterator it = dbInfo.find(
"SQLITE_FILE");
115 if(it != dbInfo.end())
116 fileName = it->second;
118 throw te::da::Exception(TR_COMMON(
"To check the existence of an SQLite database you must inform its file name or URI!"));
124 std::map<std::string, std::string>::const_iterator it = dbInfo.find(
"SQLITE_VFS");
126 if(it != dbInfo.end())
132 int ret = sqlite3_open_v2(fileName.c_str(), &db, flags, vfs.empty() ? 0 : vfs.c_str());
136 return (ret == SQLITE_OK);
143 istr.open(fileName, std::ios_base::in);
146 throw te::da::Exception((boost::format(TR_COMMON(
"Could not open file: %1%.")) % fileName).str());
168 size_t priorOffset = 0;
172 std::streamsize readbytes =
ReadLine(istr, &buff, buffsize);
181 memcpy(buff,
";", 2);
183 std::size_t lineLen = strlen(buff);
185 if((lineLen + 2) > (sqlSize - offset))
187 sql = (
char*)realloc(sql, sqlSize + buffsize);
188 sqlSize = sqlSize + buffsize;
192 sql[offset++] =
'\n';
194 memcpy(&sql[offset], buff, lineLen + 1);
195 priorOffset = offset;
198 if(offset &&
ContainsSemicolon(sql + priorOffset, lineLen) && sqlite3_complete(sql))
203 priorOffset = offset = 0;
217 boost::format errmsg(TR_COMMON(
"Error! incomplete SQL: %1%"));
219 errmsg = errmsg % sql;
224 throw te::da::Exception(errmsg.str());
236 const char* sqlLeftOver = 0;
238 while(sql[0] !=
'\0' && rc == SQLITE_OK)
240 rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, &sqlLeftOver);
243 throw te::da::Exception((boost::format(TR_COMMON(
"Error preparing the SQL statement. The follwoing error has occurried: %1%.")) % sqlite3_errmsg(db)).str());
249 while(isspace(sql[0]))
255 rc = sqlite3_step(pStmt);
257 sqlite3_finalize(pStmt);
259 if(rc != SQLITE_ROW && rc != SQLITE_OK && rc != SQLITE_DONE)
261 std::string errmsg = TR_COMMON(
"Error processing the SQL statement. The follwoing error has occurried: ");
262 errmsg += sqlite3_errmsg(db);
270 while(isspace(sql[0]))
279 std::streamsize readbytes = 0;
285 istr.getline(buff + readbytes, static_cast<std::streamsize>(buffsize - readbytes));
287 if(istr.flags() & std::ios::failbit)
290 buff = (
char*)realloc(buff, buffsize);
292 readbytes += istr.gcount();
296 readbytes = istr.gcount();
306 for(; *sqlLine; ++sqlLine)
308 if(isspace(*(
unsigned char*)sqlLine))
311 if((*sqlLine ==
'/') && (sqlLine[1] ==
'*'))
315 while(*sqlLine && ((*sqlLine !=
'*') || (sqlLine[1] !=
'/')))
326 if((*sqlLine ==
'-') && (sqlLine[1] ==
'-'))
330 while(*sqlLine && (*sqlLine !=
'\n'))
347 while(isspace(*(
unsigned char*)sqlLine))
353 if(tolower((sqlLine[0]) ==
'g') && (tolower(sqlLine[1]) ==
'o') &&
IsAllWhitespace(&sqlLine[2]))
361 for(std::size_t i = 0; i < nbytes; ++i)
375 if(len + 2 > buffsize)
378 psql = (
char*)realloc(psql, buffsize);
385 int rc = sqlite3_complete(psql);
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();
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");
425 it = connInfo.find(
"SQLITE_HIDE_TABLES");
427 if((it != itend) && (it->second.empty() ==
false))
437 const int ncols = sqlite3_column_count(pStmt);
439 for(
int i = 0; i < ncols; ++i)
441 const char* t = sqlite3_column_decltype(pStmt, i);
442 const char* name = sqlite3_column_name(pStmt, i);
453 const std::string& colName,
454 const std::string& colType,
456 std::string* defaultValue)
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"))
474 else if((uColType ==
"FLOAT") ||
475 (uColType ==
"DOUBLE") ||
476 (uColType ==
"REAL") ||
477 (uColType ==
"DOUBLE PRECISION"))
481 else if((uColType ==
"NUMERIC") ||
482 (uColType.substr(0, 7) ==
"DECIMAL"))
486 else if((uColType ==
"TEXT") ||
487 (uColType ==
"CLOB") ||
488 (uColType.substr(0, 4) ==
"CHAR") ||
489 (uColType.substr(0, 7) ==
"VARCHAR"))
493 else if(uColType ==
"BLOB")
501 else if(uColType ==
"DATE")
505 else if(uColType ==
"DATETIME")
509 else if((uColType ==
"BOOL") ||
510 (uColType ==
"BOOLEAN"))
524 if(category ==
"table")
526 else if(category ==
"view")
528 else if(category ==
"index")
530 else if(category ==
"trigger")
547 filter =
"RTreeIntersects(";
551 filter =
"RTreeWithin(";
555 filter =
"RTreeContains(";
562 filter += boost::lexical_cast<std::string>(e->
m_llx);
564 filter += boost::lexical_cast<std::string>(e->
m_lly);
566 filter += boost::lexical_cast<std::string>(e->
m_urx);
568 filter += boost::lexical_cast<std::string>(e->
m_ury);
581 filter =
"Intersects(";
589 filter =
"Contains(";
601 filter =
"Overlaps(";
609 filter =
"Disjoint(";
640 geomType =
"POINTZM";
644 geomType =
"LINESTRING";
648 geomType =
"LINESTRINGZ";
652 geomType =
"LINESTRINGM";
656 geomType =
"LINESTRINGZM";
660 geomType =
"POLYGON";
664 geomType =
"POLYGONZ";
668 geomType =
"POLYGONM";
672 geomType =
"POLYGONZM";
676 geomType =
"MULTIPOINT";
680 geomType =
"MULTIPOINTZ";
684 geomType =
"MULTIPOINTM";
688 geomType =
"MULTIPOINTZM";
692 geomType =
"MULTILINESTRING";
696 geomType =
"MULTILINESTRINGZ";
700 geomType =
"MULTILINESTRINGM";
704 geomType =
"MULTILINESTRINGZM";
708 geomType =
"MULTIPOLYGON";
712 geomType =
"MULTIPOLYGONZ";
716 geomType =
"MULTIPOLYGONM";
720 geomType =
"MULTIPOLYGONZM";
724 geomType =
"GEOMETRYCOLLECTION";
728 geomType =
"GEOMETRYCOLLECTIONZ";
732 geomType =
"GEOMETRYCOLLECTIONM";
736 geomType =
"GEOMETRYCOLLECTIONZM";
740 geomType =
"GEOMETRY";
744 geomType =
"GEOMETRYZ";
748 geomType =
"GEOMETRYM";
752 geomType =
"GEOMETRYZM";
759 if((t & 0xF00) == 0xB00)
761 else if((t & 0x0F00) == 0x300)
763 else if((t & 0xF00) == 0x700)
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());
826 if(action ==
"NO ACTION")
830 else if(action ==
"RESTRICT")
834 else if(action ==
"CASCADE")
838 else if(action ==
"SET NULL")
850 std::string sql = p->
getName();
867 sql +=
" PRIMARY KEY";
876 std::string valueNames(
"(");
880 for(std::size_t i = 0; i != np; ++i)
Configuration flags for the SQLite Data Access driver.
std::string GetRtreeFilter(const te::gm::Envelope *e, const te::gm::SpatialRelation r)
void Convert2SpatiaLiteGeom(const te::gm::GeomType t, std::string &geomType, std::string &dimension)
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
An atomic property like an integer or double.
A class that models the description of a dataset.
FKActionType
Type of action performed on the foreign key data.
void GetHiddenTables(const te::da::DataSource *ds, std::vector< std::string > &tables)
double m_urx
Upper right corner x-coordinate.
PrimaryKey * getPrimaryKey() const
It returns the primary key associated to the dataset type.
bool has(const te::dt::Property *p) const
It verifies if Property is associated to the primary key.
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
SpatialRelation
Spatial relations between geometric objects.
std::string Convert2SQLCreate(const te::dt::Property *p)
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
It models a property definition.
bool IsCommandTerminator(const char *sqlLine)
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
bool IsComplete(char **sql, size_t len, std::size_t &buffsize)
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.
double m_llx
Lower left corner x-coordinate.
An Envelope defines a 2D rectangular region.
#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...
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
bool IsAllWhitespace(const char *sqlLine)
std::string GetSQLType(const te::dt::Property *p)
void PerformCommands(sqlite3 *db, std::istream &istr)
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.
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. ...
double m_lly
Lower left corner y-coordinate.
std::string GetBindableSpatialRelation(const std::string &colName, const te::gm::SpatialRelation r)
int getType() const
It returns the property data type.
void add(Constraint *c)
It adds a new constraint.
A dataset is the unit of information manipulated by the data access module of TerraLib.
std::streamsize ReadLine(std::istream &istr, char **pbuff, std::size_t &buffsize)
static bool isGeomType(const std::string &stype)
It tells if the given string is a geometry data type.
double m_ury
Upper right corner y-coordinate.
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)
struct sqlite3_stmt sqlite3_stmt
std::string GetSQLBindValues(const te::da::DataSet *dataset)
bool ContainsSemicolon(const char *sql, std::size_t nbytes)
bool Exists(const std::map< std::string, std::string > &dbInfo)
te::da::DataSetType * Convert2TerraLib(sqlite3_stmt *pStmt)
te::da::FKActionType GetAction(const std::string &action)
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)
const std::string & getName() const
It returns the property name.
int GetConnectionFlags(const std::map< std::string, std::string > &connInfo)