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