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) 2011-2012 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, 9999, 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;
89 
90  getConnectionInfo(dsInfo);
91 
92 // create database
93  te::da::DataSource::create("POSTGIS", dsInfo);
94 
95  // Connect
96  std::map<std::string, std::string> connInfo;
97  connInfo["PG_HOST"] = dsInfo["PG_HOST"];
98  connInfo["PG_PORT"] = dsInfo["PG_PORT"];
99  connInfo["PG_USER"] = dsInfo["PG_USER"];
100  connInfo["PG_PASSWORD"] = dsInfo["PG_PASSWORD"];
101  connInfo["PG_DB_NAME"] = dsInfo["PG_NEWDB_NAME"];
102  connInfo["PG_MIN_POOL_SIZE"] = "1";
103  connInfo["PG_MAX_POOL_SIZE"] = "4";
104  connInfo["PG_CONNECT_TIMEOUT"] = "5";
105  if(!dsInfo["PG_NEWDB_ENCODING"].empty())
106  connInfo["PG_CLIENT_ENCODING"] = dsInfo["PG_NEWDB_ENCODING"];
107 
108  std::auto_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS");
109  ds->setConnectionInfo(connInfo);
110  ds->open();
111 
112  m_driver.reset(ds.release());
113 
114  if(m_driver.get() == 0)
115  {
116  QApplication::restoreOverrideCursor();
117  throw te::qt::widgets::Exception(TE_TR("Could not open POSTGIS data source due to an unknown error!"));
118  }
119 
120  QString title = m_ui->m_hostNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_newDatabaseNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_userNameLineEdit->text().trimmed();
121 
122  if(m_datasource.get() == 0)
123  {
124 // create a new data source based on form data
125  m_datasource.reset(new te::da::DataSourceInfo);
126 
127  m_datasource->setConnInfo(connInfo);
128 
129  boost::uuids::basic_random_generator<boost::mt19937> gen;
130  boost::uuids::uuid u = gen();
131  std::string dsId = boost::uuids::to_string(u);
132 
133  m_datasource->setId(dsId);
134  m_driver->setId(dsId);
135  m_datasource->setTitle(title.toUtf8().data());
136  m_datasource->setDescription("");
137  m_datasource->setAccessDriver("POSTGIS");
138  m_datasource->setType("POSTGIS");
139  }
140  else
141  {
142  m_driver->setId(m_datasource->getId());
143  m_datasource->setConnInfo(connInfo);
144  m_datasource->setTitle(title.toUtf8().data());
145  m_datasource->setDescription("");
146  }
147 
148  }
149  catch(const std::exception& e)
150  {
151  QApplication::restoreOverrideCursor();
152  QMessageBox::warning(this,
153  tr("TerraLib Qt Components"),
154  tr(e.what()));
155  return;
156  }
157  catch(...)
158  {
159  QApplication::restoreOverrideCursor();
160  QMessageBox::warning(this,
161  tr("TerraLib Qt Components"),
162  tr("Unknown error while opening PostgreSQL database!"));
163  return;
164  }
165 
166  QApplication::restoreOverrideCursor();
167  accept();
168 }
169 
171 {
172  reject();
173 }
174 
176 {
177  m_ui->m_advancedOptionsGroupBox->setVisible(t);
178 }
179 
180 void te::qt::plugins::pgis::PostGISCreatorDialog::getConnectionInfo(std::map<std::string, std::string>& connInfo) const
181 {
182 // clear input
183  connInfo.clear();
184 
185 // get host
186  QString qstr = m_ui->m_hostNameLineEdit->text().trimmed();
187 
188  if(!qstr.isEmpty())
189  connInfo["PG_HOST"] = qstr.toStdString();
190 
191 // get port
192  qstr = m_ui->m_portLineEdit->text().trimmed();
193 
194  if(!qstr.isEmpty())
195  connInfo["PG_PORT"] = qstr.toStdString();
196 
197 // get user
198  qstr = m_ui->m_userNameLineEdit->text().trimmed();
199 
200  if(!qstr.isEmpty())
201  connInfo["PG_USER"] = qstr.toStdString();
202 
203 // get password
204  qstr = m_ui->m_passwordLineEdit->text().trimmed();
205 
206  if(!qstr.isEmpty())
207  connInfo["PG_PASSWORD"] = qstr.toStdString();
208 
209 // get dbname
210  qstr = m_ui->m_newDatabaseNameLineEdit->text().trimmed();
211 
212  if(!qstr.isEmpty())
213  connInfo["PG_NEWDB_NAME"] = qstr.toStdString();
214 
215 // get Template
216  qstr = m_ui->m_templateComboBox->currentText().trimmed();
217 
218  if(!qstr.isEmpty())
219  connInfo["PG_NEWDB_TEMPLATE"] = qstr.toStdString();
220 
221 // get Owner
222  qstr = m_ui->m_ownerComboBox->currentText().trimmed();
223 
224  if(!qstr.isEmpty())
225  connInfo["PG_NEWDB_OWNER"] = qstr.toStdString();
226 
227 // get Encoding
228  qstr = m_ui->m_encodingComboBox->currentText().trimmed();
229 
230  if(!qstr.isEmpty())
231  connInfo["PG_NEWDB_ENCODING"] = qstr.toStdString();
232 
233 // get Tablespace
234  qstr = m_ui->m_tablespaceLineEdit->text().trimmed();
235 
236  if(!qstr.isEmpty())
237  connInfo["PG_NEWDB_TABLESPACE"] = qstr.toStdString();
238 
239 // get Connections limit
240  if(!m_ui->m_noLimitConnectionsGroupBox->isChecked())
241  {
242  qstr = m_ui->m_connectionsLimitSpinBox->text().trimmed();
243 
244  if(!qstr.isEmpty())
245  {
246  if(boost::lexical_cast<int>(qstr.toStdString()) >= 1)
247  connInfo["PG_NEWDB_CONN_LIMIT"] = qstr.toStdString();
248  else
249  connInfo["PG_NEWDB_CONN_LIMIT"] = "-1";
250  }
251  }
252 }
253 
255 {
256  return m_datasource;
257 }
258 
260 {
261  return m_driver;
262 }
263 
265 {
266  try
267  {
268  if(m_ui->m_userNameLineEdit->text() != "" && m_ui->m_passwordLineEdit->text() != "")
269  {
270  std::map<std::string, std::string> dsInfo;
271  getConnectionInfo(dsInfo);
272 
273  // Get Templates/Databases
274  std::vector<std::string> templates = te::da::DataSource::getDataSourceNames("POSTGIS", dsInfo);
275  if(!templates.empty())
276  for(std::size_t i = 0; i < templates.size(); i++)
277  m_ui->m_templateComboBox->addItem(templates[i].c_str());
278 
279  m_ui->m_templateComboBox->setCurrentIndex(m_ui->m_templateComboBox->findText("postgis"));
280 
281  // Get Encodings
282  m_ui->m_encodingComboBox->clear();
283  m_ui->m_encodingComboBox->addItem("");
284  std::vector<te::common::CharEncoding> encodings = te::da::DataSource::getEncodings("POSTGIS", dsInfo);
285  if(!encodings.empty())
286  for(std::size_t i = 0; i < encodings.size(); i++)
287  m_ui->m_encodingComboBox->addItem(te::common::CharEncodingConv::getCharEncodingName(encodings[i]).c_str());
288 
289  // Try to go the owners
290  m_ui->m_ownerComboBox->clear();
291  std::map<std::string, std::string> info;
292  std::map<std::string, std::string> aux;
293  getConnectionInfo(aux);
294  info["PG_HOST"] = aux["PG_HOST"].empty()?"localhost":aux["PG_HOST"];
295  info["PG_PORT"] = aux["PG_PORT"].empty()?"5432":aux["PG_PORT"];
296  info["PG_USER"] = aux["PG_USER"];
297  info["PG_PASSWORD"] = aux["PG_PASSWORD"];
298 
299  std::auto_ptr<te::da::DataSource> auxDs = te::da::DataSourceFactory::make("POSTGIS");
300  auxDs->setConnectionInfo(info);
301  auxDs->open();
302 
303  std::auto_ptr<te::da::DataSet> dsRoles = auxDs->query("select * from pg_roles");
304 
305  while(dsRoles->moveNext())
306  m_ui->m_ownerComboBox->addItem(dsRoles->getString("rolname").c_str());
307 
308  auxDs->close();
309  }
310  }
311  catch(...)
312  {
313  return;
314  }
315 }
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:345
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
void getConnectionInfo(std::map< std::string, std::string > &connInfo) const
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.
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