aster/PostGISConnectorDialog.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/plugins/datasource/pgis/PostGISConnectorDialog.cpp
22 
23  \brief A dialog window for showing the PostGIS connector widget.
24 */
25 
26 // TerraLib
27 #include "../../../../core/translator/Translator.h"
28 #include "../../../../core/uri/URI.h"
29 #include "../../../../core/uri/Utils.h"
30 #include "../../../../dataaccess/datasource/DataSource.h"
31 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
32 #include "../../../../dataaccess/datasource/DataSourceManager.h"
33 #include "../../../../dataaccess/datasource/DataSourceInfo.h"
34 #include "../../../widgets/Exception.h"
35 #include "PostGISConnectorDialog.h"
36 #include "ui_PostGISConnectorDialogForm.h"
37 
38 // Boost
39 #include <boost/algorithm/string/case_conv.hpp>
40 #include <boost/uuid/random_generator.hpp>
41 #include <boost/uuid/uuid_io.hpp>
42 #include <boost/lexical_cast.hpp>
43 
44 // Qt
45 #include <QMessageBox>
46 
48  : QDialog(parent, f),
49  m_ui(new Ui::PostGISConnectorDialogForm)
50 {
51 // add controls
52  m_ui->setupUi(this);
53 
54 // connect signal and slots
55  connect(m_ui->m_openPushButton, SIGNAL(pressed()), this, SLOT(openPushButtonPressed()));
56  connect(m_ui->m_testPushButton, SIGNAL(pressed()), this, SLOT(testPushButtonPressed()));
57  connect(m_ui->m_userNameLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
58  connect(m_ui->m_passwordLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
59 
60  m_ui->m_portLineEdit->setValidator(new QIntValidator(0, 99999, this));
61 
62  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
63  m_ui->m_helpPushButton->setPageReference("plugins/pgis/pgis.html");
64 }
65 
67  default;
68 
70 {
71  return m_datasource;
72 }
73 
75 {
76  return m_driver;
77 }
78 
80 {
81  m_datasource = ds;
82 
83  if(m_datasource.get() != 0)
84  {
85  setConnectionInfo(m_datasource->getConnInfoAsString());
86 
87  m_ui->m_datasourceTitleLineEdit->setText(QString::fromUtf8(m_datasource->getTitle().c_str()));
88 
89  m_ui->m_datasourceDescriptionTextEdit->setText(QString::fromUtf8(m_datasource->getDescription().c_str()));
90  }
91 }
92 
94 {
95  try
96  {
97  // Check if driver is loaded
98  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
99  throw te::qt::widgets::Exception(TE_TR("No data access driver loaded for PostgreSQL + PostGIS data sources!"));
100 
101  // Perform connection
102  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS", getConnectionInfo(true));
103  ds->open();
104  m_driver.reset(ds.release());
105 
106  if(m_driver.get() == 0)
107  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS data source due to an unknown error!"));
108 
109  QString title = m_ui->m_datasourceTitleLineEdit->text().trimmed();
110 
111  if(title.isEmpty())
112  title = m_ui->m_hostNameLineEdit->text().trimmed() + QString::fromUtf8("@") + m_ui->m_databaseComboBox->currentText().trimmed() + QString::fromUtf8("@") + m_ui->m_userNameLineEdit->text().trimmed();
113 
114  if(m_datasource.get() == 0)
115  {
116  // Create a new data source based on the form data
118 
119  m_datasource->setConnInfo(getConnectionInfo(m_ui->m_savePasswordCheckBox->isChecked()));
120 
121  boost::uuids::basic_random_generator<boost::mt19937> gen;
122  boost::uuids::uuid u = gen();
123  std::string dsId = boost::uuids::to_string(u);
124 
125  m_datasource->setId(dsId);
126  m_driver->setId(dsId);
127  m_datasource->setTitle(title.toUtf8().data());
128  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toUtf8().data());
129  m_datasource->setAccessDriver("POSTGIS");
130  m_datasource->setType("POSTGISRASTER");
131  }
132  else
133  {
134  m_driver->setId(m_datasource->getId());
135  m_datasource->setConnInfo(getConnectionInfo(m_ui->m_savePasswordCheckBox->isChecked()));
136  m_datasource->setTitle(title.toUtf8().data());
137  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toUtf8().data());
138  }
139  }
140  catch(const std::exception& e)
141  {
142  QMessageBox::warning(this,
143  tr("TerraLib Qt Components"),
144  tr(e.what()));
145  return;
146  }
147  catch(...)
148  {
149  QMessageBox::warning(this,
150  tr("TerraLib Qt Components"),
151  tr("Unknown error while opening PostgreSQL database!"));
152  return;
153  }
154 
155  accept();
156 }
157 
159 {
160  try
161  {
162  // Check if driver is loaded
163  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
164  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for PostgreSQL + PostGIS data sources!"));
165 
166  // Perform connection
167  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS", getConnectionInfo(true));
168  if(ds.get() == 0)
169  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS database!"));
170 
171  ds->open();
172 
173  QMessageBox::information(this,
174  tr("TerraLib Qt Components"),
175  tr("Data source is ok!"));
176 
177  ds->close();
178  }
179  catch(const std::exception& e)
180  {
181  QMessageBox::warning(this,
182  tr("TerraLib Qt Components"),
183  tr(e.what()));
184  }
185  catch(...)
186  {
187  QMessageBox::warning(this,
188  tr("TerraLib Qt Components"),
189  tr("Unknown error while testing PostgreSQL + PostGIS data source!"));
190  }
191 }
192 
194 {
195  QString qstr; // Auxiliary string used to hold temporary data
196 
197  std::string strURI = "pgsql://"; // The base of the URI
198 
199  // get user
200  qstr = m_ui->m_userNameLineEdit->text().trimmed();
201  strURI += qstr.toUtf8().data();
202  strURI += ":";
203 
204  //get password
205  if(getPrivateKeys)
206  {
207  qstr = m_ui->m_passwordLineEdit->text().trimmed();
208  strURI += qstr.toUtf8().data();
209  }
210 
211  //get host
212  strURI += "@";
213  qstr = m_ui->m_hostNameLineEdit->text().trimmed();
214  strURI += qstr.isEmpty() ? "localhost" : qstr.toUtf8().data();
215  strURI += ":";
216 
217  //get port
218  qstr = m_ui->m_portLineEdit->text().trimmed();
219  strURI += qstr.isEmpty() ? "5432" : qstr.toUtf8().data();
220  strURI += "/";
221 
222  //get db name
223  qstr = m_ui->m_databaseComboBox->currentText().trimmed();
224  if (qstr.isEmpty())
225  strURI += "template1";
226  else
227  strURI += qstr.toUtf8().data();
228 
229  //query section
230  strURI += "?";
231 
232  return strURI;
233 }
234 
236 {
237  te::core::URI uri(connInfo);
238  std::map<std::string, std::string> kvp = te::core::Expand(uri.query());
239  std::map<std::string, std::string>::const_iterator it = kvp.begin();
240  std::map<std::string, std::string>::const_iterator itend = kvp.end();
241 
242  std::string host = uri.host();
243  if (!host.empty())
244  m_ui->m_hostNameLineEdit->setText(QString::fromUtf8(host.c_str()));
245 
246  std::string port = uri.port();
247  if(!port.empty())
248  m_ui->m_portLineEdit->setText(QString::fromUtf8(port.c_str()));
249 
250  std::string dbName = uri.path().substr(1, uri.path().length());
251  if(!dbName.empty())
252  {
253  int pos = m_ui->m_databaseComboBox->findText(QString::fromUtf8(dbName.c_str()));
254 
255  if(pos != -1)
256  m_ui->m_databaseComboBox->setCurrentIndex(pos);
257  else
258  {
259  m_ui->m_databaseComboBox->addItem(QString::fromUtf8(dbName.c_str()));
260  m_ui->m_databaseComboBox->setCurrentIndex(0);
261  }
262  }
263 
264  std::string user = uri.user();
265  if(!user.empty())
266  m_ui->m_userNameLineEdit->setText(QString::fromUtf8(user.c_str()));
267 
268  std::string pass = uri.password();
269  if (!pass.empty())
270  m_ui->m_passwordLineEdit->setText(QString::fromUtf8(pass.c_str()));
271 }
272 
274 {
275  if(m_ui->m_userNameLineEdit->text() != "" || m_ui->m_passwordLineEdit->text() != "")
276  {
277  try{
278  std::string connInfo = getConnectionInfo(true);
279 
280  //get current informations
281  std::string curDb;
282 
283  if(!m_ui->m_databaseComboBox->currentText().isEmpty())
284  curDb = m_ui->m_databaseComboBox->currentText().toUtf8().data();
285 
286  m_ui->m_databaseComboBox->clear();
287 
288  // Get DataSources
289  std::vector<std::string> dbNames =
290  te::da::DataSource::getDataSourceNames("POSTGIS", connInfo);
291 
292  if(!dbNames.empty())
293  {
294  setDatabasesNames(dbNames);
295 
296  if(!curDb.empty())
297  {
298  int idx = m_ui->m_databaseComboBox->findText(curDb.c_str(),
299  Qt::MatchExactly);
300 
301  if(idx != -1)
302  m_ui->m_databaseComboBox->setCurrentIndex(idx);
303  }
304  }
305  }
306  catch(...)
307  {
308  }
309  }
310 }
311 
313 {
314  std::sort(names.begin(), names.end());
315 
316  for(std::size_t i = 0; i < names.size(); ++i)
317  {
318  m_ui->m_databaseComboBox->addItem(names[i].c_str());
319  }
320 }
std::string path() const
Retrieving the path.
Definition: URI.cpp:118
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
boost::shared_ptr< DataSource > DataSourcePtr
std::string password() const
Retrieving the password information.
Definition: URI.cpp:103
static te::dt::Date ds(2010, 01, 01)
const te::da::DataSourceInfoPtr & getDataSource() const
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
std::string query() const
Retrieving the query.
Definition: URI.cpp:123
static std::vector< std::string > getDataSourceNames(const std::string &dsType, const std::string &connInfo)
It returns the data source names available in the driver.
PostGISConnectorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
const std::string getConnectionInfo(bool getPrivateKeys) const
std::string port() const
Retrieving the port.
Definition: URI.cpp:113
std::string host() const
Retrieving the host.
Definition: URI.cpp:108
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
TECOREEXPORT std::map< std::string, std::string > Expand(const std::string &query_str)
Split a query string into its components.
A class that represents a data source component.
std::unique_ptr< Ui::PostGISConnectorDialogForm > m_ui
std::string user() const
Retrieving the user information.
Definition: URI.cpp:98
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr