00001 #include "TeSQLite.h"
00002 #include <TeDatabase.h>
00003
00004 #include "sqlite3/sqlite3.h"
00005 #include <TeWKBGeometryDecoder.h>
00006
00007 #include <string.h>
00008
00009 TeSQLite::TeSQLite()
00010 : TeDatabase()
00011 , _conn(0)
00012 , _transactionCounter(0)
00013 {
00014 sqlite3_initialize();
00015 dbmsName_ = "SQLite";
00016 }
00017
00018 TeSQLite::~TeSQLite()
00019 {
00020 close();
00021
00022 sqlite3_shutdown();
00023 }
00024
00025 bool TeSQLite::newDatabase(const string& database, const string& user, const string& password, const string& host, const int &port, bool terralibModel, const std::string& characterSet)
00026 {
00027 close();
00028
00029 errorMessage_ = "";
00030
00031 FILE* file = fopen(database.c_str(), "r");
00032 if(file != 0)
00033 {
00034 fclose(file);
00035 errorMessage_ = "Database already exists";
00036 return false;
00037 }
00038
00039 int retVal = sqlite3_open_v2(database.c_str(), &_conn, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
00040 if(retVal != SQLITE_OK)
00041 {
00042 close();
00043 return false;
00044 }
00045
00046 if(!connect(host, user, password, database, port))
00047 {
00048 return false;
00049 }
00050
00051 if(terralibModel)
00052 {
00053
00054 if(!createConceptualModel())
00055 {
00056 close();
00057 return false;
00058 }
00059 }
00060
00061 return true;
00062 }
00063
00064 bool TeSQLite::connect(const string& host, const string& user, const string& password, const string& database, int port)
00065 {
00066 errorMessage_ = "";
00067
00068 FILE* file = fopen(database.c_str(), "r");
00069 if(file == 0)
00070 {
00071 errorMessage_ = "Database does not exist!";
00072 return false;
00073 }
00074 fclose(file);
00075
00076 close();
00077
00078 int retVal = sqlite3_open_v2(database.c_str(), &_conn, SQLITE_OPEN_READWRITE, 0);
00079 if(retVal != SQLITE_OK)
00080 {
00081 close();
00082 return false;
00083 }
00084
00085 execute("PRAGMA foreign_keys = ON;");
00086
00087 isConnected_ = true;
00088 user_ = user;
00089 host_ = host;
00090 password_ = password;
00091 database_ = database;
00092 portNumber_ = port;
00093
00094 return true;
00095 }
00096
00097 void TeSQLite::close()
00098 {
00099 errorMessage_ = "";
00100 if(_conn != 0)
00101 {
00102 int result = sqlite3_close(_conn);
00103 if(result != SQLITE_OK)
00104 {
00105 int a = 0;
00106 }
00107 _conn = 0;
00108 }
00109 isConnected_ = false;
00110 }
00111
00112 bool TeSQLite::tableExist(const string& table)
00113 {
00114 std::string sql = "SELECT tbl_name FROM sqlite_master";
00115 sql += " WHERE upper(tbl_name) = upper('" + table + "')";
00116 sql += " AND type = 'table'";
00117
00118 bool exists = false;
00119
00120 TeDatabasePortal* portal = getPortal();
00121 if(portal->query(sql) && portal->fetchRow())
00122 {
00123 exists = true;
00124 }
00125
00126 delete portal;
00127
00128 return exists;
00129 }
00130
00131 bool TeSQLite::columnExist(const string& table, const string& column, TeAttribute& attr)
00132 {
00133 return true;
00134 }
00135
00136 bool TeSQLite::createTable(const string& table, TeAttributeList &attr)
00137 {
00138 errorMessage_ = "";
00139
00140 bool first = true;
00141
00142 TeAttributeList::iterator it = attr.begin();
00143
00144 string createTable ="CREATE TABLE " + table +" (";
00145
00146 string type;
00147
00148 string pkeys;
00149
00150 while(it != attr.end())
00151 {
00152 switch ((*it).rep_.type_)
00153 {
00154 case TeSTRING: type = "TEXT";
00155 break;
00156
00157 case TeREAL: type = "REAL";
00158 break;
00159
00160 case TeINT:
00161 case TeUNSIGNEDINT:
00162 type = "INTEGER";
00163 break;
00164
00165 case TeBLOB:
00166 type = "BLOB";
00167 break;
00168
00169 case TeDATETIME: type = "NUMERIC";
00170 break;
00171
00172 case TeCHARACTER: type = "TEXT";
00173 break;
00174
00175 case TeBOOLEAN: type = "NUMERIC";
00176 break;
00177
00178 case TePOINTTYPE:
00179 case TePOINTSETTYPE:
00180 if(!first)
00181 createTable += ", ";
00182 else
00183 first = false;
00184
00185 createTable += " x REAL DEFAULT 0.0,";
00186 createTable += " y REAL DEFAULT 0.0 ";
00187 ++it;
00188 continue;
00189
00190 case TeLINE2DTYPE:
00191 case TeLINESETTYPE:
00192 if(!first)
00193 createTable += ", ";
00194 else
00195 first = false;
00196
00197 createTable += "lower_x REAL not null ,";
00198 createTable += "lower_y REAL not null ,";
00199 createTable += "upper_x REAL not null ,";
00200 createTable += "upper_y REAL not null ,";
00201 createTable += "spatial_data BLOB not null ";
00202 ++it;
00203 continue;
00204
00205 case TePOLYGONTYPE:
00206 case TePOLYGONSETTYPE:
00207 if(!first)
00208 createTable += ", ";
00209 else
00210 first = false;
00211
00212 createTable += "lower_x REAL not null ,";
00213 createTable += "lower_y REAL not null ,";
00214 createTable += "upper_x REAL not null ,";
00215 createTable += "upper_y REAL not null ,";
00216 createTable += "spatial_data BLOB not null ";
00217
00218 ++it;
00219 continue;
00220
00221 case TeCELLTYPE:
00222 case TeCELLSETTYPE:
00223 if(!first)
00224 createTable += ", ";
00225 else
00226 first = false;
00227
00228 createTable += "lower_x REAL not null ,";
00229 createTable += "lower_y REAL not null ,";
00230 createTable += "upper_x REAL not null ,";
00231 createTable += "upper_y REAL not null ,";
00232 createTable += " col_number INTEGER NOT NULL,";
00233 createTable += " row_number INTEGER NOT NULL ";
00234 ++it;
00235 continue;
00236
00237 case TeRASTERTYPE:
00238 if(!first)
00239 createTable += ", ";
00240 else
00241 first = false;
00242
00243 createTable += "lower_x REAL not null ,";
00244 createTable += "lower_y REAL not null ,";
00245 createTable += "upper_x REAL not null ,";
00246 createTable += "upper_y REAL not null ,";
00247 createTable += "band_id integer unsigned not null, ";
00248 createTable += "resolution_factor integer unsigned , ";
00249 createTable += "subband integer unsigned,";
00250 createTable += "spatial_data BLOB NOT NULL, ";
00251 createTable += "block_size integer unsigned not null ";
00252 ++it;
00253 continue;
00254
00255 case TeNODETYPE:
00256 case TeNODESETTYPE:
00257 if(!first)
00258 createTable += ", ";
00259 else
00260 first = false;
00261
00262 createTable += " x REAL DEFAULT 0.0,";
00263 createTable += " y REAL DEFAULT 0.0 ";
00264 ++it;
00265 continue;
00266
00267 case TeTEXTTYPE:
00268 case TeTEXTSETTYPE:
00269
00270 default: type += "TEXT";
00271 break;
00272 }
00273
00274 if(!((*it).rep_.defaultValue_.empty()))
00275 type += " DEFAULT '" + (*it).rep_.defaultValue_ + "' ";
00276
00277 if(!((*it).rep_.null_))
00278 type += " NOT NULL ";
00279
00280 if(!first)
00281 createTable += ", ";
00282 else
00283 first = false;
00284
00285 createTable += (*it).rep_.name_ + " ";
00286 createTable += type;
00287
00288
00289 if((*it).rep_.isPrimaryKey_ && (*it).rep_.type_ != TeBLOB )
00290 {
00291 if(!pkeys.empty())
00292 pkeys += ", ";
00293
00294 pkeys += (*it).rep_.name_;
00295 }
00296
00297 ++it;
00298 }
00299
00300 if(!pkeys.empty())
00301 { string pk = ", PRIMARY KEY(";
00302 pk += pkeys;
00303 pk += ")";
00304
00305 createTable += pk;
00306 }
00307
00308 createTable += ");";
00309
00310 return execute(createTable);
00311 }
00312
00313 bool TeSQLite::addColumn(const string& table, TeAttributeRep &rep)
00314 {
00315 return true;
00316 }
00317
00318 bool TeSQLite::alterTable(const string& tableName, TeAttributeRep& rep, const string& oldColName)
00319 {
00320 return true;
00321 }
00322
00323 bool TeSQLite::alterTable(const string& oldTableName, const string& newTablename)
00324 {
00325 return true;
00326 }
00327
00328 bool TeSQLite::getIndexesFromTable(const string& tableName, std::vector<TeDatabaseIndex>& vecIndexes)
00329 {
00330 TeDatabasePortal* portal = getPortal();
00331
00332 std::string sqlIndexes = "PRAGMA index_list(" + tableName + ");";
00333 if(portal->query(sqlIndexes) == false)
00334 {
00335 delete portal;
00336 return false;
00337 }
00338
00339 while(portal->fetchRow())
00340 {
00341 TeDatabaseIndex dbIndex;
00342 dbIndex.setIndexName(portal->getData("name"));
00343
00344 vecIndexes.push_back(dbIndex);
00345 }
00346
00347 portal->freeResult();
00348
00349 for(unsigned int i = 0; i < vecIndexes.size(); ++i)
00350 {
00351 std::string sqlIndex = "PRAGMA index_info(" + vecIndexes[i].getIndexName() + ");";
00352
00353 if(portal->query(sqlIndex) == false)
00354 {
00355 delete portal;
00356 return false;
00357 }
00358
00359 std::vector<std::string> vecColumns;
00360 while(portal->fetchRow())
00361 {
00362 vecColumns.push_back(portal->getData("name"));
00363 }
00364 portal->freeResult();
00365
00366 vecIndexes[i].setColumns(vecColumns);
00367 }
00368
00369 delete portal;
00370
00371 return true;
00372 }
00373
00374 bool TeSQLite::createRelation(const string& relName, const string& table, const string& fieldName, const string& relatedTable, const string& relatedField, bool cascadeDeletion)
00375 {
00376 return true;
00377 }
00378
00379 TeDBRelationType TeSQLite::existRelation(const string& tableName, const string& relName)
00380 {
00381 return TeNoRelation;
00382 }
00383
00384 bool TeSQLite::getAttributeList(const string& tableName,TeAttributeList& attList)
00385 {
00386 if(!tableExist(tableName))
00387 {
00388 return false;
00389 }
00390
00391 TeDatabasePortal* portal = this->getPortal();
00392 if (!portal)
00393 return false;
00394
00395 string sql = "PRAGMA table_info(" + tableName + ")";
00396 if (!portal->query(sql))
00397 {
00398 delete portal;
00399 return false;
00400 }
00401
00402 while(portal->fetchRow())
00403 {
00404 TeAttribute attr;
00405 attr.rep_.name_ = portal->getData("name");
00406 attr.rep_.isPrimaryKey_ = portal->getBool("pk");
00407 attr.rep_.null_ = !portal->getBool("notnull");
00408 attr.rep_.defaultValue_ = portal->getData("dflt_value");
00409
00410 std::string type = portal->getData("type");
00411 if(type == "TEXT")
00412 {
00413 attr.rep_.type_ = TeSTRING;
00414 }
00415 else if(type == "INTEGER")
00416 {
00417 attr.rep_.type_ = TeINT;
00418 }
00419 else if(type == "REAL")
00420 {
00421 attr.rep_.type_ = TeREAL;
00422 }
00423 else if(type == "BLOB")
00424 {
00425 attr.rep_.type_ = TeBLOB;
00426 }
00427 else
00428 {
00429 attr.rep_.type_ = TeSTRING;
00430 }
00431
00432 attList.push_back(attr);
00433 }
00434
00435 delete portal;
00436
00437 return true;
00438 }
00439
00440 int TeSQLite::getLastInsertedSerial()
00441 {
00442 return sqlite3_last_insert_rowid(_conn);
00443 }
00444
00445 int getMaxValue(TeDatabase* database, const std::string& tableName, const std::string& intColumnName)
00446 {
00447 TeDatabasePortal* portal = database->getPortal();
00448
00449 std::string sql = "SELECT MAX(" + intColumnName + ") FROM " + tableName;
00450
00451 int maxVal = 0;
00452 if(portal->query(sql) && portal->fetchRow())
00453 {
00454 maxVal = portal->getInt(0);
00455 }
00456
00457 delete portal;
00458
00459 return maxVal;
00460 }
00461
00462 bool TeSQLite::insertProject(TeProject *project)
00463 {
00464 errorMessage_ = "";
00465
00466 if (!project)
00467 return false;
00468
00469 string sql = "INSERT INTO te_project (name, description, current_view) VALUES(";
00470 sql += " '";
00471 sql += project->name();
00472 sql += "', '";
00473 sql += project->description();
00474 sql += "', ";
00475 sql += Te2String(project->getCurrentViewId());
00476 sql += ")";
00477
00478 if(this->execute(sql))
00479 {
00480
00481 int newId = getLastInsertedSerial();
00482 if(newId >= 0)
00483 {
00484 project->setId(newId);
00485 }
00486 }
00487 else
00488 return false;
00489 projectMap()[project->id()] = project;
00490 for (unsigned int i=0; i<project->getViewVector().size(); i++)
00491 insertProjectViewRel(project->id(), project->getViewVector()[i]);
00492 return true;
00493 }
00494
00495 bool TeSQLite::insertRelationInfo(const int tableId, const string& tField, const string& rTable, const string& rField, int& relId)
00496 {
00497 if(tableId < 0)
00498 {
00499 return false;
00500 }
00501
00502 TeDatabasePortal* portal = this->getPortal();
00503
00504 if(!portal)
00505 return false;
00506
00507 relId = -1;
00508
00509 string sel = "SELECT relation_id FROM te_tables_relation WHERE";
00510 sel += " related_table_id = " + Te2String(tableId);
00511 sel += " AND related_attr = '" + tField + "'";
00512 sel += " AND external_table_name = '" + rTable + "'";
00513 sel += " AND external_attr = '" + rField + "'";
00514
00515 if(!portal->query(sel))
00516 {
00517 delete portal;
00518 return false;
00519 }
00520
00521 if(portal->fetchRow())
00522 {
00523 relId = atoi(portal->getData("relation_id"));
00524 delete portal;
00525 return true;
00526 }
00527
00528 delete portal;
00529
00530 string sql = "INSERT INTO te_tables_relation (related_table_id, related_attr, external_table_name, external_attr) VALUES(";
00531 sql += Te2String(tableId);
00532 sql += ", '";
00533 sql += tField;
00534 sql += "', '";
00535 sql += rTable;
00536 sql += "', '";
00537 sql += rField;
00538 sql += "')";
00539
00540 if(this->execute(sql))
00541 {
00542
00543 int newId = getLastInsertedSerial();
00544 if(newId >= 0)
00545 {
00546 relId = newId;
00547 }
00548 }
00549 else
00550 return false;
00551
00552 return true;
00553 }
00554
00555 bool TeSQLite::insertTableInfo(int layerId, TeTable &table, const string& user)
00556 {
00557 errorMessage_ = "";
00558
00559 if(table.name().empty())
00560 return false;
00561
00562 if(table.id() <= 0)
00563 {
00564 string sql = "INSERT INTO te_layer_table (";
00565
00566 if(layerId > 0)
00567 {
00568 sql += "layer_id, ";
00569 }
00570
00571 sql += "attr_table, unique_id, attr_link, attr_initial_time, attr_final_time, ";
00572 sql += "attr_time_unit, attr_table_type, user_name) VALUES(";
00573
00574 if(layerId > 0)
00575 {
00576 sql += Te2String(layerId) + ", ";
00577 }
00578
00579 sql += "'" + table.name();
00580 sql += "', '" + table.uniqueName();
00581 sql += "', '";
00582 sql += table.linkName();
00583 sql += "', '";
00584 sql += table.attInitialTime();
00585 sql += "', '";
00586 sql += table.attFinalTime();
00587 sql += "', ";
00588 sql += Te2String(table.attTimeUnit());
00589 sql += ", ";
00590 sql += Te2String(table.tableType());
00591 sql += ", '";
00592 sql += user;
00593 sql += "')";
00594
00595 if(this->execute(sql))
00596 {
00597
00598 int newId = getLastInsertedSerial();
00599 if(newId >= 0)
00600 {
00601 table.setId(newId);
00602 }
00603 }
00604 else
00605 return false;
00606 }
00607
00608 return true;
00609 }
00610
00611 bool TeSQLite::insertBlob(const string& tableName, const string& columnBlob, const string& whereClause, unsigned char* data, int size)
00612 {
00613 return true;
00614 }
00615
00616 bool TeSQLite::insertProjection(TeProjection* proj)
00617 {
00618 errorMessage_ = "";
00619
00620 TeProjectionParams par = proj->params();
00621
00622 string sql = "INSERT INTO te_projection (name, long0, lat0, offx, ";
00623 sql += "offy, stlat1, stlat2, unit, scale, ";
00624 sql += "hemis, datum)";
00625 sql += " VALUES('";
00626 sql += proj->name();
00627 sql += "', ";
00628 sql += Te2String(par.lon0*TeCRD, 15);
00629 sql += ", ";
00630 sql += Te2String(par.lat0*TeCRD, 15);
00631 sql += ", ";
00632 sql += Te2String(par.offx, 15);
00633 sql += ", ";
00634 sql += Te2String(par.offy, 15);
00635 sql += ", ";
00636 sql += Te2String(par.stlat1*TeCRD, 15);
00637 sql += ", ";
00638 sql += Te2String(par.stlat2*TeCRD, 15);
00639 sql += ", '";
00640 sql += par.units;
00641 sql += "', ";
00642 sql += Te2String(par.scale, 15);
00643 sql += ", ";
00644 sql += Te2String(par.hemisphere);
00645 sql += ", '";
00646 sql += proj->datum().name();
00647 sql += "')";
00648
00649 if(this->execute(sql))
00650 {
00651
00652 int newId = getLastInsertedSerial();
00653 if(newId >= 0)
00654 {
00655 proj->id(newId);
00656 }
00657 }
00658 else
00659 return false;
00660
00661 int srsid = proj->epsgCode();
00662 return insertSRSId(proj, srsid);
00663 }
00664
00665 bool TeSQLite::insertLayer(TeLayer* layer)
00666 {
00667 errorMessage_ = "";
00668
00669 TeProjection* proj = layer->projection();
00670 if (!proj || !insertProjection(proj))
00671 {
00672 errorMessage_ = "Error inserting projection!";
00673 return false;
00674 }
00675
00676 string sql = "INSERT INTO te_layer (projection_id, name, lower_x, lower_y, upper_x, ";
00677 sql += "upper_y, edition_time) VALUES(";
00678 sql += Te2String(proj->id());
00679 sql += ", '";
00680 sql += layer->name();
00681 sql += "', ";
00682 sql += Te2String(layer->box().x1(), 15);
00683 sql += ", ";
00684 sql += Te2String(layer->box().y1(), 15);
00685 sql += ", ";
00686 sql += Te2String(layer->box().x2(), 15);
00687 sql += ", ";
00688 sql += Te2String(layer->box().y2(), 15);
00689 sql += ", ";
00690 TeTime editionTime = layer->getEditionTime();
00691 sql += this->getSQLTime(editionTime);
00692 sql += ")";
00693
00694 if(this->execute(sql))
00695 {
00696
00697 int newId = getLastInsertedSerial();
00698 if(newId >= 0)
00699 {
00700 layer->id(newId);
00701 }
00702 }
00703 else
00704 return false;
00705
00706 layerMap()[layer->id()] = layer;
00707
00708 return true;
00709 }
00710
00711 bool TeSQLite::insertRepresentation(int layerId, TeRepresentation& rep)
00712 {
00713 errorMessage_ = "";
00714
00715 if(layerId <= 0)
00716 return false;
00717
00718
00719 string sql = "INSERT INTO te_representation (layer_id, geom_type, geom_table, description, lower_x, ";
00720 sql += "lower_y, upper_x, upper_y, res_x, res_y, num_cols, num_rows) VALUES(";
00721 sql += Te2String(layerId);
00722 sql += ", ";
00723 sql += Te2String(static_cast<long>(rep.geomRep_));
00724 sql += ", '";
00725 sql += rep.tableName_;
00726 sql += "', '";
00727 sql += rep.description_;
00728 sql += "', ";
00729 sql += Te2String(rep.box_.x1(), 15);
00730 sql += ", ";
00731 sql += Te2String(rep.box_.y1(), 15);
00732 sql += ", ";
00733 sql += Te2String(rep.box_.x2(), 15);
00734 sql += ", ";
00735 sql += Te2String(rep.box_.y2(), 15);
00736 sql += ", ";
00737 sql += Te2String(rep.resX_, 15);
00738 sql += ", ";
00739 sql += Te2String(rep.resY_, 15);
00740 sql += ", ";
00741 sql += Te2String(static_cast<long>(rep.nCols_));
00742 sql += ", ";
00743 sql += Te2String(static_cast<long>(rep.nLins_));
00744 sql += ")";
00745
00746 if(this->execute(sql))
00747 {
00748
00749 int newId = getLastInsertedSerial();
00750 if(newId >= 0)
00751 {
00752 rep.id_ = newId;
00753 }
00754 }
00755 else
00756 return false;
00757
00758 return true;
00759 }
00760
00761 bool TeSQLite::insertView(TeView *view)
00762 {
00763 errorMessage_ = "";
00764
00765
00766 TeProjection* proj = view->projection();
00767 if ( !proj || !insertProjection(proj))
00768 {
00769 errorMessage_ = "Error inserting projection";
00770 return false;
00771 }
00772
00773 string sql = "INSERT INTO te_view (projection_id, name, user_name, visibility, lower_x, lower_y, upper_x, upper_y, current_theme) VALUES(";
00774 sql += Te2String(proj->id());
00775 sql += ", '";
00776 sql += view->name();
00777 sql += "', '";
00778 sql += view->user();
00779 sql += "', ";
00780 sql += Te2String(view->isVisible()) + ", ";
00781 sql += Te2String(view->getCurrentBox().lowerLeft().x(),15) + ", ";
00782 sql += Te2String(view->getCurrentBox().lowerLeft().y(),15) + ", ";
00783 sql += Te2String(view->getCurrentBox().upperRight().x(),15) + ", ";
00784 sql += Te2String(view->getCurrentBox().upperRight().y(),15) + ", ";
00785 if(view->getCurrentTheme() == -1)
00786 sql += "null ";
00787 else
00788 sql += Te2String(view->getCurrentTheme());
00789 sql += ")";
00790
00791 if(this->execute(sql))
00792 {
00793
00794 int newId = getLastInsertedSerial();
00795 if(newId >= 0)
00796 {
00797 view->id(newId);
00798 }
00799 }
00800 else
00801 return false;
00802
00803 for(unsigned int th = 0; th < view->size(); ++th)
00804 {
00805 TeViewNode* node = view->get (th);
00806 if (node->type() == TeTHEME)
00807 {
00808 TeTheme *theme = (TeTheme*) node;
00809 insertTheme (theme);
00810 }
00811 else
00812 {
00813 TeViewTree* tree = (TeViewTree*)node;
00814 insertViewTree (tree);
00815 }
00816 }
00817
00818 viewMap()[view->id()] = view;
00819
00820 return true;
00821 }
00822
00823 bool TeSQLite::insertViewTree(TeViewTree *tree)
00824 {
00825 errorMessage_ = "";
00826
00827 string sql = "INSERT INTO te_theme (view_id, name, parent_id, priority, node_type) VALUES(";
00828
00829 sql += Te2String(tree->view());
00830 sql += ", '";
00831 sql += tree->name();
00832 sql += "', ";
00833 sql += Te2String(tree->parentId());
00834 sql += ", ";
00835 sql += Te2String(tree->priority());
00836 sql += ", ";
00837 sql += Te2String(tree->type());
00838
00839 sql += ")";
00840
00841 if(this->execute(sql))
00842 {
00843
00844 int newId = getLastInsertedSerial();
00845 if(newId >= 0)
00846 {
00847 tree->id(newId);
00848 }
00849 }
00850 else
00851 return false;
00852
00853 return true;
00854 }
00855
00856 bool TeSQLite::insertThemeGroup(TeViewTree* tree)
00857 {
00858 errorMessage_ = "";
00859
00860 string sql = "INSERT INTO te_theme (name, parent_id, node_type, view_id, priority) VALUES(";
00861 sql += "'";
00862 sql += tree->name();
00863 sql += "', 1, 1, ";
00864 sql += Te2String(tree->view());
00865 sql += ", ";
00866 sql += Te2String(tree->priority());
00867 sql += ")";
00868
00869 if(this->execute(sql))
00870 {
00871
00872 int newId = getLastInsertedSerial();
00873 if(newId >= 0)
00874 {
00875 tree->id(newId);
00876 }
00877 }
00878 else
00879 return false;
00880
00881 return true;
00882 }
00883
00884 bool
00885 TeSQLite::generateLabelPositions(TeTheme *theme, const std::string& objectId)
00886 {
00887 string geomTable, upd;
00888 string collTable = theme->collectionTable();
00889
00890 if((collTable.empty()) || (!tableExist(collTable)))
00891 return false;
00892
00893 if( theme->layer()->hasGeometry(TeCELLS) )
00894 {
00895 geomTable = theme->layer()->tableName(TeCELLS);
00896
00897 upd= "UPDATE " + collTable + " SET ";
00898 upd += " label_x = (SELECT MAX(lower_x + (upper_x - lower_x)/2) ";
00899 upd += "FROM " + geomTable + " WHERE object_id = c_object_id), ";
00900
00901 upd += " label_y = (SELECT MAX(lower_y + (upper_y - lower_y)/2) ";
00902 upd += "FROM " + geomTable + " WHERE object_id = c_object_id) ";
00903 upd += " WHERE label_x IS NULL OR label_y IS NULL";
00904 }
00905
00906 if( theme->layer()->hasGeometry(TePOLYGONS) )
00907 {
00908 geomTable = theme->layer()->tableName(TePOLYGONS);
00909
00910 upd= "UPDATE " + collTable + " SET ";
00911 upd += " label_x = (SELECT MAX(lower_x + (upper_x - lower_x)/2) ";
00912 upd += "FROM " + geomTable + " WHERE object_id = c_object_id), ";
00913
00914 upd += " label_y = (SELECT MAX(lower_y + (upper_y - lower_y)/2) ";
00915 upd += "FROM " + geomTable + " WHERE object_id = c_object_id) ";
00916 upd += " WHERE label_x IS NULL OR label_y IS NULL";
00917 }
00918
00919 if( theme->layer()->hasGeometry(TeLINES) )
00920 {
00921 geomTable = theme->layer()->tableName(TeLINES);
00922
00923 upd= "UPDATE " + collTable + " SET ";
00924 upd += " label_x = (SELECT MAX(lower_x + (upper_x - lower_x)/2) ";
00925 upd += "FROM " + geomTable + " WHERE object_id = c_object_id), ";
00926
00927 upd += " label_y = (SELECT MAX(lower_y + (upper_y - lower_y)/2) ";
00928 upd += "FROM " + geomTable + " WHERE object_id = c_object_id) ";
00929 upd += " WHERE label_x IS NULL OR label_y IS NULL";
00930 }
00931
00932 if(theme->layer()->hasGeometry(TePOINTS))
00933 {
00934 geomTable = theme->layer()->tableName(TePOINTS);
00935
00936 upd= " UPDATE " + collTable + " SET ";
00937 upd += " label_x = (SELECT MAX(x) ";
00938 upd += " FROM " + geomTable + " p WHERE object_id = c_object_id), ";
00939
00940 upd += " label_y = (SELECT MAX(y) ";
00941 upd += " FROM " + geomTable + " p WHERE object_id = c_object_id) ";
00942 upd += " WHERE label_x IS NULL OR label_y IS NULL";
00943 }
00944
00945 if (!upd.empty())
00946 {
00947 if (!objectId.empty())
00948 {
00949 upd += " AND c_object_id='"+objectId+"'";
00950 }
00951 if(!execute(upd))
00952 return false;
00953 }
00954 return true;
00955 }
00956
00957 bool TeSQLite::insertTheme(TeAbstractTheme *theme)
00958 {
00959 errorMessage_ = "";
00960
00961 string sql = "INSERT INTO te_theme (layer_id, view_id, name, parent_id, priority, node_type, ";
00962 sql += "min_scale, max_scale, generate_attribute_where, generate_spatial_where, ";
00963 sql += "generate_temporal_where, collection_table, visible_rep, enable_visibility, ";
00964 sql += "lower_x, lower_y, upper_x, upper_y, creation_time) VALUES(";
00965
00966 if(theme->type()==TeTHEME)
00967 sql += Te2String(static_cast<TeTheme*>(theme)->layerId());
00968 else
00969 sql += " NULL ";
00970 sql += ", ";
00971 sql += Te2String(theme->view());
00972 sql += ", '";
00973 sql += theme->name();
00974 sql += "', ";
00975 sql += Te2String(theme->parentId());
00976 sql += ", ";
00977 sql += Te2String(theme->priority());
00978 sql += ", ";
00979 sql += Te2String(theme->type());
00980 sql += ", ";
00981 sql += Te2String(theme->minScale(), 15);
00982 sql += ", ";
00983 sql += Te2String(theme->maxScale(), 15);
00984 sql += ", '";
00985 sql += escapeSequence(theme->attributeRest());
00986 sql += "', '";
00987 sql += escapeSequence(theme->spatialRest());
00988 sql += "', '";
00989 sql += escapeSequence(theme->temporalRest());
00990 sql += "', '";
00991 if(theme->type()==TeTHEME)
00992 sql += static_cast<TeTheme*>(theme)->collectionTable();
00993 sql += "', ";
00994 sql += Te2String(theme->visibleRep());
00995 sql += ", ";
00996 sql += Te2String(theme->visibility());
00997 sql += ", ";
00998 sql += Te2String(theme->box().x1(), 15);
00999 sql += ", ";
01000 sql += Te2String(theme->box().y1(), 15);
01001 sql += ", ";
01002 sql += Te2String(theme->box().x2(), 15);
01003 sql += ", ";
01004 sql += Te2String(theme->box().y2(), 15);
01005 sql += ", ";
01006 TeTime creationTime = theme->getCreationTime();
01007 sql += getSQLTime(creationTime);
01008 sql += " )";
01009
01010 if(this->execute(sql))
01011 {
01012
01013 int newId = getLastInsertedSerial();
01014 if(newId >= 0)
01015 {
01016 theme->id(newId);
01017 }
01018 }
01019 else
01020 return false;
01021
01022
01023 if((theme->type()==TeTHEME || theme->type()==TeEXTERNALTHEME) && static_cast<TeTheme*>(theme)->collectionTable().empty())
01024 {
01025 sql = "UPDATE te_theme SET";
01026 sql += " collection_table = 'te_collection_" + Te2String(theme->id()) + "'";
01027 sql += " WHERE theme_id = ";
01028 sql += Te2String(theme->id());
01029
01030 static_cast<TeTheme*>(theme)->collectionTable(string("te_collection_") + Te2String(theme->id()));
01031
01032 if(!this->execute(sql))
01033 return false;
01034 }
01035 if(theme->parentId() == 0)
01036 {
01037 std::string sql = "UPDATE te_theme SET";
01038 sql += " parent_id = " + Te2String(theme->id());
01039 sql += " WHERE theme_id = ";
01040 sql += Te2String(theme->id());
01041
01042 theme->parentId(theme->id());
01043
01044 if(!this->execute(sql))
01045 return false;
01046 }
01047
01048 bool status;
01049
01050
01051 int numSlices = 0;
01052 if(theme->grouping().groupMode_ != TeNoGrouping)
01053 {
01054 if(!insertGrouping (theme->id(), theme->grouping()))
01055 return false;
01056 numSlices = theme->grouping().groupNumSlices_;
01057 }
01058
01059
01060 theme->outOfCollectionLegend().group(-1);
01061 theme->outOfCollectionLegend().theme(theme->id());
01062 status = insertLegend (&(theme->outOfCollectionLegend()));
01063 if (!status)
01064 return status;
01065
01066 theme->withoutDataConnectionLegend().group(-2);
01067 theme->withoutDataConnectionLegend().theme(theme->id());
01068 status = insertLegend (&(theme->withoutDataConnectionLegend()));
01069 if (!status)
01070 return status;
01071
01072 theme->defaultLegend().group(-3);
01073 theme->defaultLegend().theme(theme->id());
01074 status = insertLegend (&(theme->defaultLegend()));
01075 if (!status)
01076 return status;
01077
01078 theme->pointingLegend().group(-4);
01079 theme->pointingLegend().theme(theme->id());
01080 status = insertLegend (&(theme->pointingLegend()));
01081 if (!status)
01082 return status;
01083
01084 theme->queryLegend().group(-5);
01085 theme->queryLegend().theme(theme->id());
01086 status = insertLegend (&(theme->queryLegend()));
01087 if (!status)
01088 return status;
01089
01090 theme->queryAndPointingLegend().group(-6);
01091 theme->queryAndPointingLegend().theme(theme->id());
01092 status = insertLegend (&(theme->queryAndPointingLegend()));
01093 if (!status)
01094 return status;
01095
01096 for (int i = 0; i < numSlices; i++)
01097 {
01098 theme->legend()[i].group(i);
01099 theme->legend()[i].theme(theme->id());
01100 status = insertLegend (&(theme->legend()[i]));
01101 if (!status)
01102 return status;
01103 }
01104 if (!status)
01105 return status;
01106
01107
01108 if(!theme->saveMetadata(this))
01109 return false;
01110
01111 themeMap()[theme->id()] = theme;
01112
01113 if(theme->type()==TeTHEME && !updateThemeTable(static_cast<TeTheme*>(theme)))
01114 return false;
01115
01116 return true;
01117 }
01118
01119 bool TeSQLite::insertThemeTable(int themeId, int tableId, int relationId, int tableOrder)
01120 {
01121 errorMessage_ = "";
01122
01123 string sql = "INSERT INTO te_theme_table (theme_id, table_id, ";
01124
01125 if(relationId > 0)
01126 sql += "relation_id, ";
01127
01128 sql += "table_order) VALUES(";
01129 sql += Te2String(themeId);
01130 sql += ", ";
01131 sql += Te2String(tableId);
01132 sql += ", ";
01133
01134 if(relationId > 0)
01135 {
01136 sql += Te2String(relationId);
01137 sql += ", ";
01138 }
01139
01140 sql += Te2String(tableOrder);
01141 sql += ")";
01142
01143 if(this->execute(sql))
01144 {
01145
01146
01147
01148
01149
01150
01151
01152
01153 }
01154 else
01155 return false;
01156
01157 return true;
01158 }
01159
01160 bool TeSQLite::insertLegend(TeLegendEntry *legend)
01161 {
01162 errorMessage_ = "";
01163
01164 string sql = "INSERT INTO te_legend (theme_id, group_id, num_objs, lower_value, upper_value, ";
01165 sql += "label) VALUES(";
01166 sql += Te2String(legend->theme());
01167 sql += ", ";
01168 sql += Te2String(legend->group());
01169 sql += ", ";
01170 sql += Te2String(legend->count());
01171 sql += ", '";
01172 sql += escapeSequence(legend->from());
01173 sql += "', '";
01174 sql += escapeSequence(legend->to());
01175 sql += "', '";
01176 sql += escapeSequence(legend->label());
01177 sql += "')";
01178
01179 if(this->execute(sql))
01180 {
01181
01182 int newId = getLastInsertedSerial();
01183 if(newId >= 0)
01184 {
01185 legend->id(newId);
01186 }
01187 }
01188 else
01189 return false;
01190
01191 legendMap()[legend->id()] = legend;
01192
01193 return insertVisual(legend);
01194 }
01195
01196 bool TeSQLite::insertPolygon(const string& table, TePolygon &p)
01197 {
01198 errorMessage_ = "";
01199
01200 std::string objectId = p.objectId();
01201
01202 char* wkb = 0;
01203 unsigned int wkbSize = 0;
01204
01205 TeWKBGeometryDecoder::encodePolygon(p, wkb, wkbSize);
01206
01207 std::string command = "INSERT INTO ";
01208 command += table;
01209 command += " (object_id, lower_x, lower_y, upper_x, upper_y, spatial_data)";
01210 command += " VALUES (?1, ?2, ?3, ?4, ?5, ?6)";
01211
01212 sqlite3_stmt* recordSet = 0;
01213 int retValue = sqlite3_prepare_v2(_conn, command.c_str(), -1, &recordSet, 0);
01214
01215 if(retValue != SQLITE_OK)
01216 {
01217 errorMessage_ = errorMessage();
01218 return false;
01219 }
01220
01221 sqlite3_bind_text(recordSet, 1, objectId.c_str(), objectId.size(), SQLITE_TRANSIENT);
01222 sqlite3_bind_double(recordSet, 2, p.box().x1());
01223 sqlite3_bind_double(recordSet, 3, p.box().y1());
01224 sqlite3_bind_double(recordSet, 4, p.box().x2());
01225 sqlite3_bind_double(recordSet, 5, p.box().y2());
01226 sqlite3_bind_blob(recordSet, 6, wkb, wkbSize, SQLITE_TRANSIENT);
01227
01228 delete wkb;
01229
01230 retValue = sqlite3_step(recordSet);
01231 if(retValue != SQLITE_DONE)
01232 {
01233 return false;
01234 }
01235
01236 sqlite3_finalize(recordSet);
01237
01238
01239 int newId = getLastInsertedSerial();
01240 if(newId >= 0)
01241 {
01242 p.geomId(newId);
01243 }
01244
01245 return true;
01246 }
01247 bool TeSQLite::updatePolygon(const string& table, TePolygon &p)
01248 {
01249 errorMessage_ = "";
01250
01251 std::string command = "UPDATE " + table + " SET ";
01252 command += "object_id=?";
01253 command += ", lower_x=?, lower_y=?, upper_x=?, upper_y=?, ";
01254 command += ", spatial_data=? WHERE geom_id = " + Te2String(p.geomId());
01255
01256
01257 std::string objectId = p.objectId();
01258
01259 char* wkb = 0;
01260 unsigned int wkbSize = 0;
01261
01262 TeWKBGeometryDecoder::encodePolygon(p, wkb, wkbSize);
01263
01264 sqlite3_stmt* recordSet = 0;
01265 int retValue = sqlite3_prepare_v2(_conn, command.c_str(), -1, &recordSet, 0);
01266
01267 if(retValue != SQLITE_OK)
01268 {
01269 errorMessage_ = errorMessage();
01270 return false;
01271 }
01272
01273 sqlite3_bind_text(recordSet, 1, objectId.c_str(), objectId.size(), SQLITE_TRANSIENT);
01274 sqlite3_bind_double(recordSet, 2, p.box().x1());
01275 sqlite3_bind_double(recordSet, 3, p.box().y1());
01276 sqlite3_bind_double(recordSet, 4, p.box().x2());
01277 sqlite3_bind_double(recordSet, 5, p.box().y2());
01278 sqlite3_bind_blob(recordSet, 6, wkb, wkbSize, SQLITE_TRANSIENT);
01279
01280 delete wkb;
01281
01282 retValue = sqlite3_step(recordSet);
01283 if(retValue != SQLITE_DONE)
01284 {
01285 return false;
01286 }
01287
01288 sqlite3_finalize(recordSet);
01289
01290 return true;
01291 }
01292
01293 bool TeSQLite::insertLine(const string& table, TeLine2D &l)
01294 {
01295 errorMessage_ = "";
01296
01297 std::string objectId = l.objectId();
01298
01299 char* wkb = 0;
01300 unsigned int wkbSize = 0;
01301
01302 TeWKBGeometryDecoder::encodeLine(l, wkb, wkbSize);
01303
01304 std::string command = "INSERT INTO ";
01305 command += table;
01306 command += " (object_id, lower_x, lower_y, upper_x, upper_y, spatial_data)";
01307 command += " VALUES (?1, ?2, ?3, ?4, ?5, ?6)";
01308
01309 sqlite3_stmt* recordSet = 0;
01310 int retValue = sqlite3_prepare_v2(_conn, command.c_str(), -1, &recordSet, 0);
01311
01312 if(retValue != SQLITE_OK)
01313 {
01314 errorMessage_ = errorMessage();
01315 return false;
01316 }
01317
01318 sqlite3_bind_text(recordSet, 1, objectId.c_str(), objectId.size(), SQLITE_TRANSIENT);
01319 sqlite3_bind_double(recordSet, 2, l.box().x1());
01320 sqlite3_bind_double(recordSet, 3, l.box().y1());
01321 sqlite3_bind_double(recordSet, 4, l.box().x2());
01322 sqlite3_bind_double(recordSet, 5, l.box().y2());
01323 sqlite3_bind_blob(recordSet, 6, wkb, wkbSize, SQLITE_TRANSIENT);
01324
01325 delete wkb;
01326
01327 retValue = sqlite3_step(recordSet);
01328 if(retValue != SQLITE_DONE)
01329 {
01330 return false;
01331 }
01332
01333 sqlite3_finalize(recordSet);
01334
01335
01336 int newId = getLastInsertedSerial();
01337 if(newId >= 0)
01338 {
01339 l.geomId(newId);
01340 }
01341
01342 return true;
01343 }
01344
01345 bool TeSQLite::updateLine(const string& table, TeLine2D &l)
01346 {
01347 errorMessage_ = "";
01348
01349 std::string command = "UPDATE " + table + " SET ";
01350 command += "object_id=?";
01351 command += ", lower_x=?, lower_y=?, upper_x=?, upper_y=?, ";
01352 command += ", spatial_data=? WHERE geom_id = " + Te2String(l.geomId());
01353
01354 std::string objectId = l.objectId();
01355
01356 char* wkb = 0;
01357 unsigned int wkbSize = 0;
01358
01359 TeWKBGeometryDecoder::encodeLine(l, wkb, wkbSize);
01360
01361 sqlite3_stmt* recordSet = 0;
01362 int retValue = sqlite3_prepare_v2(_conn, command.c_str(), -1, &recordSet, 0);
01363
01364 if(retValue != SQLITE_OK)
01365 {
01366 errorMessage_ = errorMessage();
01367 return false;
01368 }
01369
01370 sqlite3_bind_text(recordSet, 1, objectId.c_str(), objectId.size(), SQLITE_TRANSIENT);
01371 sqlite3_bind_double(recordSet, 2, l.box().x1());
01372 sqlite3_bind_double(recordSet, 3, l.box().y1());
01373 sqlite3_bind_double(recordSet, 4, l.box().x2());
01374 sqlite3_bind_double(recordSet, 5, l.box().y2());
01375 sqlite3_bind_blob(recordSet, 6, wkb, wkbSize, SQLITE_TRANSIENT);
01376
01377 delete wkb;
01378
01379 retValue = sqlite3_step(recordSet);
01380 if(retValue != SQLITE_DONE)
01381 {
01382 return false;
01383 }
01384
01385 sqlite3_finalize(recordSet);
01386
01387 return true;
01388 }
01389
01390 bool TeSQLite::insertPoint(const string& table, TePoint &p)
01391 {
01392 std::string q = "INSERT INTO " + table + "(object_id, x, y)";
01393 q += " VALUES(";
01394 q += "'" + escapeSequence(p.objectId()) + "',";
01395 q += Te2String(p.location().x_) + ",";
01396 q += Te2String(p.location().y_) + ")";
01397
01398 if(execute(q) == false)
01399 {
01400 return false;
01401 }
01402
01403
01404 int newId = getLastInsertedSerial();
01405 if(newId >= 0)
01406 {
01407 p.geomId(newId);
01408 }
01409 return true;
01410 }
01411
01412 bool TeSQLite::insertText(const string& table, TeText &t)
01413 {
01414 return true;
01415 }
01416
01417 bool TeSQLite::insertArc(const string& table,TeArc &arc)
01418 {
01419 return true;
01420 }
01421
01422 bool TeSQLite::insertNode(const string& table, TeNode &node)
01423 {
01424 return true;
01425 }
01426
01427 bool TeSQLite::insertCell(const string& table, TeCell &c)
01428 {
01429 return true;
01430 }
01431
01432 bool TeSQLite::insertRasterBlock(const string& table, const string& blockId, const TeCoord2D& ll, const TeCoord2D& ur, unsigned char *buf, unsigned long size, int band, unsigned int res, unsigned int subband)
01433 {
01434 errorMessage_ = "";
01435
01436 if (blockId.empty())
01437 {
01438 errorMessage_ = "bloco sem identificador";
01439 return false;
01440 }
01441
01442 TeDatabasePortal* portal = getPortal();
01443 bool insert = true;
01444
01445 std::string sql = "SELECT block_id FROM " + table + " WHERE block_id='" + blockId + "'";
01446 if(!portal->query(sql))
01447 {
01448 delete portal;
01449 errorMessage_ = portal->errorMessage();
01450
01451 return false;
01452 }
01453
01454 if(portal->fetchRow())
01455 {
01456 insert = false;
01457 }
01458
01459 delete portal;
01460
01461 if(insert)
01462 {
01463 sql = "INSERT INTO " + table + " (lower_x, lower_y, upper_x, upper_y, band_id, resolution_factor, subband, block_size, spatial_data, block_id) ";
01464 sql += " VALUES (?,?,?,?,?,?,?,?,?,?)";
01465 }
01466 else
01467 {
01468 sql = "UPDATE " + table + " SET lower_x=?, lower_y=?, upper_x=?, upper_y=?, band_id=?,";
01469 sql += "resolution_factor=?, subband=?, block_size=?, spatial_data=? WHERE block_id=? ";
01470 }
01471
01472
01473 sqlite3_stmt* recordSet = 0;
01474 int retValue = sqlite3_prepare_v2(_conn, sql.c_str(), -1, &recordSet, 0);
01475
01476 if(retValue != SQLITE_OK)
01477 {
01478 errorMessage_ = errorMessage();
01479 return false;
01480 }
01481
01482 sqlite3_bind_double(recordSet, 1, ll.x());
01483 sqlite3_bind_double(recordSet, 2, ll.y());
01484 sqlite3_bind_double(recordSet, 3, ur.x());
01485 sqlite3_bind_double(recordSet, 4, ur.y());
01486 sqlite3_bind_int(recordSet, 5, band);
01487 sqlite3_bind_int(recordSet, 6, (int)res);
01488 sqlite3_bind_int(recordSet, 7, (int)subband);
01489 sqlite3_bind_int(recordSet, 8, (int)size);
01490 sqlite3_bind_blob(recordSet, 9, buf, size, SQLITE_TRANSIENT);
01491 sqlite3_bind_text(recordSet, 10, blockId.c_str(), blockId.size(), SQLITE_TRANSIENT);
01492
01493 retValue = sqlite3_step(recordSet);
01494 if(retValue != SQLITE_DONE)
01495 {
01496 return false;
01497 }
01498
01499 sqlite3_finalize(recordSet);
01500
01501 return true;
01502 }
01503
01504 bool TeSQLite::execute(const string &sql)
01505 {
01506 errorMessage_ = "";
01507
01508 int retVal = sqlite3_exec(_conn, sql.c_str(), 0, 0, 0);
01509
01510 if(retVal != SQLITE_OK)
01511 {
01512 errorMessage_ = errorMessage();
01513 return false;
01514 }
01515
01516 return true;
01517 }
01518
01519 bool TeSQLite::beginTransaction()
01520 {
01521 ++_transactionCounter;
01522
01523 if (_transactionCounter > 1)
01524 return true;
01525 else
01526 return execute("BEGIN TRANSACTION");
01527 }
01528
01529 bool TeSQLite::commitTransaction()
01530 {
01531 _transactionCounter--;
01532
01533 if (_transactionCounter > 0)
01534 return true;
01535 else
01536 return execute("COMMIT TRANSACTION");
01537 }
01538
01539 bool TeSQLite::rollbackTransaction()
01540 {
01541 _transactionCounter = 0;
01542
01543 return execute("ROLLBACK TRANSACTION");
01544 }
01545
01546 string TeSQLite::escapeSequence(const string& from)
01547 {
01548 int fa = 0;
01549 std::string to = from;
01550 to.insert(0, " ");
01551 std::string::iterator it = to.begin();
01552 while(it != to.end())
01553 {
01554 int f = to.find("'", fa);
01555 if(f > fa)
01556 {
01557 to.insert(f, "'");
01558 fa = f + 2;
01559 }
01560 else
01561 break;
01562 }
01563 to = to.substr(1, to.size() - 1);
01564 return to;
01565 }
01566
01567 string TeSQLite::concatValues(vector<string>& values, const string& unionString)
01568 {
01569 return "";
01570 }
01571
01572 string TeSQLite::toUpper(const string& value)
01573 {
01574 std::string upper = "upper(" + value + ")";
01575 return upper;
01576 }
01577
01578 string TeSQLite::getSQLTime(const TeTime& time) const
01579 {
01580 return "'" + time.getDateTime("YYYYsMMsDDsHHsmmsSS", "-") + "'";
01581 }
01582
01583 std::string TeSQLite::getSQLOrderBy(const TeGeomRep& rep) const
01584 {
01585 std::string orderBy = "object_id ASC";
01586 return orderBy;
01587 }
01588
01589 string TeSQLite::errorMessage()
01590 {
01591 if(errorMessage_.empty())
01592 {
01593 errorMessage_ =std::string(sqlite3_errmsg(_conn));
01594 }
01595
01596 return errorMessage_;
01597 }
01598
01599 TeDatabasePortal* TeSQLite::getPortal()
01600 {
01601 return new TeSQLitePortal(this);
01602 }
01603
01604
01605
01606
01607
01608
01609 TeSQLitePortal::TeSQLitePortal() : TeDatabasePortal()
01610 , _recordSet(0)
01611 , _conn(0)
01612 , _skipFirstFetch(false)
01613 , _firstFetchResult(false)
01614 , _currentRow(-1)
01615 {
01616 }
01617
01618 TeSQLitePortal::TeSQLitePortal(TeDatabase* pDatabase) : TeDatabasePortal()
01619 , _recordSet(0)
01620 , _skipFirstFetch(false)
01621 , _firstFetchResult(false)
01622 , _currentRow(-1)
01623 {
01624 db_ = pDatabase;
01625 _conn = ((static_cast<TeSQLite*>(pDatabase))->_conn);
01626 }
01627
01628 TeSQLitePortal::~TeSQLitePortal()
01629 {
01630 freeResult();
01631 }
01632
01633 bool TeSQLitePortal::query(const string &qry, TeCursorLocation l, TeCursorType t, TeCursorEditType e, TeCursorDataType dt)
01634 {
01635 errorMessage_ = "";
01636 freeResult();
01637
01638 _skipFirstFetch = false;
01639 _firstFetchResult = false;
01640 _mapColumnNames.clear();
01641
01642 int retValue = sqlite3_prepare_v2(_conn, qry.c_str(), -1, &_recordSet, 0);
01643 if(retValue != SQLITE_OK)
01644 {
01645 errorMessage_ = errorMessage();
01646 freeResult();
01647 return false;
01648 }
01649
01650 _query = qry;
01651
01652 _firstFetchResult = fetchRow();
01653 _skipFirstFetch = true;
01654 _currentRow = -1;
01655
01656 numFields_ = sqlite3_column_count(_recordSet);
01657 for(int i = 0; i < numFields_; ++i)
01658 {
01659 int type = sqlite3_column_type(_recordSet, i);
01660 std::string cName = sqlite3_column_name(_recordSet, i);
01661
01662 _mapColumnNames[cName] = i;
01663
01664 TeAttribute attr;
01665 attr.rep_.name_ = cName;
01666
01667 if(type == SQLITE3_TEXT)
01668 {
01669 attr.rep_.type_ = TeSTRING;
01670 }
01671 else if(type == SQLITE_INTEGER)
01672 {
01673 attr.rep_.type_ = TeINT;
01674 }
01675 else if(type == SQLITE_FLOAT)
01676 {
01677 attr.rep_.type_ = TeREAL;
01678 }
01679 else if(type == SQLITE_BLOB)
01680 {
01681 attr.rep_.type_ = TeBLOB;
01682 }
01683 else
01684 {
01685 attr.rep_.type_ = TeSTRING;
01686 }
01687
01688 attList_.push_back(attr);
01689 }
01690
01691 return true;
01692 }
01693
01694 bool TeSQLitePortal::fetchRow()
01695 {
01696 if(_skipFirstFetch == true)
01697 {
01698 _currentRow = 0;
01699 _skipFirstFetch = false;
01700 return _firstFetchResult;
01701 }
01702
01703 ++_currentRow;
01704 int retValue = sqlite3_step(_recordSet);
01705
01706 bool hasNext = false;
01707 if(retValue == SQLITE_ROW)
01708 {
01709 hasNext = true;
01710 }
01711 else if(retValue == SQLITE_DONE)
01712 {
01713 hasNext = false;
01714 }
01715
01716 return hasNext;
01717 }
01718
01719 bool TeSQLitePortal::fetchRow(int i)
01720 {
01721 if(i == _currentRow)
01722 {
01723 return true;
01724 }
01725 else if(i == (_currentRow + 1))
01726 {
01727 return fetchRow();
01728 }
01729 else if(i > _currentRow)
01730 {
01731 while(_currentRow < i)
01732 {
01733 if(fetchRow() == false)
01734 {
01735 return false;
01736 }
01737 }
01738 return true;
01739 }
01740 else
01741 {
01742 std::string queryCopy = _query;
01743 if(query(queryCopy) == false)
01744 {
01745 return false;
01746 }
01747 return fetchRow(i);
01748 }
01749
01750 return true;
01751 }
01752
01753 void TeSQLitePortal::freeResult()
01754 {
01755 if(_recordSet != 0)
01756 {
01757 sqlite3_reset(_recordSet);
01758 sqlite3_finalize(_recordSet);
01759 }
01760 _recordSet = 0;
01761 _currentRow = -1;
01762 _query = "";
01763 attList_.clear();
01764 _mapColumnNames.clear();
01765 }
01766
01767 char* TeSQLitePortal::getData(int i)
01768 {
01769 const unsigned char* value = sqlite3_column_text(_recordSet, i);
01770
01771 if(value == 0)
01772 {
01773 static char emptyStr = '\0';
01774 return &emptyStr;
01775 }
01776 return (char*) value;
01777 }
01778
01779 char* TeSQLitePortal::getData(const string& s)
01780 {
01781 return getData(getColumnIndex(s));
01782 }
01783
01784 int TeSQLitePortal::getInt(int i)
01785 {
01786 return sqlite3_column_int(_recordSet, i);
01787 }
01788
01789 int TeSQLitePortal::getInt(const string& s)
01790 {
01791 return getInt(getColumnIndex(s));
01792 }
01793
01794 bool TeSQLitePortal::getBool(int i)
01795 {
01796 if(sqlite3_column_int(_recordSet, i) == 0)
01797 {
01798 return false;
01799 }
01800 return true;
01801 }
01802
01803 bool TeSQLitePortal::getBool(const string& s)
01804 {
01805 return getBool(getColumnIndex(s));
01806 }
01807
01808 TeTime TeSQLitePortal::getDate(int i)
01809 {
01810 char* value = (char*) sqlite3_column_text(_recordSet, i);
01811
01812 TeTime time;
01813 if(value != 0)
01814 {
01815 time = TeTime(value, TeChronon(), "YYYYsMMsDDsHHsmmsSS", "-");
01816 }
01817
01818 return time;
01819 }
01820
01821 TeTime TeSQLitePortal::getDate(const string& s)
01822 {
01823 return getDate(getColumnIndex(s));
01824 }
01825
01826 string TeSQLitePortal::getDateAsString(int i)
01827 {
01828 return "";
01829 }
01830
01831 string TeSQLitePortal::getDateAsString(const string& s)
01832 {
01833 return "";
01834 }
01835
01836 bool TeSQLitePortal::getBlob(const string& s, unsigned char* &data, long& size)
01837 {
01838 errorMessage_ = "";
01839
01840 const char* bValue = (const char*) sqlite3_column_blob(_recordSet, getColumnIndex("spatial_data"));
01841 size = (unsigned int)sqlite3_column_bytes(_recordSet, getColumnIndex("spatial_data"));
01842
01843 if(data == NULL)
01844 {
01845 data = new unsigned char[size];
01846 }
01847
01848 memcpy(data, bValue, size);
01849
01850 return true;
01851 }
01852
01853 bool TeSQLitePortal::getRasterBlock(unsigned long& size, unsigned char* ptData)
01854 {
01855 long lSize = 0;
01856 bool result = getBlob("spatial_data", ptData, lSize);
01857
01858 size = static_cast<unsigned long>(lSize);
01859
01860 return result;
01861 }
01862
01863 int TeSQLitePortal::getColumnIndex(const string& s)
01864 {
01865 std::map<std::string, int>::iterator it = _mapColumnNames.find(s);
01866 if(it != _mapColumnNames.end())
01867 {
01868 return it->second;
01869 }
01870
01871 return TeDatabasePortal::getColumnIndex(s);
01872 }
01873
01874 bool TeSQLitePortal::fetchGeometry(TePolygon& geom)
01875 {
01876 return fetchGeometry(geom, 0);
01877 }
01878
01879 bool TeSQLitePortal::fetchGeometry(TePolygon& geom, const unsigned int& initIndex)
01880 {
01881 errorMessage_ = "";
01882
01883 const char* bValue = (const char*) sqlite3_column_blob(_recordSet, initIndex + 6);
01884 unsigned int size = (unsigned int)sqlite3_column_bytes(_recordSet, initIndex + 6);
01885
01886 TeWKBGeometryDecoder::decodePolygon(bValue, geom, size);
01887
01888 geom.geomId(getInt(initIndex + 0));
01889 geom.objectId(getData(initIndex + 1));
01890
01891
01892 return fetchRow();
01893 }
01894
01895 bool TeSQLitePortal::fetchGeometry(TeLine2D& geom)
01896 {
01897 return fetchGeometry(geom, 0);
01898 }
01899
01900 bool TeSQLitePortal::fetchGeometry(TeLine2D& geom, const unsigned int& initIndex)
01901 {
01902 errorMessage_ = "";
01903
01904 const char* bValue = (const char*) sqlite3_column_blob(_recordSet, initIndex + 6);
01905 unsigned int size = (unsigned int) sqlite3_column_bytes(_recordSet, initIndex + 6);
01906
01907 TeWKBGeometryDecoder::decodeLine(bValue, geom, size);
01908
01909 geom.geomId(getInt(initIndex + 0));
01910 geom.objectId(getData(initIndex + 1));
01911
01912
01913 return fetchRow();
01914 }
01915
01916 bool TeSQLitePortal::fetchGeometry(TeNode& geom)
01917 {
01918 return fetchGeometry(geom, 0);
01919 }
01920
01921 bool TeSQLitePortal::fetchGeometry(TeNode& geom, const unsigned int& initIndex)
01922 {
01923 errorMessage_ = "";
01924
01925 TeCoord2D pt(getDouble(initIndex + 2), getDouble(initIndex + 3));
01926
01927 geom.add(pt);
01928 geom.geomId(getInt(initIndex + 0));
01929 geom.objectId(string(getData(initIndex + 1)));
01930
01931 return fetchRow();
01932 }
01933
01934 bool TeSQLitePortal::fetchGeometry(TePoint& geom)
01935 {
01936 return fetchGeometry(geom, 0);
01937 }
01938
01939 bool TeSQLitePortal::fetchGeometry(TePoint& geom, const unsigned int& initIndex)
01940 {
01941 errorMessage_ = "";
01942
01943 TeCoord2D pt(getDouble(initIndex + 2), getDouble(initIndex + 3));
01944
01945 geom.add(pt);
01946 geom.geomId(getInt(initIndex + 0));
01947 geom.objectId(string(getData(initIndex + 1)));
01948
01949 return fetchRow();
01950 }
01951
01952
01953 string TeSQLitePortal::errorMessage()
01954 {
01955 if(errorMessage_.empty())
01956 {
01957 errorMessage_ =std::string(sqlite3_errmsg(_conn));
01958 }
01959
01960 return errorMessage_;
01961 }