All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PostGISCreatorDialog.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/PostGISCreatorDialog.cpp
22 
23  \brief A dialog window for showing the PostgreSQL creator widget.
24 */
25 
26 // TerraLib
27 #include "PostGISCreatorDialog.h"
28 #include "../../../../common/Translator.h"
29 #include "../../../../dataaccess/datasource/DataSource.h"
30 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
31 #include "../../../../dataaccess/datasource/DataSourceInfo.h"
32 #include "../../../../dataaccess/datasource/DataSourceManager.h"
33 #include "../../../widgets/Exception.h"
34 #include "../../../widgets/utils/ScopedCursor.h"
35 #include "ui_PostGISCreatorDialogForm.h"
36 
37 // Boost
38 #include <boost/algorithm/string/case_conv.hpp>
39 #include <boost/lexical_cast.hpp>
40 #include <boost/uuid/random_generator.hpp>
41 #include <boost/uuid/uuid_io.hpp>
42 
43 // Qt
44 #include <QMessageBox>
45 
47  : QDialog(parent, f),
48  m_ui(new Ui::PostGISCreatorDialogForm)
49 {
50  // add controls
51  m_ui->setupUi(this);
52 
53 // init controls
54  m_ui->m_advancedOptionsGroupBox->hide();
55 
56 // connect signal and slots
57  connect(m_ui->m_advancedOptionsCheckBox, SIGNAL(toggled(bool)), this, SLOT(advancedCreationOptionsCheckBoxToggled(bool)));
58  connect(m_ui->m_applyPushButton, SIGNAL(pressed()), this, SLOT(applyPushButtonPressed()));
59  connect(m_ui->m_closePushButton, SIGNAL(pressed()), this, SLOT(closePushButtonPressed()));
60  connect(m_ui->m_userNameLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
61  connect(m_ui->m_passwordLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
62 
63  m_ui->m_portLineEdit->setValidator(new QIntValidator(0, 99999, this));
64 
65  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
66  m_ui->m_helpPushButton->setPageReference("plugins/pgis/pgis_creator.html");
67 }
68 
70 {
71 
72 }
73 
75 {
76  QApplication::setOverrideCursor(Qt::WaitCursor);
77 
78  try
79  {
80 // check if driver is loaded
81  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
82  {
83  QApplication::restoreOverrideCursor();
84  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for PostgreSQL data sources!"));
85  }
86 
87 // get data source connection info based on form data
88  std::map<std::string, std::string> dsInfo = getConnectionInfo(true);
89 
90 // create database
91  te::da::DataSource::create("POSTGIS", dsInfo);
92 
93  {
94  // Connect
95  std::map<std::string, std::string> connInfo;
96  if(!dsInfo["PG_HOST"].empty())
97  connInfo["PG_HOST"] = dsInfo["PG_HOST"];
98 
99  if(!dsInfo["PG_PORT"].empty())
100  connInfo["PG_PORT"] = dsInfo["PG_PORT"];
101 
102  connInfo["PG_USER"] = dsInfo["PG_USER"];
103  connInfo["PG_PASSWORD"] = dsInfo["PG_PASSWORD"];
104  connInfo["PG_DB_NAME"] = dsInfo["PG_NEWDB_NAME"];
105  connInfo["PG_MIN_POOL_SIZE"] = "1";
106  connInfo["PG_MAX_POOL_SIZE"] = "4";
107  connInfo["PG_CONNECT_TIMEOUT"] = "5";
108  if(!dsInfo["PG_NEWDB_ENCODING"].empty())
109  connInfo["PG_CLIENT_ENCODING"] = dsInfo["PG_NEWDB_ENCODING"];
110 
111  std::auto_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS");
112  ds->setConnectionInfo(connInfo);
113  ds->open();
114 
115  m_driver.reset(ds.release());
116  }
117 
118  if(m_driver.get() == 0)
119  {
120  QApplication::restoreOverrideCursor();
121  throw te::qt::widgets::Exception(TE_TR("Could not open POSTGIS data source due to an unknown error!"));
122  }
123 
124  QString title = m_ui->m_hostNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_newDatabaseNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_userNameLineEdit->text().trimmed();
125 
126  std::map<std::string, std::string> connInfo;
127  if(!dsInfo["PG_HOST"].empty())
128  connInfo["PG_HOST"] = dsInfo["PG_HOST"];
129 
130  if(!dsInfo["PG_PORT"].empty())
131  connInfo["PG_PORT"] = dsInfo["PG_PORT"];
132 
133  connInfo["PG_USER"] = dsInfo["PG_USER"];
134 
135  if(m_ui->m_savePasswordCheckBox)
136  connInfo["PG_PASSWORD"] = dsInfo["PG_PASSWORD"];
137 
138  connInfo["PG_DB_NAME"] = dsInfo["PG_NEWDB_NAME"];
139  connInfo["PG_MIN_POOL_SIZE"] = "1";
140  connInfo["PG_MAX_POOL_SIZE"] = "4";
141  connInfo["PG_CONNECT_TIMEOUT"] = "5";
142  if(!dsInfo["PG_NEWDB_ENCODING"].empty())
143  connInfo["PG_CLIENT_ENCODING"] = dsInfo["PG_NEWDB_ENCODING"];
144 
145  if(m_datasource.get() == 0)
146  {
147 // create a new data source based on form data
148  m_datasource.reset(new te::da::DataSourceInfo);
149 
150  m_datasource->setConnInfo(connInfo);
151 
152  boost::uuids::basic_random_generator<boost::mt19937> gen;
153  boost::uuids::uuid u = gen();
154  std::string dsId = boost::uuids::to_string(u);
155 
156  m_datasource->setId(dsId);
157  m_driver->setId(dsId);
158  m_datasource->setTitle(title.toUtf8().data());
159  m_datasource->setDescription("");
160  m_datasource->setAccessDriver("POSTGIS");
161  m_datasource->setType("POSTGIS");
162  }
163  else
164  {
165  m_driver->setId(m_datasource->getId());
166  m_datasource->setConnInfo(connInfo);
167  m_datasource->setTitle(title.toUtf8().data());
168  m_datasource->setDescription("");
169  }
170 
171  }
172  catch(const std::exception& e)
173  {
174  QApplication::restoreOverrideCursor();
175  QMessageBox::warning(this,
176  tr("TerraLib Qt Components"),
177  tr(e.what()));
178  return;
179  }
180  catch(...)
181  {
182  QApplication::restoreOverrideCursor();
183  QMessageBox::warning(this,
184  tr("TerraLib Qt Components"),
185  tr("Unknown error while opening PostgreSQL database!"));
186  return;
187  }
188 
189  QApplication::restoreOverrideCursor();
190  accept();
191 }
192 
194 {
195  reject();
196 }
197 
199 {
200  m_ui->m_advancedOptionsGroupBox->setVisible(t);
201 }
202 
203 std::map<std::string, std::string> te::qt::plugins::pgis::PostGISCreatorDialog::getConnectionInfo(bool getPrivateKeys) const
204 {
205  std::map<std::string, std::string> connInfo;
206 
207 // get host
208  QString qstr = m_ui->m_hostNameLineEdit->text().trimmed();
209 
210  if(!qstr.isEmpty())
211  connInfo["PG_HOST"] = qstr.toStdString();
212 
213 // get port
214  qstr = m_ui->m_portLineEdit->text().trimmed();
215 
216  if(!qstr.isEmpty())
217  connInfo["PG_PORT"] = qstr.toStdString();
218 
219 // get user
220  qstr = m_ui->m_userNameLineEdit->text().trimmed();
221 
222  if(!qstr.isEmpty())
223  connInfo["PG_USER"] = qstr.toStdString();
224 
225 // get password
226  if(getPrivateKeys)
227  {
228  qstr = m_ui->m_passwordLineEdit->text().trimmed();
229 
230  if(!qstr.isEmpty())
231  connInfo["PG_PASSWORD"] = qstr.toStdString();
232  }
233 
234 // get dbname
235  qstr = m_ui->m_newDatabaseNameLineEdit->text().trimmed();
236 
237  if(!qstr.isEmpty())
238  connInfo["PG_NEWDB_NAME"] = qstr.toStdString();
239 
240 // get Template
241  qstr = m_ui->m_templateComboBox->currentText().trimmed();
242 
243  if(!qstr.isEmpty())
244  connInfo["PG_NEWDB_TEMPLATE"] = qstr.toStdString();
245 
246 // get Owner
247  qstr = m_ui->m_ownerComboBox->currentText().trimmed();
248 
249  if(!qstr.isEmpty())
250  connInfo["PG_NEWDB_OWNER"] = qstr.toStdString();
251 
252 // get Encoding
253  qstr = m_ui->m_encodingComboBox->currentText().trimmed();
254 
255  if(!qstr.isEmpty())
256  connInfo["PG_NEWDB_ENCODING"] = qstr.toStdString();
257 
258 // get Tablespace
259  qstr = m_ui->m_tablespaceLineEdit->text().trimmed();
260 
261  if(!qstr.isEmpty())
262  connInfo["PG_NEWDB_TABLESPACE"] = qstr.toStdString();
263 
264 // get Connections limit
265  if(!m_ui->m_noLimitConnectionsGroupBox->isChecked())
266  {
267  qstr = m_ui->m_connectionsLimitSpinBox->text().trimmed();
268 
269  if(!qstr.isEmpty())
270  {
271  if(boost::lexical_cast<int>(qstr.toStdString()) >= 1)
272  connInfo["PG_NEWDB_CONN_LIMIT"] = qstr.toStdString();
273  else
274  connInfo["PG_NEWDB_CONN_LIMIT"] = "-1";
275  }
276  }
277 
278  return connInfo;
279 }
280 
282 {
283  return m_datasource;
284 }
285 
287 {
288  return m_driver;
289 }
290 
292 {
293  try
294  {
295  if(m_ui->m_userNameLineEdit->text() != "" && m_ui->m_passwordLineEdit->text() != "")
296  {
297  std::map<std::string, std::string> dsInfo = getConnectionInfo(true);
298 
299  // Get Templates/Databases
300  std::vector<std::string> templates = te::da::DataSource::getDataSourceNames("POSTGIS", dsInfo);
301  if(!templates.empty())
302  for(std::size_t i = 0; i < templates.size(); i++)
303  m_ui->m_templateComboBox->addItem(templates[i].c_str());
304 
305  m_ui->m_templateComboBox->setCurrentIndex(m_ui->m_templateComboBox->findText("postgis"));
306 
307  // Get Encodings
308  m_ui->m_encodingComboBox->clear();
309  m_ui->m_encodingComboBox->addItem("");
310  std::vector<te::common::CharEncoding> encodings = te::da::DataSource::getEncodings("POSTGIS", dsInfo);
311  if(!encodings.empty())
312  for(std::size_t i = 0; i < encodings.size(); i++)
313  m_ui->m_encodingComboBox->addItem(te::common::CharEncodingConv::getCharEncodingName(encodings[i]).c_str());
314 
315  // Try to go the owners
316  m_ui->m_ownerComboBox->clear();
317  std::map<std::string, std::string> info;
318  std::map<std::string, std::string> aux = getConnectionInfo(true);
319  info["PG_HOST"] = aux["PG_HOST"].empty()?"localhost":aux["PG_HOST"];
320  info["PG_PORT"] = aux["PG_PORT"].empty()?"5432":aux["PG_PORT"];
321  info["PG_USER"] = aux["PG_USER"];
322  info["PG_PASSWORD"] = aux["PG_PASSWORD"];
323 
324  std::auto_ptr<te::da::DataSource> auxDs = te::da::DataSourceFactory::make("POSTGIS");
325  auxDs->setConnectionInfo(info);
326  auxDs->open();
327 
328  std::auto_ptr<te::da::DataSet> dsRoles = auxDs->query("select * from pg_roles");
329 
330  while(dsRoles->moveNext())
331  m_ui->m_ownerComboBox->addItem(dsRoles->getString("rolname").c_str());
332 
333  auxDs->close();
334  }
335  }
336  catch(...)
337  {
338  return;
339  }
340 }
static bool find(const std::string &dsType)
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
const te::da::DataSourceInfoPtr & getDataSource() const
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
static std::auto_ptr< DataSource > make(const std::string &dsType)
PostGISCreatorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
static std::vector< te::common::CharEncoding > getEncodings(const std::string &dsType, const std::map< std::string, std::string > &info)
It gets the encoding names of the data source.
Definition: DataSource.cpp:552
static std::vector< std::string > getDataSourceNames(const std::string &dsType, const std::map< std::string, std::string > &info)
It returns the data source names available in the driver.
Definition: DataSource.cpp:542
static std::auto_ptr< DataSource > create(const std::string &dsType, const std::map< std::string, std::string > &dsInfo)
It creates a new repository for a data source.
Definition: DataSource.cpp:510
A class that represents a data source component.
std::map< std::string, std::string > getConnectionInfo(bool getPrivateKeys) const
static std::string getCharEncodingName(const CharEncoding &code)
It returns the name of the given charset.
const te::da::DataSourcePtr & getDriver() const
std::auto_ptr< Ui::PostGISCreatorDialogForm > m_ui
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr