| 416 | } |
| 417 | |
| 418 | void ImportSQLDatabaseWidget::read(AbstractDataSource* dataSource, AbstractFileFilter::ImportMode importMode) { |
| 419 | if (!dataSource) |
| 420 | return; |
| 421 | |
| 422 | // execute the current query and determine the start/end rows and columns to read |
| 423 | QSqlQuery q; |
| 424 | if (!prepareAndExecute(q) || m_actualRows == 0) { |
| 425 | RESET_CURSOR; |
| 426 | return; |
| 427 | } |
| 428 | |
| 429 | // pointers to the actual data containers |
| 430 | // columnOffset indexes the "start column" in the datasource. Data will be imported starting from this column. |
| 431 | std::vector<void*> dataContainer; |
| 432 | bool ok = false; |
| 433 | const int columnOffset = dataSource->prepareImport(dataContainer, importMode, m_actualRows, m_actualCols, m_actualColumnNames, m_actualColumnModes, ok); |
| 434 | // TODO: error handling |
| 435 | if (!ok) |
| 436 | return; |
| 437 | |
| 438 | // number and DateTime formatting |
| 439 | const auto& dateTimeFormat = ui.cbDateTimeFormat->currentText(); |
| 440 | |
| 441 | // TODO: use general setting for decimal separator? |
| 442 | QLocale::Language lang; |
| 443 | if (ui.cbDecimalSeparator->currentIndex() == 0) |
| 444 | lang = QLocale::Language::C; |
| 445 | else |
| 446 | lang = QLocale::Language::German; |
| 447 | const QLocale numberFormat = QLocale(lang); |
| 448 | |
| 449 | // read the data |
| 450 | int progressIndex = 0; |
| 451 | const qreal progressInterval = 0.01 * m_actualRows; // update on every 1% only |
| 452 | int rowIndex = 0; |
| 453 | while (q.next()) { |
| 454 | if (rowIndex < m_startRow) { |
| 455 | ++rowIndex; |
| 456 | continue; |
| 457 | } |
| 458 | |
| 459 | if (rowIndex > m_endRow) |
| 460 | break; |
| 461 | |
| 462 | for (int colIndex = m_startCol; colIndex <= m_endCol; ++colIndex) { |
| 463 | const auto& valueString = q.value(colIndex).toString(); |
| 464 | const int col = colIndex - m_startCol; |
| 465 | const int row = rowIndex - m_startRow; |
| 466 | |
| 467 | // set the value depending on the data type |
| 468 | switch (m_actualColumnModes.at(col)) { |
| 469 | case AbstractColumn::ColumnMode::Double: { |
| 470 | bool isNumber; |
| 471 | const double value = numberFormat.toDouble(valueString, &isNumber); |
| 472 | static_cast<QVector<double>*>(dataContainer[col])->operator[](row) = (isNumber ? value : NAN); |
| 473 | break; |
| 474 | } |
| 475 | case AbstractColumn::ColumnMode::Integer: { |
no test coverage detected