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