diff --git a/src/GSvar/NGSDReplicationWidget.cpp b/src/GSvar/NGSDReplicationWidget.cpp index cac3cd2e9..1fc1fb309 100644 --- a/src/GSvar/NGSDReplicationWidget.cpp +++ b/src/GSvar/NGSDReplicationWidget.cpp @@ -444,6 +444,11 @@ void NGSDReplicationWidget::replicateVariantData() updateTable("variant_publication", true); updateTable("variant_validation", true, "WHERE variant_id IS NOT NULL"); //small variants updateCnvTable("variant_validation", "WHERE cnv_id IS NOT NULL"); //CNVs + updateSvTable("variant_validation", StructuralVariantType::DEL, "WHERE sv_deletion_id IS NOT NULL"); //SVs (DEL) + updateSvTable("variant_validation", StructuralVariantType::DUP, "WHERE sv_duplication_id IS NOT NULL"); //SVs (DUP) + updateSvTable("variant_validation", StructuralVariantType::INS, "WHERE sv_insertion_id IS NOT NULL"); //SVs (INS) + updateSvTable("variant_validation", StructuralVariantType::INV, "WHERE sv_inversion_id IS NOT NULL"); //SVs (INV) + updateSvTable("variant_validation", StructuralVariantType::BND, "WHERE sv_translocation_id IS NOT NULL"); //SVs (BND) } void NGSDReplicationWidget::replicateReportConfiguration() @@ -461,6 +466,7 @@ void NGSDReplicationWidget::replicateReportConfiguration() } qDebug() << "report config small variants: samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); updateTable("report_configuration_variant", true, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ")"); + //import report CNVs for samples with imported CNVs that are not already imported rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM cnv_callset WHERE id IN (SELECT cnv_callset_id FROM cnv))"); rc_ids_already_present = db_target_->getValues("SELECT DISTINCT report_configuration_id FROM report_configuration_cnv"); @@ -471,14 +477,95 @@ void NGSDReplicationWidget::replicateReportConfiguration() qDebug() << "report config CNVs: samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); updateCnvTable("report_configuration_cnv", "WHERE report_configuration_id IN (" + rc_todo.join(",") + ")"); + + //import report SVs for samples with imported SVs that are not already imported + rc_ids_already_present = db_target_->getValues("SELECT DISTINCT report_configuration_id FROM report_configuration_sv"); + //DEL + rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM sv_callset WHERE id IN (SELECT sv_callset_id FROM sv_deletion))"); + foreach(QString id, rc_ids_already_present) + { + rc_todo.removeAll(id); + } + qDebug() << "report config SVs (DEL): samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); + updateSvTable("report_configuration_sv", StructuralVariantType::DEL, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ") AND sv_deletion_id IS NOT NULL"); + //DUP + rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM sv_callset WHERE id IN (SELECT sv_callset_id FROM sv_duplication))"); + foreach(QString id, rc_ids_already_present) + { + rc_todo.removeAll(id); + } + qDebug() << "report config SVs (DUP): samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); + updateSvTable("report_configuration_sv", StructuralVariantType::DUP, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ") AND sv_duplication_id IS NOT NULL"); + //INS + rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM sv_callset WHERE id IN (SELECT sv_callset_id FROM sv_insertion))"); + foreach(QString id, rc_ids_already_present) + { + rc_todo.removeAll(id); + } + qDebug() << "report config SVs (INS): samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); + updateSvTable("report_configuration_sv", StructuralVariantType::INS, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ") AND sv_insertion_id IS NOT NULL"); + //INV + rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM sv_callset WHERE id IN (SELECT sv_callset_id FROM sv_inversion))"); + foreach(QString id, rc_ids_already_present) + { + rc_todo.removeAll(id); + } + qDebug() << "report config SVs (INV): samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); + updateSvTable("report_configuration_sv", StructuralVariantType::INV, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ") AND sv_inversion_id IS NOT NULL"); + //BND + rc_todo = db_target_->getValues("SELECT id FROM report_configuration WHERE processed_sample_id IN (SELECT processed_sample_id FROM sv_callset WHERE id IN (SELECT sv_callset_id FROM sv_translocation))"); + foreach(QString id, rc_ids_already_present) + { + rc_todo.removeAll(id); + } + qDebug() << "report config SVs (BND): samples todo:" << rc_todo.count() << " already imported:" << rc_ids_already_present.count(); + updateSvTable("report_configuration_sv", StructuralVariantType::BND, "WHERE report_configuration_id IN (" + rc_todo.join(",") + ") AND sv_translocation_id IS NOT NULL"); + + //(2) somatic updateTable("somatic_report_configuration_variant", true); updateTable("somatic_report_configuration_germl_var", true); } +void NGSDReplicationWidget::performPostChecks() +{ + addHeader("post-checks"); + + //test if all tables are processed + QStringList target_tables = db_target_->tables(); + foreach(QString table, target_tables) + { + //skip - analysis jobs + if (table=="analysis_job") continue; + if (table=="analysis_job_history") continue; + if (table=="analysis_job_sample") continue; + //skip - sample variant and QC import + if (table=="cnv_callset") continue; + if (table=="cnv") continue; + if (table=="detected_somatic_variant") continue; + if (table=="detected_variant") continue; + if (table=="somatic_cnv_callset") continue; + if (table=="somatic_cnv") continue; + if (table=="sv_callset") continue; + if (table=="sv_deletion") continue; + if (table=="sv_duplication") continue; + if (table=="sv_insertion") continue; + if (table=="sv_inversion") continue; + if (table=="sv_translocation") continue; + if (table=="processed_sample_qc") continue; + //skip - others + if (table=="secondary_analysis") continue; + if (table=="subpanels") continue; + + if (!tables_done_.contains(table)) + { + addWarning("Table '" + table + "' not filled!"); + } + } +} + //TODO NGSDReplicationWidget: -//- SVs: report_configuration_sv //- CNVs somatic: somatic_report_configuration_cnv //- misc: gaps, cfdna_panel_genes, cfdna_panels @@ -538,43 +625,6 @@ int NGSDReplicationWidget::liftOverVariant(int source_variant_id, bool debug_out return variant_id.toInt(); } -void NGSDReplicationWidget::performPostChecks() -{ - addHeader("post-checks"); - - //test if all tables are processed - QStringList target_tables = db_target_->tables(); - foreach(QString table, target_tables) - { - //skip - analysis jobs - if (table=="analysis_job") continue; - if (table=="analysis_job_history") continue; - if (table=="analysis_job_sample") continue; - //skip - sample variant and QC import - if (table=="cnv_callset") continue; - if (table=="cnv") continue; - if (table=="detected_somatic_variant") continue; - if (table=="detected_variant") continue; - if (table=="somatic_cnv_callset") continue; - if (table=="somatic_cnv") continue; - if (table=="sv_callset") continue; - if (table=="sv_deletion") continue; - if (table=="sv_duplication") continue; - if (table=="sv_insertion") continue; - if (table=="sv_inversion") continue; - if (table=="sv_translocation") continue; - if (table=="processed_sample_qc") continue; - //skip - others - if (table=="secondary_analysis") continue; - if (table=="subpanels") continue; - - if (!tables_done_.contains(table)) - { - addWarning("Table '" + table + "' not filled!"); - } - } -} - int NGSDReplicationWidget::liftOverCnv(int source_cnv_id, int callset_id, QString& error_message) { CopyNumberVariant var = db_source_->cnv(source_cnv_id); @@ -625,6 +675,137 @@ int NGSDReplicationWidget::liftOverCnv(int source_cnv_id, int callset_id, QStrin return cnv_id.toInt(); } +int NGSDReplicationWidget::liftOverSv(int source_sv_id, StructuralVariantType sv_type, int callset_id, QString& error_message) +{ + BedpeFile dummy; //dummy BEDPE file to pass as structure + QList annotation_headers; + annotation_headers << "QUAL" << "FILTER" << "ALT_A" << "INFO_A"; + dummy.setAnnotationHeaders(annotation_headers); + BedpeLine sv = db_source_->structuralVariant(source_sv_id, sv_type, dummy, false); + + //lift-over coordinates + BedLine coords1, coords2; + try + { + coords1 = GSvarHelper::liftOver(sv.chr1(), sv.start1(), sv.end1()); + } + catch(Exception& e) + { + error_message = "lift-over failed (pos1): " + e.message().replace("\t", " ").replace("
", " ").replace(" ", " "); + return -1; + } + try + { + coords2 = GSvarHelper::liftOver(sv.chr2(), sv.start2(), sv.end2()); + } + catch(Exception& e) + { + error_message = "lift-over failed (pos2): " + e.message().replace("\t", " ").replace("
", " ").replace(" ", " "); + return -1; + } + + + //check new chromosome is ok + if (!coords1.chr().isNonSpecial()) + { + error_message = "chromosome 1 is now special chromosome: " + coords1.chr().strNormalized(true); + return -2; + } + if (!coords2.chr().isNonSpecial()) + { + error_message = "chromosome 2 is now special chromosome: " + coords2.chr().strNormalized(true); + return -2; + } + + //check for strand changes + if (sv_type != StructuralVariantType::INS && coords2 < coords1) + { + // switch positions + error_message = "(WARNING: strand changed!) "; + BedLine tmp = coords1; + coords1 = coords2; + coords2 = tmp; + } + + //check for SV in target NGSD + sv.setChr1(coords1.chr()); + sv.setStart1(coords1.start()); + sv.setEnd1(coords1.end()); + sv.setChr2(coords2.chr()); + sv.setStart2(coords2.start()); + sv.setEnd2(coords2.end()); + QString sv_id = db_target_->svId(sv, callset_id, dummy, false); + if (sv_id.isEmpty()) + { + // no exact match found -> try fuzzy match (overlapping of CI) + SqlQuery query = db_target_->getQuery(); + QByteArray query_string; + + // prepare query + if (sv.type() == StructuralVariantType::BND) + { + //BND + query_string = "SELECT id FROM sv_translocation sv WHERE sv_callset_id = :0 AND sv.chr1 = :1 AND sv.start1 <= :2 AND :3 <= sv.end1 AND sv.chr2 = :4 AND sv.start2 <= :5 AND :6 <= sv.end2"; + query.prepare(query_string); + query.bindValue(0, callset_id); + query.bindValue(1, sv.chr1().strNormalized(true)); + query.bindValue(2, sv.end1()); + query.bindValue(3, sv.start1()); + query.bindValue(4, sv.chr2().strNormalized(true)); + query.bindValue(5, sv.end2()); + query.bindValue(6, sv.start2()); + + } + else if (sv.type() == StructuralVariantType::INS) + { + //INS + + //get min and max position + int min_pos = std::min(sv.start1(), sv.start2()); + int max_pos = std::max(sv.end1(), sv.end2()); + + query_string = "SELECT id FROM sv_insertion sv WHERE sv_callset_id = :0 AND sv.chr = :1 AND sv.pos <= :2 AND :3 <= (sv.pos + sv.ci_upper)"; + query.prepare(query_string); + query.bindValue(0, callset_id); + query.bindValue(1, sv.chr1().strNormalized(true)); + query.bindValue(2, max_pos); + query.bindValue(3, min_pos); + } + else + { + //DEL, DUP, INV + query_string = "SELECT id FROM " + db_target_->svTableName(sv.type()).toUtf8() + " sv WHERE sv_callset_id = :0 AND sv.chr = :1 AND sv.start_min <= :2 AND :3 <= sv.start_max AND sv.end_min <= :4 AND :5 <= sv.end_max"; + query.prepare(query_string); + query.bindValue(0, callset_id); + query.bindValue(1, sv.chr1().strNormalized(true)); + query.bindValue(2, sv.end1()); + query.bindValue(3, sv.start1()); + query.bindValue(4, sv.end2()); + query.bindValue(5, sv.start2()); + } + + query.exec(); + + //parse result + if (query.size() == 0) + { + error_message = "SV not found in NGSD"; + return -4; + } + else if (query.size() > 1) + { + error_message = "Multiple matching SVs found in NGSD"; + return -5; + } + query.next(); + return query.value(0).toInt(); + + } + // return id + return sv_id.toInt(); + +} + void NGSDReplicationWidget::updateCnvTable(QString table, QString where_clause) { QFile file(QCoreApplication::applicationDirPath() + QDir::separator() + "liftover_" + table + ".tsv"); @@ -844,3 +1025,267 @@ void NGSDReplicationWidget::updateCnvTable(QString table, QString where_clause) addLine(" Table '"+table+"' replicated: "+details.join(", ")+". Time: " + Helper::elapsedTime(timer)); tables_done_ << table; } + +void NGSDReplicationWidget::updateSvTable(QString table, StructuralVariantType sv_type, QString where_clause) +{ + BedpeFile dummy; //dummy BEDPE file to pass as structure + QList annotation_headers; + annotation_headers << "QUAL" << "FILTER" << "ALT_A" << "INFO_A"; + dummy.setAnnotationHeaders(annotation_headers); + + QFile file(QCoreApplication::applicationDirPath() + QDir::separator() + "liftover_" + table + "_" + StructuralVariantTypeToString(sv_type) + ".tsv"); + file.open(QIODevice::WriteOnly); + QTextStream debug_stream(&file); + debug_stream << "#ps\tSV\ttype\tfound_in_HG38\terror\tcomments\n"; + + QStringList fields = db_target_->tableInfo(table).fieldNames(); + + //init + QTime timer; + timer.start(); + + int c_added = 0; + int c_kept = 0; + int c_removed = 0; + int c_updated = 0; + int c_not_mappable = 0; + int c_not_in_ngsd = 0; + int c_no_callset = 0; + int c_strand_changed = 0; + + SqlQuery q_del = db_target_->getQuery(); + q_del.prepare("DELETE FROM "+table+" WHERE id=:0"); + + SqlQuery q_add = db_target_->getQuery(); + q_add.prepare("INSERT INTO "+table+" VALUES (:" + fields.join(", :") + ")"); + + SqlQuery q_get = db_target_->getQuery(); + q_get.prepare("SELECT * FROM "+table+" WHERE id=:0"); + + SqlQuery q_update = db_target_->getQuery(); + QString query_str = "UPDATE "+table+" SET"; + bool first = true; + foreach(const QString& field, fields) + { + if (field=="id") continue; + + //special handling of SV (lifted-over) + if (field=="sv_id") continue; + + query_str += (first? " " : ", ") + field + "=:" + field; + + if (first) first = false; + } + query_str += " WHERE id=:id"; + q_update.prepare(query_str); + + //delete removed entries + QSet source_ids = db_source_->getValuesInt("SELECT id FROM " + table + " " + where_clause + " ORDER BY id ASC").toSet(); + QSet target_ids = db_target_->getValuesInt("SELECT id FROM " + table + " " + where_clause + " ORDER BY id ASC").toSet(); + foreach(int id, target_ids) + { + if (!source_ids.contains(id)) + { + q_del.bindValue(0, id); + q_del.exec(); + + ++c_removed; + } + } + + //add/update entries + SqlQuery query = db_source_->getQuery(); + query.exec("SELECT * FROM " + table + " " + where_clause + " ORDER BY id ASC"); + while(query.next()) + { + int id = query.value("id").toInt(); + if (target_ids.contains(id)) + { + //check if changed + q_get.bindValue(0, id); + q_get.exec(); + q_get.next(); + bool changed = false; + foreach(const QString& field, fields) + { + //special handling of SV ids (lifted-over) + if (sv_type == StructuralVariantType::DEL && field=="sv_deletion_id") continue; + if (sv_type == StructuralVariantType::DUP && field=="sv_duplication_id") continue; + if (sv_type == StructuralVariantType::INS && field=="sv_insertion_id") continue; + if (sv_type == StructuralVariantType::INV && field=="sv_inversion_id") continue; + if (sv_type == StructuralVariantType::BND && field=="sv_translocation_id") continue; + + if (q_get.value(field)!=query.value(field)) + { + changed = true; + } + } + + //update if changed + if (changed) + { + foreach(const QString& field, fields) + { + //special handling of SV ids (lifted-over) + if (sv_type == StructuralVariantType::DEL && field=="sv_deletion_id") continue; + if (sv_type == StructuralVariantType::DUP && field=="sv_duplication_id") continue; + if (sv_type == StructuralVariantType::INS && field=="sv_insertion_id") continue; + if (sv_type == StructuralVariantType::INV && field=="sv_inversion_id") continue; + if (sv_type == StructuralVariantType::BND && field=="sv_translocation_id") continue; + + q_update.bindValue(":"+field, query.value(field)); + } + q_update.exec(); + + ++c_updated; + } + else + { + ++c_kept; + } + } + else //row not in target table > add + { + int source_sv_id; + QString ps_id; + switch (sv_type) + { + case StructuralVariantType::DEL: + source_sv_id = query.value("sv_deletion_id").toInt(); + ps_id = db_source_->getValue("SELECT cs.processed_sample_id FROM sv_deletion sv, sv_callset cs WHERE sv.sv_callset_id=cs.id AND sv.id=" + QString::number(source_sv_id)).toString(); + break; + case StructuralVariantType::DUP: + source_sv_id = query.value("sv_duplication_id").toInt(); + ps_id = db_source_->getValue("SELECT cs.processed_sample_id FROM sv_duplication sv, sv_callset cs WHERE sv.sv_callset_id=cs.id AND sv.id=" + QString::number(source_sv_id)).toString(); + break; + case StructuralVariantType::INS: + source_sv_id = query.value("sv_insertion_id").toInt(); + ps_id = db_source_->getValue("SELECT cs.processed_sample_id FROM sv_insertion sv, sv_callset cs WHERE sv.sv_callset_id=cs.id AND sv.id=" + QString::number(source_sv_id)).toString(); + break; + case StructuralVariantType::INV: + source_sv_id = query.value("sv_inversion_id").toInt(); + ps_id = db_source_->getValue("SELECT cs.processed_sample_id FROM sv_inversion sv, sv_callset cs WHERE sv.sv_callset_id=cs.id AND sv.id=" + QString::number(source_sv_id)).toString(); + break; + case StructuralVariantType::BND: + source_sv_id = query.value("sv_translocation_id").toInt(); + ps_id = db_source_->getValue("SELECT cs.processed_sample_id FROM sv_translocation sv, sv_callset cs WHERE sv.sv_callset_id=cs.id AND sv.id=" + QString::number(source_sv_id)).toString(); + break; + default: + THROW(ArgumentException, "Invalid SV type!"); + break; + } + int target_sv_id = -1; + QString ps = db_source_->processedSampleName(ps_id); + QVariant callset_id = db_target_->getValue("SELECT id FROM sv_callset WHERE processed_sample_id=" + ps_id); + if (!callset_id.isValid()) + { + ++c_no_callset; + continue; + } + + bool causal_variant = table=="report_configuration_sv" && query.value("causal").toInt()==1; + bool pathogenic_variant = table=="report_configuration_sv" && query.value("class").toInt()>3; + QString error_message = ""; + target_sv_id = liftOverSv(source_sv_id, sv_type, callset_id.toInt(), error_message); + + QStringList comments; + if (causal_variant) comments << "causal"; + if (pathogenic_variant) comments << "pathogenic"; + BedpeLine sv = db_source_->structuralVariant(source_sv_id, sv_type, dummy, true); + + debug_stream << ps << "\t" << sv.toString() << "\t" << StructuralVariantTypeToString(sv_type) << "\t" << (target_sv_id>=0 ? "yes" : "no") << "\t" << error_message << "\t" + << comments.join(", ") << "\n"; + debug_stream.flush(); + + + //check for strand changes + if (error_message.contains("(WARNING: strand changed!)")) c_strand_changed++; + + //warn if causal/pathogenic SV could not be lifed + if (target_sv_id<0) + { + if (causal_variant) + { + addWarning("Causal SV " + db_source_->structuralVariant(source_sv_id, sv_type, dummy, true).toString() + " of sample " + ps + " could not be lifted (" + + QString::number(target_sv_id) + ", '" + error_message +"')!"); + } + else if (pathogenic_variant) + { + addWarning("Pathogenic SV " + db_source_->structuralVariant(source_sv_id, sv_type, dummy, true).toString() + " of sample " + ps + " (class " + + query.value("class").toString() + ") could not be lifted (" + QString::number(target_sv_id) + ", '" + error_message +"')!"); + } + } + + if (target_sv_id>=0) + { + foreach(const QString& field, fields) + { + //special handling of SV ids (lifted-over) + if (sv_type == StructuralVariantType::DEL && field=="sv_deletion_id") + { + q_add.bindValue(":"+field, target_sv_id); + continue; + } + if (sv_type == StructuralVariantType::DUP && field=="sv_duplication_id") + { + q_add.bindValue(":"+field, target_sv_id); + continue; + } + if (sv_type == StructuralVariantType::INS && field=="sv_insertion_id") + { + q_add.bindValue(":"+field, target_sv_id); + continue; + } + if (sv_type == StructuralVariantType::INV && field=="sv_inversion_id") + { + q_add.bindValue(":"+field, target_sv_id); + continue; + } + if (sv_type == StructuralVariantType::BND && field=="sv_translocation_id") + { + q_add.bindValue(":"+field, target_sv_id); + continue; + } + + q_add.bindValue(":"+field, query.value(field)); + } + try + { + q_add.exec(); + } + catch (Exception& e) + { + THROW(Exception, "Could not add table "+table+" entry with id "+QString::number(id)+": "+e.message()); + } + ++c_added; + } + else if (target_sv_id>=-3) + { + ++c_not_mappable; + } + else if (target_sv_id==-4) + { + ++c_not_in_ngsd; + } + else + { + THROW(NotImplementedException, "Unhandled SV error: " + QString::number(target_sv_id)); + } + } + } + + //output + QStringList details; + if (c_added>0) details << "added " + QString::number(c_added); + if (c_not_mappable>0) details << "skipped unmappable " + StructuralVariantTypeToString(sv_type) + "s " + QString::number(c_not_mappable); + if (c_not_in_ngsd>0) details << "skipped " + StructuralVariantTypeToString(sv_type) + "s not found in NGSD " + QString::number(c_not_in_ngsd); + if (c_no_callset>0) details << "skipped " + StructuralVariantTypeToString(sv_type) + "s of samples without callset " + QString::number(c_no_callset); + if (c_kept>0) details << "kept " + QString::number(c_kept); + if (c_updated>0) details << "updated " + QString::number(c_updated); + if (c_removed>0) details << "removed " + QString::number(c_removed); + if (c_strand_changed>0) details << "strand changed " + QString::number(c_strand_changed); + + addLine(" Table '" + table + "' replicated (" + StructuralVariantTypeToString(sv_type) + "): "+details.join(", ")+". Time: " + Helper::elapsedTime(timer)); + tables_done_ << table; +} + diff --git a/src/GSvar/NGSDReplicationWidget.h b/src/GSvar/NGSDReplicationWidget.h index c75cf7a75..2d2f3c938 100644 --- a/src/GSvar/NGSDReplicationWidget.h +++ b/src/GSvar/NGSDReplicationWidget.h @@ -31,9 +31,11 @@ protected slots: void performPostChecks(); int liftOverVariant(int source_variant_id, bool debug_output); + int liftOverCnv(int source_cnv_id, int callset_id, QString& error_message); + int liftOverSv(int source_sv_id, StructuralVariantType sv_type, int callset_id, QString& error_message); void updateTable(QString table, bool contains_variant_id=false, QString where_clause=""); void updateCnvTable(QString table, QString where_clause=""); - int liftOverCnv(int source_cnv_id, int callset_id, QString& error_message); + void updateSvTable(QString table, StructuralVariantType sv_type, QString where_clause=""); private: Ui::NGSDReplicationWidget ui_; diff --git a/src/cppGUI b/src/cppGUI index 01ccd7999..4527aa205 160000 --- a/src/cppGUI +++ b/src/cppGUI @@ -1 +1 @@ -Subproject commit 01ccd7999d0d241199aba8a51c5f249d18f6abd7 +Subproject commit 4527aa2051068bfeb9ceeaa577a6445247b82348