All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Transactor.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/dataaccess/postgis/Transactor.cpp
22 
23  \brief A Transactor can be viewed as a gateway for reading/writing things into the data source.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../common/Translator.h"
29 #include "../dataaccess/dataset/CheckConstraint.h"
30 #include "../dataaccess/dataset/DataSet.h"
31 #include "../dataaccess/dataset/ForeignKey.h"
32 #include "../dataaccess/dataset/Index.h"
33 #include "../dataaccess/dataset/ObjectIdSet.h"
34 #include "../dataaccess/dataset/PrimaryKey.h"
35 #include "../dataaccess/dataset/Sequence.h"
36 #include "../dataaccess/dataset/UniqueKey.h"
37 #include "../dataaccess/datasource/ScopedTransaction.h"
38 #include "../dataaccess/query/Select.h"
39 #include "../dataaccess/query/SQLDialect.h"
40 #include "../dataaccess/utils/Utils.h"
41 #include "../datatype/Array.h"
42 #include "../datatype/Enums.h"
43 #include "../datatype/Property.h"
44 #include "../datatype/SimpleData.h"
45 #include "../geometry/GeometryProperty.h"
46 #include "../geometry/Utils.h"
47 #include "../raster/Grid.h"
48 #include "../raster/BandProperty.h"
49 #include "../raster/RasterProperty.h"
50 #include "../geometry/Geometry.h"
51 #include "Connection.h"
52 #include "ConnectionPool.h"
53 #include "DataSource.h"
54 #include "DataSet.h"
55 #include "Exception.h"
56 #include "Globals.h"
57 #include "PreparedQuery.h"
58 #include "SQLVisitor.h"
59 #include "Transactor.h"
60 #include "Utils.h"
61 
62 // STL
63 #include <cassert>
64 #include <memory>
65 
66 // Boost
67 #include <boost/format.hpp>
68 
69 // libpq
70 #include <libpq-fe.h>
71 
73  : m_ds(ds),
74  m_conn(conn),
75  m_isInTransaction(false)
76 {
77 }
78 
80 {
81  m_ds->getConnPool()->release(m_conn);
82 }
83 
85 {
86  return m_ds;
87 }
88 
90 {
91  return m_conn;
92 }
93 
95 {
96  execute("BEGIN");
97  m_isInTransaction = true;
98 }
99 
101 {
102  m_isInTransaction = false;
103  execute("COMMIT");
104 }
105 
107 {
108  m_isInTransaction = false;
109  execute("ROLLBACK");
110 }
111 
113 {
114  return m_isInTransaction;
115 }
116 
117 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::getDataSet(const std::string& name,
118  te::common::TraverseType travType,
119  bool /*isConnected*/,
121 {
122  std::auto_ptr<std::string> sql(new std::string("SELECT * FROM "));
123  *sql += name;
124 
125  PGresult* result = m_conn->query(*sql);
126 
127  std::vector<int> ptypes;
128  Convert2TerraLib(result, m_ds->getGeomTypeId(), m_ds->getRasterTypeId(), ptypes);
129 
130  return std::auto_ptr<te::da::DataSet>(new DataSet(result, ptypes, m_ds->isTimeAnInteger(), m_ds->getCharEncoding()));
131 }
132 
133 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::getDataSet(const std::string& name,
134  const std::string& propertyName,
135  const te::gm::Envelope* e,
137  te::common::TraverseType travType,
138  bool /*isConnected*/,
140 {
141  if(e == 0)
142  throw Exception(TE_TR("The envelope is missing!"));
143 
144  std::auto_ptr<te::dt::Property> p = getProperty(name, propertyName);
145 
146  const te::gm::GeometryProperty* gp = static_cast<const te::gm::GeometryProperty*>(p.get());
147 
148  std::string rel = GetBoxSpatialRelation(r);
149 
150  std::string sql("SELECT * FROM ");
151  sql += name;
152  sql += " WHERE ";
153  sql += propertyName;
154  sql += rel;
155 
156  Convert2PostGIS(e, gp->getSRID(), sql);
157 
158  PGresult* result = m_conn->query(sql);
159 
160  std::vector<int> ptypes;
161  Convert2TerraLib(result, m_ds->getGeomTypeId(), m_ds->getRasterTypeId(), ptypes);
162 
163  return std::auto_ptr<te::da::DataSet>(new DataSet(result, ptypes, m_ds->isTimeAnInteger(), m_ds->getCharEncoding()));
164 }
165 
166 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::getDataSet(const std::string& name,
167  const std::string& propertyName,
168  const te::gm::Geometry* g,
170  te::common::TraverseType travType,
171  bool /*isConnected*/,
173 {
174  if(g == 0)
175  throw Exception(TE_TR("The geometry is missing!"));
176 
177  std::string rel = GetSpatialRelation(r);
178 
179  std::string sql("SELECT * FROM ");
180  sql += name;
181  sql += " WHERE ";
182  sql += rel;
183  sql += "(";
184 
185  Convert2PostGIS(m_conn->m_pgconn, g, sql);
186 
187  sql += ",";
188  sql += propertyName;
189  sql += ")";
190 
191  PGresult* result = m_conn->query(sql);
192 
193  std::vector<int> ptypes;
194  Convert2TerraLib(result, m_ds->getGeomTypeId(), m_ds->getRasterTypeId(), ptypes);
195 
196  return std::auto_ptr<te::da::DataSet>(new DataSet(result, ptypes, m_ds->isTimeAnInteger(), m_ds->getCharEncoding()));
197 }
198 
199 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::query(const te::da::Select& q,
200  te::common::TraverseType travType,
201  bool isConnected,
202  const te::common::AccessPolicy accessPolicy)
203 {
204  std::string sql;
205 
206  SQLVisitor visitor(*(m_ds->getDialect()), sql, m_conn->getConn());
207  q.accept(visitor);
208 
209  return query(sql, travType, isConnected,accessPolicy);
210 }
211 
212 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::query(const std::string& query,
213  te::common::TraverseType travType,
214  bool isConnected,
216 {
217  PGresult* result = m_conn->query(query);
218 
219  std::vector<int> ptypes;
220  Convert2TerraLib(result, m_ds->getGeomTypeId(), m_ds->getRasterTypeId(), ptypes);
221 
222  return std::auto_ptr<te::da::DataSet>(new DataSet(result, ptypes, m_ds->isTimeAnInteger(), m_ds->getCharEncoding()));
223 }
224 
226 {
227  std::string sql;
228 
229  SQLVisitor visitor(*(m_ds->getDialect()), sql, m_conn->getConn());
230  command.accept(visitor);
231 
232  execute(sql);
233 }
234 
235 void te::pgis::Transactor::execute(const std::string& command)
236 {
237  m_conn->execute(command);
238 }
239 
240 std::auto_ptr<te::da::PreparedQuery> te::pgis::Transactor::getPrepared(const std::string& qName)
241 {
242  return std::auto_ptr<te::da::PreparedQuery>(new PreparedQuery(this, qName));
243 }
244 
245 std::auto_ptr<te::da::BatchExecutor> te::pgis::Transactor::getBatchExecutor()
246 {
247  return std::auto_ptr<te::da::BatchExecutor>(0);
248 }
249 
251 {
252 }
253 
255 {
256  throw Exception(TE_TR("Not implemented yet!"));
257 }
258 
259 std::string te::pgis::Transactor::escape(const std::string& value)
260 {
261  return value;
262 }
263 
264 std::vector<std::string> te::pgis::Transactor::getDataSetNames()
265 {
266  std::vector<std::string> datasetNames;
267 
268  std::string sql("SELECT pg_class.oid, pg_namespace.nspname, pg_class.relname, pg_class.relkind "
269  "FROM pg_class, pg_namespace "
270  "WHERE pg_class.relname !~ '^pg_' "
271  "AND pg_class.relname NOT IN ('spatial_ref_sys', 'geometry_columns', 'geography_columns', 'raster_columns', 'raster_overviews') "
272  "AND pg_class.relkind in ('r','v') "
273  "AND pg_class.relnamespace = pg_namespace.oid "
274  "AND pg_namespace.nspname NOT IN ('information_schema', 'pg_toast', 'pg_temp_1', 'pg_catalog', 'topology')");
275 
276  std::auto_ptr<te::da::DataSet> datasetInfo = query(sql);
277 
278  while(datasetInfo->moveNext())
279  {
280  std::string datasetName = std::string(datasetInfo->getString(1) + "." + datasetInfo->getString(2));
281  datasetNames.push_back(datasetName);
282  }
283 
284  return datasetNames;
285 }
286 
288 {
289  return getDataSetNames().size();
290 }
291 
292 std::auto_ptr<te::da::DataSetType> te::pgis::Transactor::getDataSetType(const std::string& name)
293 {
294  std::string datasetName = getFullName(name);
295 
296  // Find the dataset id
297  unsigned int dtid = getDataSetId(datasetName);
298 
299  // Create the dataset type
300  te::da::DataSetType* dt = new te::da::DataSetType(datasetName, dtid);
301  dt->setTitle(datasetName);
302 
303  // Get the properties of the dataset and add them to its schema
304  boost::ptr_vector<te::dt::Property> properties = getProperties(datasetName);
305  for(std::size_t i = 0; i < properties.size(); ++i)
306  {
307  te::dt::Property* p = properties[i].clone();
308  dt->add(p);
309  }
310 
311  // Get all the constraints of the dataset and load them to its schema
312  getConstraints(dt);
313 
314  // Get the indexes of the dataset and add them to its schema
315  getIndexes(dt);
316 
317  return std::auto_ptr<te::da::DataSetType>(dt);
318 }
319 
320 boost::ptr_vector<te::dt::Property> te::pgis::Transactor::getProperties(const std::string& datasetName)
321 {
322  std::string fullDatasetName = getFullName(datasetName);
323 
324  boost::ptr_vector<te::dt::Property> properties;
325 
326  std::auto_ptr<te::da::DataSet> pInfo = getPropertiesInfo(fullDatasetName);
327 
328  while(pInfo->moveNext())
329  {
330  unsigned int attNum = pInfo->getInt16(0);
331  std::string attName = pInfo->getString(1);
332  unsigned int attType = pInfo->getInt32(2);
333  bool attNotNull = pInfo->getBool(3);
334  std::string fmt = pInfo->getString(4);
335  bool attHasDefault = pInfo->getBool(5);
336  std::string attDefValue = pInfo->getString(6);
337  int ndims = pInfo->getInt32(7);
338 
339  te::dt::Property* p = Convert2TerraLib(attNum, attName.c_str(), attType, attNotNull,
340  fmt.c_str(), attHasDefault, attDefValue.c_str(),
341  ndims, m_ds->getGeomTypeId(), m_ds->getRasterTypeId());
342 
343  properties.push_back(p);
344 
345  if(p->getType() == te::dt::GEOMETRY_TYPE)
346  {
347  getGeometryInfo(datasetName, static_cast<te::gm::GeometryProperty*>(p));
348  }
349  else if(p->getType() == te::dt::RASTER_TYPE)
350  {
351  getRasterInfo(datasetName, static_cast<te::rst::RasterProperty*>(p));
352  }
353  }
354 
355  return properties;
356 }
357 
358 std::auto_ptr<te::dt::Property> te::pgis::Transactor::getProperty(const std::string& datasetName, const std::string& name)
359 {
360  std::string fullDatasetName = getFullName(datasetName);
361 
362  te::dt::Property* p = 0;
363 
364  std::string pName = name;
365 
366  // If the property name contains also the dataset name, strip it from the name.
367  std::size_t pos = pName.find_last_of(".");
368  if(pos != std::string::npos)
369  pName = pName.substr(++pos);
370 
371  std::auto_ptr<te::da::DataSet> pInfo = getPropertiesInfo(fullDatasetName);
372  while(pInfo->moveNext())
373  {
374  std::string attName = pInfo->getString(1);
375  if(attName != pName)
376  continue;
377 
378  unsigned int attNum = pInfo->getInt16(0);
379  unsigned int attType = pInfo->getInt32(2);
380  bool attNotNull = pInfo->getBool(3);
381  std::string fmt = pInfo->getString(4);
382  bool attHasDefault = pInfo->getBool(5);
383  std::string attDefValue = pInfo->getString(6);
384  int ndims = pInfo->getInt32(7);
385 
386  p = Convert2TerraLib(attNum, attName.c_str(), attType, attNotNull,
387  fmt.c_str(), attHasDefault, attDefValue.c_str(),
388  ndims, m_ds->getGeomTypeId(), m_ds->getRasterTypeId());
389 
390  if(p->getType() == te::dt::GEOMETRY_TYPE)
391  {
392  getGeometryInfo(datasetName, static_cast<te::gm::GeometryProperty*>(p));
393  }
394  else if(p->getType() == te::dt::RASTER_TYPE)
395  {
396  getRasterInfo(datasetName, static_cast<te::rst::RasterProperty*>(p));
397  }
398  }
399 
400  return std::auto_ptr<te::dt::Property>(p);
401 }
402 
403 std::auto_ptr<te::dt::Property> te::pgis::Transactor::getProperty(const std::string& datasetName, std::size_t propertyPos)
404 {
405  std::string fullDatasetName = getFullName(datasetName);
406 
407  boost::ptr_vector<te::dt::Property> properties = getProperties(fullDatasetName);
408 
409  assert(propertyPos < properties.size());
410 
411  return std::auto_ptr<te::dt::Property>(properties[propertyPos].clone());
412 }
413 
414 std::vector<std::string> te::pgis::Transactor::getPropertyNames(const std::string& datasetName)
415 {
416  std::string fullDatasetName = getFullName(datasetName);
417 
418  boost::ptr_vector<te::dt::Property> properties = getProperties(fullDatasetName);
419 
420  std::size_t numProperties = properties.size();
421 
422  std::vector<std::string> pNames(numProperties);
423 
424  for(std::size_t i = 0; i < numProperties; ++i)
425  pNames[i] = properties[i].getName();
426 
427  return pNames;
428 }
429 
430 std::size_t te::pgis::Transactor::getNumberOfProperties(const std::string& datasetName)
431 {
432  std::string fullDatasetName = getFullName(datasetName);
433  return getProperties(fullDatasetName).size();
434 }
435 
436 bool te::pgis::Transactor::propertyExists(const std::string& datasetName, const std::string& name)
437 {
438  std::string fullDatasetName = getFullName(datasetName);
439 
440  std::vector<std::string> pNames = getPropertyNames(fullDatasetName);
441 
442  if(std::find(pNames.begin(), pNames.end(), name) != pNames.end())
443  return true;
444 
445  return false;
446 }
447 
448 void te::pgis::Transactor::addProperty(const std::string& datasetName, te::dt::Property* p)
449 {
450  std::string fullDatasetName = getFullName(datasetName);
451 
452  std::string pName = p->getName();
453 
454  // Persist the property in the database
455  std::string sql;
456 
457  if(p->getType() == te::dt::GEOMETRY_TYPE)
458  {
459  te::gm::GeometryProperty* gp = static_cast<te::gm::GeometryProperty*>(p);
460 
461  sql = "SELECT AddGeometryColumn('";
462 
463  // split schema-name.table-name
464  std::size_t pos = fullDatasetName.find(".");
465 
466  if(pos == std::string::npos)
467  {
468  sql += te::common::Convert2LCase(fullDatasetName);
469  sql += "', '";
470  }
471  else
472  {
473  sql += te::common::Convert2LCase(fullDatasetName.substr(0, pos));
474  sql += "', '";
475  sql += te::common::Convert2LCase(fullDatasetName.substr(pos + 1));
476  sql += "', '";
477  }
478 
479  sql += te::common::Convert2LCase(gp->getName());
480  sql += "', ";
481  sql += te::common::Convert2String(gp->getSRID());
482  sql += ", '";
484  sql += "', ";
486  sql += ")";
487  }
488  else
489  {
490  sql = "ALTER TABLE ";
491  sql += fullDatasetName;
492  sql += " ADD COLUMN ";
493  sql += pName;
494  sql += " ";
495 
496  SetColumnDef(sql, p);
497  }
498 
499  execute(sql);
500 }
501 
502 void te::pgis::Transactor::dropProperty(const std::string& datasetName, const std::string& name)
503 {
504  std::string fullDatasetName = getFullName(datasetName);
505 
506  std::auto_ptr<te::dt::Property> p = getProperty(fullDatasetName, name);
507 
508  std::string sql;
509 
510  if(p->getType() == te::dt::GEOMETRY_TYPE)
511  {
512  sql = "SELECT DropGeometryColumn('";
513 
514  // Split schema-name.table-name, if needed
515  std::size_t pos = fullDatasetName.find(".");
516 
517  if(pos == std::string::npos)
518  {
519  sql += m_ds->getCurrentSchema();
520  sql += "', '";
521  sql += te::common::Convert2LCase(fullDatasetName);
522  }
523  else
524  {
525  sql += te::common::Convert2LCase(fullDatasetName.substr(0, pos));
526  sql += "', '";
527  sql += te::common::Convert2LCase(fullDatasetName.substr(pos + 1));
528  }
529 
530  sql += "', '";
531  sql += te::common::Convert2LCase(name) + "'";
532  sql += ")";
533  }
534  else
535  {
536  sql = " ALTER TABLE ";
537  sql += fullDatasetName;
538  sql += " DROP COLUMN ";
539  sql += name;
540  }
541 
542  execute(sql);
543 }
544 
545 void te::pgis::Transactor::renameProperty(const std::string& datasetName,
546  const std::string& name,
547  const std::string& newName)
548 {
549  std::string fullDatasetName = getFullName(datasetName);
550 
551  std::auto_ptr<te::dt::Property> p = getProperty(fullDatasetName, name);
552 
553  std::string sql("ALTER TABLE ");
554  sql += fullDatasetName;
555  sql += " RENAME COLUMN ";
556  sql += name + " TO ";
557  sql += newName;
558 
559  execute(sql);
560 
561  if(p->getType() == te::dt::GEOMETRY_TYPE)
562  {
563  sql = "UPDATE geometry_columns SET f_geometry_column = '" + newName + "'";
564  sql += " WHERE f_table_name = '" ;
565 
566  // Split schema-name.table-name
567  std::size_t pos = fullDatasetName.find(".");
568 
569  if(pos == std::string::npos)
570  {
571  sql += fullDatasetName;
572  sql += "' AND f_table_schema ='";
573  sql += m_ds->getCurrentSchema();
574  sql += "'";
575  }
576  else
577  {
578  sql += fullDatasetName.substr(pos + 1);
579  sql += "' AND f_table_schema ='";
580  sql += fullDatasetName.substr(0, pos);
581  sql += "'";
582  }
583 
584  sql += " AND f_geometry_column = '" + name + "'";
585 
586  execute(sql);
587  }
588 }
589 
590 void te::pgis::Transactor::changePropertyDefinition(const std::string& datasetName, const std::string& propName, te::dt::Property* newProp)
591 {
592  std::auto_ptr<te::dt::Property> prp(newProp);
593  std::string type;
594 
595  if(prp->getType() == te::dt::DOUBLE_TYPE)
596  type = "NUMERIC USING " + propName+ "::numeric";
597 
598  if(type.empty())
599  SetColumnDef(type, prp.get());
600 
601  std::string sql("ALTER TABLE ");
602  sql += datasetName + " ALTER COLUMN " + propName + " TYPE " + type;
603 
604  execute(sql);
605 }
606 
607 std::auto_ptr<te::da::PrimaryKey> te::pgis::Transactor::getPrimaryKey(const std::string& datasetName)
608 {
609  std::string fullDatasetName = getFullName(datasetName);
610 
611  te::da::PrimaryKey* pk = 0;
612 
613  std::auto_ptr<te::da::DataSet> pkInfo = getConstraints(fullDatasetName, 'p');
614 
615  while(pkInfo->moveNext())
616  {
617  unsigned int pkId = pkInfo->getInt32(0);
618  std::string pkName = pkInfo->getString(2);
619 
620  pk = new te::da::PrimaryKey(pkName, 0, pkId);
621 
622  std::auto_ptr<te::dt::Array> pkCols(pkInfo->getArray(8));
623  std::size_t size = pkCols->getDimensionSize(0);
624 
625  std::vector<std::size_t> pos;
626  pos.push_back(0);
627  for(std::size_t i = 0; i < size; ++i)
628  {
629  pos[0] = i;
630 
631  te::dt::AbstractData* pkCol = pkCols->getData(pos);
632 
633  std::auto_ptr<te::dt::Property> p = getProperty(static_cast<te::dt::Int16*>(pkCol)->getValue(), fullDatasetName);
634  pk->add(p.release());
635  }
636  }
637 
638  // Try to link the pk to an index
639  std::vector<std::string> idxNames = getIndexNames(fullDatasetName);
640 
641  for(std::size_t i = 0; i < idxNames.size(); ++i)
642  {
643  if(pk->getName() == idxNames[i])
644  {
645  pk->setAssociatedIndex(getIndex(fullDatasetName, idxNames[i]).get());
646  break;
647  }
648  }
649 
650  return std::auto_ptr<te::da::PrimaryKey>(pk);
651 }
652 
653 bool te::pgis::Transactor::primaryKeyExists(const std::string& datasetName, const std::string& name)
654 {
655  std::string fullDatasetName = getFullName(datasetName);
656 
657  std::auto_ptr<te::da::PrimaryKey> pk = getPrimaryKey(fullDatasetName);
658 
659  if(pk->getName() == name)
660  return true;
661 
662  return false;
663 }
664 
665 void te::pgis::Transactor::addPrimaryKey(const std::string& datasetName, te::da::PrimaryKey* pk)
666 {
667  std::string fullDatasetName = getFullName(datasetName);
668 
669  // Check if there is a primary key in the dataset
670  // If true, drop it from the dataset
671  if(getPrimaryKey(fullDatasetName).get() != 0)
672  dropPrimaryKey(fullDatasetName);
673 
674  std::string pkName;
675 
676  if(pk->getName().empty())
677  {
678  pkName = fullDatasetName + "_pk";
679 
680  boost::replace_all(pkName, ".", "_");
681 
682  pk->setName(pkName);
683  }
684 
685  pkName = pk->getName();
686 
687  std::string sql("ALTER TABLE ");
688  sql += fullDatasetName;
689  sql += " ADD CONSTRAINT ";
690  sql += pkName;
691  sql += " PRIMARY KEY (";
692 
693  const std::vector<te::dt::Property*>& properties = pk->getProperties();
694 
695  std::size_t size = properties.size();
696 
697  for(std::size_t i = 0; i < size; ++i)
698  {
699  if(i != 0)
700  sql += ", ";
701 
702  sql += properties[i]->getName();
703  }
704 
705  sql += ")";
706 
707  execute(sql);
708 }
709 
710 void te::pgis::Transactor::dropPrimaryKey(const std::string& datasetName)
711 {
712  std::string fullDatasetName = getFullName(datasetName);
713 
714  std::auto_ptr<te::da::PrimaryKey> pk = getPrimaryKey(fullDatasetName);
715 
716  std::string pkName = pk->getName();
717 
718  std::string sql("ALTER TABLE ");
719  sql += fullDatasetName;
720  sql += " DROP CONSTRAINT " + pkName;
721 
722  execute(sql);
723 }
724 
725 std::auto_ptr<te::da::ForeignKey> te::pgis::Transactor::getForeignKey(const std::string& datasetName, const std::string& name)
726 {
727  std::string fullDatasetName = getFullName(datasetName);
728 
729  te::da::ForeignKey* fk = 0;
730 
731  std::auto_ptr<te::da::DataSet> fkInfo = getConstraints(fullDatasetName, 'f');
732 
733  while(fkInfo->moveNext())
734  {
735  std::string fkName = fkInfo->getString(2);
736 
737  if(fkName != name)
738  continue;
739 
740  unsigned int fkId = fkInfo->getInt32(0);
741  unsigned int refDatasetId = fkInfo->getInt32(4);
742  char onUpdate = fkInfo->getChar(5);
743  char onDeletion = fkInfo->getChar(6);
744 
745  std::auto_ptr<te::dt::Array> fkCols(fkInfo->getArray(8));
746  std::auto_ptr<te::dt::Array> fkRefCols(fkInfo->getArray(9));
747 
748  assert(fkCols->getDimension() == 1);
749  assert(fkCols->getDimension() == fkRefCols->getDimension());
750  assert(fkCols->getDimensionSize(0) == fkRefCols->getDimensionSize(0));
751 
752  std::string refName = getDataSetName(refDatasetId);
753  std::auto_ptr<te::da::DataSetType> refdt = getDataSetType(refName);
754 
755  fk = new te::da::ForeignKey(fkName, fkId);
756  fk->setOnUpdateAction(GetAction(onUpdate));
757  fk->setOnDeleteAction(GetAction(onDeletion));
758  fk->setReferencedDataSetType(refdt.get());
759 
760  std::size_t size = fkCols->getDimensionSize(0);
761 
762  std::vector<std::size_t> pos;
763  pos.push_back(0);
764 
765  for(std::size_t i = 0; i < size; ++i)
766  {
767  pos[0] = i;
768 
769  te::dt::AbstractData* fkRefCol = fkRefCols->getData(pos);
770  fk->addRefProperty(refdt->getPropertyById(static_cast<te::dt::Int16*>(fkRefCol)->getValue()));
771 
772  te::dt::AbstractData* fkCol = fkCols->getData(pos);
773  fk->add(getProperty(static_cast<te::dt::Int16*>(fkCol)->getValue(), datasetName).release());
774  }
775  }
776 
777  return std::auto_ptr<te::da::ForeignKey>(fk);
778 }
779 
780 std::vector<std::string> te::pgis::Transactor::getForeignKeyNames(const std::string& datasetName)
781 {
782  std::string fullDatasetName = getFullName(datasetName);
783 
784  std::vector<std::string> fkNames;
785 
786  std::auto_ptr<te::da::DataSet> fkInfo = getConstraints(fullDatasetName, 'f');
787 
788  while(fkInfo->moveNext())
789  {
790  std::string fkName = fkInfo->getString(2);
791  fkNames.push_back(fkName);
792  }
793 
794  return fkNames;
795 }
796 
797 bool te::pgis::Transactor::foreignKeyExists(const std::string& datasetName, const std::string& name)
798 {
799  std::string fullDatasetName = getFullName(datasetName);
800 
801  std::vector<std::string> fkNames = getForeignKeyNames(fullDatasetName);
802  if(std::find(fkNames.begin(), fkNames.end(), name) != fkNames.end())
803  return true;
804 
805  return false;
806 }
807 
808 void te::pgis::Transactor::addForeignKey(const std::string& datasetName, te::da::ForeignKey* fk)
809 {
810  std::string fullDatasetName = getFullName(datasetName);
811 
812  std::string fkName = fk->getName();
813 
814  std::string sql("ALTER TABLE ");
815  sql += fullDatasetName;
816  sql += " ADD CONSTRAINT ";
817  sql += fkName;
818  sql += " FOREIGN KEY (";
819 
820  std::size_t size = fk->getProperties().size();
821 
822  for(std::size_t i = 0; i < size; ++i)
823  {
824  if(i != 0)
825  sql += ", ";
826 
827  sql += fk->getProperties()[i]->getName();
828  }
829 
830  sql += ") REFERENCES " + fk->getReferencedDataSetType()->getName() + " (";
831 
832  size = fk->getReferencedProperties().size();
833 
834  for(size_t i = 0; i < size; ++i)
835  {
836  if(i != 0)
837  sql += ", ";
838 
839  sql += fk->getReferencedProperties()[i]->getName();
840  }
841 
842  sql += ") ON DELETE ";
843 
844  switch(fk->getOnDeleteAction())
845  {
846  case te::da::NO_ACTION:
847  sql += " NO ACTION ";
848  break;
849 
850  case te::da::RESTRICT:
851  sql += " RESTRICT ";
852  break;
853 
854  case te::da::CASCADE:
855  sql += " CASCADE ";
856  break;
857 
858  case te::da::SET_NULL:
859  sql += "SET NULL ";
860  break;
861 
862  case te::da::SET_DEFAULT:
863  default:
864  sql += "SET DEFAULT ";
865  break;
866  }
867 
868  sql += " ON UPDATE ";
869 
870  switch(fk->getOnUpdateAction())
871  {
872  case te::da::NO_ACTION:
873  sql += " NO ACTION ";
874  break;
875 
876  case te::da::RESTRICT:
877  sql += " RESTRICT ";
878  break;
879 
880  case te::da::CASCADE:
881  sql += " CASCADE ";
882  break;
883 
884  case te::da::SET_NULL:
885  sql += "SET NULL ";
886  break;
887 
888  case te::da::SET_DEFAULT:
889  default:
890  sql += "SET DEFAULT ";
891  break;
892  }
893 
894  execute(sql);
895 }
896 
897 void te::pgis::Transactor::dropForeignKey(const std::string& datasetName, const std::string& name)
898 {
899  std::string fullDatasetName = getFullName(datasetName);
900 
901  std::string sql("ALTER TABLE ");
902  sql += fullDatasetName;
903  sql += " DROP CONSTRAINT ";
904  sql += name;
905 
906  execute(sql);
907 }
908 
909 std::auto_ptr<te::da::UniqueKey> te::pgis::Transactor::getUniqueKey(const std::string& datasetName, const std::string& name)
910 {
911  std::string fullDatasetName = getFullName(datasetName);
912 
913  te::da::UniqueKey* uk = 0;
914 
915  std::auto_ptr<te::da::DataSet> ukInfo = getConstraints(fullDatasetName, 'u');
916 
917  while(ukInfo->moveNext())
918  {
919  std::string ukName = ukInfo->getString(2);
920 
921  if(ukName != name)
922  continue;
923 
924  unsigned int ukId = ukInfo->getInt32(0);
925 
926  std::auto_ptr<te::dt::Array> ukCols(ukInfo->getArray(8));
927 
928  uk = new te::da::UniqueKey(ukName, 0, ukId);
929 
930  std::size_t size = ukCols->getDimensionSize(0);
931 
932  std::vector<std::size_t> pos;
933  pos.push_back(0);
934 
935  for(std::size_t i = 0; i < size; ++i)
936  {
937  pos[0] = i;
938 
939  te::dt::AbstractData* ukCol = ukCols->getData(pos);
940 
941  std::auto_ptr<te::dt::Property> p = getProperty(static_cast<te::dt::Int16*>(ukCol)->getValue(), fullDatasetName);
942 
943  uk->add(p.release());
944  }
945  }
946 
947  // Try to link the uk to an index
948  std::vector<std::string> idxNames = getIndexNames(fullDatasetName);
949 
950  for(std::size_t i = 0; i < idxNames.size(); ++i)
951  {
952  if(uk->getName() == idxNames[i])
953  {
954  uk->setAssociatedIndex(getIndex(fullDatasetName, idxNames[i]).get());
955  break;
956  }
957  }
958 
959  return std::auto_ptr<te::da::UniqueKey>(uk);
960 }
961 
962 std::vector<std::string> te::pgis::Transactor::getUniqueKeyNames(const std::string& datasetName)
963 {
964  std::string fullDatasetName = getFullName(datasetName);
965 
966  std::vector<std::string> ukNames;
967 
968  std::auto_ptr<te::da::DataSet> ukInfo = getConstraints(fullDatasetName, 'u');
969 
970  while(ukInfo->moveNext())
971  {
972  std::string ukName = ukInfo->getString(2);
973  ukNames.push_back(ukName);
974  }
975 
976  return ukNames;
977 }
978 
979 bool te::pgis::Transactor::uniqueKeyExists(const std::string& datasetName, const std::string& name)
980 {
981  std::string fullDatasetName = getFullName(datasetName);
982 
983  std::vector<std::string> ukNames = getUniqueKeyNames(fullDatasetName);
984 
985  if(std::find(ukNames.begin(), ukNames.end(), name) != ukNames.end())
986  return true;
987 
988  return false;
989 }
990 
991 void te::pgis::Transactor::addUniqueKey(const std::string& datasetName, te::da::UniqueKey* uk)
992 {
993  std::string fullDatasetName = getFullName(datasetName);
994 
995  std::string ukName = uk->getName();
996 
997  std::string sql("ALTER TABLE ");
998  sql += fullDatasetName;
999  sql += " ADD CONSTRAINT ";
1000  sql += ukName;
1001  sql += " UNIQUE (";
1002 
1003  const std::vector<te::dt::Property*>& properties = uk->getProperties();
1004 
1005  std::size_t size = properties.size();
1006 
1007  for(std::size_t i = 0; i < size; ++i)
1008  {
1009  if(i != 0)
1010  sql += ", ";
1011 
1012  sql += properties[i]->getName();
1013  }
1014 
1015  sql += ")";
1016 
1017  execute(sql);
1018 }
1019 
1020 void te::pgis::Transactor::dropUniqueKey(const std::string& datasetName, const std::string& name)
1021 {
1022  std::string fullDatasetName = getFullName(datasetName);
1023 
1024  std::string sql("ALTER TABLE ");
1025  sql += fullDatasetName;
1026  sql += " DROP CONSTRAINT ";
1027  sql += name;
1028 
1029  execute(sql);
1030 
1031  // Remove the index associated to the unique key
1032  if(indexExists(fullDatasetName, name))
1033  dropIndex(fullDatasetName, name);
1034 }
1035 
1036 std::auto_ptr<te::da::CheckConstraint> te::pgis::Transactor::getCheckConstraint(const std::string& datasetName, const std::string& name)
1037 {
1038  std::string fullDatasetName = getFullName(datasetName);
1039 
1040  te::da::CheckConstraint* cc = 0;
1041 
1042  std::auto_ptr<te::da::DataSet> ccInfo = getConstraints(datasetName, 'c');
1043 
1044  while(ccInfo->moveNext())
1045  {
1046  std::string ccName = ccInfo->getString(2);
1047 
1048  if(ccName != name)
1049  continue;
1050 
1051  unsigned int ccId = ccInfo->getInt32(0);
1052 
1053  cc = new te::da::CheckConstraint(ccName);
1054  cc->setId(ccId);
1055  cc->setExpression(ccInfo->getString(10));
1056  }
1057 
1058  return std::auto_ptr<te::da::CheckConstraint>(cc);
1059 }
1060 
1061 std::vector<std::string> te::pgis::Transactor::getCheckConstraintNames(const std::string& datasetName)
1062 {
1063  std::string fullDatasetName = getFullName(datasetName);
1064 
1065  std::vector<std::string> ccNames;
1066 
1067  std::auto_ptr<te::da::DataSet> ccInfo = getConstraints(fullDatasetName, 'c');
1068 
1069  while(ccInfo->moveNext())
1070  {
1071  std::string ccName = ccInfo->getString(2);
1072 
1073  ccNames.push_back(ccName);
1074  }
1075 
1076  return ccNames;
1077 }
1078 
1079 bool te::pgis::Transactor::checkConstraintExists(const std::string& datasetName, const std::string& name)
1080 {
1081  std::string fullDatasetName = getFullName(datasetName);
1082 
1083  std::vector<std::string> ccNames = getCheckConstraintNames(fullDatasetName);
1084 
1085  if(std::find(ccNames.begin(), ccNames.end(), name) != ccNames.end())
1086  return true;
1087 
1088  return false;
1089 }
1090 
1092 {
1093  std::string fullDatasetName = getFullName(datasetName);
1094 
1095  std::string ccName = cc->getName();
1096 
1097  std::string sql("ALTER TABLE ");
1098  sql += fullDatasetName;
1099  sql += " ADD CONSTRAINT ";
1100  sql += ccName;
1101  sql += " CHECK(";
1102  sql += cc->getExpression();
1103  sql += ")";
1104 
1105  execute(sql);
1106 }
1107 
1108 void te::pgis::Transactor::dropCheckConstraint(const std::string& datasetName, const std::string& name)
1109 {
1110  std::string fullDatasetName = getFullName(datasetName);
1111 
1112  std::string sql("ALTER TABLE ");
1113  sql += fullDatasetName;
1114  sql += " DROP CONSTRAINT ";
1115  sql += name;
1116 
1117  execute(sql);
1118 }
1119 
1120 std::auto_ptr<te::da::Index> te::pgis::Transactor::getIndex(const std::string& datasetName, const std::string& name)
1121 {
1122  std::string fullDatasetName = getFullName(datasetName);
1123 
1124  te::da::Index* idx = 0;
1125 
1126  unsigned int dtid = getDataSetId(fullDatasetName);
1127 
1128  std::string sql("SELECT idx_table.oid, s.nspname, idx_table.relname, pg_index.indkey, pg_am.amname, pg_index.indisunique, pg_index.indisprimary "
1129  "FROM pg_index, pg_class idx_table, pg_am, pg_namespace s "
1130  "WHERE s.oid = idx_table.relnamespace "
1131  "AND pg_index.indexrelid = idx_table.oid "
1132  "AND idx_table.relam = pg_am.oid "
1133  "AND pg_index.indrelid = ");
1134  sql += te::common::Convert2String(dtid);
1135 
1136  std::auto_ptr<te::da::DataSet> idxInfo = query(sql);
1137 
1138  while(idxInfo->moveNext())
1139  {
1140  std::string idxName = idxInfo->getString(2);
1141 
1142  if(idxName != name)
1143  continue;
1144 
1145  unsigned int idxId = idxInfo->getInt32(0);
1146 
1147  std::auto_ptr<te::dt::Array> idxCols(idxInfo->getArray(3));
1148 
1149  std::string idxType = idxInfo->getString(4);
1150 
1151  idx = new te::da::Index(idxName, GetIndexType(idxType.c_str()), 0, idxId);
1152 
1153  std::size_t size = idxCols->getDimensionSize(0);
1154 
1155  std::vector<std::size_t> pos;
1156  pos.push_back(0);
1157 
1158  for(std::size_t i = 0; i < size; ++i)
1159  {
1160  pos[0] = i;
1161  te::dt::AbstractData* idxCol = idxCols->getData(pos);
1162 
1163  std::auto_ptr<te::dt::Property> p = getProperty(static_cast<te::dt::Int16*>(idxCol)->getValue(), fullDatasetName);
1164 
1165  idx->add(p.release());
1166  }
1167  }
1168 
1169  return std::auto_ptr<te::da::Index>(idx);
1170 }
1171 
1172 std::vector<std::string> te::pgis::Transactor::getIndexNames(const std::string& datasetName)
1173 {
1174  std::string fullDatasetName = getFullName(datasetName);
1175 
1176  std::vector<std::string> idxNames;
1177 
1178  unsigned int dtid = getDataSetId(fullDatasetName);
1179 
1180  std::string sql("SELECT idx_table.oid, s.nspname, idx_table.relname, pg_index.indkey, pg_am.amname, pg_index.indisunique, pg_index.indisprimary "
1181  "FROM pg_index, pg_class idx_table, pg_am, pg_namespace s "
1182  "WHERE s.oid = idx_table.relnamespace "
1183  "AND pg_index.indexrelid = idx_table.oid "
1184  "AND idx_table.relam = pg_am.oid "
1185  "AND pg_index.indrelid = ");
1186  sql += te::common::Convert2String(dtid);
1187 
1188  std::auto_ptr<te::da::DataSet> idxInfo = query(sql);
1189 
1190  while(idxInfo->moveNext())
1191  {
1192  std::string idxName = idxInfo->getString(2);
1193 
1194  idxNames.push_back(idxName);
1195  }
1196 
1197  return idxNames;
1198 }
1199 
1200 bool te::pgis::Transactor::indexExists(const std::string& datasetName, const std::string& name)
1201 {
1202  std::string fullDatasetName = getFullName(datasetName);
1203 
1204  std::vector<std::string> idxNames = getIndexNames(fullDatasetName);
1205 
1206  if(std::find(idxNames.begin(), idxNames.end(), name) != idxNames.end())
1207  return true;
1208 
1209  return false;
1210 }
1211 
1212 void te::pgis::Transactor::addIndex(const std::string& datasetName, te::da::Index* idx,
1213  const std::map<std::string, std::string>& options)
1214 {
1215  std::string fullDatasetName = getFullName(datasetName);
1216 
1217  std::string idxName = idx->getName();
1218 
1219  // Check if the index is associated to a UK or PK
1220  std::auto_ptr<te::da::PrimaryKey> pk = getPrimaryKey(fullDatasetName);
1221 
1222  if(pk.get() && (pk->getAssociatedIndex() == idx))
1223  return;
1224 
1225  std::vector<std::string> ukNames = getUniqueKeyNames(datasetName);
1226 
1227  for(std::size_t i = 0; i < ukNames.size(); ++i)
1228  if(getUniqueKey(datasetName, ukNames[i])->getAssociatedIndex() == idx)
1229  return;
1230 
1231  // If there is not a uk or pk associated, let's create the index!
1232  std::string sql("CREATE INDEX ");
1233  sql += idxName;
1234  sql += " ON ";
1235  sql += fullDatasetName;
1236 
1237  if(idx->getIndexType() == te::da::HASH_TYPE)
1238  sql += " USING HASH (";
1239  else if(idx->getIndexType() == te::da::R_TREE_TYPE)
1240  sql += " USING GIST (";
1241  else if(idx->getIndexType() == te::da::B_TREE_TYPE)
1242  sql += " USING BTREE (";
1243  else
1244  throw Exception(TE_TR("The index type is not supported!"));
1245 
1246  std::size_t numProperties = idx->getProperties().size();
1247 
1248  for(size_t i = 0; i < numProperties; ++i)
1249  {
1250  if(i != 0)
1251  sql += ", ";
1252 
1253  sql += idx->getProperties()[i]->getName();
1254  }
1255 
1256  sql += ")";
1257 
1258  execute(sql);
1259 }
1260 
1261 void te::pgis::Transactor::dropIndex(const std::string& datasetName, const std::string& name)
1262 {
1263  std::string fullDatasetName = getFullName(datasetName);
1264 
1265  std::string sql("DROP INDEX ");
1266  sql += name;
1267 
1268  execute(sql);
1269 }
1270 
1271 std::auto_ptr<te::da::Sequence> te::pgis::Transactor::getSequence(const std::string& name)
1272 {
1273  te::da::Sequence* seq = 0;
1274 
1275  // Query the data source for the sequences
1276  std::vector<std::string> seqNames;
1277 
1278  std::string sql("SELECT c.oid, n.nspname, c.relname, c.relkind "
1279  "FROM pg_class c, pg_namespace n "
1280  "WHERE c.relname !~ '^pg_' "
1281  "AND c.relkind = 'S' "
1282  "AND c.relnamespace = n.oid "
1283  "AND n.nspname NOT IN ('information_schema', 'pg_toast', 'pg_temp_1', 'pg_catalog')");
1284 
1285  std::auto_ptr<te::da::DataSet> seqNamesInfo = query(sql);
1286 
1287  while(seqNamesInfo->moveNext())
1288  {
1289  std::string seqName(seqNamesInfo->getString(2));
1290 
1291  if(seqName != name)
1292  continue;
1293 
1294  std::string sql("SELECT * FROM ");
1295  sql += seqName;
1296 
1297  std::auto_ptr<te::da::DataSet> result(query(sql));
1298 
1299  if(result->moveNext())
1300  {
1301  unsigned int seqId = getDataSetId(seqName);
1302 
1303  seq = new te::da::Sequence(seqName, 0, 0, 0, seqId);
1304 
1305  // Check if the sequence is cycled
1306  if(result->getBool(8))
1307  seq->setAsCycle();
1308  else
1309  seq->setAsNoCycle();
1310 
1311  seq->setCachedValues(result->getInt64(6)); // "cache_value"
1312  seq->setIncrement(result->getInt64(3)); // "increment_by";
1313  seq->setMaxValue(result->getInt64(4)); // "max_value";
1314  seq->setMinValue(result->getInt64(5)); // "min_value";
1315  }
1316  }
1317 
1318  return std::auto_ptr<te::da::Sequence>(seq);
1319 }
1320 
1321 std::vector<std::string> te::pgis::Transactor::getSequenceNames()
1322 {
1323  std::vector<std::string> seqNames;
1324 
1325  std::string sql("SELECT c.oid, n.nspname, c.relname, c.relkind "
1326  "FROM pg_class c, pg_namespace n "
1327  "WHERE c.relname !~ '^pg_' "
1328  "AND c.relkind = 'S' "
1329  "AND c.relnamespace = n.oid "
1330  "AND n.nspname NOT IN ('information_schema', 'pg_toast', 'pg_temp_1', 'pg_catalog')");
1331 
1332  std::auto_ptr<te::da::DataSet> seqNamesInfo = query(sql);
1333 
1334  while(seqNamesInfo->moveNext())
1335  {
1336  std::string seqName(seqNamesInfo->getString(2));
1337  seqNames.push_back(seqName);
1338  }
1339 
1340  return seqNames;
1341 }
1342 
1343 bool te::pgis::Transactor::sequenceExists(const std::string& name)
1344 {
1345  std::vector<std::string> seqNames = getSequenceNames();
1346 
1347  if(std::find(seqNames.begin(), seqNames.end(), name) != seqNames.end())
1348  return true;
1349 
1350  return false;
1351 }
1352 
1354 {
1355  std::string seqName = sequence->getName();
1356 
1357  std::string sql("CREATE SEQUENCE ");
1358  sql += seqName;
1359  sql += " INCREMENT BY ";
1360  sql += te::common::Convert2String(sequence->getIncrement());
1361  sql += " MINVALUE ";
1362  sql += te::common::Convert2String(sequence->getMinValue());
1363  sql += " MAXVALUE ";
1364  sql += te::common::Convert2String(sequence->getMaxValue());
1365  sql += " START WITH ";
1366  sql += te::common::Convert2String(sequence->getStartValue());
1367  sql += " CACHE ";
1368  sql += te::common::Convert2String(sequence->getCachedValues());
1369 
1370  if(sequence->isCycled() == false)
1371  sql += " NO";
1372 
1373  sql += " CYCLE ";
1374 
1375  if(sequence->getOwner())
1376  {
1377  sql += " OWNED BY ";
1378  sql += sequence->getOwner()->getParent()->getName();
1379  sql += ".";
1380  sql += sequence->getOwner()->getName();
1381  }
1382 
1383  execute(sql);
1384 
1385  unsigned int seqId = getDataSetId(seqName);
1386 
1387  sequence->setId(seqId);
1388 }
1389 
1390 void te::pgis::Transactor::dropSequence(const std::string& name)
1391 {
1392  std::auto_ptr<te::da::Sequence> seq = getSequence(name);
1393 
1394  std::string sql("DROP SEQUENCE ");
1395  sql += name;
1396 
1397  execute(sql);
1398 }
1399 
1400 std::auto_ptr<te::gm::Envelope> te::pgis::Transactor::getExtent(const std::string& datasetName, const std::string& propertyName)
1401 {
1402  std::string sql("SELECT ST_Extent(");
1403  sql += propertyName;
1404  sql += ") FROM ";
1405  sql += datasetName;
1406 
1407  PGresult* result = PQexec(m_conn->getConn(), sql.c_str());
1408 
1409  if(PQresultStatus(result) != PGRES_TUPLES_OK)
1410  {
1411  std::string errmsg(TE_TR("Could not find the envelope for the given geometry property due to the following error: "));
1412  errmsg += PQerrorMessage(m_conn->getConn());
1413 
1414  PQclear(result);
1415 
1416  throw Exception(errmsg);
1417  }
1418 
1419  const char* boxStr = PQgetvalue(result, 0, 0);
1420 
1421  te::gm::Envelope* mbr = 0;
1422 
1423  if(*boxStr != '\0')
1424  mbr = GetEnvelope(boxStr);
1425 
1426  PQclear(result);
1427  return std::auto_ptr<te::gm::Envelope>(mbr);
1428 }
1429 
1430 std::auto_ptr<te::gm::Envelope> te::pgis::Transactor::getExtent(const std::string& datasetName, std::size_t propertyPos)
1431 {
1432  std::auto_ptr<te::dt::Property> p = getProperty(datasetName, propertyPos);
1433 
1434  std::string sql("SELECT ST_Extent(");
1435  sql += p->getName();
1436  sql += ") FROM ";
1437  sql += datasetName;
1438 
1439  PGresult* result = PQexec(m_conn->getConn(), sql.c_str());
1440 
1441  if(PQresultStatus(result) != PGRES_TUPLES_OK)
1442  {
1443  std::string errmsg(TE_TR("Could not find the envelope for the given geometry property due to the following error: "));
1444  errmsg += PQerrorMessage(m_conn->getConn());
1445 
1446  PQclear(result);
1447 
1448  throw Exception(errmsg);
1449  }
1450 
1451  const char* boxStr = PQgetvalue(result, 0, 0);
1452 
1453  te::gm::Envelope* mbr = 0;
1454 
1455  if(*boxStr != '\0')
1456  mbr = GetEnvelope(boxStr);
1457 
1458  PQclear(result);
1459  return std::auto_ptr<te::gm::Envelope>(mbr);
1460 }
1461 
1462 std::size_t te::pgis::Transactor::getNumberOfItems(const std::string& datasetName)
1463 {
1464  std::auto_ptr<te::da::DataSet> result = getDataSet(datasetName);
1465  return result->size();
1466 }
1467 
1469 {
1470  std::vector<std::string> datasetNames = getDataSetNames();
1471 
1472  if(datasetNames.empty())
1473  return false;
1474 
1475  return true;
1476 }
1477 
1478 bool te::pgis::Transactor::dataSetExists(const std::string& name)
1479 {
1480  std::string datasetName = getFullName(name);
1481 
1482  std::vector<std::string> datasetNames = getDataSetNames();
1483 
1484  if(std::find(datasetNames.begin(), datasetNames.end(), datasetName) != datasetNames.end())
1485  return true;
1486 
1487  return false;
1488 }
1489 
1490 void te::pgis::Transactor::createDataSet(te::da::DataSetType* dt, const std::map<std::string, std::string>& options)
1491 {
1492  std::string datasetName = dt->getName();
1493  datasetName = getFullName(datasetName);
1494 
1495  std::string sql = "CREATE TABLE ";
1496  sql += datasetName;
1497  sql += "()";
1498 
1499  execute(sql);
1500 
1501  // Find the table id
1502  unsigned int dtid = getDataSetId(datasetName);
1503 
1504  dt->setId(dtid);
1505 
1506  // Add the properties
1507  std::size_t nCols = dt->size();
1508  for(std::size_t i = 0; i < nCols; ++i)
1509  addProperty(datasetName, dt->getProperty(i));
1510 
1511  // Add the primary key
1512  if(dt->getPrimaryKey())
1513  addPrimaryKey(datasetName, dt->getPrimaryKey());
1514 
1515  // Add the unique keys
1516  std::size_t nUKs = dt->getNumberOfUniqueKeys();
1517  for(std::size_t i = 0; i < nUKs; ++i)
1518  addUniqueKey(datasetName, dt->getUniqueKey(i));
1519 
1520  // Add the indexes, just if no primary key or unique key with the same name exists!
1521  std::size_t nIdxs = dt->getNumberOfIndexes();
1522  for(std::size_t i = 0; i < nIdxs; ++i)
1523  addIndex(datasetName, dt->getIndex(i), options);
1524 
1525  // Add the foreign keys
1526  std::size_t nFKs = dt->getNumberOfForeignKeys();
1527  for(std::size_t i = 0; i < nFKs; ++i)
1528  addForeignKey(datasetName, dt->getForeignKey(i));
1529 
1530  // Add the the check constraints
1531  std::size_t nCCs = dt->getNumberOfCheckConstraints();
1532 
1533  for(std::size_t i = 0; i < nCCs; ++i)
1534  addCheckConstraint(datasetName, dt->getCheckConstraint(i));
1535 
1536  // Try to link the primary key to an index
1537  std::vector<std::string> indexNames = getIndexNames(datasetName);
1538 
1539  te::da::PrimaryKey* pk = dt->getPrimaryKey();
1540  if(pk)
1541  {
1542  for(std::size_t i = 0; i < indexNames.size(); ++i)
1543  {
1544  if(pk->getName() == indexNames[i])
1545  {
1546  pk->setAssociatedIndex(dt->getIndex(indexNames[i]));
1547  break;
1548  }
1549  }
1550  }
1551 
1552  // Try to link the unique keys to an index
1553  std::size_t numUKs = dt->getNumberOfUniqueKeys();
1554 
1555  for(std::size_t i = 0; i < numUKs; ++i)
1556  {
1557  te::da::UniqueKey* uk = dt->getUniqueKey(i);
1558 
1559  for(std::size_t j = 0; j < indexNames.size(); ++j)
1560  {
1561  if(uk->getName() == indexNames[j])
1562  {
1563  uk->setAssociatedIndex(dt->getIndex(indexNames[j]));
1564  break;
1565  }
1566  }
1567  }
1568 }
1569 
1570 void te::pgis::Transactor::cloneDataSet(const std::string& /*name*/,
1571  const std::string& /*cloneName*/,
1572  const std::map<std::string, std::string>& /*options*/)
1573 {
1574  throw Exception(TE_TR("Not implemented yet!"));
1575 }
1576 
1577 void te::pgis::Transactor::dropDataSet(const std::string& name)
1578 {
1579  std::auto_ptr<te::da::DataSetType> dt = getDataSetType(name);
1580 
1581  std::string sql;
1582 
1583  if(dt->hasGeom())
1584  {
1585  std::string tSchema, tName;
1586  SplitTableName(dt->getName(), &(m_ds->getCurrentSchema()), tSchema, tName);
1587 
1588  sql = "SELECT DropGeometryTable('";
1589  sql += te::common::Convert2LCase(tSchema);
1590  sql += "', '";
1591  sql += te::common::Convert2LCase(tName);
1592  sql += "')";
1593  }
1594  else
1595  {
1596  sql += "DROP TABLE ";
1597  sql += dt->getName();
1598  }
1599 
1600  execute(sql);
1601 }
1602 
1603 void te::pgis::Transactor::renameDataSet(const std::string& name, const std::string& newName)
1604 {
1605  std::string newTableName, newTableSchema, oldTableName, oldTableSchema;
1606 
1607  std::string sql("ALTER TABLE ");
1608  sql += name;
1609  sql += " RENAME TO ";
1610 
1611  SplitTableName(newName, &(m_ds->getCurrentSchema()), newTableSchema, newTableName);
1612 
1613  sql += newTableName;
1614 
1615  execute(sql);
1616 
1617  // If the table has a geometry column, we need to propagate changes to the geometry columns table
1618  std::auto_ptr<te::da::DataSetType> dt = getDataSetType(name);
1619 
1620  if(dt->hasGeom())
1621  {
1622  SplitTableName(name, &(m_ds->getCurrentSchema()), oldTableSchema, oldTableName);
1623 
1624  sql = "UPDATE geometry_columns SET f_table_name = '";
1625  sql += newTableName;
1626  sql += "' WHERE f_table_name = '";
1627  sql += oldTableName;
1628  sql += "' AND f_table_schema ='";
1629  sql += oldTableSchema;
1630  sql += "'";
1631 
1632  execute(sql);
1633  }
1634 }
1635 
1636 void te::pgis::Transactor::add(const std::string& datasetName,
1637  te::da::DataSet* d,
1638  const std::map<std::string, std::string>& options,
1639  std::size_t limit)
1640 {
1641  if(limit == 0)
1642  limit = std::string::npos;
1643 
1644 // create a prepared statement
1645  std::string sql = "INSERT INTO ";
1646  sql += datasetName;
1647  sql += te::da::GetSQLValueNames(d);
1648  sql += " VALUES";
1649  sql += GetSQLBindValues(d->getNumProperties());
1650 
1651  std::auto_ptr<PreparedQuery> pq(new PreparedQuery(this, "a" + boost::lexical_cast<std::string>((intptr_t)(this))));
1652 
1653  te::da::ScopedTransaction st(*this);
1654 
1655  std::vector<int> paramTypes = te::da::GetPropertyDataTypes(d);
1656 
1657  std::size_t nProcessedRows = 0;
1658 
1659  pq->prepare(sql, paramTypes);
1660 
1661  while(d->moveNext() && (nProcessedRows != limit))
1662  {
1663  pq->bind(d);
1664  pq->execute();
1665 
1666  ++nProcessedRows;
1667  }
1668 
1669  st.commit();
1670 }
1671 
1672 
1673 void te::pgis::Transactor::remove(const std::string& /*datasetName*/, const te::da::ObjectIdSet* /*oids*/)
1674 {
1675  throw Exception(TE_TR("Not implemented yet!"));
1676  //std::string sql("DELETE FROM ");
1677  // sql += datasetName);
1678 
1679  //m_t->execute(sql);
1680 
1681 // const std::vector<te::dt::Property*>* keyProperties = 0;
1682 //
1683 // if(dt->getPrimaryKey())
1684 // {
1685 // keyProperties = &(dt->getPrimaryKey()->getProperties());
1686 // }
1687 // else if(dt->getNumberOfUniqueKeys() > 0)
1688 // {
1689 // keyProperties = &(dt->getUniqueKey(0)->getProperties());
1690 // }
1691 // else
1692 // {
1693 // throw Exception(TE_TR("Can not remove dataset items because dataset doesn't have a primary key or unique key!"));
1694 // }
1695 //
1696 //// create a prepared statement
1697 // std::string sql = "DELETE FROM ";
1698 // sql += dt->getName();
1699 // sql += " WHERE ";
1700 // sql += GetBindableWhereSQL(*keyProperties);
1701 //
1702 // std::vector<std::size_t> propertiesPos;
1703 //
1704 // te::dt::GetPropertiesPosition(*keyProperties, dt, propertiesPos);
1705 //
1706 // std::auto_ptr<PreparedQuery> pq(m_t->getPGPrepared("a" + boost::lexical_cast<std::string>((boost::int64_t)(this))));
1707 //
1708 // te::da::ScopedTransaction st(*m_t);
1709 //
1710 // pq->prepare(sql, *keyProperties);
1711 //
1712 // do
1713 // {
1714 // pq->bind(propertiesPos, dt, d);
1715 // pq->execute();
1716 //
1717 // }while(d->moveNext());
1718 //
1719 // st.commit();
1720 
1721 // const std::vector<te::dt::Property*>* keyProperties = 0;
1722 //
1723 // if(dt->getPrimaryKey())
1724 // {
1725 // keyProperties = &(dt->getPrimaryKey()->getProperties());
1726 // }
1727 // else if(dt->getNumberOfUniqueKeys() > 0)
1728 // {
1729 // keyProperties = &(dt->getUniqueKey(0)->getProperties());
1730 // }
1731 // else
1732 // {
1733 // throw Exception(TE_TR("Can not remove dataset item because dataset type doesn't have a primary key or unique key!"));
1734 // }
1735 //
1736 //// create a prepared statement
1737 // std::string sql = "DELETE FROM ";
1738 // sql += dt->getName();
1739 // sql += " WHERE ";
1740 // sql += GetBindableWhereSQL(*keyProperties);
1741 //
1742 // std::vector<std::size_t> propertiesPos;
1743 //
1744 // te::dt::GetPropertiesPosition(*keyProperties, dt, propertiesPos);
1745 //
1746 // std::auto_ptr<PreparedQuery> pq(m_t->getPGPrepared("a" + boost::lexical_cast<std::string>((boost::int64_t)(this))));
1747 //
1748 // pq->prepare(sql, *keyProperties);
1749 // pq->bind(propertiesPos, dt, item);
1750 // pq->execute();
1751 }
1752 
1753 void te::pgis::Transactor::update(const std::string& /*datasetName*/,
1754  te::da::DataSet* /*dataset*/,
1755  const std::vector<std::size_t>& /*properties*/,
1756  const te::da::ObjectIdSet* /*oids*/,
1757  const std::map<std::string, std::string>& /*options*/,
1758  std::size_t /*limit*/)
1759 {
1760  throw Exception(TE_TR("Not implemented yet!"));
1761 
1762 // const std::vector<te::dt::Property*>* keyProperties = 0;
1763 //
1764 // if(dt->getPrimaryKey())
1765 // {
1766 // keyProperties = &(dt->getPrimaryKey()->getProperties());
1767 // }
1768 // else if(dt->getNumberOfUniqueKeys() > 0)
1769 // {
1770 // keyProperties = &(dt->getUniqueKey(0)->getProperties());
1771 // }
1772 // else
1773 // {
1774 // throw Exception(TE_TR("Can not update dataset item(s) because dataset doesn't have a primary key or unique key!"));
1775 // }
1776 //
1777 //// create a prepared statement
1778 // std::string sql = "UPDATE ";
1779 // sql += dt->getName();
1780 // sql += " SET ";
1781 // sql += GetBindableUpdateSQL(properties);
1782 // sql += " WHERE ";
1783 // sql += GetBindableWhereSQL(*keyProperties, properties.size());
1784 //
1785 // std::vector<std::size_t> propertiesPos;
1786 //
1787 // te::dt::GetPropertiesPosition(properties, dt, propertiesPos);
1788 //
1789 // te::dt::GetPropertiesPosition(*keyProperties, dt, propertiesPos);
1790 //
1791 // std::auto_ptr<PreparedQuery> pq(m_t->getPGPrepared("a" + boost::lexical_cast<std::string>((boost::int64_t)(this))));
1792 //
1793 // std::vector<te::dt::Property*> allprops(properties);
1794 //
1795 // std::copy(keyProperties->begin(), keyProperties->end(), allprops.end());
1796 //
1797 // te::da::ScopedTransaction st(*m_t);
1798 //
1799 // pq->prepare(sql, allprops);
1800 //
1801 // do
1802 // {
1803 // pq->bind(propertiesPos, dt, dataset);
1804 // pq->execute();
1805 //
1806 // }while(dataset->moveNext());
1807 //
1808 // st.commit();
1809 }
1810 
1811 void te::pgis::Transactor::update(const std::string& datasetName,
1812  te::da::DataSet* dataset,
1813  const std::vector< std::set<int> >& properties,
1814  const std::vector<size_t>& ids)
1815 {
1816  dataset->moveFirst();
1817 
1818  int i=0;
1819  std::set<int> plst;
1820  std::set<int>::iterator it;
1821 
1822  try
1823  {
1824  begin();
1825 
1826  do
1827  {
1828  std::string sql = "UPDATE " + datasetName + " SET ";
1829  plst = properties[i];
1830  std::string pName;
1831  std::string value;
1832  std::string id;
1833  int k = 0;
1834 
1835  for(it = plst.begin(); it != plst.end(); ++it)
1836  {
1837  if(k>0)
1838  {
1839  pName += ",";
1840  value += ",";
1841  }
1842 
1843  pName += dataset->getPropertyName(*it);
1844 
1845  if(dataset->getPropertyDataType(*it) == te::dt::STRING_TYPE)
1846  value += "\'" + dataset->getAsString(*it) + "\'";
1847  else
1848  value += dataset->getAsString(*it);
1849 
1850  k++;
1851  }
1852 
1853  for(size_t j=0; j<ids.size(); ++j)
1854  {
1855  if(j>0)
1856  id += " AND ";
1857 
1858  id += dataset->getPropertyName(j) += "=";
1859 
1860  if(dataset->getPropertyDataType(j) == te::dt::STRING_TYPE)
1861  id += "\'" + dataset->getAsString(j) + "\'";
1862  else
1863  id += dataset->getAsString(j);
1864  }
1865 
1866  sql += "(" + pName + ")=(" + value + ") WHERE " + id;
1867 
1868  execute(sql);
1869 
1870  i++;
1871  } while (dataset->moveNext());
1872 
1873  commit();
1874  }
1875  catch(te::pgis::Exception& e)
1876  {
1877  rollBack();
1878 
1879  throw e;
1880  }
1881 }
1882 
1883 void te::pgis::Transactor::optimize(const std::map<std::string, std::string>& /*opInfo*/)
1884 {
1885  throw Exception(TE_TR("Not implemented yet!"));
1886 }
1887 
1889 {
1890  std::string sql("SELECT oid FROM pg_type WHERE typname = 'geometry'");
1891 
1892  std::auto_ptr<te::da::DataSet> result(query(sql));
1893 
1894  unsigned int id = 0;
1895 
1896  if(result->moveNext())
1897  id = result->getInt32(0);
1898 
1899  return id;
1900 }
1901 
1903 {
1904  std::string sql("SELECT oid FROM pg_type WHERE typname = 'raster'");
1905 
1906  std::auto_ptr<te::da::DataSet> result(query(sql));
1907 
1908  unsigned int id = 0;
1909 
1910  if(result->moveNext())
1911  id = result->getInt32(0);
1912 
1913  return id;
1914 }
1915 
1916 void te::pgis::Transactor::getDatabaseInfo(std::string& currentSchema)
1917 {
1918  std::string sql("SELECT current_schema()");
1919 
1920  std::auto_ptr<te::da::DataSet> result(query(sql));
1921 
1922  if(!result->moveNext())
1923  Exception(TE_TR("Could not get information about PostgreSQL database backend!"));
1924 
1925  currentSchema = result->getString(0);
1926 }
1927 
1928 void te::pgis::Transactor::getGeometryInfo(const std::string& datasetName, te::gm::GeometryProperty* gp)
1929 {
1930  std::string sql = "SELECT g.coord_dimension, g.srid, g.type "
1931  "FROM geometry_columns g "
1932  "WHERE g.f_table_name = '";
1933 
1934  std::string tname, sname;
1935 
1936  SplitTableName(datasetName, &(m_ds->getCurrentSchema()), sname, tname);
1937 
1938  sql += tname;
1939  sql += "' AND g.f_table_schema = '";
1940  sql += sname;
1941  sql += "' AND f_geometry_column = '";
1942  sql += gp->getName();
1943  sql += "'";
1944 
1945  std::auto_ptr<te::da::DataSet> result(query(sql));
1946 
1947  if(result->moveNext())
1948  {
1949  //int cdim = result->getInt(0);
1950  int srid = result->getInt32(1);
1951  te::gm::GeomType t = te::gm::Geometry::getGeomTypeId(result->getString(2));
1952  //gp->setCoordDimension(cdim);
1953  gp->setSRID(srid);
1954  gp->setGeometryType(t);
1955  }
1956  else
1957  {
1958 // Don't throw: someone can create a geometry column without using AddGeometryColumn function!!
1959  gp->setSRID(-1);
1961  }
1962 }
1963 
1964 void te::pgis::Transactor::getRasterInfo(const std::string& datasetName, te::rst::RasterProperty* rp)
1965 {
1966  std::string sql = "SELECT * FROM raster_columns as r WHERE r.r_table_name = '";
1967 
1968  std::string tname, sname;
1969 
1970  SplitTableName(datasetName, &(m_ds->getCurrentSchema()), sname, tname);
1971 
1972  sql += tname;
1973  sql += "' AND r.r_table_schema = '";
1974  sql += sname;
1975  sql += "' AND r_raster_column = '";
1976  sql += rp->getName();
1977  sql += "'";
1978 
1979  std::auto_ptr<te::da::DataSet> result(query(sql));
1980 
1981  if(result->moveNext())
1982  {
1983  int srid = result->getInt32("srid");
1984 
1985  double scale_x = result->getDouble("scale_x");
1986 
1987  double scale_y = result->getDouble("scale_y");
1988 
1989  int blocksize_x = result->getInt32("blocksize_x");
1990 
1991  int blocksize_y = result->getInt32("blocksize_y");
1992 
1993  //bool regular_blocking = result->getBool("regular_blocking");
1994 
1995  int nbands = result->getInt32("num_bands");
1996 
1997  std::auto_ptr<te::dt::Array> pixel_types(result->getArray("pixel_types"));
1998 
1999  std::auto_ptr<te::dt::Array> nodata_values(result->getArray("nodata_values"));
2000 
2001  std::auto_ptr<te::gm::Geometry> g(result->getGeometry("extent"));
2002 
2003  const te::gm::Envelope* e = g->getMBR();
2004 
2005  std::auto_ptr<te::rst::Grid> grid(new te::rst::Grid(scale_x, scale_y, new te::gm::Envelope(*e), srid));
2006 
2007  rp->set(grid.release());
2008 
2009  for(int i = 0; i != nbands; ++i)
2010  {
2011  std::vector<std::size_t> pos(1, i);
2012 
2013  std::string st = pixel_types->getData(pos)->toString();
2014 
2015  int t = te::dt::UNKNOWN_TYPE;
2016 
2017  if(st == "8BI")
2018  t = te::dt::CHAR_TYPE;
2019  else if(st == "8BUI")
2020  t = te::dt::UCHAR_TYPE;
2021  else if(st == "16BI")
2022  t = te::dt::INT16_TYPE;
2023  else if(st == "16BUI")
2024  t = te::dt::UINT16_TYPE;
2025  else if(st == "32BI")
2026  t = te::dt::INT32_TYPE;
2027  else if(st == "32BUI")
2028  t = te::dt::UINT32_TYPE;
2029  else if(st == "32BF")
2030  t = te::dt::FLOAT_TYPE;
2031  else if(st == "64BF")
2032  t = te::dt::DOUBLE_TYPE;
2033  else
2034  throw Exception(TE_TR("Band data type not supported by PostGIS driver!"));
2035 
2037 
2038  bp->m_blkh = blocksize_y;
2039 
2040  bp->m_blkw = blocksize_x;
2041 
2042  te::dt::AbstractData* ab = nodata_values->getData(pos);
2043 
2044  if(ab)
2045  bp->m_noDataValue = static_cast<te::dt::Double*>(ab)->getValue();
2046 
2047  rp->add(bp);
2048  }
2049  }
2050  else
2051  {
2052  //throw Exception(TE_TR("We must add support for rasters that don't have constraints!"));
2053  }
2054 }
2055 
2056 std::string te::pgis::Transactor::getFullName(const std::string& name)
2057 {
2058  std::string fullName = name;
2059 
2060  if(fullName.find(".") == std::string::npos)
2061  fullName = m_ds->getCurrentSchema() + "." + name;
2062 
2063  return fullName;
2064 }
2065 
2066 /////////// Protected methods
2067 
2068 unsigned int te::pgis::Transactor::getDataSetId(const std::string& tableName)
2069 {
2070  std::string tname, sname;
2071 
2072  SplitTableName(tableName, &(m_ds->getCurrentSchema()), sname, tname);
2073 
2074  std::string sql("SELECT pg_class.oid "
2075  "FROM pg_class, pg_namespace "
2076  "WHERE pg_class.relnamespace = pg_namespace.oid "
2077  "AND lower(pg_class.relname) = '");
2078 
2079  sql += te::common::Convert2LCase(tname);
2080  sql += "' AND lower(pg_namespace.nspname) = '";
2081  sql += te::common::Convert2LCase(sname);
2082  sql += "'";
2083 
2084  std::auto_ptr<te::da::DataSet> result(query(sql));
2085 
2086  if(result->moveNext() == false)
2087  throw Exception(TE_TR("Could not find the table oid!"));
2088 
2089  unsigned int tableid = result->getInt32(0);
2090 
2091  return tableid;
2092 }
2093 
2094 std::string te::pgis::Transactor::getDataSetName(unsigned int id)
2095 {
2096  std::string sql("SELECT pg_namespace.nspname, pg_class.relname "
2097  "FROM pg_class, pg_namespace "
2098  "WHERE pg_class.relnamespace = pg_namespace.oid "
2099  "AND pg_class.oid = ");
2100 
2101  sql += te::common::Convert2String(id);
2102 
2103  std::auto_ptr<te::da::DataSet> result(query(sql));
2104 
2105  if(result->moveNext() == false)
2106  throw Exception(TE_TR("Could not find the dataset name!"));
2107 
2108  std::string tname = result->getString(0);
2109  tname += ".";
2110  tname += result->getString(1);
2111 
2112  return tname;
2113 }
2114 
2115 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::getPropertiesInfo(const std::string& datasetName)
2116 {
2117  std::string fullDatasetName = getFullName(datasetName);
2118 
2119  unsigned int dtid = getDataSetId(fullDatasetName);
2120 
2121  std::string sql("SELECT a.attnum, a.attname, t.oid, a.attnotnull, format_type(a.atttypid, a.atttypmod), a.atthasdef, pg_get_expr(d.adbin, d.adrelid), a.attndims "
2122  "FROM pg_attribute AS a INNER JOIN pg_type AS t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef AS d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) "
2123  "WHERE a.attrelid = ");
2124  sql += te::common::Convert2String(dtid);
2125  sql += " AND a.attisdropped = false"
2126  " AND a.attnum > 0"
2127  " ORDER BY a.attnum";
2128 
2129  return query(sql);
2130 }
2131 
2133 {
2134  if((p->getParent()==0) || (p->getParent()->getType() != te::dt::DATASET_TYPE))
2135  throw Exception(TE_TR("The informed property is not valid!"));
2136 
2137  std::string sql("SELECT attnum "
2138  "FROM pg_attribute WHERE attrelid = ");
2139  sql += te::common::Convert2String(p->getParent()->getId());
2140  sql += " AND attisdropped = false "
2141  "AND attname = '";
2142  sql += te::common::Convert2LCase(p->getName());
2143  sql += "' ";
2144 
2145  std::auto_ptr<te::da::DataSet> result(query(sql));
2146 
2147  if(result->moveNext() == false)
2148  throw Exception(TE_TR("Could not find the property ID!"));
2149 
2150  unsigned int id = result->getInt32(0);
2151  p->setId(id);
2152 }
2153 
2154 std::auto_ptr<te::dt::Property> te::pgis::Transactor::getProperty(unsigned int pid, const std::string& datasetName)
2155 {
2156  unsigned int dtid = getDataSetId(datasetName);
2157 
2158  std::string sql("SELECT a.attnum, a.attname, t.oid, a.attnotnull, format_type(a.atttypid, a.atttypmod), a.atthasdef, pg_get_expr(d.adbin, d.adrelid), a.attndims "
2159  "FROM pg_attribute AS a INNER JOIN pg_type AS t ON (a.atttypid = t.oid) LEFT JOIN pg_attrdef AS d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) "
2160  "WHERE a.attrelid = ");
2161  sql += te::common::Convert2String(dtid);
2162  sql += " AND a.attnum = ";
2163  sql += te::common::Convert2String(pid);
2164  sql += " AND a.attisdropped = false"
2165  " AND a.attnum > 0";
2166 
2167  std::auto_ptr<te::da::DataSet> result(query(sql));
2168 
2169  std::auto_ptr<te::dt::Property> p(0);
2170 
2171  if(result->moveNext())
2172  {
2173  unsigned int attNum = result->getInt16(0);
2174  std::string attName = result->getString(1);
2175  unsigned int attType = result->getInt32(2);
2176  bool attNotNull = result->getBool(3);
2177  std::string fmt = result->getString(4);
2178  bool attHasDefault = result->getBool(5);
2179  std::string attDefValue = result->getString(6);
2180  int ndims = result->getInt32(7);
2181 
2182  p.reset(Convert2TerraLib(attNum, attName.c_str(), attType, attNotNull, fmt.c_str(), attHasDefault,
2183  attDefValue.c_str(),ndims, m_ds->getGeomTypeId(), m_ds->getRasterTypeId()));
2184 
2185  if(p->getType() == te::dt::GEOMETRY_TYPE)
2186  getGeometryInfo(datasetName, static_cast<te::gm::GeometryProperty*>(p.get()));
2187  }
2188 
2189  return p;
2190 }
2191 
2192 std::auto_ptr<te::da::DataSet> te::pgis::Transactor::getConstraints(const std::string& datasetName, char conType)
2193 {
2194  unsigned int dtid = getDataSetId(datasetName);
2195 
2196  std::string sql("SELECT c.oid, n.nspname, c.conname, c.contype, c.confrelid, c.confupdtype, c.confdeltype, c.confmatchtype, c.conkey, c.confkey, pg_get_constraintdef(c.oid) "
2197  "FROM pg_constraint c, pg_namespace n "
2198  "WHERE c.connamespace = n.oid "
2199  "AND c.conrelid = ");
2200  sql += te::common::Convert2String(dtid);
2201 
2202  if(conType != '\0')
2203  {
2204  sql += " AND c.contype = '";
2205  sql += conType;
2206  sql += "'";
2207  }
2208 
2209  return query(sql);
2210 }
2211 
2213 {
2214  std::string datasetName = dt->getName();
2215  unsigned int dtid = dt->getId();
2216 
2217  std::string sql("SELECT c.oid, n.nspname, c.conname, c.contype, c.confrelid, c.confupdtype, c.confdeltype, c.confmatchtype, c.conkey, c.confkey, pg_get_constraintdef(c.oid) "
2218  "FROM pg_constraint c, pg_namespace n "
2219  "WHERE c.connamespace = n.oid "
2220  "AND c.conrelid = ");
2221  sql += te::common::Convert2String(dtid);
2222 
2223  std::auto_ptr<te::da::DataSet> cInfo = query(sql);
2224 
2225  while(cInfo->moveNext())
2226  {
2227  char cType = cInfo->getChar(3);
2228  if(cType == 'p')
2229  {
2230  // begin of the dataset primary key
2231  unsigned int pkId = cInfo->getInt32(0);
2232  std::string pkName = cInfo->getString(2);
2233 
2234  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pkName, 0, pkId);
2235 
2236  std::auto_ptr<te::dt::Array> pkCols(cInfo->getArray(8));
2237  std::size_t size = pkCols->getDimensionSize(0);
2238 
2239  std::vector<std::size_t> pos;
2240  pos.push_back(0);
2241  for(std::size_t i = 0; i < size; ++i)
2242  {
2243  pos[0] = i;
2244 
2245  te::dt::AbstractData* pkCol = pkCols->getData(pos);
2246 
2247  te::dt::Property* p = dt->getPropertyById(static_cast<te::dt::Int16*>(pkCol)->getValue());
2248  pk->add(p);
2249  }
2250 
2251  // Try to link the pk to an index
2252  std::vector<std::string> idxNames = getIndexNames(datasetName);
2253 
2254  for(std::size_t i = 0; i < idxNames.size(); ++i)
2255  {
2256  if(pk->getName() == idxNames[i])
2257  {
2258  pk->setAssociatedIndex(getIndex(datasetName, idxNames[i]).get());
2259  break;
2260  }
2261  }
2262 
2263  // Add the primary key to the schema
2264  dt->add(pk);
2265 
2266  } // end of the dataset primary key
2267  else if (cType == 'f')
2268  {
2269  // begin of foreign key constraint
2270  unsigned int fkId = cInfo->getInt32(0);
2271  unsigned int refDatasetId = cInfo->getInt32(4);
2272  char onUpdate = cInfo->getChar(5);
2273  char onDeletion = cInfo->getChar(6);
2274 
2275  std::auto_ptr<te::dt::Array> fkCols(cInfo->getArray(8));
2276  std::auto_ptr<te::dt::Array> fkRefCols(cInfo->getArray(9));
2277 
2278  assert(fkCols->getDimension() == 1);
2279  assert(fkCols->getDimension() == fkRefCols->getDimension());
2280  assert(fkCols->getDimensionSize(0) == fkRefCols->getDimensionSize(0));
2281 
2282  std::string refName = getDataSetName(refDatasetId);
2283 
2284  std::auto_ptr<te::da::DataSetType> refDatasetType = getDataSetType(refName);
2285 
2286  std::string fkName = cInfo->getString(2);
2287 
2288  te::da::ForeignKey* fk = new te::da::ForeignKey(fkName, fkId);
2289  fk->setOnUpdateAction(GetAction(onUpdate));
2290  fk->setOnDeleteAction(GetAction(onDeletion));
2291  fk->setReferencedDataSetType(refDatasetType.get());
2292 
2293  std::size_t size = fkCols->getDimensionSize(0);
2294 
2295  std::vector<std::size_t> pos;
2296  pos.push_back(0);
2297 
2298  for(std::size_t i = 0; i < size; ++i)
2299  {
2300  pos[0] = i;
2301 
2302  te::dt::AbstractData* fkRefCol = fkRefCols->getData(pos);
2303  fk->addRefProperty(refDatasetType->getPropertyById(static_cast<te::dt::Int16*>(fkRefCol)->getValue()));
2304 
2305  te::dt::AbstractData* fkCol = fkCols->getData(pos);
2306  fk->add(getProperty(static_cast<te::dt::Int16*>(fkCol)->getValue(), datasetName).release());
2307  }
2308 
2309  // Add the foreign key to the schema
2310  dt->add(fk);
2311 
2312  } // end of foreign key constraint
2313  else if(cType == 'u')
2314  {
2315  // begin of unique key constraint
2316  unsigned int ukId = cInfo->getInt32(0);
2317  std::string ukName = cInfo->getString(2);
2318 
2319  std::auto_ptr<te::dt::Array> ukCols(cInfo->getArray(8));
2320 
2321  te::da::UniqueKey* uk = new te::da::UniqueKey(ukName, 0, ukId);
2322 
2323  std::size_t size = ukCols->getDimensionSize(0);
2324 
2325  std::vector<std::size_t> pos;
2326  pos.push_back(0);
2327 
2328  for(std::size_t i = 0; i < size; ++i)
2329  {
2330  pos[0] = i;
2331 
2332  te::dt::AbstractData* ukCol = ukCols->getData(pos);
2333 
2334  std::auto_ptr<te::dt::Property> p = getProperty(static_cast<te::dt::Int16*>(ukCol)->getValue(), datasetName);
2335  uk->add(p.release());
2336  }
2337 
2338  // Try to link the uk to an index
2339  std::vector<std::string> idxNames = getIndexNames(datasetName);
2340 
2341  for(std::size_t i = 0; i < idxNames.size(); ++i)
2342  {
2343  if(uk->getName() == idxNames[i])
2344  {
2345  uk->setAssociatedIndex(getIndex(datasetName, idxNames[i]).get());
2346  break;
2347  }
2348  }
2349 
2350  // Add the unique key to the schema
2351  dt->add(uk);
2352 
2353  } // end of the unique key constraint
2354  else if(cType == 'c')
2355  {
2356  // begin of check constraint
2357  std::string ccName = cInfo->getString(2);
2358 
2359  unsigned int ccId = cInfo->getInt32(0);
2360 
2362  cc->setId(ccId);
2363  cc->setExpression(cInfo->getString(10));
2364 
2365  // Add the check constraint to the schema
2366  dt->add(cc);
2367 
2368  } // end of check constraint
2369  } // end of moveNext
2370 }
2371 
2373 {
2374  std::string datasetName = dt->getName();
2375  unsigned int dtid = dt->getId();
2376 
2377  std::string sql("SELECT idx_table.oid, s.nspname, idx_table.relname, pg_index.indkey, pg_am.amname, pg_index.indisunique, pg_index.indisprimary "
2378  "FROM pg_index, pg_class idx_table, pg_am, pg_namespace s "
2379  "WHERE s.oid = idx_table.relnamespace "
2380  "AND pg_index.indexrelid = idx_table.oid "
2381  "AND idx_table.relam = pg_am.oid "
2382  "AND pg_index.indrelid = ");
2383  sql += te::common::Convert2String(dtid);
2384 
2385  std::auto_ptr<te::da::DataSet> idxInfo = query(sql);
2386 
2387  while(idxInfo->moveNext())
2388  {
2389  unsigned int idxId = idxInfo->getInt32(0);
2390  std::string idxName = idxInfo->getString(2);
2391 
2392  std::auto_ptr<te::dt::Array> idxCols(idxInfo->getArray(3));
2393 
2394  std::string idxType = idxInfo->getString(4);
2395  bool isUK = idxInfo->getBool(5);
2396  bool isPK = idxInfo->getBool(6);
2397 
2398  te::da::Index* idx = new te::da::Index(idxName, GetIndexType(idxType.c_str()), dt, idxId);
2399 
2400  std::size_t size = idxCols->getDimensionSize(0);
2401 
2402  std::vector<std::size_t> pos;
2403  pos.push_back(0);
2404 
2405  for(std::size_t i = 0; i < size; ++i)
2406  {
2407  pos[0] = i;
2408  te::dt::AbstractData* idxCol = idxCols->getData(pos);
2409 
2410  idx->add(dt->getPropertyById(static_cast<te::dt::Int16*>(idxCol)->getValue()));
2411  }
2412 
2413  // Look if there is an association with a pk and uk
2414  idxName = idxInfo->getString(2);
2415  if(isPK && dt->getPrimaryKey() && (dt->getPrimaryKey()->getName() == idxName))
2416  {
2417  dt->getPrimaryKey()->setAssociatedIndex(idx);
2418  }
2419  else if(isUK)
2420  {
2421  te::da::UniqueKey* uk = dt->getUniqueKey(idxName);
2422 
2423  if(uk)
2424  uk->setAssociatedIndex(idx);
2425  }
2426  }
2427 }
2428 
2429 std::vector<te::da::Sequence*> te::pgis::Transactor::getSequences()
2430 {
2431  std::vector<te::da::Sequence*> seqs;
2432 
2433  // Query the data source for the sequences
2434  std::vector<std::string> seqNames;
2435 
2436  std::string sql("SELECT c.oid, n.nspname, c.relname, c.relkind "
2437  "FROM pg_class c, pg_namespace n "
2438  "WHERE c.relname !~ '^pg_' "
2439  "AND c.relkind = 'S' "
2440  "AND c.relnamespace = n.oid "
2441  "AND n.nspname NOT IN ('information_schema', 'pg_toast', 'pg_temp_1', 'pg_catalog')");
2442 
2443  std::auto_ptr<te::da::DataSet> seqNamesInfo = query(sql);
2444 
2445  while(seqNamesInfo->moveNext())
2446  {
2447  std::string seqName(seqNamesInfo->getString(2));
2448  seqNames.push_back(seqName);
2449  }
2450 
2451  for(std::size_t i = 0; i < seqNames.size(); ++i)
2452  {
2453  std::string seqName = seqNames[i];
2454 
2455  std::string sql("SELECT * FROM ");
2456  sql += seqName;
2457 
2458  std::auto_ptr<te::da::DataSet> result(query(sql));
2459 
2460  if(result->moveNext() == false)
2461  throw Exception((boost::format(TE_TR("There is no information about the sequence \"%1%\"!")) % seqName).str());
2462 
2463  unsigned int seqId = getDataSetId(seqName);
2464 
2465  te::da::Sequence* seq = new te::da::Sequence(seqName, 0, 0, 0, seqId);
2466 
2467  // Check if the sequence is cycled
2468  if(result->getBool(8))
2469  seq->setAsCycle();
2470  else
2471  seq->setAsNoCycle();
2472 
2473  seq->setCachedValues(result->getInt64(6)); // "cache_value"
2474  seq->setIncrement(result->getInt64(3)); // "increment_by";
2475  seq->setMaxValue(result->getInt64(4)); // "max_value";
2476  seq->setMinValue(result->getInt64(5)); // "min_value";
2477 
2478  seqs.push_back(seq);
2479  }
2480 
2481  return seqs;
2482 }
2483 
2485 {
2486  int encodingId = PQclientEncoding(m_conn->getConn());
2487  std::string encodingStr = pg_encoding_to_char(encodingId);
2488  return te::pgis::GetTeEncoding(encodingStr.c_str());
2489 }
virtual void setName(const std::string &name)
It sets the constraint name.
Definition: Constraint.h:126
void setTitle(const std::string &title)
It sets a human descriptive title for the DataSetType.
Definition: DataSetType.h:137
Property * getProperty(std::size_t i) const
It returns the i-th property.
void getDatabaseInfo(std::string &currentSchema)
It retrieves some information about the database such as the default schema used when no one is provi...
boost::int64_t getMinValue() const
It returns the minimum value that the sequence can generate.
Definition: Sequence.h:168
void getIndexes(te::da::DataSetType *dt)
It gets all the indexes of the given dataset and adds them to the dummy schema.
std::auto_ptr< te::da::DataSet > getPropertiesInfo(const std::string &datasetName)
It gets the information about the given dataset.
Geometric property.
std::auto_ptr< te::da::PrimaryKey > getPrimaryKey(const std::string &datasetName)
It retrieves the primary key of the dataset.
Definition: Transactor.cpp:607
void set(te::rst::Grid *grid)
Sets the definition of the raster grid support.
bool isInTransaction() const
It returns true if a transaction is in progress, otherwise, it returns false.
Definition: Transactor.cpp:112
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.
std::auto_ptr< te::da::DataSetType > getDataSetType(const std::string &name)
It gets information about the given dataset.
Definition: Transactor.cpp:292
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.
Definition: Enums.h:41
Utility functions for the data access module.
boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
Definition: Transactor.cpp:320
void SplitTableName(const std::string &fullName, const std::string *defaultSchema, std::string &schemaName, std::string &tableName)
Definition: Utils.cpp:408
void setMaxValue(boost::int64_t value)
It sets the maximum value that the sequence can generate.
Definition: Sequence.h:189
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
void setGeometryType(GeomType t)
It sets the geometry subtype.
std::auto_ptr< te::da::DataSet > getConstraints(const std::string &datasetName, char conType= '\0')
It gets the dataset containing information about one of the constraints(primary, foreign or unique ke...
CharEncoding
Supported charsets (character encoding).
void getRasterInfo(const std::string &datasetName, te::rst::RasterProperty *rp)
It loads information about a given raster column.
te::dt::Property * getOwner() const
It returns the property type associated to the sequence.
Definition: Sequence.h:237
std::auto_ptr< te::da::ForeignKey > getForeignKey(const std::string &datasetName, const std::string &name)
It retrieves the foreign key from the given dataset.
Definition: Transactor.cpp:725
std::vector< std::string > getDataSetNames()
It It gets the dataset names available in the data source.
Definition: Transactor.cpp:264
std::auto_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.
bool uniqueKeyExists(const std::string &datasetName, const std::string &name)
It checks if a unique key with the given name exists in the dataset.
Definition: Transactor.cpp:979
std::string Convert2LCase(const std::string &value)
It converts a string to lower case.
Definition: StringUtils.h:197
void setAsNoCycle()
It sets the sequence as not cycled (it can't wrap).
Definition: Sequence.h:230
boost::int64_t getMaxValue() const
It returns the maximum value that the sequence can generate.
Definition: Sequence.h:182
void addForeignKey(const std::string &datasetName, te::da::ForeignKey *fk)
It adds a foreign key constraint to a dataset.
Definition: Transactor.cpp:808
A raster band description.
Definition: BandProperty.h:61
Connection * getConnection() const
It returns the underlying connection.
Definition: Transactor.cpp:89
std::auto_ptr< te::da::BatchExecutor > getBatchExecutor()
It creates a batch command executor.
Definition: Transactor.cpp:245
A class that models the description of a dataset.
Definition: DataSetType.h:72
std::vector< std::string > getUniqueKeyNames(const std::string &datasetName)
It gets the unique key names of the given dataset.
Definition: Transactor.cpp:962
void addPrimaryKey(const std::string &datasetName, te::da::PrimaryKey *pk)
It adds a primary key constraint to the dataset schema.
Definition: Transactor.cpp:665
std::size_t getNumberOfUniqueKeys() const
It returns the number of unique keys defined for the dataset type.
Definition: DataSetType.h:269
const std::string & GetGeometryName(te::gm::GeomType t)
It returns the geometry names as usual for PostGIS.
Definition: Utils.cpp:149
CheckConstraint * getCheckConstraint(std::size_t i) const
It returns the i-th check-constraint associated to the dataset type.
Definition: DataSetType.h:354
struct pg_result PGresult
Definition: Connection.h:48
void addUniqueKey(const std::string &datasetName, te::da::UniqueKey *uk)
It adds a unique key constraint to the dataset.
Definition: Transactor.cpp:991
virtual Property * clone() const =0
It returns a clone of the object.
An static class with global definitions.
std::string getDataSetName(unsigned int id)
It looks for a dataset name with the given id in the PostgreSQL.
A visitor for building an SQL statement using PostGIS dialect.
Definition: SQLVisitor.h:52
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.
PrimaryKey * getPrimaryKey() const
It returns the primary key associated to the dataset type.
Definition: DataSetType.h:214
virtual void setId(unsigned int id)
It sets the constraint identifier.
Definition: Constraint.h:112
An utility class to coordinate transactions.
boost::int64_t getCachedValues() const
It returns how many sequence numbers are preallocated.
Definition: Sequence.h:210
SpatialRelation
Spatial relations between geometric objects.
Definition: Enums.h:122
void dropForeignKey(const std::string &datasetName, const std::string &fkName)
It removes the foreign key constraint from the dataset schema.
Definition: Transactor.cpp:897
It describes a sequence (a number generator).
Definition: Sequence.h:56
void add(te::dt::Property *p)
It adds the property to the list of properties of the index.
Definition: Index.h:197
te::gm::Envelope * GetEnvelope(const char *str)
It converts the pgType to a valid TerraLib data type.
Definition: Utils.h:169
A class that implements a connection to a PostgreSQL database.
Definition: Connection.h:68
TEDATAACCESSEXPORT std::string GetSQLValueNames(const DataSetType *dt)
Definition: Utils.cpp:621
A class that describes a check constraint.
void commit()
It commits the transaction.
Definition: Transactor.cpp:100
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:118
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
std::auto_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.
Definition: Transactor.cpp:240
int GetCoordDimension(GeomType t)
It returns the number of measurements or axes needed to describe a position in a coordinate system...
Definition: Utils.h:55
std::auto_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...
Definition: Transactor.cpp:199
It models a property definition.
Definition: Property.h:59
Raster property.
void remove(const std::string &datasetName, const te::da::ObjectIdSet *oids=0)
It removes all the informed items from the dataset.
std::vector< te::da::Sequence * > getSequences()
It gets information about all the sequences in the datasource.
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
Definition: PrimaryKey.h:109
void dropCheckConstraint(const std::string &datasetName, const std::string &name)
It removes the check constraint from the dataset.
void commit()
It commits the transaction.
void renameDataSet(const std::string &name, const std::string &newName)
It renames a dataset.
Index * getIndex(std::size_t i) const
It returns the i-th index associated to the dataset type.
Definition: DataSetType.h:428
The PostGIS driver.
Definition: DataSource.h:54
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:117
void changePropertyDefinition(const std::string &datasetName, const std::string &propName, te::dt::Property *newProp)
Definition: Transactor.cpp:590
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...
bool dataSetExists(const std::string &name)
It checks if a dataset with the given name exists in the data source.
void setIncrement(boost::int64_t n)
It sets the increment value.
Definition: Sequence.h:161
te::da::DataSource * getDataSource() const
It returns the parent data source of the transactor.
Definition: Transactor.cpp:84
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).
Definition: Enums.h:40
TraverseType
A dataset can be traversed in two ways:
Definition: Enums.h:53
std::auto_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.
Definition: Transactor.cpp:117
void dropDataSet(const std::string &name)
It removes the dataset schema from the data source.
~Transactor()
The destructor will automatically release the connection to the pool.
Definition: Transactor.cpp:79
std::size_t getNumberOfForeignKeys() const
It returns the number of foreign keys defined for the dataset type.
Definition: DataSetType.h:467
void getGeometryInfo(const std::string &datasetName, te::gm::GeometryProperty *gp)
It loads information about a given geometry column.
void add(te::rst::BandProperty *b)
It adds a new band information to the property.
std::auto_ptr< te::dt::Property > getProperty(const std::string &datasetName, const std::string &name)
It retrieves the property with the given name from the dataset.
Definition: Transactor.cpp:358
std::auto_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.
const std::string & getExpression() const
It returns the check constraint expression.
void setOnDeleteAction(FKActionType a)
It sets the action to be performed when a referenced element value in the referenced DataSetType is b...
Definition: ForeignKey.h:174
void setCachedValues(boost::int64_t value)
It sets how many sequence numbers are to be preallocated.
Definition: Sequence.h:217
int getSRID() const
It returns the spatial reference system identifier associated to this property.
std::size_t getNumberOfItems(const std::string &datasetName)
It retrieves the number of items of the given dataset.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
Implementation of a dataset for the PostGIS driver.
Definition: DataSet.h:60
void add(te::dt::Property *p)
It adds a property to the foreign key constraint.
Definition: ForeignKey.h:112
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:53
virtual std::string getPropertyName(std::size_t i) const =0
It returns the property name at position pos.
void dropPrimaryKey(const std::string &datasetName)
It removes the primary key constraint from the dataset schema.
Definition: Transactor.cpp:710
void Convert2PostGIS(const te::gm::Envelope *e, int srid, std::string &output)
It converts the envelope into a PostGIS BOX3D.
Definition: Utils.h:225
std::string escape(const std::string &value)
It escapes a string for using in commands and queries.
Definition: Transactor.cpp:259
Property * getPropertyById(unsigned int id) const
It searches for a property with the given ID.
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
std::size_t getNumberOfProperties(const std::string &datasetName)
It gets the number of properties of the given dataset.
Definition: Transactor.cpp:430
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.
std::size_t getNumberOfIndexes() const
It returns the number of indexes defined for the dataset type.
Definition: DataSetType.h:391
DataSetType * getReferencedDataSetType() const
It returns the referenced DataSetType of this foreign key constraint.
Definition: ForeignKey.h:153
std::size_t getNumberOfDataSets()
It retrieves the number of data sets available in the data source.
Definition: Transactor.cpp:287
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.
Definition: DataSet.cpp:218
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
void addRefProperty(te::dt::Property *p)
It adds a reference property (on the referenced DataSetType) of this foreign key constraint.
Definition: ForeignKey.h:137
It describes a unique key (uk) constraint.
Definition: UniqueKey.h:53
void setAssociatedIndex(Index *idx)
It sets the associated index.
Definition: UniqueKey.h:138
void add(const std::string &datasetName, te::da::DataSet *d, const std::map< std::string, std::string > &options, std::size_t limit=0)
It adds data items to the dataset in the data source.
Property * getParent() const
It returns the parent of this property, or NULL, if it doesn't have one.
Definition: Property.h:150
std::size_t size() const
It returns the number of properties of the CompositeProperty.
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
TEDATAACCESSEXPORT std::vector< int > GetPropertyDataTypes(const te::da::DataSet *dataset)
Definition: Utils.cpp:659
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
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.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
A class that implements a connection to a PostgreSQL database.
void getPropertyId(te::dt::Property *p)
It sets the property id from the PostgreSQL system.
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
std::auto_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.
Definition: Transactor.cpp:909
bool isCycled() const
It returns true if the sequence can wrap, otherwise it returns false.
Definition: Sequence.h:224
Implementation of the data source for the PostGIS driver.
int getType() const
It returns the property data type.
Definition: Property.h:143
void add(Constraint *c)
It adds a new constraint.
A Transactor can be viewed as a connection to the data source for reading/writing things into it...
void rollBack()
It aborts the transaction. Any changes will be rolled-back.
Definition: Transactor.cpp:106
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
void addProperty(const std::string &datasetName, te::dt::Property *p)
It adds a new property to the dataset schema.
Definition: Transactor.cpp:448
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that form the unique key.
Definition: UniqueKey.h:110
bool sequenceExists(const std::string &name)
It checks if a sequence 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.
te::common::CharEncoding getEncoding()
It return the DataSource current encoding.
te::common::CharEncoding GetTeEncoding(const char *const encoding)
Definition: Utils.cpp:658
void setAssociatedIndex(Index *idx)
It sets the associated index.
Definition: PrimaryKey.h:130
ForeignKey * getForeignKey(std::size_t i) const
It returns the i-th foreign key associated to the dataset type.
Definition: DataSetType.h:480
void setOnUpdateAction(FKActionType a)
It sets the action to be performed when a referenced element value in the referenced DataSetType is b...
Definition: ForeignKey.h:188
An exception class for the PostGIS driver.
A visitor for building an SQL statement using PostGIS dialect.
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
std::string GetSpatialRelation(te::gm::SpatialRelation rel)
It converts the spatial relationship to PostGIS dialect.
Definition: Utils.h:803
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the index.
Definition: Index.h:183
std::size_t getNumberOfCheckConstraints() const
It returns the number of check-constraints defined over the dataset type.
Definition: DataSetType.h:331
std::vector< std::string > getIndexNames(const std::string &datasetName)
It gets the index names of the given dataset.
bool indexExists(const std::string &datasetName, const std::string &name)
It checks if an index with the given name exists in the dataset.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
Transactor(DataSource *ds, Connection *conn)
Constructor.
Definition: Transactor.cpp:72
void renameProperty(const std::string &datasetName, const std::string &propertyName, const std::string &newPropertyName)
It renames a property of the given dataset.
Definition: Transactor.cpp:545
void setExpression(const std::string &e)
It sets the check constraint expression.
std::string getFullName(const std::string &name)
It gets the full name of the given name including the schema name.
te::dt::Property * Convert2TerraLib(unsigned int attNum, const char *attName, unsigned int attType, bool attNotNull, const char *fmt, bool attHasDefault, const char *attDefValue, unsigned int pgisGeomTypeOid, unsigned int pgisRasterTypeOid)
It creates a PropertyType from a PostgreSQL attribute description.
Definition: Utils.h:456
void execute(const te::da::Query &command)
It executes the specified command using a generic query representation.
Definition: Transactor.cpp:225
unsigned int getGeomTypeId()
It will check in the database catalog the number that identifies the PostGIS Geometry type...
std::vector< std::string > getSequenceNames()
It gets the sequence names available in the data source.
boost::int64_t getIncrement() const
It returns the increment value.
Definition: Sequence.h:154
void dropSequence(const std::string &name)
It removes the sequence from the data source.
boost::int64_t getStartValue() const
It returns the initial value of the sequence.
Definition: Sequence.h:196
bool propertyExists(const std::string &datasetName, const std::string &name)
It checks if a property with the given name exists in the dataset.
Definition: Transactor.cpp:436
FKActionType getOnUpdateAction() const
It returns the action performed when a referenced element value in the referenced DataSetType is bein...
Definition: ForeignKey.h:181
void dropProperty(const std::string &datasetName, const std::string &name)
It removes a property from the given dataset.
Definition: Transactor.cpp:502
unsigned int getRasterTypeId()
It will check in the database catalog the number that identifies the PostGIS Raster type...
std::vector< std::string > getPropertyNames(const std::string &datasetName)
It gets the property names of the given dataset.
Definition: Transactor.cpp:414
void addCheckConstraint(const std::string &datasetName, te::da::CheckConstraint *cc)
It adds a check constraint to the dataset.
void setAsCycle()
It sets the sequence as cycled (it can wrap).
Definition: Sequence.h:227
te::da::IndexType GetIndexType(const char *t)
It converts the PostgreSQL index string to a TerraLib index type.
Definition: Utils.h:141
std::string GetBoxSpatialRelation(te::gm::SpatialRelation rel)
It converts the spatial relationship to PostGIS dialect.
Definition: Utils.h:849
void setReferencedDataSetType(DataSetType *refDt)
It sets the referenced DataSetType of this foreign key constraint.
Definition: ForeignKey.h:160
std::vector< std::string > getForeignKeyNames(const std::string &datasetName)
It gets the foreign key names of the given dataset.
Definition: Transactor.cpp:780
te::da::FKActionType GetAction(char a)
It converts the PostgreSQL foreign key modifier to a TerraLib data type.
Definition: Utils.h:113
void dropIndex(const std::string &datasetName, const std::string &idxName)
It removes the index from the dataset schema.
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:51
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
A dataset is the unit of information manipulated by the data access module of TerraLib.
virtual const std::string & getName() const
It returns the constraint name.
Definition: Constraint.h:119
A class that implements a connection pool for PostGIS.
const std::string & getName() const
It returns the sequence name.
Definition: Sequence.h:140
std::vector< std::string > getCheckConstraintNames(const std::string &datasetName)
It gets the check constraint names of the given dataset.
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
IndexType getIndexType() const
It gets the index type.
Definition: Index.h:169
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
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.
Definition: Transactor.cpp:797
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the foreign key constraint.
Definition: ForeignKey.h:103
void addSequence(te::da::Sequence *sequence)
It creates a new sequence in the data source.
void begin()
It starts a new transaction.
Definition: Transactor.cpp:94
virtual bool moveFirst()=0
It moves the internal pointer to the first item in the collection.
const std::vector< te::dt::Property * > & getReferencedProperties() const
It returns the referenced properties (on the referenced DataSetType) of this foreign key constraint...
Definition: ForeignKey.h:128
boost::int64_t getLastGeneratedId()
It returns the last id generated by an insertion command.
Definition: Transactor.cpp:254
A class that implements a prepared query for PostgreSQL data access driver.
Definition: PreparedQuery.h:68
void cancel()
It requests that the data source stop the processing of the current command.
Definition: Transactor.cpp:250
void setId(unsigned int id)
It sets the sequence identifier.
Definition: Sequence.h:133
A Query is independent from the data source language/dialect.
Definition: Query.h:46
It describes an index associated to a DataSetType.
Definition: Index.h:54
bool hasDataSets()
It checks if the data source has any dataset.
bool primaryKeyExists(const std::string &datasetName, const std::string &name)
It checks if a primary key exists in the dataset.
Definition: Transactor.cpp:653
unsigned int getId() const
It returns the property identifier.
Definition: Property.h:108
std::string GetSQLBindValues(std::size_t nproperties)
Definition: Utils.cpp:446
UniqueKey * getUniqueKey(std::size_t i) const
It returns the i-th unique key.
Definition: DataSetType.h:294
void setMinValue(boost::int64_t value)
It sets the minimum value that the sequence can generate.
Definition: Sequence.h:175
bool SetColumnDef(std::string &s, const std::string &tname, const te::dt::SimpleProperty *p, bool justDataType=false)
Definition: Utils.cpp:48
unsigned int getDataSetId(const std::string &datasetName)
It looks for the dataset id in the PostgreSQL system.
std::auto_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 dropUniqueKey(const std::string &datasetName, const std::string &name)
It removes the unique key constraint from the dataset.
A class that implements a prepared query for PostgreSQL data access driver.
std::auto_ptr< te::da::Sequence > getSequence(const std::string &name)
It gets the sequence with the given name in the data source.
FKActionType getOnDeleteAction() const
It returns the action performed when a referenced element value in the referenced DataSetType is bein...
Definition: ForeignKey.h:167
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
const std::string & getName() const
It returns the index name.
Definition: Index.h:155