TeSTEFunctionsDB.h

Go to the documentation of this file.
00001 /************************************************************************************
00002 TerraLib - a library for developing GIS applications.
00003 Copyright © 2001-2007 INPE and Tecgraf/PUC-Rio.
00004 
00005 This code is part of the TerraLib library.
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 You should have received a copy of the GNU Lesser General Public
00012 License along with this library.
00013 
00014 The authors reassure the license terms regarding the warranties.
00015 They specifically disclaim any warranties, including, but not limited to,
00016 the implied warranties of merchantability and fitness for a particular purpose.
00017 The library p rovided hereunder is on an "as is" basis, and the authors have no
00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00020 indirect, special, incidental, or consequential damages arising out of the use
00021 of this library and its documentation.
00022 *************************************************************************************/
00023 /*! \file TeSTEFunctionsDB.h
00024     \brief This file contains a set of functions to build spatio-temporal sets from a TerraLib databse  
00025 */
00026 #ifndef  __TERRALIB_INTERNAL_STOFUNCTIONS_H
00027 #define  __TERRALIB_INTERNAL_STOFUNCTIONS_H
00028 
00029 #include "TeDatabase.h"
00030 #include "TeProgress.h"
00031 #include <vector>
00032 #include <string>
00033 
00034 //! Builds the spatial object set from database according to the restrictions previously defined
00035 /*! 
00036         \param stoset                           the STOSet that will be filled 
00037         \param loadGeometries           if the STOSet will be filled with the geometries 
00038         \param loadAllAttributes        if the STOSet will be filled with all attributes of the tables of the STOSet 
00039         \param attrNames                        a subset of the attribute names that will be loaded, if the param loadAllAttributes is false 
00040 */
00041 template<typename elementSet>
00042 bool TeSTOSetBuildDB(elementSet* stoset, bool loadGeometries = false, bool loadAllAttributes = false, vector<string> attrNames = vector<string>());
00043 
00044 //! Builds the spatial object set from database according to the restrictions previously defined
00045 /*! 
00046         \param stoset                           the STOSet that will be filled 
00047         \param groupAttr                        a map from attribute name to statistic type  
00048         \param loadGeometries           if the STOSet will be filled with the geometries 
00049 */
00050 template<typename elementSet>
00051 bool TeSTOSetBuildDB(elementSet* stoset, TeGroupingAttr& groupAttr, bool loadGeometries = false);
00052 
00053 
00054 //! Updates or inserts a database table from a spatial object set
00055 /*! 
00056         \param elemSet          the set of spatial objects that will be inserted or updated into database
00057         \param tableName        database table name that will be updated  
00058         \param indexes          the attribute indexes of the spatial objects that must be updated
00059 */
00060 template<typename elementSet> 
00061 bool TeUpdateDBFromSet (elementSet* elemSet, const string& tableName, vector<int>* indexes = 0);
00062 
00063 
00064 //! Auxiliary function to insert a row
00065 template<typename Element> 
00066 bool insertRow (Element* elem, TeTable& table, const string& uniqueValue, TeDatabase* db, vector<int>* indexes=0);
00067 
00068 //! Auxiliary function to update a row
00069 template<typename Element>
00070 bool updateRow (Element* elem, TeTable table, const string& uniqueId, TeDatabase* db, vector<int>* indexes=0);
00071 
00072 
00073 //--------------- Implementation
00074 
00075 template<typename elementSet> 
00076 bool TeSTOSetBuildDB(elementSet* stoset, bool loadGeometries, bool loadAllAttributes, vector<string> attrNames)
00077 {
00078         if(!stoset->build(loadGeometries, loadAllAttributes, attrNames))
00079                 return false;
00080         return true;
00081 }
00082 
00083 template<typename elementSet>
00084 bool TeSTOSetBuildDB(elementSet* stoset, TeGroupingAttr& groupAttr, bool loadGeometries)
00085 {
00086         if(!stoset->build(groupAttr, loadGeometries))
00087                 return false;
00088         return true;
00089 }
00090 
00091 template<typename elementSet>  
00092 bool TeUpdateDBFromSet (elementSet* elemSet, const string& tableName, vector<int>* indexes)
00093 {
00094         TeDatabase* db = 0;
00095         if((elemSet->getTheme()) && (elemSet->theme()->layer()))
00096                 db = elemSet->getTheme()->layer()->database();
00097         else if(elemSet->getLayer())
00098                 db = elemSet->getLayer()->database();
00099         
00100         if(!db)
00101                 return false;
00102          
00103         //progress bar
00104         int step = 0;
00105         int numSteps = elemSet->numSTInstance();
00106         if(TeProgress::instance())
00107                 TeProgress::instance()->setTotalSteps(numSteps);
00108         
00109         try
00110         {
00111                 TeAttrTableVector attrTables;
00112                 if(elemSet->getTheme())
00113                         elemSet->getTheme()->getAttTables(attrTables); 
00114                 else if(elemSet->getLayer())
00115                         elemSet->getLayer()->getAttrTables(attrTables); 
00116 
00117                 if(attrTables.empty())
00118                         return false;   
00119 
00120                 TeTable table;
00121                 int     uniqueIndex = -1;
00122         
00123                 //! verify if the table is in the stoset
00124                 for(unsigned int i=0; i<attrTables.size(); i++)
00125                 {
00126                         if(attrTables[i].name()==tableName)
00127                         {
00128                                 uniqueIndex = i;
00129                                 table = attrTables[i];
00130                                 break;
00131                         }
00132                 }
00133                 
00134                 if((uniqueIndex==-1) || ((table.tableType()!=TeAttrEvent) && 
00135                                                                  (table.tableType()!=TeAttrStatic) && 
00136                                                                  (table.tableType()!=TeFixedGeomDynAttr) &&
00137                                                                  (table.tableType()!=TeAttrExternal)))
00138                         return false;
00139 
00140                 // get some information about the attribute table required
00141                 string uniqueIdName = table.uniqueName();
00142         
00143                 TeDatabasePortal* portal = db->getPortal();
00144                 if(!portal)
00145                         return false;
00146 
00147                 map<string, string> uniqueIds;
00148                 string sql = "SELECT "+ uniqueIdName +" FROM "+ table.name();
00149                 
00150                 if(!portal->query (sql))
00151                 {
00152                         delete portal;
00153                         return false;
00154                 }
00155 
00156                 while(portal->fetchRow())
00157                         uniqueIds[string(portal->getData(0))] = string(portal->getData(0));
00158                 
00159                 delete portal;
00160 
00161                 //verifies if the attribute column exists in the table
00162                 TeAttributeList attList = elemSet->getAttributeList();
00163                 for(unsigned int i=0; i<attList.size(); ++i)
00164                 {
00165                         if(indexes && (find(indexes->begin(), indexes->end(),(int)i) == indexes->end()))
00166                                 continue;
00167 
00168                         //verify if the table has this column 
00169                         string attrName = attList[i].rep_.name_;
00170                         size_t pos = attrName.find(".", 0, 1);
00171                         if (pos != string::npos)
00172                                 attList[i].rep_.name_ = attrName.substr(pos+1);
00173 
00174                         if (!db->columnExist(tableName, attList[i].rep_.name_, attList[i]))
00175                         {
00176                                 if(!db->addColumn (tableName, attList[i].rep_))
00177                                         return false; 
00178 
00179                                 TeAttributeList attrListTable = table.attributeList();
00180                                 attrListTable.push_back (attList[i]);
00181                                 table.setAttributeList(attrListTable);
00182                         }
00183                 }
00184                 
00185                 // Update all the objects 
00186                 typename elementSet::iterator itObj = elemSet->begin();
00187                 while (itObj != elemSet->end())
00188                 {
00189                         string uniqueId =  (*itObj).getUniqueId(uniqueIndex); 
00190 
00191                         if(uniqueIds.find(uniqueId) ==  uniqueIds.end())
00192                         {       
00193                                 if (!insertRow (&(*itObj), table, uniqueId, db, indexes))
00194                                         return false;
00195 
00196                                 uniqueIds[uniqueId] = uniqueId;
00197                         }
00198                         else
00199                         {       
00200                                 if (!updateRow (&(*itObj), table, uniqueId, db, indexes))
00201                                         return false;
00202                         }
00203                                         
00204                         ++itObj;
00205 
00206                         if(TeProgress::instance())
00207                         {
00208                                 if (TeProgress::instance()->wasCancelled())
00209                                 {
00210                                         TeProgress::instance()->reset();
00211                                         return false;
00212                                 }
00213                                 else
00214                                         TeProgress::instance()->setProgress(step);
00215                         }       
00216                         ++step;
00217                 }
00218         }
00219         catch(...)
00220         {
00221                 if (TeProgress::instance())
00222                         TeProgress::instance()->reset();
00223                 return false;
00224         }
00225         
00226         if (TeProgress::instance())
00227                 TeProgress::instance()->reset();
00228         
00229         return true;
00230 }
00231 
00232 template<typename Element> 
00233 bool insertRow (Element* elem, TeTable& table, const string& uniqueValue, TeDatabase* db, vector<int>* indexes)
00234 {
00235         vector<string> attrs;
00236         table.attributeNames(attrs);
00237         
00238         string ins = " INSERT INTO "+ table.name() +" (";
00239         string values = " VALUES ( ";
00240         
00241         TePropertyVector prop = elem->getPropertyVector();
00242         int count=0;
00243 
00244         for(unsigned int i=0; i<prop.size(); ++i)
00245         {
00246                 if(indexes && (find(indexes->begin(), indexes->end(),(int)i) == indexes->end()))
00247                         continue;
00248                 
00249                 string attrName = prop[i].attr_.rep_.name_;
00250                 size_t pos = attrName.find(".", 0, 1);
00251                 if (pos != string::npos)
00252                         attrName = attrName.substr(pos+1);
00253                                 
00254                 if( (find(attrs.begin(), attrs.end(), attrName)!=attrs.end()) &&
00255                         (TeStringCompare(attrName, table.uniqueName()) == false) && 
00256                         (TeStringCompare(attrName,table.linkName()) == false)&&
00257                         (TeStringCompare(attrName,table.attInitialTime()) == false)&&
00258                         (TeStringCompare(attrName,table.attFinalTime()) == false)  )
00259                         
00260                 {
00261                         if((prop[i].attr_.rep_.type_!=TeSTRING) && prop[i].value_.empty())
00262                                 continue; 
00263 
00264                         if(count>0)
00265                         {
00266                                 ins += ",";
00267                                 values += ",";
00268                         }
00269                         ++count;
00270                         ins += attrName;
00271                         if(prop[i].attr_.rep_.type_==TeSTRING)
00272                                 values += "'"+ prop[i].value_ +"'";
00273                         else if(prop[i].attr_.rep_.type_==TeREAL)
00274                         {
00275                                 std::string strValue = prop[i].value_;
00276                                 replace (strValue.begin(), strValue.end(), ',', '.');
00277                                 values += strValue;
00278                         }
00279                         else if(prop[i].attr_.rep_.type_==TeDATETIME)
00280                         {
00281                                 TeTime time(prop[i].value_, prop[i].attr_.dateChronon_, prop[i].attr_.dateTimeFormat_, prop[i].attr_.dateSeparator_, prop[i].attr_.timeSeparator_);  
00282                                 values += db->getSQLTime(time);
00283                         }
00284                         else
00285                                 values += prop[i].value_;
00286                 }
00287         }
00288 
00289         // -------- object_id, unique_id and timeInterval
00290                 
00291         if(count>0)
00292         {
00293                 ins +=          " ,";
00294                 values +=       " ,";
00295         }
00296 
00297         ins +=          table.linkName();
00298         values +=       "'"+ elem->objectId() +"'";
00299 
00300         if(table.linkName() != table.uniqueName())
00301         {
00302                 ins +=          ", "+ table.uniqueName();
00303                 values +=       ", '"+ uniqueValue +"'";
00304         }
00305 
00306         if(!table.attInitialTime().empty())
00307         {
00308                 TeTime time (elem->timeInterval().getT1());
00309                 ins +=          ", "+ table.attInitialTime();
00310                 values +=       ", "+ db->getSQLTime(time); 
00311         }
00312 
00313         if((!table.attFinalTime().empty()) && (table.attInitialTime()!=table.attFinalTime()))
00314         {
00315                 TeTime time (elem->timeInterval().getT2());
00316                 ins +=          ", "+ table.attFinalTime();
00317                 values +=       ", "+ db->getSQLTime(time); 
00318         }
00319         // ----------
00320 
00321         ins += ") "+ values +" )";
00322         
00323         if(!db->execute (ins))
00324                 return false;
00325 
00326         return true;
00327 }
00328 
00329 template<typename Element>
00330 bool updateRow (Element* elem, TeTable table, const string& uniqueId, TeDatabase* db, vector<int>* indexes)
00331 {
00332         
00333         vector<string> attrs;
00334         table.attributeNames(attrs);
00335 
00336         string ins = " UPDATE "+ table.name() +" SET ";
00337         
00338         TePropertyVector prop = elem->getPropertyVector();
00339         int count = 0;
00340         for(unsigned int i=0; i<prop.size(); ++i)
00341         {
00342                 if(indexes && (find(indexes->begin(), indexes->end(),(int)i) == indexes->end()))
00343                         continue;
00344 
00345                 string attrName = prop[i].attr_.rep_.name_;
00346                 size_t pos = attrName.find(".", 0, 1);
00347 
00348                 std::string tableName; 
00349                 if (pos != string::npos)
00350                 {
00351                         attrName = attrName.substr(pos+1);
00352                         tableName = attrName.substr(0, pos-1);
00353                         if (tableName != table.name())
00354                continue;
00355                 } 
00356 
00357                 if( (find(attrs.begin(), attrs.end(), attrName)!=attrs.end()) &&
00358                         (TeStringCompare(attrName,table.uniqueName()) == false) && 
00359                         (TeStringCompare(attrName,table.linkName()) == false) && 
00360                         (TeStringCompare(attrName,table.attInitialTime()) == false) && 
00361                         (TeStringCompare(attrName,table.attFinalTime()) == false) )
00362                 {
00363                 
00364                         if((prop[i].attr_.rep_.type_!=TeSTRING) && (prop[i].value_.empty()))
00365                                 continue; 
00366 
00367                         if(count>0)
00368                                 ins += ",";
00369                         
00370                         ++count;
00371                         ins += attrName +" = ";
00372                 
00373                         if(prop[i].attr_.rep_.type_==TeSTRING)
00374                                 ins += "'"+ db->escapeSequence(prop[i].value_) +"'";
00375                         else if(prop[i].attr_.rep_.type_==TeREAL)
00376                         {
00377                                 std::string strValue = prop[i].value_;
00378                                 replace (strValue.begin(), strValue.end(), ',', '.');
00379                                 ins += strValue;
00380                         }
00381                         else if(prop[i].attr_.rep_.type_==TeDATETIME)
00382                         {
00383                                 TeTime time(prop[i].value_, prop[i].attr_.dateChronon_, prop[i].attr_.dateTimeFormat_, prop[i].attr_.dateSeparator_, prop[i].attr_.timeSeparator_);  
00384                                 ins += db->getSQLTime(time);
00385                         }
00386                         else
00387                                 ins += prop[i].value_;
00388                 }
00389         }
00390 
00391         // -------- timeInterval
00392         if(!table.attInitialTime().empty())
00393         {
00394                 TeTime time (elem->timeInterval().getT1());
00395                 if(count>0)
00396                         ins +=  ", "; 
00397                 ins += table.attInitialTime() +" = ";
00398                 ins +=  db->getSQLTime(time); 
00399                 ++count;
00400         }
00401 
00402         if((!table.attFinalTime().empty()) && (table.attInitialTime()!=table.attFinalTime()))
00403         {
00404                 TeTime time (elem->timeInterval().getT2());
00405                 if(count>0)
00406                         ins +=  ", "; 
00407                 ins += table.attFinalTime() +" = ";
00408                 ins +=  db->getSQLTime(time);
00409                 ++count;
00410         }
00411         // ----------
00412 
00413         if ( count == 0 ) 
00414                 return true; 
00415 
00416         ins += " WHERE "+ table.uniqueName() +" = '"+ uniqueId +"'";
00417         
00418         if(!db->execute (ins))
00419                 return false;
00420 
00421         return true;
00422 }
00423  
00424 /** \example createSTElementSetFromLayer.cpp
00425         Shows how to create a new Spatial Temporal Element Set (STElementSet) from a layer
00426  */
00427 
00428 /** \example createSTElementSetFromTheme.cpp
00429         Shows how to create a new Spatial Temporal Element Set (STElementSet) from a theme
00430  */
00431 #endif
00432 

Generated on Sun Jul 29 04:01:28 2012 for TerraLib - Development Source by  doxygen 1.5.3