src/terralib/ogr/Transactor.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 // TerraLib
21 #include "../common/progress/TaskProgress.h"
22 #include "../common/StringUtils.h"
23 #include "../core/translator/Translator.h"
24 #include "../core/uri/URI.h"
25 #include "../core/uri/Utils.h"
26 #include "../dataaccess/dataset/ObjectId.h"
27 #include "../dataaccess/dataset/ObjectIdSet.h"
28 #include "../dataaccess/query/DataSetName.h"
29 #include "../dataaccess/query/Query.h"
30 #include "../dataaccess/query/Select.h"
31 #include "../dataaccess/utils/Utils.h"
32 #include "../datatype/ByteArray.h"
33 #include "../datatype/Date.h"
34 #include "../datatype/TimeInstant.h"
35 #include "../geometry/Envelope.h"
36 #include "../geometry/GeometryProperty.h"
37 #include "../srs/SpatialReferenceSystemManager.h"
38 #include "../srs/Config.h"
39 #include "DataSource.h"
40 #include "DataSet.h"
41 #include "SQLVisitor.h"
42 #include "Transactor.h"
43 #include "Utils.h"
44 
45 //BOOST
46 #include <boost/thread/locks.hpp>
47 
48 // OGR
49 #include <ogrsf_frmts.h>
50 
51 OGRFieldType GetOGRType(int te_type)
52 {
53  switch (te_type)
54  {
55  case te::dt::CHAR_TYPE:
56  case te::dt::UCHAR_TYPE:
58  return OFTString;
59 
60  case te::dt::INT16_TYPE:
62  case te::dt::INT32_TYPE:
64  return OFTInteger;
65 
66  case te::dt::INT64_TYPE:
68  return OFTInteger64;
69 
70  case te::dt::FLOAT_TYPE:
73  return OFTReal;
74 
76  return OFTDateTime;
77  };
78 
79  return OFTInteger;
80 }
81 
83 {
84 }
85 
87 
89 {
90  return nullptr;
91 }
92 
94 {
95 }
96 
98 {
99  if (!m_ogrDs->getOGRDataSource())
100  return;
101 
102  m_ogrDs->getOGRDataSource()->FlushCache();
103 }
104 
106 {
107 }
108 
110 {
111  return false;
112 }
113 
114 std::unique_ptr<te::da::DataSet> te::ogr::Transactor::getDataSet(const std::string& name,
115  te::common::TraverseType /*travType*/,
116  bool /*connected*/,
117  const te::common::AccessPolicy pol)
118 {
119  boost::unique_lock< boost::mutex > lockGuard(getStaticMutex());
120 
121  if (!m_ogrDs->getOGRDataSource())
122  {
123  lockGuard.release();
124  getStaticMutex().unlock();
125  return std::unique_ptr<te::da::DataSet>(nullptr);
126  }
127 
128  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(m_ogrDs->getEncoding()).c_str());
129 
130  unsigned int ogropenflags = (pol == te::common::RWAccess || pol == te::common::WAccess) ? GDAL_OF_UPDATE : GDAL_OF_READONLY;
131  GDALDataset* ds = static_cast<GDALDataset*>(GDALOpenEx(m_ogrDs->getOGRDataSource()->GetDescription(), ogropenflags, nullptr, nullptr, nullptr));
132  if (!ds)
133  {
134  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
135  return std::unique_ptr<te::da::DataSet>(nullptr);
136  }
137 
138  std::string sql = "SELECT FID, * FROM \"" + name + "\"";
139  OGRLayer* layer = ds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
140 
141  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
142 
143  lockGuard.release();
144  getStaticMutex().unlock();
145 
146  if(layer == nullptr)
147  throw Exception(TE_TR("The informed data set could not be found in the data source."));
148 
149  return std::unique_ptr<te::da::DataSet>(new DataSet(ds, layer));
150 }
151 
152 std::unique_ptr<te::da::DataSet> te::ogr::Transactor::getDataSet(const std::string& name,
153  const std::string& /*propertyName*/,
154  const te::gm::Envelope* e,
156  te::common::TraverseType /*travType*/,
157  bool /*connected*/,
158  const te::common::AccessPolicy pol)
159 {
160  boost::unique_lock< boost::mutex > lockGuard(getStaticMutex());
161 
162  if (!m_ogrDs->getOGRDataSource())
163  {
164  lockGuard.release();
165  getStaticMutex().unlock();
166  return std::unique_ptr<te::da::DataSet>(nullptr);
167  }
168 
169  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(m_ogrDs->getEncoding()).c_str());
170 
171  unsigned int ogropenflags = (pol == te::common::RWAccess || pol == te::common::WAccess) ? GDAL_OF_UPDATE : GDAL_OF_READONLY;
172  GDALDataset* ds = static_cast<GDALDataset*>(GDALOpenEx(m_ogrDs->getOGRDataSource()->GetDescription(), ogropenflags, nullptr, nullptr, nullptr));
173  if (!ds)
174  {
175  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
176  return std::unique_ptr<te::da::DataSet>(nullptr);
177  }
178 
179  std::string sql = "SELECT FID, * FROM \"" + name + "\"";
180  OGRLayer* layer = ds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
181 
182  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
183 
184  lockGuard.release();
185  getStaticMutex().unlock();
186 
187  if(layer == nullptr)
188  throw Exception(TE_TR("The informed data set could not be found in the data source."));
189 
190  layer->SetSpatialFilterRect(e->m_llx, e->m_lly, e->m_urx, e->m_ury);
191 
192  return std::unique_ptr<te::da::DataSet>(new DataSet(ds, layer));
193 }
194 
195 std::unique_ptr<te::da::DataSet> te::ogr::Transactor::getDataSet(const std::string& name,
196  const std::string& /*propertyName*/,
197  const te::gm::Geometry* g,
199  te::common::TraverseType /*travType*/,
200  bool /*connected*/,
201  const te::common::AccessPolicy pol)
202 {
203  boost::unique_lock< boost::mutex > lockGuard(getStaticMutex());
204 
205  if (!m_ogrDs->getOGRDataSource())
206  {
207  lockGuard.release();
208  getStaticMutex().unlock();
209  return std::unique_ptr<te::da::DataSet>(nullptr);
210  }
211 
212  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(m_ogrDs->getEncoding()).c_str());
213 
214  unsigned int ogropenflags = (pol == te::common::RWAccess || pol == te::common::WAccess) ? GDAL_OF_UPDATE : GDAL_OF_READONLY;
215  GDALDataset* ds = static_cast<GDALDataset*>(GDALOpenEx(m_ogrDs->getOGRDataSource()->GetDescription(), ogropenflags, nullptr, nullptr, nullptr));
216  if (!ds)
217  {
218  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
219  return std::unique_ptr<te::da::DataSet>(nullptr);
220  }
221 
222  std::string sql = "SELECT FID, * FROM \"" + name + "\"";
223  OGRLayer* layer = ds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
224 
225  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
226 
227  lockGuard.release();
228  getStaticMutex().unlock();
229 
230  if(layer == nullptr)
231  throw Exception(TE_TR("The informed data set could not be found in the data source."));
232 
233  OGRGeometry* ogrg = Convert2OGR(g);
234 
235  layer->SetSpatialFilter(ogrg);
236 
237  OGRGeometryFactory::destroyGeometry(ogrg);
238 
239  return std::unique_ptr<te::da::DataSet>(new DataSet(ds, layer));
240 }
241 
242 std::unique_ptr<te::da::DataSet> te::ogr::Transactor::query(const te::da::Select& q,
243  te::common::TraverseType /*travType*/,
244  bool /*connected*/,
245  const te::common::AccessPolicy pol)
246 {
247  boost::unique_lock< boost::mutex > lockGuard(getStaticMutex());
248 
249  if (!m_ogrDs->getOGRDataSource())
250  {
251  lockGuard.release();
252  getStaticMutex().unlock();
253  return std::unique_ptr<te::da::DataSet>(nullptr);
254  }
255 
256  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(m_ogrDs->getEncoding()).c_str());
257 
258  unsigned int ogropenflags = (pol == te::common::RWAccess || pol == te::common::WAccess) ? GDAL_OF_UPDATE : GDAL_OF_READONLY;
259  GDALDataset* ds = static_cast<GDALDataset*>(GDALOpenEx(m_ogrDs->getOGRDataSource()->GetDescription(), ogropenflags, nullptr, nullptr, nullptr));
260  if (!ds)
261  {
262  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
263  return std::unique_ptr<te::da::DataSet>();
264  }
265 
266  std::string sql;
267 
268  SQLVisitor visitor(*m_ogrDs->getDialect(), sql);
269 
270  q.accept(visitor);
271 
272  sql = RemoveSpatialSql(sql);
273 
274  OGRLayer* layer = ds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
275 
276  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
277 
278  lockGuard.release();
279  getStaticMutex().unlock();
280 
281  if(layer == nullptr)
282  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
283 
284  CPLSetConfigOption("SHAPE_ENCODING", "UTF-8");
285 
286  te::gm::Envelope* e = visitor.getMBR();
287 
288  if(e != nullptr)
289  layer->SetSpatialFilterRect(e->m_llx, e->m_lly, e->m_urx, e->m_ury);
290 
291  return std::unique_ptr<te::da::DataSet>(new DataSet(ds, layer));
292 }
293 
294 std::unique_ptr<te::da::DataSet> te::ogr::Transactor::query(const std::string& query,
295  te::common::TraverseType /*travType*/,
296  bool /*connected*/,
297  const te::common::AccessPolicy pol)
298 {
299  boost::unique_lock< boost::mutex > lockGuard(getStaticMutex());
300 
301  if (!m_ogrDs->getOGRDataSource())
302  {
303  lockGuard.release();
304  getStaticMutex().unlock();
305  return std::unique_ptr<te::da::DataSet>();
306  }
307 
308  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(m_ogrDs->getEncoding()).c_str());
309 
310  unsigned int ogropenflags = (pol == te::common::RWAccess || pol == te::common::WAccess) ? GDAL_OF_UPDATE : GDAL_OF_READONLY;
311  GDALDataset* ds = static_cast<GDALDataset*>(GDALOpenEx(m_ogrDs->getOGRDataSource()->GetDescription(), ogropenflags, nullptr, nullptr, nullptr));
312  if (!ds)
313  {
314  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
315  return std::unique_ptr<te::da::DataSet>();
316  }
317 
318  // Adding FID attribute case "SELECT *"
319  std::string queryCopy = query;
320  std::size_t pos = queryCopy.find("*");
321  if(pos != std::string::npos)
322  {
323  std::string fid = "FID, *";
324  queryCopy.replace(pos, 1, fid);
325  }
326 
327  OGRLayer* layer = ds->ExecuteSQL(queryCopy.c_str(), nullptr, nullptr);
328 
329  CPLSetConfigOption("SHAPE_ENCODING", te::core::CharEncoding::getEncodingName(te::core::EncodingType::UTF8).c_str());
330 
331  lockGuard.release();
332  getStaticMutex().unlock();
333 
334  if(layer == nullptr)
335  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
336 
337  return std::unique_ptr<te::da::DataSet>(new DataSet(ds, layer));
338 }
339 
341 {
342  std::string sql;
343  SQLVisitor v(*m_ogrDs->getDialect(), sql);
344 
345  command.accept(v);
346 
347  execute(sql);
348 }
349 
350 void te::ogr::Transactor::execute(const std::string& command)
351 {
352  if (!m_ogrDs->getOGRDataSource())
353  return;
354 
355  OGRLayer* layer = m_ogrDs->getOGRDataSource()->ExecuteSQL(command.c_str(), nullptr, "");
356 
357  if(layer != nullptr)
358  m_ogrDs->getOGRDataSource()->ReleaseResultSet(layer);
359 }
360 
361 std::unique_ptr<te::da::PreparedQuery> te::ogr::Transactor::getPrepared(const std::string& /*qName*/)
362 {
363  return std::unique_ptr<te::da::PreparedQuery>();
364 }
365 
366 std::unique_ptr<te::da::BatchExecutor> te::ogr::Transactor::getBatchExecutor()
367 {
368  return std::unique_ptr<te::da::BatchExecutor>();
369 }
370 
372 {
373 }
374 
376 {
377  return m_fid;
378 }
379 
380 std::string te::ogr::Transactor::escape(const std::string& value)
381 {
382  return value;
383 }
384 
385 std::vector<std::string> te::ogr::Transactor::getDataSetNames()
386 {
387  std::vector<std::string> names;
388 
389  if (!m_ogrDs->getOGRDataSource())
390  return names;
391 
392  for(int i=0; i<m_ogrDs->getOGRDataSource()->GetLayerCount(); i++)
393  names.push_back(m_ogrDs->getOGRDataSource()->GetLayer(i)->GetName());
394 
395  return names;
396 }
397 
399 {
400  if (!m_ogrDs->getOGRDataSource())
401  return 0;
402 
403  return static_cast<size_t>(m_ogrDs->getOGRDataSource()->GetLayerCount());
404 }
405 
406 std::unique_ptr<te::da::DataSetType> te::ogr::Transactor::getDataSetType(const std::string& name)
407 {
408  if (!m_ogrDs->getOGRDataSource())
409  return std::unique_ptr<te::da::DataSetType>();
410 
411  std::string sql("SELECT FID, * FROM \"");
412  sql += name + "\"";
413 
414  OGRLayer* l = m_ogrDs->getOGRDataSource()->ExecuteSQL(sql.c_str(), nullptr, nullptr);
415 
416  if (l == nullptr)
417  return std::unique_ptr<te::da::DataSetType>();
418 
419  std::unique_ptr<te::da::DataSetType> type(Convert2TerraLib(l->GetLayerDefn()));
420 
421  type->setName(name);
422 
423  const char* colIdName = l->GetFIDColumn();
424 
425  if (colIdName == nullptr || colIdName[0] == '\0')
426  colIdName = "FID";
427 
428  int pos = l->GetLayerDefn()->GetFieldIndex(colIdName);
429  if (pos >= 0)
430  {
431  te::da::PrimaryKey* pk = new te::da::PrimaryKey(colIdName, type.get());
432  pk->add(type->getProperty(static_cast<size_t>(pos)));
433  }
434 
435  int srs = te::ogr::Convert2TerraLibProjection(l->GetSpatialRef());
436 
438 
439  if (gp != nullptr)
440  gp->setSRID(srs);
441 
442  if ((gp != nullptr) && (gp->getGeometryType() == te::gm::GeometryType))
443  {
444  OGRLayerH lh(l);
445 
446  OGR_L_ResetReading(lh);
447 
448  OGRFeatureH nextFeature = OGR_L_GetNextFeature(lh);
449  if (nextFeature)
450  {
451  OGRGeometryH geometry = OGR_F_GetGeometryRef(nextFeature);
452  if (geometry)
453  {
454  te::gm::GeomType geomType = Convert2TerraLib(OGR_G_GetGeometryType(geometry));
455 
456  if (geomType != te::gm::GeometryType)
457  {
458  gp->setGeometryType(geomType);
459  }
460  }
461  }
462 
463  OGR_L_ResetReading(lh);
464  }
465 
466  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
467 
468  return type;
469 }
470 
471 std::unique_ptr<te::da::DataSetTypeCapabilities> te::ogr::Transactor::getCapabilities(const std::string &name)
472 {
473  std::unique_ptr<te::da::DataSetTypeCapabilities> cap(new te::da::DataSetTypeCapabilities);
474 
475  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(name.c_str());
476 
477  if(l != nullptr)
478  {
479  cap->setSupportAddColumn((l->TestCapability(OLCCreateField) == 0) ? false : true);
480  cap->setSupportRemoveColumn((l->TestCapability(OLCDeleteField) == 0) ? false : true);
481  cap->setSupportDataEdition((l->TestCapability(OLCRandomWrite) == 0) ? false : true);
482  }
483 
484  return cap;
485 }
486 
487 boost::ptr_vector<te::dt::Property> te::ogr::Transactor::getProperties(const std::string& datasetName)
488 {
489  boost::ptr_vector<te::dt::Property> ps;
490 
491  if (!m_ogrDs->getOGRDataSource())
492  return ps;
493 
494  std::string sql("SELECT FID, * FROM \"");
495  sql += datasetName + "\"";
496 
497  OGRLayer* l = m_ogrDs->getOGRDataSource()->ExecuteSQL(sql.c_str(), nullptr, nullptr);
498 
499  if(l!=nullptr)
500  {
501  int srs = te::ogr::Convert2TerraLibProjection(l->GetSpatialRef());
502  std::unique_ptr<te::da::DataSetType> dt(Convert2TerraLib(l->GetLayerDefn(),srs));
503  std::vector<te::dt::Property*> props = dt->getProperties();
504  std::vector<te::dt::Property*>::iterator it;
505 
506  for(it=props.begin(); it!=props.end(); ++it)
507  ps.push_back((*it)->clone());
508  }
509 
510  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
511 
512  return ps;
513 }
514 
515 std::unique_ptr<te::dt::Property> te::ogr::Transactor::getProperty(const std::string& datasetName, const std::string& name)
516 {
517  if (!m_ogrDs->getOGRDataSource())
518  return std::unique_ptr<te::dt::Property>();
519 
520  int idx = -1;
521  std::string sql("SELECT FID, * FROM \"");
522  sql += datasetName + "\"";
523 
524  OGRLayer* l = m_ogrDs->getOGRDataSource()->ExecuteSQL(sql.c_str(), nullptr, nullptr);
525 
526  if(l != nullptr)
527  idx = l->GetLayerDefn()->GetFieldIndex(name.c_str());
528 
529  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
530 
531  return getProperty(datasetName, static_cast<size_t>(idx));
532 }
533 
534 std::unique_ptr<te::dt::Property> te::ogr::Transactor::getProperty(const std::string& datasetName, std::size_t propertyPos)
535 {
536  GDALDataset* ogrds = m_ogrDs->getOGRDataSource();
537  if (!ogrds)
538  return std::unique_ptr<te::dt::Property>();
539 
540  std::unique_ptr<te::dt::Property> res;
541  std::string sql ("SELECT FID, * FROM \"");
542  sql += datasetName + "\"";
543 
544  OGRLayer* l = ogrds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
545 
546  if(l != nullptr)
547  {
548  OGRFeatureDefn* def = l->GetLayerDefn();
549  OGRFieldDefn* fdef = def->GetFieldDefn(static_cast<int>(propertyPos));
550 
551  if(fdef != nullptr)
552  res.reset(Convert2TerraLib(fdef));
553  }
554 
555  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
556 
557  return res;
558 }
559 
560 std::vector<std::string> te::ogr::Transactor::getPropertyNames(const std::string& datasetName)
561 {
562  GDALDataset* ogrds = m_ogrDs->getOGRDataSource();
563  if (!ogrds)
564  return std::vector<std::string>();
565 
566  std::vector<std::string> res;
567  std::string sql ("SELECT FID, * FROM \"");
568  sql += datasetName + "\"";
569 
570  OGRLayer* l = ogrds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
571 
572  if(l != nullptr)
573  {
574  OGRFeatureDefn* def = l->GetLayerDefn();
575 
576  for(int i=0; i<def->GetFieldCount(); i++)
577  res.push_back(def->GetFieldDefn(i)->GetNameRef());
578  }
579 
580  ogrds->ReleaseResultSet(l);
581 
582  return res;
583 }
584 
585 std::size_t te::ogr::Transactor::getNumberOfProperties(const std::string& datasetName)
586 {
587  GDALDataset* ogrds = m_ogrDs->getOGRDataSource();
588  if (!ogrds)
589  return 0;
590 
591  std::string sql("SELECT FID, * FROM \"");
592  sql += datasetName + "\"";
593 
594  OGRLayer* l = ogrds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
595 
596  int res = 0;
597 
598  if(l != nullptr)
599  {
600  res = l->GetLayerDefn()->GetFieldCount();
601  ogrds->ReleaseResultSet(l);
602  }
603 
604  return static_cast<size_t>(res);
605 }
606 
607 bool te::ogr::Transactor::propertyExists(const std::string& datasetName, const std::string& name)
608 {
609  GDALDataset* ogrds = m_ogrDs->getOGRDataSource();
610  if (!ogrds)
611  return false;
612 
613  std::string sql("SELECT FID, * FROM \"");
614  sql += datasetName + "\"";
615  bool res = false;
616 
617  OGRLayer* l = ogrds->ExecuteSQL(sql.c_str(), nullptr, nullptr);
618 
619  if(l != nullptr)
620  {
621  res = (l->GetLayerDefn()->GetFieldIndex(name.c_str()) != -1);
622  ogrds->ReleaseResultSet(l);
623  }
624 
625  return res;
626 }
627 
628 void te::ogr::Transactor::addProperty(const std::string& datasetName, te::dt::Property* p)
629 {
630  if (!m_ogrDs->getOGRDataSource())
631  return;
632 
633  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
634 
635  if(l != nullptr)
636  {
637  if(p->getType() != te::dt::GEOMETRY_TYPE)
638  {
639  OGRFieldDefn* nField = Convert2OGR(p);
640  OGRErr error = l->CreateField(nField);
641 
642  delete nField;
643 
644  if(error != OGRERR_NONE)
645  throw Exception(TE_TR("Error when attempting add the property: " + p->getName() + "."));
646 
647  error = l->SyncToDisk();
648 
649  if(error != OGRERR_NONE)
650  throw Exception(TE_TR("Error saving changes on the file."));
651  }
652  }
653 }
654 
655 void te::ogr::Transactor::dropProperty(const std::string& datasetName, const std::string& name)
656 {
657  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
658 
659  if(l != nullptr)
660  {
661  if(!l->TestCapability(OLCDeleteField))
662  throw Exception(TE_TR("This dataset do not support remove properties operation."));
663 
664  int fPos = l->GetLayerDefn()->GetFieldIndex(name.c_str());
665 
666  if(fPos < 0)
667  throw Exception(TE_TR("Field not found."));
668 
669  OGRErr error = l->DeleteField(fPos);
670 
671  if(error != OGRERR_NONE)
672  throw Exception(TE_TR("Error when attempting remove the property."));
673 
674  error = l->SyncToDisk();
675 
676  if(error != OGRERR_NONE)
677  throw Exception(TE_TR("Error saving changes on the file."));
678  }
679 }
680 
681 void te::ogr::Transactor::renameProperty(const std::string& datasetName,
682  const std::string& propertyName,
683  const std::string& newPropertyName)
684 {
685  if (!m_ogrDs->getOGRDataSource())
686  return;
687 
688  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
689 
690  if(l != nullptr)
691  {
692  int idx = l->GetLayerDefn()->GetFieldIndex(propertyName.c_str());
693 
694  if(idx == -1)
695  throw Exception(TE_TR("Field to be renamed does not exists."));
696 
697  OGRFieldDefn* df = l->GetLayerDefn()->GetFieldDefn(idx);
698 
699  OGRFieldDefn* dfn = new OGRFieldDefn(df);
700 
701  dfn->SetName(newPropertyName.c_str());
702 
703  OGRErr err = l->AlterFieldDefn(idx, dfn, ALTER_NAME_FLAG);
704 
705  if(err != OGRERR_NONE)
706  throw Exception(TE_TR("Fail to rename field."));
707  }
708 }
709 
710 void te::ogr::Transactor::changePropertyDefinition(const std::string& datasetName, const std::string& propName, te::dt::Property* newProp)
711 {
712  if (!m_ogrDs->getOGRDataSource())
713  return;
714 
715  std::unique_ptr<te::dt::Property> p;
716 
717  p.reset(newProp);
718 
719  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
720 
721  if(l != nullptr)
722  {
723  if(!l->TestCapability(OLCAlterFieldDefn))
724  throw Exception(TE_TR("This data source do not support the operation of alter columns type."));
725 
726  int idx = l->GetLayerDefn()->GetFieldIndex(propName.c_str());
727 
728  if(idx == -1)
729  throw Exception(TE_TR("Field to be renamed does not exists."));
730 
731  OGRFieldDefn* dfn = new OGRFieldDefn(l->GetLayerDefn()->GetFieldDefn(idx));
732 
733  dfn->SetType(GetOGRType(newProp->getType()));
734 
735  OGRErr err = l->AlterFieldDefn(idx, dfn, ALTER_TYPE_FLAG);
736 
737  if(err != OGRERR_NONE)
738  throw Exception(TE_TR("Fail to to change field type."));
739 
740  std::string name = m_ogrDs->getOGRDataSource()->GetDescription();
741 
742  err = l->SyncToDisk();
743  }
744 }
745 
746 std::unique_ptr<te::da::PrimaryKey> te::ogr::Transactor::getPrimaryKey(const std::string& datasetName)
747 {
748  if (!m_ogrDs->getOGRDataSource())
749  return std::unique_ptr<te::da::PrimaryKey>();
750 
751  std::unique_ptr<te::da::PrimaryKey> res;
752  std::string sql("SELECT FID, * FROM \"");
753  sql += datasetName + "\"";
754 
755  OGRLayer* layer = m_ogrDs->getOGRDataSource()->ExecuteSQL(sql.c_str(), nullptr, nullptr);
756 
757  if(layer != nullptr)
758  {
759  const char* colIdName = layer->GetFIDColumn();
760 
761  if(colIdName == nullptr || colIdName[0] == '\0')
762  colIdName = "FID";
763 
764  int pos = layer->GetLayerDefn()->GetFieldIndex(colIdName);
765 
766  if(pos >= 0)
767  {
768  res.reset(new te::da::PrimaryKey);
769  res->add(getProperty(datasetName, static_cast<size_t>(pos)).get());
770  }
771  }
772 
773  m_ogrDs->getOGRDataSource()->ReleaseResultSet(layer);
774 
775  return res;
776 }
777 
778 bool te::ogr::Transactor::primaryKeyExists(const std::string& /*datasetName*/, const std::string& /*name*/)
779 {
780  return false;
781 }
782 
783 void te::ogr::Transactor::addPrimaryKey(const std::string& /*datasetName*/, te::da::PrimaryKey* /*pk*/)
784 {
785 }
786 
787 void te::ogr::Transactor::dropPrimaryKey(const std::string& /*datasetName*/)
788 {
789 }
790 
791 std::unique_ptr<te::da::ForeignKey> te::ogr::Transactor::getForeignKey(const std::string& /*datasetName*/, const std::string& /*name*/)
792 {
793  return std::unique_ptr<te::da::ForeignKey>();
794 }
795 
796 std::vector<std::string> te::ogr::Transactor::getForeignKeyNames(const std::string& /*datasetName*/)
797 {
798  return std::vector<std::string>();
799 }
800 
801 bool te::ogr::Transactor::foreignKeyExists(const std::string& /*datasetName*/, const std::string& /*name*/)
802 {
803  return false;
804 }
805 
806 void te::ogr::Transactor::addForeignKey(const std::string& /*datasetName*/, te::da::ForeignKey* /*fk*/)
807 {
808 }
809 
810 void te::ogr::Transactor::dropForeignKey(const std::string& /*datasetName*/, const std::string& /*fkName*/)
811 {
812 }
813 
814 std::unique_ptr<te::da::UniqueKey> te::ogr::Transactor::getUniqueKey(const std::string& /*datasetName*/, const std::string& /*name*/)
815 {
816  return std::unique_ptr<te::da::UniqueKey>();
817 }
818 
819 std::vector<std::string> te::ogr::Transactor::getUniqueKeyNames(const std::string& /*datasetName*/)
820 {
821  return std::vector<std::string>();
822 }
823 
824 bool te::ogr::Transactor::uniqueKeyExists(const std::string& /*datasetName*/, const std::string& /*name*/)
825 {
826  return false;
827 }
828 
829 void te::ogr::Transactor::addUniqueKey(const std::string& /*datasetName*/, te::da::UniqueKey* /*uk*/)
830 {
831 }
832 
833 void te::ogr::Transactor::dropUniqueKey(const std::string& /*datasetName*/, const std::string& /*name*/)
834 {
835 }
836 
837 std::unique_ptr<te::da::CheckConstraint> te::ogr::Transactor::getCheckConstraint(const std::string& /*datasetName*/, const std::string& /*name*/)
838 {
839  return std::unique_ptr<te::da::CheckConstraint>();
840 }
841 
842 std::vector<std::string> te::ogr::Transactor::getCheckConstraintNames(const std::string& /*datasetName*/)
843 {
844  return std::vector<std::string>();
845 }
846 
847 bool te::ogr::Transactor::checkConstraintExists(const std::string& /*datasetName*/, const std::string& /*name*/)
848 {
849  return false;
850 }
851 
852 void te::ogr::Transactor::addCheckConstraint(const std::string& /*datasetName*/, te::da::CheckConstraint* /*cc*/)
853 {
854 }
855 
856 void te::ogr::Transactor::dropCheckConstraint(const std::string& /*datasetName*/, const std::string& /*name*/)
857 {
858 }
859 
860 std::unique_ptr<te::da::Index> te::ogr::Transactor::getIndex(const std::string& /*datasetName*/, const std::string& /*name*/)
861 {
862  return std::unique_ptr<te::da::Index>();
863 }
864 
865 std::vector<std::string> te::ogr::Transactor::getIndexNames(const std::string& /*datasetName*/)
866 {
867  return std::vector<std::string>();
868 }
869 
870 bool te::ogr::Transactor::indexExists(const std::string& /*datasetName*/, const std::string& /*name*/)
871 {
872  return false;
873 }
874 
875 void te::ogr::Transactor::addIndex(const std::string& /*datasetName*/, te::da::Index* /*idx*/,
876  const std::map<std::string, std::string>& /*options*/)
877 {
878 }
879 
880 void te::ogr::Transactor::dropIndex(const std::string& /*datasetName*/, const std::string& /*idxName*/)
881 {
882 }
883 
884 std::unique_ptr<te::da::Sequence> te::ogr::Transactor::getSequence(const std::string& /*name*/)
885 {
886  return std::unique_ptr<te::da::Sequence>();
887 }
888 
889 std::vector<std::string> te::ogr::Transactor::getSequenceNames()
890 {
891  return std::vector<std::string>();
892 }
893 
894 bool te::ogr::Transactor::sequenceExists(const std::string& /*name*/)
895 {
896  return false;
897 }
898 
900 {
901 }
902 
903 void te::ogr::Transactor::dropSequence(const std::string& /*name*/)
904 {
905 }
906 
907 std::unique_ptr<te::gm::Envelope> te::ogr::Transactor::getExtent(const std::string& datasetName,
908  const std::string& propertyName)
909 {
910  if (!m_ogrDs->getOGRDataSource())
911  return std::unique_ptr<te::gm::Envelope>();
912 
913  std::unique_ptr<te::gm::Envelope> res;
914  std::string sql("SELECT ");
915  sql += propertyName + " FROM \"";
916  sql += datasetName + "\"";
917 
918  OGRLayer* l = m_ogrDs->getOGRDataSource()->ExecuteSQL(sql.c_str(), nullptr, nullptr);
919 
920  if(l != nullptr)
921  {
922  std::unique_ptr<OGREnvelope> env(new OGREnvelope);
923 
924  if(l->GetExtent(env.get()) != OGRERR_NONE)
925  {
926  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
927  throw Exception(TE_TR("Error when attempting get extent."));
928  }
929 
930  res.reset(Convert2TerraLib(env.get()));
931 
932  m_ogrDs->getOGRDataSource()->ReleaseResultSet(l);
933  }
934 
935  return res;
936 }
937 
938 std::unique_ptr<te::gm::Envelope> te::ogr::Transactor::getExtent(const std::string& datasetName,
939  std::size_t /*propertyPos*/)
940 {
941  return getExtent(datasetName, "OGR_GEOMETRY");
942 }
943 
944 std::size_t te::ogr::Transactor::getNumberOfItems(const std::string& datasetName)
945 {
946  if (!m_ogrDs->getOGRDataSource())
947  return 0;
948 
949  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
950 
951  if(l != nullptr)
952  return static_cast<size_t>(l->GetFeatureCount());
953 
954  return 0;
955 }
956 
958 {
959  if (!m_ogrDs->getOGRDataSource())
960  return false;
961 
962  return (m_ogrDs->getOGRDataSource()->GetLayerCount() > 0);
963 }
964 
965 bool te::ogr::Transactor::dataSetExists(const std::string& name)
966 {
967  if (!m_ogrDs->getOGRDataSource())
968  return false;
969 
970  return (m_ogrDs->getOGRDataSource()->GetLayerByName(name.c_str()) != nullptr);
971 }
972 
973 void te::ogr::Transactor::createDataSet(te::da::DataSetType* dt, const std::map<std::string, std::string>& /*options*/)
974 {
975  if (!m_ogrDs->getOGRDataSource())
976  {
978  }
979 
980  if (!m_ogrDs->getOGRDataSource())
981  return;
982 
983  if(!m_ogrDs->getOGRDataSource()->TestCapability(ODsCCreateLayer))
984  throw Exception(TE_TR("This driver does not support dataset creation."));
985 
986  OGRwkbGeometryType geomType = wkbUnknown;
987  OGRSpatialReference* srs = nullptr;
988  if(dt->hasGeom())
989  {
990  geomType = Convert2OGR(te::da::GetFirstGeomProperty(dt)->getGeometryType());
991  int srid = te::da::GetFirstGeomProperty(dt)->getSRID();
992  if (srid != TE_UNKNOWN_SRS)
993  {
994  srs = Convert2OGRProjection( srid );
995  }
996  }
997 
998  char** papszOptions = nullptr;
999 
1000  std::map<std::string, std::string> kvp = te::core::Expand(m_ogrDs->getConnectionInfo().query());
1001  std::map<std::string, std::string>::const_iterator it = kvp.begin();
1002  while(it != kvp.end())
1003  {
1004  papszOptions = CSLSetNameValue(papszOptions, it->first.c_str(), it->second.c_str());
1005  ++it;
1006  }
1007 
1008  OGRLayer* newLayer = m_ogrDs->getOGRDataSource()->CreateLayer(dt->getName().c_str(), srs, geomType, papszOptions);
1009 
1010  if (srs)
1011  srs->Release();
1012 
1013  if(papszOptions)
1014  CSLDestroy(papszOptions);
1015 
1016  if(newLayer == nullptr)
1017  throw Exception(TE_TR("Error when attempting create the dataset type."));
1018 
1019  dt->setName(newLayer->GetName());
1020 
1021 // add the properties
1022  for (size_t i = 0; i < dt->size(); ++i)
1023  {
1024  te::dt::Property* p = dt->getProperty(i);
1025 
1026  if (te::common::Convert2UCase(p->getName()) == "FID")
1027  continue;
1028 
1029  addProperty(dt->getName(), p);
1030  }
1031 }
1032 
1033 void te::ogr::Transactor::cloneDataSet(const std::string& name,
1034  const std::string& cloneName,
1035  const std::map<std::string, std::string>& /*options*/)
1036 {
1037  if (!m_ogrDs->getOGRDataSource())
1038  return;
1039 
1040  if(!m_ogrDs->getOGRDataSource()->TestCapability(ODsCCreateLayer))
1041  throw Exception(TE_TR("This driver does not support creates a dataset."));
1042 
1043  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(name.c_str());
1044 
1045  if(l == nullptr)
1046  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
1047 
1048  OGRLayer* cl = m_ogrDs->getOGRDataSource()->CopyLayer(l, cloneName.c_str());
1049 
1050  if(cl == nullptr)
1051  throw Exception(TE_TR("Error when attempting clone the dataset."));
1052 }
1053 
1054 void te::ogr::Transactor::dropDataSet(const std::string& name)
1055 {
1056  if (!m_ogrDs->getOGRDataSource())
1057  return;
1058 
1059  if(!m_ogrDs->getOGRDataSource()->TestCapability(ODsCDeleteLayer))
1060  throw Exception(TE_TR("This driver does not support remove a dataset."));
1061 
1062  int i=0;
1063 
1064  for(; i<m_ogrDs->getOGRDataSource()->GetLayerCount(); i++)
1065  if(name.compare(m_ogrDs->getOGRDataSource()->GetLayer(i)->GetName()) == 0)
1066  break;
1067 
1068  if(i == m_ogrDs->getOGRDataSource()->GetLayerCount())
1069  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
1070 
1071  if(m_ogrDs->getOGRDataSource()->DeleteLayer(i) != OGRERR_NONE)
1072  throw Exception(TE_TR("Error when attempting to remove the dataset."));
1073 }
1074 
1075 void te::ogr::Transactor::renameDataSet(const std::string& /*name*/, const std::string& /*newName*/)
1076 {
1077 }
1078 
1079 void te::ogr::Transactor::add(const std::string& datasetName,
1080  te::da::DataSet* d,
1081  const std::map<std::string, std::string>&/* options*/,
1082  std::size_t limit,
1083  bool enableProgress)
1084 {
1085  if(limit == 0)
1086  limit = std::string::npos;
1087 
1088  if (!m_ogrDs->getOGRDataSource())
1089  return;
1090 
1091  OGRLayer* layer = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
1092 
1093  if(layer == nullptr)
1094  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
1095 
1096  //verify geometry property and get OGRSpatialReference information
1097  OGRSpatialReference* srs = nullptr;
1098 
1099  try
1100  {
1101  begin();
1102 
1103  std::size_t nproperties = d->getNumProperties();
1104 
1105  std::size_t nProcessedRows = 0;
1106 
1107  std::unique_ptr< te::common::TaskProgress > progressPtr;
1108  if(enableProgress == true)
1109  {
1110  progressPtr.reset( new te::common::TaskProgress );
1111  progressPtr->setTotalSteps(1 + static_cast<int>(d->size()));
1112  progressPtr->setMessage("Saving...");
1113  progressPtr->useTimer(true);
1114  progressPtr->pulse();
1115  }
1116 
1117  while(d->moveNext() && (nProcessedRows != limit))
1118  {
1119  OGRFeature* feat = OGRFeature::CreateFeature(layer->GetLayerDefn());
1120 
1121  std::size_t currfield = 0;
1122 
1123  for(std::size_t i = 0; i != nproperties; ++i)
1124  {
1125  if(te::common::Convert2UCase(d->getPropertyName(i)) == "FID")
1126  continue;
1127 
1128  if(d->isNull(i))
1129  {
1131  ++currfield;
1132 
1133  continue;
1134  }
1135 
1136  switch(d->getPropertyDataType(i))
1137  {
1138  case te::dt::INT16_TYPE:
1139  feat->SetField(static_cast<int>(currfield), d->getInt16(i));
1140  ++currfield;
1141  break;
1142 
1143  case te::dt::INT32_TYPE:
1144  feat->SetField(static_cast<int>(currfield), d->getInt32(i));
1145  ++currfield;
1146  break;
1147 
1148  case te::dt::INT64_TYPE:
1149  feat->SetField(static_cast<int>(currfield), static_cast<GIntBig>(d->getInt64(i)));
1150  ++currfield;
1151  break;
1152 
1153  case te::dt::STRING_TYPE:
1154  feat->SetField(static_cast<int>(currfield), d->getAsString(i).c_str());
1155  ++currfield;
1156  break;
1157 
1158  case te::dt::DOUBLE_TYPE:
1159  feat->SetField(static_cast<int>(currfield), d->getDouble(i));
1160  ++currfield;
1161  break;
1162 
1163  case te::dt::NUMERIC_TYPE:
1164  feat->SetField(static_cast<int>(currfield), atof(d->getNumeric(i).c_str()));
1165  ++currfield;
1166  break;
1167 
1169  {
1170  std::unique_ptr<te::dt::ByteArray> ba(d->getByteArray(i));
1171  feat->SetField(static_cast<int>(currfield), static_cast<int>(ba->bytesUsed()), reinterpret_cast<unsigned char*>(ba->getData()));
1172  ++currfield;
1173  }
1174  break;
1175 
1176  case te::dt::DATETIME_TYPE:
1177  {
1178  std::unique_ptr<te::dt::DateTime> dtm(d->getDateTime(i));
1179 
1180  te::dt::Date* dtime = dynamic_cast<te::dt::Date*>(dtm.get());
1181 
1182  if(dtime)
1183  {
1184  feat->SetField(static_cast<int>(currfield),
1185  static_cast<int>(dtime->getYear()),
1186  static_cast<int>(dtime->getMonth()),
1187  static_cast<int>(dtime->getDay()));
1188  ++currfield;
1189  break;
1190  }
1191 
1192  te::dt::TimeDuration* tduration = dynamic_cast<te::dt::TimeDuration*>(dtm.get());
1193 
1194  if(tduration)
1195  {
1196  feat->SetField(static_cast<int>(currfield), 0, 0, 0,
1197  static_cast<int>(tduration->getHours()),
1198  static_cast<int>(tduration->getMinutes()),
1199  static_cast<float>(tduration->getSeconds()));
1200  ++currfield;
1201  break;
1202  }
1203 
1204  te::dt::TimeInstant* tinst = dynamic_cast<te::dt::TimeInstant*>(dtm.get());
1205 
1206  if(tinst)
1207  {
1208  feat->SetField(static_cast<int>(currfield),
1209  static_cast<int>(tinst->getDate().getYear()),
1210  static_cast<int>(tinst->getDate().getMonth()),
1211  static_cast<int>(tinst->getDate().getDay()),
1212  static_cast<int>(tinst->getTime().getHours()),
1213  static_cast<int>(tinst->getTime().getMinutes()),
1214  static_cast<float>(tinst->getTime().getSeconds()));
1215  ++currfield;
1216  break;
1217  }
1218 
1219  throw Exception (TE_TR("Unsupported date and time type by OGR."));
1220  }
1221 
1222  case te::dt::GEOMETRY_TYPE:
1223  {
1224  std::unique_ptr<te::gm::Geometry> geom(d->getGeometry(i));
1225 
1226  if (!srs)
1227  srs = Convert2OGRProjection(geom->getSRID());
1228 
1229  OGRGeometry* OGRgeom = Convert2OGR(geom.get(), srs);
1230  feat->SetGeometryDirectly(OGRgeom);
1231  }
1232  break;
1233 
1234  default:
1235  throw Exception(TE_TR("Unsupported data type by OGR."));
1236  }
1237  }
1238 
1239  if(layer->CreateFeature(feat) != OGRERR_NONE)
1240  {
1241  OGRFeature::DestroyFeature(feat);
1242  throw Exception(TE_TR("Fail to insert dataset item."));
1243  }
1244 
1245  m_fid = static_cast<long>(feat->GetFID());
1246 
1247  OGRFeature::DestroyFeature(feat);
1248  nProcessedRows++;
1249 
1250  if(progressPtr.get())
1251  {
1252  progressPtr->pulse();
1253 
1254  if(progressPtr->isActive() == false)
1255  throw Exception(TE_TR("Save canceled!"));
1256  }
1257  }
1258 
1259  commit();
1260  }
1261  catch(Exception& e)
1262  {
1263  if (srs)
1264  srs->Release();
1265 
1266  rollBack();
1267  throw e;
1268  }
1269 
1270  if (srs)
1271  srs->Release();
1272 }
1273 
1274 void te::ogr::Transactor::remove(const std::string& datasetName, const te::da::ObjectIdSet* oids)
1275 {
1276  if(!m_ogrDs->getOGRDataSource())
1277  return;
1278 
1279  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
1280 
1281  if(l == nullptr)
1282  throw Exception(TE_TR("Could not retrieve the DataSet from data source."));
1283 
1284  if(!l->TestCapability(OLCDeleteFeature))
1285  throw Exception(TE_TR("Driver does not support removal of features."));
1286 
1287  std::vector<GIntBig> oidsInt;
1288 
1289  if (oids)
1290  {
1291  std::set<te::da::ObjectId*, te::common::LessCmp<te::da::ObjectId*> >::const_iterator it = oids->begin();
1292 
1293  while (it != oids->end())
1294  {
1295  std::string id = (*it)->getValueAsString();
1296 
1297  char* endptr = nullptr;
1298 
1299  GIntBig idLongLong = strtoll(id.c_str(), &endptr, 10);
1300 
1301  oidsInt.push_back(idLongLong);
1302 
1303  ++it;
1304  }
1305  }
1306  else
1307  {
1308  GIntBig count = l->GetFeatureCount();
1309 
1310  for (GIntBig i = 0; i < count; ++i)
1311  {
1312  oidsInt.push_back(i);
1313  }
1314  }
1315 
1316  begin();
1317 
1318 
1319  GIntBig s = static_cast<GIntBig>(oidsInt.size());
1320 
1321  for (GIntBig i = 0; i < s; ++i)
1322  {
1323  if (l->DeleteFeature(oidsInt[i]) != OGRERR_NONE)
1324  {
1325  rollBack();
1326  throw Exception(TE_TR("Error when attempting to remove the feature."));
1327  }
1328  }
1329 
1330  l->SyncToDisk();
1331 
1332  commit();
1333 
1334  m_ogrDs->getOGRDataSource()->ExecuteSQL(("REPACK " + datasetName).c_str(), nullptr, nullptr);
1335 }
1336 
1337 
1338 void te::ogr::Transactor::update(const std::string&/* datasetName*/,
1339  te::da::DataSet* /*dataset*/,
1340  const std::vector<std::size_t>&/* properties*/,
1341  const te::da::ObjectIdSet* /*oids*/,
1342  const std::map<std::string, std::string>& /*options*/,
1343  std::size_t /*limit*/)
1344 {
1345 }
1346 
1347 void te::ogr::Transactor::update(const std::string &datasetName, te::da::DataSet *dataset, const std::vector< std::set<int> >& properties,
1348  const std::vector<size_t>& ids)
1349 {
1350  if(m_ogrDs->getOGRDataSource() == nullptr)
1351  throw Exception(TE_TR("Data source failure"));
1352 
1353  OGRLayer* l = m_ogrDs->getOGRDataSource()->GetLayerByName(datasetName.c_str());
1354 
1355  if(l == nullptr)
1356  throw Exception(TE_TR("Could not retrieve dataset"));
1357 
1358  dataset->moveFirst();
1359  int i = 0;
1360 
1361  do
1362  {
1363  size_t id_pos = ids[0];
1364  int id = -1;
1365 
1366  int type = dataset->getPropertyDataType(id_pos);
1367 
1368  switch (type)
1369  {
1370  case te::dt::INT16_TYPE:
1371  id = dataset->getInt16(id_pos);
1372  break;
1373 
1374  case te::dt::INT32_TYPE:
1375  id = dataset->getInt32(id_pos);
1376  break;
1377 
1378  default:
1379  id = static_cast<int>(dataset->getInt64(id_pos));
1380  break;
1381  }
1382 
1383  if (id < 0)
1384  continue;
1385 
1386  OGRFeature* feat = l->GetFeature(id)->Clone();
1387 
1388  std::set<int> ls = properties[static_cast<size_t>(i)];
1389  std::set<int>::iterator it;
1390 
1391  for(it = ls.begin(); it != ls.end(); ++it)
1392  {
1393  int fpos = *it;
1394  int fpos_o = fpos - 1;
1395 
1396  switch(dataset->getPropertyDataType(static_cast<size_t>(fpos)))
1397  {
1398  case te::dt::INT32_TYPE:
1399  feat->SetField(fpos_o, dataset->getInt32(static_cast<size_t>(fpos)));
1400  break;
1401 
1402  case te::dt::DOUBLE_TYPE:
1403  case te::dt::NUMERIC_TYPE:
1404  feat->SetField(fpos_o, dataset->getDouble(static_cast<size_t>(fpos)));
1405  break;
1406 
1407  case te::dt::STRING_TYPE:
1408  feat->SetField(fpos_o, dataset->getString(static_cast<size_t>(fpos)).c_str());
1409  break;
1410 
1411  case te::dt::GEOMETRY_TYPE:
1412  {
1413  std::unique_ptr<te::gm::Geometry> gm = dataset->getGeometry(static_cast<size_t>(fpos));
1414  feat->SetGeometry(te::ogr::Convert2OGR(gm.get()));
1415  }
1416  }
1417  }
1418 
1419  OGRErr error = l->SetFeature(feat);
1420 
1421  if(error != OGRERR_NONE)
1422  {
1423  //TODO There are codes that describes the error. Send a message according to it.
1424  throw Exception(TE_TR("Fail updating data."));
1425  }
1426 
1427  i++;
1428  } while (dataset->moveNext());
1429 
1430  l->SyncToDisk();
1431 }
1432 
1433 void te::ogr::Transactor::optimize(const std::map<std::string, std::string>& /*opInfo*/)
1434 {
1435 }
virtual std::unique_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
Property * getProperty(std::size_t i) const
It returns the i-th property.
std::unique_ptr< te::da::CheckConstraint > getCheckConstraint(const std::string &datasetName, const std::string &name)
It gets the check constraint of the dataset with the given name.
void add(const std::string &datasetName, te::da::DataSet *d, const std::map< std::string, std::string > &options, std::size_t limit=0, bool enableProgress=true)
It adds data items to the dataset in the data source.
std::vector< std::string > getUniqueKeyNames(const std::string &datasetName)
It gets the unique key names of the given dataset.
void dropProperty(const std::string &datasetName, const std::string &name)
It removes a property from the given dataset.
Geometric property.
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
void addForeignKey(const std::string &datasetName, te::da::ForeignKey *fk)
It adds a foreign key constraint to a dataset.
virtual double getDouble(std::size_t i) const =0
Method for retrieving a double attribute value.
void dropCheckConstraint(const std::string &datasetName, const std::string &name)
It removes the check constraint from the dataset.
boost::int64_t getLastGeneratedId()
It returns the last id generated by an insertion command.
A class that informs what kind of constraint and index is supported by a given data source...
TEOGREXPORT OGRGeometry * Convert2OGR(const te::gm::Geometry *teGeom)
It converts the TerraLib Geometry to OGR Geometry.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
virtual std::unique_ptr< te::dt::ByteArray > getByteArray(std::size_t i) const =0
Method for retrieving a byte array.
A visitor for building an SQL statement using OGR dialect.
bool isInTransaction() const
It returns true if a transaction is in progress, otherwise, it returns false.
void commit()
It commits the transaction.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
bool hasGeom() const
It returns true if the DataSetType has at least one geometry property; otherwise, it returns false...
Definition: DataSetType.h:655
boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
bool sequenceExists(const std::string &name)
It checks if a sequence with the given name exists in the data source.
te::da::DataSource * getDataSource() const
It returns the parent data source of the transactor.
Base exception class for plugin module.
A class that models the description of a dataset.
Definition: DataSetType.h:72
virtual std::string getNumeric(std::size_t i) const =0
Method for retrieving a numeric attribute value.
te::core::EncodingType getEncoding()
It return the DataSource current encoding.
std::unique_ptr< te::da::Sequence > getSequence(const std::string &name)
It gets the sequence with the given name in the data source.
void addProperty(const std::string &datasetName, te::dt::Property *p)
It adds a new property to the dataset schema.
long getSeconds() const
It returns the seconds of a minute - from 0 to 59.
Definition: TimeDuration.h:105
std::size_t getNumberOfProperties(const std::string &datasetName)
It gets the number of properties of the given dataset.
std::unique_ptr< te::da::ForeignKey > getForeignKey(const std::string &datasetName, const std::string &name)
It retrieves the foreign key from the given dataset.
TEOGREXPORT boost::mutex & getStaticMutex()
Returns a reference to a static mutex initialized when this module is initialized.
bool checkConstraintExists(const std::string &datasetName, const std::string &name)
It checks if a check-constraint with the given name exists in the data source.
void cloneDataSet(const std::string &name, const std::string &cloneName, const std::map< std::string, std::string > &options)
It clones the dataset in the data source.
void dropForeignKey(const std::string &datasetName, const std::string &fkName)
It removes the foreign key constraint from the dataset schema.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
boost::gregorian::greg_year getYear() const
It returns the gregorian year.
Definition: Date.h:111
std::unique_ptr< te::da::BatchExecutor > getBatchExecutor()
It creates a batch command executor.
bool indexExists(const std::string &datasetName, const std::string &name)
It checks if an index with the given name exists in the dataset.
double m_urx
Upper right corner x-coordinate.
void renameDataSet(const std::string &name, const std::string &newName)
It renames a dataset.
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:168
SpatialRelation
Spatial relations between geometric objects.
boost::gregorian::greg_day getDay() const
It returns the gregorian day - from 1 to 31.
Definition: Date.h:97
It describes a sequence (a number generator).
bool dataSetExists(const std::string &name)
It checks if a dataset with the given name exists in the data source.
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
static te::dt::Date ds(2010, 01, 01)
A class that describes a check constraint.
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
TEOGREXPORT std::string RemoveSpatialSql(const std::string &sql)
void dropUniqueKey(const std::string &datasetName, const std::string &name)
It removes the unique key constraint from the dataset.
void dropDataSet(const std::string &name)
It removes the dataset schema from the data source.
void update(const std::string &datasetName, te::da::DataSet *dataset, const std::vector< std::size_t > &properties, const te::da::ObjectIdSet *oids, const std::map< std::string, std::string > &options, std::size_t limit=0)
It updates the contents of a dataset for the set of data items.
It models a property definition.
Definition: Property.h:59
void cancel()
It requests that the data source stop the processing of the current command.
bool foreignKeyExists(const std::string &datasetName, const std::string &name)
It checks if a foreign key with the given name exists in the data source.
void remove(const std::string &datasetName, const te::da::ObjectIdSet *oids=0)
It removes all the informed items from the dataset.
std::unique_ptr< te::da::DataSetTypeCapabilities > getCapabilities(const std::string &name)
It gets capabilities about a data set.
std::string query() const
Retrieving the query.
Definition: URI.cpp:123
void optimize(const std::map< std::string, std::string > &opInfo)
For some data access drivers, this method will perform some operations to optimize the data storage...
A class to represent time instant.
Definition: TimeInstant.h:55
void addPrimaryKey(const std::string &datasetName, te::da::PrimaryKey *pk)
It adds a primary key constraint to the dataset schema.
std::vector< std::string > getCheckConstraintNames(const std::string &datasetName)
It gets the check constraint names of the given dataset.
bool primaryKeyExists(const std::string &datasetName, const std::string &name)
It checks if a primary key exists in the dataset.
void begin()
It starts a new transaction.
virtual std::size_t size() const =0
It returns the collection size, if it is known.
std::size_t getNumberOfDataSets()
It retrieves the number of data sets available in the data source.
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
AccessPolicy
Supported data access policies (can be used as bitfield).
TraverseType
A dataset can be traversed in two ways:
std::unique_ptr< te::da::Index > getIndex(const std::string &datasetName, const std::string &name)
It gets the index with the given name from the dataset.
void addCheckConstraint(const std::string &datasetName, te::da::CheckConstraint *cc)
It adds a check constraint to the dataset.
void setName(const std::string &name)
It sets the property name.
Definition: Property.h:137
static std::string getEncodingName(EncodingType et)
Retrive a string from a given character encoding type enum.
double m_llx
Lower left corner x-coordinate.
std::unique_ptr< te::dt::Property > getProperty(const std::string &datasetName, const std::string &name)
It retrieves the property with the given name from the dataset.
std::unique_ptr< te::da::PreparedQuery > getPrepared(const std::string &qName=std::string(""))
It creates a prepared query object that may be used for query commands (select, insert, update and delete) that are used repeatedly.
virtual boost::int16_t getInt16(std::size_t i) const =0
Method for retrieving a 16-bit integer attribute value (2 bytes long).
Date getDate() const
It returns the date associated to time instant.
Definition: TimeInstant.h:106
int getSRID() const
It returns the spatial reference system identifier associated to this property.
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
An Envelope defines a 2D rectangular region.
A base class for date data types.
Definition: Date.h:53
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
std::unique_ptr< te::da::UniqueKey > getUniqueKey(const std::string &datasetName, const std::string &name)
It gets the unique key in the dataset with the given name.
void changePropertyDefinition(const std::string &datasetName, const std::string &propName, te::dt::Property *newProp)
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
virtual boost::int32_t getInt32(std::size_t i) const =0
Method for retrieving a 32-bit integer attribute value (4 bytes long).
void DataSet()
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
static te::dt::TimeDuration dt(20, 30, 50, 11)
std::unique_ptr< te::da::DataSetType > getDataSetType(const std::string &name)
It gets information about the given dataset.
te::gm::Polygon * p
It models a foreign key constraint for a DataSetType.
Definition: ForeignKey.h:50
virtual std::string getAsString(std::size_t i, int precision=0) const
Method for retrieving a data value as a string plain representation.
std::unique_ptr< te::da::DataSet > query(const te::da::Select &q, te::common::TraverseType travType=te::common::FORWARDONLY, bool connected=false, const te::common::AccessPolicy accessPolicy=te::common::RAccess)
It executes a query that may return some data using a generic query. A dataset can be connected or di...
It describes a unique key (uk) constraint.
Definition: UniqueKey.h:53
std::size_t size() const
It returns the number of properties of the CompositeProperty.
std::vector< std::string > getDataSetNames()
It It gets the dataset names available in the data source.
The OGR data source provider.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
void dropPrimaryKey(const std::string &datasetName)
It removes the primary key constraint from the dataset schema.
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
std::unique_ptr< te::da::PrimaryKey > getPrimaryKey(const std::string &datasetName)
It retrieves the primary key of the dataset.
void dropSequence(const std::string &name)
It removes the sequence from the data source.
OGRFieldType GetOGRType(int te_type)
double m_lly
Lower left corner y-coordinate.
void execute(const te::da::Query &command)
It executes the specified command using a generic query representation.
void dropIndex(const std::string &datasetName, const std::string &idxName)
It removes the index from the dataset schema.
int getType() const
It returns the property data type.
Definition: Property.h:161
virtual std::unique_ptr< te::dt::DateTime > getDateTime(std::size_t i) const =0
Method for retrieving a date and time attribute value.
A dataset is the unit of information manipulated by the data access module of TerraLib.
std::string escape(const std::string &value)
It escapes a string for using in commands and queries.
void createDataSet(te::da::DataSetType *dt, const std::map< std::string, std::string > &options)
It creates the dataset schema definition in the target data source.
This file contains utility functions used to manipulate data from a URI.
double m_ury
Upper right corner y-coordinate.
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator end() const
Returns an iterator for the object ids in container.
A class to represent time duration with nano-second/micro-second resolution.
Definition: TimeDuration.h:51
void addSequence(te::da::Sequence *sequence)
It creates a new sequence in the data source.
A class for data providers of OGR.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
const te::core::URI & getConnectionInfo() const
An Uniform Resource Identifier used to describe the datasource connection.
void renameProperty(const std::string &datasetName, const std::string &propertyName, const std::string &newPropertyName)
It renames a property of the given dataset.
TECOREEXPORT std::map< std::string, std::string > Expand(const std::string &query_str)
Split a query string into its components.
TimeDuration getTime() const
It returns the time duration associated to time instant.
Definition: TimeInstant.cpp:49
Implementation of a DataSet for OGR data provider.
void rollBack()
It aborts the transaction. Any changes will be rolled-back.
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
virtual boost::int64_t getInt64(std::size_t i) const =0
Method for retrieving a 64-bit integer attribute value (8 bytes long).
std::vector< std::string > getPropertyNames(const std::string &datasetName)
It gets the property names of the given dataset.
const te::da::SQLDialect * getDialect() const
It returns the data source SQL dialect, if there is one.
long getMinutes() const
It returns the minutes of a hour - from 0 to 59.
Definition: TimeDuration.h:98
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
virtual std::string getPropertyName(std::size_t i) const =0
It returns the property name at position pos.
std::unique_ptr< te::da::DataSet > getDataSet(const std::string &name, te::common::TraverseType travType=te::common::FORWARDONLY, bool connected=false, const te::common::AccessPolicy accessPolicy=te::common::RAccess)
It gets the dataset identified by the given name. A dataset can be connected or disconnected. A connected dataset, after its creation through the data source transactor, continues to depend on the connection given by its associated data source. Differently, a disconnected dataset, after its creation, no more depends of the connection given by the data source, and it continues to live after the connection has been released to the data source.
std::vector< std::string > getForeignKeyNames(const std::string &datasetName)
It gets the foreign key names of the given dataset.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
std::unique_ptr< te::gm::Envelope > getExtent(const std::string &datasetName, const std::string &propertyName)
It retrieves the bounding rectangle of the spatial property for the given dataset.
void addUniqueKey(const std::string &datasetName, te::da::UniqueKey *uk)
It adds a unique key constraint to the dataset.
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator begin() const
Returns an iterator for the object ids in container.
std::vector< std::string > getSequenceNames()
It gets the sequence names available in the data source.
virtual bool moveFirst()=0
It moves the internal pointer to the first item in the collection.
void addIndex(const std::string &datasetName, te::da::Index *idx, const std::map< std::string, std::string > &options)
It adds an index to the dataset.
bool propertyExists(const std::string &datasetName, const std::string &name)
It checks if a property with the given name exists in the dataset.
boost::gregorian::greg_month getMonth() const
It returns the gregorian month - from 1 to 12.
Definition: Date.h:104
TEOGREXPORT OGRSpatialReference * Convert2OGRProjection(int srid)
It converts the TerraLib Projection to OGR Projection.
bool uniqueKeyExists(const std::string &datasetName, const std::string &name)
It checks if a unique key with the given name exists in the dataset.
A Query is independent from the data source language/dialect.
Definition: Query.h:46
It describes an index associated to a DataSetType.
long getHours() const
It returns the hours of a day - from 0 to 23.
Definition: TimeDuration.h:91
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
virtual std::string getString(std::size_t i) const =0
Method for retrieving a string value attribute.
std::size_t getNumberOfItems(const std::string &datasetName)
It retrieves the number of items of the given dataset.
const std::string & getName() const
It returns the property name.
Definition: Property.h:127
std::vector< std::string > getIndexNames(const std::string &datasetName)
It gets the index names of the given dataset.
bool hasDataSets()
It checks if the data source has any dataset.