QueryDataSourceDialog.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/widgets/query/QueryDataSourceDialog.cpp
22 
23  \brief This file defines a class for a Query DataSource Dialog Dialog.
24 */
25 
26 // TerraLib
27 #include "../../../common/StringUtils.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/dataset/DataSetAdapter.h"
30 #include "../../../dataaccess/dataset/DataSetTypeConverter.h"
31 #include "../../../dataaccess/dataset/DataSetType.h"
32 #include "../../../dataaccess/dataset/ObjectIdSet.h"
33 #include "../../../dataaccess/datasource/DataSourceCapabilities.h"
34 #include "../../../dataaccess/datasource/DataSourceInfoManager.h"
35 #include "../../../dataaccess/datasource/DataSourceInfo.h"
36 #include "../../../dataaccess/datasource/DataSourceManager.h"
37 #include "../../../dataaccess/query/SQLDialect.h"
38 #include "../../../dataaccess/query/SQLFunctionEncoder.h"
39 #include "../../../dataaccess/utils/Utils.h"
40 #include "../../../datatype/NumericProperty.h"
41 #include "../../../datatype/SimpleProperty.h"
42 #include "../../../datatype/StringProperty.h"
43 #include "../../../geometry/GeometryProperty.h"
44 #include "../../../maptools/DataSetLayer.h"
45 #include "../datasource/selector/DataSourceSelectorDialog.h"
46 #include "../layer/utils/DataSet2Layer.h"
47 #include "../utils/ScopedCursor.h"
48 #include "../ceditor/ScriptWidget.h"
49 #include "QueryDataSourceDialog.h"
50 #include "ui_QueryDataSourceDialogForm.h"
51 
52 // Qt
53 #include <QCursor>
54 #include <QFileDialog>
55 #include <QGridLayout>
56 #include <QMessageBox>
57 #include <QTextStream>
58 #include <QListWidgetItem>
59 
60 // STL
61 #include <cassert>
62 #include <memory>
63 
64 // Boost
65 #include <boost/filesystem.hpp>
66 #include <boost/uuid/random_generator.hpp>
67 #include <boost/uuid/uuid_io.hpp>
68 
70 
71 te::qt::widgets::QueryDataSourceDialog::QueryDataSourceDialog(QWidget* parent, Qt::WindowFlags f)
72  : QDialog(parent, f),
73  m_ui(new Ui::QueryDataSourceDialogForm)
74 {
75  m_ui->setupUi(this);
76 
77  m_ui->m_applyToolButton->setIcon(QIcon::fromTheme("media-playback-start-green"));
78  m_ui->m_executeToolButton->setIcon(QIcon::fromTheme("media-playback-start-green-execute"));
79  m_ui->m_clearToolButton->setIcon(QIcon::fromTheme("edit-clear"));
80  m_ui->m_applySelToolButton->setIcon(QIcon::fromTheme("pointer-selection"));
81  m_ui->m_targetDatasourceToolButton->setIcon(QIcon::fromTheme("datasource"));
82  m_ui->m_createLayerlToolButton->setIcon(QIcon::fromTheme("layer-new"));
83 
84 
85  m_ui->m_saveSqlToolButton->setIcon(QIcon::fromTheme("document-save-as"));
86  m_ui->m_openSqlToolButton->setIcon(QIcon::fromTheme("document-open"));
87 
88  //table view
89  m_tableModel = new te::qt::widgets::DataSetTableModel(m_ui->m_tableView);
90  m_ui->m_tableView->setModel(m_tableModel);
91 
92  //dataset display
93  m_dataSetDisplay = new te::qt::widgets::DataSetDisplay(this);
94 
95  m_appMapDisplay = nullptr;
96 
97  QGridLayout* displayGridLayout = new QGridLayout(m_ui->m_displayWidget);
98  displayGridLayout->setContentsMargins(0, 0, 0, 0);
99  displayGridLayout->addWidget(m_dataSetDisplay);
100 
101  m_ui->m_sqlEditor->setHighlightMode("sql");
102 
103  // Signals¨& slots
104  connect(m_ui->m_dataSourceComboBox, SIGNAL(activated(int)), this, SLOT(onDataSourceSelected(int)));
105  connect(m_ui->m_baseDataSetComboBox, SIGNAL(activated(int)), this, SLOT(onBaseDataSetSelected(int)));
106  connect(m_ui->m_dataSetListWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(onDataSetItemClicked(QListWidgetItem*)));
107  connect(m_ui->m_applyToolButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
108  connect(m_ui->m_executeToolButton, SIGNAL(clicked()), this, SLOT(onExecutePushButtonClicked()));
109  connect(m_ui->m_clearToolButton, SIGNAL(clicked()), this, SLOT(onClearPushButtonClicked()));
110  connect(m_ui->m_saveSqlToolButton, SIGNAL(clicked()), this, SLOT(onSaveSqlToolButtonClicked()));
111  connect(m_ui->m_openSqlToolButton, SIGNAL(clicked()), this, SLOT(onOpenSqlToolButtonClicked()));
112  connect(m_ui->m_applySelToolButton, SIGNAL(clicked()), this, SLOT(onApplySelToolButtonClicked()));
113  connect(m_ui->m_createLayerlToolButton, SIGNAL(pressed()), this, SLOT(onCreateLayerToolButtonClicked()));
114  connect(m_ui->m_targetDatasourceToolButton, SIGNAL(pressed()), this, SLOT(onTargetDatasourceToolButtonPressed()));
115  connect(m_ui->m_targetFileToolButton, SIGNAL(pressed()), this, SLOT(onTargetFileToolButtonPressed()));
116  connect(m_ui->m_pkTableComboBox, SIGNAL(activated(int)), this, SLOT(onPkTableComboBoxSelected(int)));
117  connect(m_ui->m_attrDataSetListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(onListWidgetDoubleClicked(QListWidgetItem*)));
118  connect(m_ui->m_dataSetListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(onListWidgetDoubleClicked(QListWidgetItem*)));
119 
120  //load data sources information
121  loadDataSourcesInformation();
122 
123  //
124  m_ui->m_helpPushButton->setPageReference("widgets/query/query_datasource.html");
125 }
126 
128 {
129  m_keyWords.clear();
130 }
131 
132 void te::qt::widgets::QueryDataSourceDialog::setLayerList(std::list<te::map::AbstractLayerPtr> layerList)
133 {
134  m_layerList = layerList;
135 
136  if(m_ui->m_baseDataSetComboBox->count() > 0)
138 }
139 
141 {
142  m_appMapDisplay = appMapDisplay;
143 }
144 
146 {
147  m_ui->m_dataSourceComboBox->clear();
148 
149  std::map<std::string, te::da::DataSourceInfoPtr>::const_iterator it = te::da::DataSourceInfoManager::getInstance().begin();
150  std::map<std::string, te::da::DataSourceInfoPtr>::const_iterator itend =te::da::DataSourceInfoManager::getInstance().end();
151 
152  while(it != itend)
153  {
154  try
155  {
156  te::da::DataSourcePtr ds = te::da::GetDataSource(it->second->getId());
157 
158  const te::da::SQLDialect* dialect = ds->getDialect();
159 
160  if (dialect)
161  m_ui->m_dataSourceComboBox->addItem(it->second->getTitle().c_str(), QVariant(it->second->getId().c_str()));
162  }
163  catch (...)
164  {
165  ++it;
166  continue;
167  }
168 
169  ++it;
170  }
171 
172  if(m_ui->m_dataSourceComboBox->count() != 0)
173  onDataSourceSelected(m_ui->m_dataSourceComboBox->currentIndex());
174 }
175 
177 {
178  m_keyWords.clear();
179 
180  // add defaul SQL key words
181  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("SELECT", Qt::blue));
182  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("FROM", Qt::blue));
183  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("WHERE", Qt::blue));
184  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("JOIN", Qt::blue));
185  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("INNER", Qt::blue));
186  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("LEFT", Qt::blue));
187  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("RIGHT", Qt::blue));
188  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("AS", Qt::blue));
189  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("GROUP", Qt::blue));
190  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("ORDER", Qt::blue));
191  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type("BY", Qt::blue));
192 
193  //add data source specific key words
194  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
195 
197 
198  const te::da::SQLDialect* dialect = ds->getDialect();
199 
200  std::vector<std::string> names = dialect->getRegisteredNames();
201 
202  for(std::size_t t = 0; t < names.size(); ++t)
203  {
204  QString s = names[t].c_str();
205  QString sUpper = s.toUpper();
206 
207  m_keyWords.insert(std::map<std::string, Qt::GlobalColor>::value_type(sUpper.toUtf8().data(), Qt::red));
208  }
209 
210 }
211 
213 {
214  m_ui->m_baseDataSetComboBox->clear();
215  m_ui->m_dataSetListWidget->clear();
216  m_ui->m_attrDataSetListWidget->clear();
217  m_ui->m_pkTableComboBox->clear();
218  m_ui->m_pkAttrComboBox->clear();
219 
220  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(index).toString().toUtf8().data();
221 
223 
224  if(!ds->isOpened())
225  ds->open();
226 
227  std::vector<std::string> dataSetNames;
228  te::da::GetDataSetNames(dataSetNames, dataSourceId);
229 
230  for(std::size_t t = 0; t < dataSetNames.size(); ++t)
231  {
232  m_ui->m_baseDataSetComboBox->addItem(dataSetNames[t].c_str());
233  m_ui->m_dataSetListWidget->addItem(dataSetNames[t].c_str());
234  m_ui->m_pkTableComboBox->addItem(dataSetNames[t].c_str());
235  }
236 
237  if(m_ui->m_baseDataSetComboBox->count() > 0)
239 
240  if (m_ui->m_pkTableComboBox->count() > 0)
242 
243  buildMap();
244 }
245 
247 {
248  std::string dataSet = m_ui->m_baseDataSetComboBox->itemText(index).toUtf8().data();
249 
250  m_ui->m_layerComboBox->clear();
251 
252  std::list<te::map::AbstractLayerPtr>::iterator it = m_layerList.begin();
253 
254  while(it != m_layerList.end())
255  {
257 
258  std::unique_ptr<te::da::DataSetType> dsType = l->getSchema();
259 
260  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
261 
262  if(dsLayer && dsType->getName() == dataSet)
263  m_ui->m_layerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
264 
265  ++it;
266  }
267 
268  m_ui->m_pkTableComboBox->setCurrentIndex(index);
270 }
271 
273 {
274  m_ui->m_attrDataSetListWidget->clear();
275 
276  if(!item)
277  return;
278 
279  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
280 
281  std::string dataSetName = item->text().toUtf8().data();
282 
283  te::da::DataSetType* dsType = te::da::GetDataSetType(dataSetName, dataSourceId);
284 
285  std::vector<te::dt::Property*> propVec = dsType->getProperties();
286 
287  for(std::size_t t = 0; t < propVec.size(); ++t)
288  {
289  m_ui->m_attrDataSetListWidget->addItem(propVec[t]->getName().c_str());
290  }
291 
292  delete dsType;
293 }
294 
296 {
297  std::string dataSetName = m_ui->m_pkTableComboBox->itemText(index).toUtf8().data();
298 
299  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
300 
301  te::da::DataSetType* dsType = te::da::GetDataSetType(dataSetName, dataSourceId);
302 
303  std::vector<te::dt::Property*> propVec = dsType->getProperties();
304 
305  for (std::size_t t = 0; t < propVec.size(); ++t)
306  {
307  m_ui->m_pkAttrComboBox->addItem(propVec[t]->getName().c_str());
308  }
309 
310  delete dsType;
311 }
312 
314 {
315  te::qt::widgets::ScopedCursor cursor(Qt::WaitCursor);
316 
317  m_ui->m_sqlEditor->setFocus();
318 
319  if(m_ui->m_sqlEditor->text().isEmpty())
320  {
321  return;
322  }
323 
324  std::string sql;
325 
326  if (m_ui->m_sqlEditor->selectedText().isEmpty())
327  sql = m_ui->m_sqlEditor->text().toUtf8().data();
328  else
329  sql = m_ui->m_sqlEditor->selectedText().toUtf8().data();
330 
331  std::vector<std::string> tokens;
332  te::common::Tokenize(sql, tokens, " ");
333 
334  if (te::common::Convert2UCase(tokens[0]) != te::common::Convert2UCase("select"))
335  {
336  QString errorMessage = "SQL Error: ";
337  errorMessage += tr("Use the \"Execute\" option to execute a instruction.");
338  errorMessage += "\n";
339  errorMessage += "-------------------------------------------------------------------------\n";
340 
341  m_ui->m_logPlainTextEdit->appendPlainText(errorMessage);
342 
343  m_ui->m_tabWidget->setCurrentIndex(1);
344 
345  return;
346  }
347 
348  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
349 
351 
352  std::string dataSetName = m_ui->m_baseDataSetComboBox->currentText().toUtf8().data();
353 
354  te::da::DataSetTypePtr dsType(te::da::GetDataSetType(dataSetName, dataSourceId));
355 
356  //get dataset
357  std::unique_ptr<te::da::DataSet> dataSet;
358 
359  try
360  {
361  dataSet = ds->query(sql);
362  }
363  catch(const std::exception& e)
364  {
366  m_tableModel->setDataSet(nullptr);
367 
368  std::string errorMessage = "SQL Error: ";
369  errorMessage += e.what();
370  errorMessage += "\n";
371  errorMessage += "-------------------------------------------------------------------------\n";
372 
373  m_ui->m_logPlainTextEdit->appendPlainText(errorMessage.c_str());
374 
375  m_ui->m_tabWidget->setCurrentIndex(1);
376 
377  return;
378  }
379 
380  std::string message = "SQL Done: ";
381  message += sql;
382  message += "\n";
383  message += "-------------------------------------------------------------------------\n";
384 
385  m_ui->m_logPlainTextEdit->appendPlainText(message.c_str());
386 
387  //draw dataset
389 
390  bool draw = false;
391  for(std::size_t t = 0; t < dataSet->getNumProperties(); ++t)
392  {
393  int type = dataSet->getPropertyDataType(t);
394 
395  if(type == te::dt::GEOMETRY_TYPE)
396  {
397  draw = true;
398  break;
399  }
400  }
401 
402  if(draw)
403  m_dataSetDisplay->draw(dsType, ds, dataSet.get());
404  else
406 
407  //show dataset on table
408  m_tableModel->setDataSet(dataSet.release());
409 
410  m_ui->m_tabWidget->setCurrentIndex(0);
411 }
412 
414 {
415  te::qt::widgets::ScopedCursor cursor(Qt::WaitCursor);
416 
417  m_ui->m_sqlEditor->setFocus();
418 
419  if (m_ui->m_sqlEditor->text().isEmpty())
420  {
421  return;
422  }
423 
424  std::string sql;
425 
426  if (m_ui->m_sqlEditor->selectedText().isEmpty())
427  sql = m_ui->m_sqlEditor->text().toUtf8().data();
428  else
429  sql = m_ui->m_sqlEditor->selectedText().toUtf8().data();
430 
431  std::vector<std::string> tokens;
432  te::common::Tokenize(sql, tokens, " ");
433 
434  if (te::common::Convert2UCase(tokens[0]) == te::common::Convert2UCase("select"))
435  {
436  QString errorMessage = "SQL Error: ";
437  errorMessage += tr("Use the \"Query\" option to execute a selection.");
438  errorMessage += "\n";
439  errorMessage += "-------------------------------------------------------------------------\n";
440 
441  m_ui->m_logPlainTextEdit->appendPlainText(errorMessage);
442 
443  m_ui->m_tabWidget->setCurrentIndex(1);
444 
445  return;
446  }
447 
448  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
449 
451 
452  std::string dataSetName = m_ui->m_baseDataSetComboBox->currentText().toUtf8().data();
453 
454  te::da::DataSetTypePtr dsType(te::da::GetDataSetType(dataSetName, dataSourceId));
455 
456  try
457  {
458  ds->execute(sql);
459  }
460  catch (const std::exception& e)
461  {
463  m_tableModel->setDataSet(nullptr);
464 
465  std::string errorMessage = "SQL Error: ";
466  errorMessage += e.what();
467  errorMessage += "\n";
468  errorMessage += "-------------------------------------------------------------------------\n";
469 
470  m_ui->m_logPlainTextEdit->appendPlainText(errorMessage.c_str());
471 
472  m_ui->m_tabWidget->setCurrentIndex(1);
473 
474  return;
475  }
476 
477  std::string message = "SQL Done: ";
478  message += sql;
479  message += "\n";
480  message += "-------------------------------------------------------------------------\n";
481 
482  m_ui->m_logPlainTextEdit->appendPlainText(message.c_str());
483 
484  m_ui->m_tabWidget->setCurrentIndex(1);
485 }
486 
488 {
489  m_ui->m_sqlEditor->setText("");
490 
492 
493  m_tableModel->setDataSet(nullptr);
494 }
495 
497 {
498 }
499 
501 {
502  //select file
503  QString path = QFileDialog::getSaveFileName(this, tr("Set a SQL file..."), "", tr("SQL File *.sql"));
504 
505  if(path.isNull())
506  return;
507 
508  if (!path.endsWith(".sql"))
509  path += ".sql";
510 
511  //open file
512  QFile file(path);
513 
514  if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
515  {
516  QMessageBox::warning(this, tr("Query DataSource"), file.errorString());
517  return;
518  }
519 
520  // save to file
521  QTextStream out(&file);
522 
523  out << m_ui->m_sqlEditor->text();
524 
525  file.close();
526 }
527 
529 {
530  //select file
531  QString path = QFileDialog::getOpenFileName(this, tr("Select a SQL file..."), "", tr("SQL File *.sql"));
532 
533  if(path.isNull())
534  return;
535 
536  m_ui->m_sqlEditor->open(path);
537 }
538 
540 {
541  if(m_ui->m_sqlEditor->text().isEmpty())
542  {
543  QMessageBox::information(this, tr("Warning"), tr("SQL not defined."));
544  return;
545  }
546 
547  QVariant varLayer = m_ui->m_layerComboBox->itemData(m_ui->m_layerComboBox->currentIndex(), Qt::UserRole);
548  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
549 
550  if(!layer.get())
551  {
552  QMessageBox::warning(this, tr("Query DataSource"), tr("No layer selected."));
553  return;
554  }
555 
556  te::qt::widgets::ScopedCursor cursor(Qt::WaitCursor);
557 
558  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
559 
561 
562  std::string dataSetName = m_ui->m_baseDataSetComboBox->currentText().toUtf8().data();
563 
564  te::da::DataSetTypePtr dsType(te::da::GetDataSetType(dataSetName, dataSourceId));
565 
566  std::string sql;
567 
568  if (m_ui->m_sqlEditor->selectedText().isEmpty())
569  sql = m_ui->m_sqlEditor->text().toUtf8().data();
570  else
571  sql = m_ui->m_sqlEditor->selectedText().toUtf8().data();
572 
573  //get dataset
574  std::unique_ptr<te::da::DataSet> dataSet;
575 
576  try
577  {
578  dataSet = ds->query(sql);
579  }
580  catch(...)
581  {
582  QMessageBox::warning(this, tr("Query DataSource"), tr("Error executing SQL."));
583  return;
584  }
585 
586  try
587  {
588  if(m_ui->m_newSelRadioButton->isChecked())
589  {
590  // Generates the oids
591  dataSet->moveBeforeFirst();
592  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataSet.get(), dsType.get());
593 
594  oids->setExpressionByInClause();
595 
596  layer->clearSelected();
597  layer->select(oids);
598  }
599  else if(m_ui->m_addSelRadioButton->isChecked())
600  {
601  // Generates the oids
602  dataSet->moveBeforeFirst();
603  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataSet.get(), dsType.get());
604 
605  oids->setExpressionByInClause();
606 
607  layer->select(oids);
608  }
609 
610  if(m_appMapDisplay)
611  {
613  }
614  }
615  catch(te::common::Exception& e)
616  {
617  QMessageBox::warning(this, tr("Query DataSource"), tr("Error selecting objects: ") + e.what());
618  return;
619  }
620  QMessageBox::information(this, tr("Query DataSource"), tr("Selection done."));
621 }
622 
623 
625 {
626  // check input parameters
627  if(m_ui->m_sqlEditor->text().isEmpty())
628  {
629  QMessageBox::information(this, tr("Warning"), tr("SQL not defined."));
630  return;
631  }
632 
633  if(m_ui->m_repositoryLineEdit->text().isEmpty())
634  {
635  QMessageBox::information(this, tr("Warning"), tr("Define a repository for the result."));
636  return;
637  }
638 
639  if(m_ui->m_newLayerNameLineEdit->text().isEmpty())
640  {
641  QMessageBox::information(this, tr("Warning"), tr("Define a name for the resulting layer."));
642  return;
643  }
644 
645  te::qt::widgets::ScopedCursor cursor(Qt::WaitCursor);
646 
647  //create dataset
648  std::string dataSourceId = m_ui->m_dataSourceComboBox->itemData(m_ui->m_dataSourceComboBox->currentIndex()).toString().toUtf8().data();
649 
651 
652  std::string inputDataSetName = m_ui->m_baseDataSetComboBox->currentText().toUtf8().data();
653 
654  te::da::DataSetTypePtr inputDataSetType(te::da::GetDataSetType(inputDataSetName, dataSourceId));
655 
656  std::string sql;
657 
658  if(m_ui->m_sqlEditor->selectedText().isEmpty())
659  sql = m_ui->m_sqlEditor->text().toUtf8().data();
660  else
661  sql = m_ui->m_sqlEditor->selectedText().toUtf8().data();
662 
663  std::unique_ptr<te::da::DataSet> dataSet;
664 
665  try
666  {
667  dataSet = ds->query(sql);
668  }
669  catch(...)
670  {
671  QMessageBox::warning(this, tr("Query DataSource"), tr("Error executing SQL."));
672  return;
673  }
674 
675  if (dataSet->size() == 0)
676  {
677  QMessageBox::warning(this, tr("Query DataSource"), tr("Query result is empty."));
678  return;
679  }
680 
681  //create / get data source
682  te::da::DataSourcePtr outputDataSource;
683 
684  if(m_toFile)
685  {
686  //create new data source
687  boost::filesystem::path uri(m_ui->m_repositoryLineEdit->text().toUtf8().data());
688 
689  const std::string connInfo("file://" + uri.string());
690 
691  boost::uuids::basic_random_generator<boost::mt19937> gen;
692  boost::uuids::uuid u = gen();
693  std::string id_ds = boost::uuids::to_string(u);
694 
696  dsInfoPtr->setConnInfo(connInfo);
697  dsInfoPtr->setTitle(uri.stem().string());
698  dsInfoPtr->setAccessDriver("OGR");
699  dsInfoPtr->setType("OGR");
700  dsInfoPtr->setDescription(uri.string());
701  dsInfoPtr->setId(id_ds);
702 
704 
705  outputDataSource = te::da::DataSourceManager::getInstance().get(id_ds, "OGR", dsInfoPtr->getConnInfo());
706  }
707  else
708  {
709  outputDataSource = te::da::GetDataSource(m_outputDatasource->getId());
710  }
711 
712  //get output dataset name
713  std::string dataSetName = m_ui->m_newLayerNameLineEdit->text().toUtf8().data();
714 
715  std::size_t idx = dataSetName.find(".");
716  if (idx != std::string::npos)
717  dataSetName=dataSetName.substr(0,idx);
718 
719  //save data
720  std::unique_ptr<te::da::DataSetType> dsType(new te::da::DataSetType(dataSetName));
721 
722  dataSet->moveFirst();
723 
724  std::set<std::string> names;
725 
726  int srid = 0;
727 
728  for(std::size_t t = 0; t < dataSet->getNumProperties(); ++t)
729  {
730  //check if the property name its duplicated
731  std::string propName = dataSet->getPropertyName(t);
732 
733  int count = 1;
734  while(names.find(propName) != names.end())
735  {
736  propName += "_";
737  propName += te::common::Convert2String(count);
738  }
739 
740  names.insert(propName);
741 
742  //create output property
743  te::dt::Property* p = nullptr;
744  if(dataSet->getPropertyDataType(t) != te::dt::GEOMETRY_TYPE)
745  {
746  if (dataSet->getPropertyDataType(t) == te::dt::STRING_TYPE)
747  {
748  p = new te::dt::StringProperty(propName, te::dt::VAR_STRING, 255, false);
749  }
750  else if (dataSet->getPropertyDataType(t) == te::dt::NUMERIC_TYPE)
751  {
752  p = new te::dt::NumericProperty(propName, 0, 0, false);
753  }
754  else
755  p = new te::dt::SimpleProperty(propName, dataSet->getPropertyDataType(t));
756  }
757  else
758  {
759  std::unique_ptr<te::gm::Geometry> geom = dataSet->getGeometry(t);
760 
761  srid = geom->getSRID();
762 
763  p = new te::gm::GeometryProperty(propName, srid, geom->getGeomTypeId());
764  }
765 
766  //add property to output datasetype
767  if(p)
768  {
769  dsType->add(p);
770 
771  //check primary key
772  if (m_ui->m_pkCheckBox->isChecked())
773  {
774  std::string pkAttrName = m_ui->m_pkAttrComboBox->itemText(m_ui->m_pkAttrComboBox->currentIndex()).toUtf8().data();
775 
777  {
778  std::string pkName = dataSetName + "_" + p->getName() + "_pk";
779  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pkName, dsType.get());
780  pk->add(p->clone());
781  }
782  }
783  }
784  else
785  {
786  QMessageBox::warning(this, tr("Query DataSource"), tr("Error creating output dataset."));
787  return;
788  }
789  }
790 
791  dataSet->moveBeforeFirst();
792 
793  //create converter in case property name changed
794  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(dsType.get(), outputDataSource->getCapabilities(), outputDataSource->getEncoding());
795 
797 
798  std::unique_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(dataSet.get(), converter));
799 
800  //save data
801  std::map<std::string, std::string> options;
802 
803  outputDataSource->createDataSet(dsType.get(), options);
804 
805  outputDataSource->add(dataSetName, dsAdapter.get(), options);
806 
807  //create layer
808  try
809  {
810  te::qt::widgets::DataSet2Layer converter(outputDataSource->getId());
811 
812  te::da::DataSetTypePtr dt(outputDataSource->getDataSetType(dataSetName).release());
813 
814  te::map::AbstractLayerPtr layer = converter(dt);
815 
816  emit createNewLayer(layer);
817  }
818  catch(te::common::Exception& e)
819  {
820  QMessageBox::warning(this, tr("Query DataSource"), tr("Error creating layer. ") + e.what());
821  return;
822  }
823  QMessageBox::information(this, tr("Query DataSource"), tr("Layer created."));
824 }
825 
827 {
828  m_ui->m_newLayerNameLineEdit->clear();
829  m_ui->m_newLayerNameLineEdit->setEnabled(true);
830 
832  dlg.exec();
833 
834  std::list<te::da::DataSourceInfoPtr> dsPtrList = dlg.getSelecteds();
835 
836  if(dsPtrList.empty())
837  return;
838 
839  std::list<te::da::DataSourceInfoPtr>::iterator it = dsPtrList.begin();
840 
841  m_ui->m_repositoryLineEdit->setText(QString(it->get()->getTitle().c_str()));
842 
843  m_outputDatasource = *it;
844 
845  m_toFile = false;
846 }
847 
849 {
850  m_ui->m_newLayerNameLineEdit->clear();
851  m_ui->m_repositoryLineEdit->clear();
852 
853  QString fileName = QFileDialog::getSaveFileName(this, tr("Save as..."), QString(), tr("Shapefile (*.shp *.SHP);;"),nullptr, QFileDialog::DontConfirmOverwrite);
854 
855  if (fileName.isEmpty())
856  return;
857 
858  boost::filesystem::path outfile(fileName.toUtf8().data());
859 
860  m_ui->m_repositoryLineEdit->setText(outfile.string().c_str());
861 
862  m_ui->m_newLayerNameLineEdit->setText(outfile.leaf().string().c_str());
863 
864  m_ui->m_newLayerNameLineEdit->setEnabled(false);
865 
866  m_toFile = true;
867 }
868 
870 {
871  m_ui->m_sqlEditor->insert(item->text());
872 }
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
void createNewLayer(te::map::AbstractLayerPtr layer)
virtual void refresh(bool redraw=false)
It updates the contents in the map display.
Geometric property.
std::unique_ptr< Ui::QueryDataSourceDialogForm > m_ui
te::da::SQLDialect * dialect
Definition: WFSDialect.h:1
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
te::qt::widgets::MapDisplay * m_appMapDisplay
boost::shared_ptr< DataSetType > DataSetTypePtr
Definition: DataSetType.h:653
An atomic property like an integer or double.
boost::shared_ptr< DataSource > DataSourcePtr
TEDATAACCESSEXPORT void AssociateDataSetTypeConverterSRID(DataSetTypeConverter *converter, const int &inputSRID, const int &outputSRID=TE_UNKNOWN_SRS)
A class that models the description of a dataset.
Definition: DataSetType.h:72
virtual const char * what() const
It outputs the exception message.
It represents the SQL query dialect accepted by a given data source.
Definition: SQLDialect.h:55
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:168
void draw(const te::da::DataSetTypePtr &dataset, const te::da::DataSourcePtr &ds, te::da::DataSet *datasetData=0)
te::qt::widgets::DataSetDisplay * m_dataSetDisplay
A widget to control the display of a set of layers.
static te::dt::Date ds(2010, 01, 01)
std::list< te::map::AbstractLayerPtr > m_layerList
virtual Property * clone() const =0
It returns a clone of the object.
It models a property definition.
Definition: Property.h:59
An converter for DataSetType.
The type for arbitrary precison numbers, like numeric(p, q).
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:221
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
static DataSourceInfoManager & getInstance()
It returns a reference to the singleton instance.
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
void setExpressionByInClause(const std::string source="")
URI C++ Library.
Definition: Attributes.h:37
static te::dt::TimeDuration dt(20, 30, 50, 11)
te::qt::widgets::DataSetTableModel * m_tableModel
te::gm::Polygon * p
The type for string types: FIXED_STRING, VAR_STRING or STRING.
A map display for a dataset.
TEDATAACCESSEXPORT ObjectIdSet * GenerateOIDSet(DataSet *dataset, const DataSetType *type)
TEDATAACCESSEXPORT void GetDataSetNames(std::vector< std::string > &datasetNames, const std::string &datasourceId)
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
void setLayerList(std::list< te::map::AbstractLayerPtr > layerList)
This method is used to set the list of layers.
const std::list< te::da::DataSourceInfoPtr > & getSelecteds() const
std::map< std::string, Qt::GlobalColor > m_keyWords
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr) te
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
void setDataSet(te::da::DataSet *dset, const bool &clearEditor=true)
Updates the data being used.
A dialog for selecting a data source.
void setAppMapDisplay(te::qt::widgets::MapDisplay *appMapDisplay)
A class that represents a data source component.
std::vector< std::string > getRegisteredNames() const
It gets the all registered names from registed functions.
Definition: SQLDialect.cpp:51
void onListWidgetDoubleClicked(QListWidgetItem *item)
TEDATAACCESSEXPORT DataSetType * GetDataSetType(const std::string &name, const std::string &datasourceId)
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
void onDataSetItemClicked(QListWidgetItem *item)
std::string Convert2String(boost::int16_t value)
It converts a short integer value to a string.
Definition: StringUtils.h:56
A table model representing a te::da::DataSet.
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
This file defines a class for a Query DataSource Dialog Dialog.
file(WRITE ${CMAKE_BINARY_DIR}/config_qhelp.cmake"configure_file (${TERRALIB_ABSOLUTE_ROOT_DIR}/doc/qhelp/help.qhcp.in ${CMAKE_BINARY_DIR}/share/terraview/help/help.qhcp @ONLY)") add_custom_command(OUTPUT del_dir COMMAND $
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
An object that when created shows a cursor during its scope.
Definition: ScopedCursor.h:48
const std::string & getName() const
It returns the property name.
Definition: Property.h:127