From c6d1db96440b76adfbd80c04d1d42a667d7bdaaa Mon Sep 17 00:00:00 2001 From: xkenia Date: Mon, 16 Oct 2023 21:35:04 +0200 Subject: [PATCH] Added relays into Quickshow (#949) * Added relays into Quickshow * Fix code review --------- Co-authored-by: Lukas Konig --- quickshow/src/application.cpp | 2 + quickshow/src/cellrenderer.cpp | 27 ++++- quickshow/src/model.cpp | 204 +++++++++++++++++++++++---------- 3 files changed, 168 insertions(+), 65 deletions(-) diff --git a/quickshow/src/application.cpp b/quickshow/src/application.cpp index 23df4363b..8eb76e313 100644 --- a/quickshow/src/application.cpp +++ b/quickshow/src/application.cpp @@ -102,6 +102,8 @@ QVariantMap Application::eventInfo() while(q.next()) info[q.value(0).toString().mid(6)] = q.value(1); info["profile"] = profile(); + //set info about relay + info["isRelay"] = (info["disciplineId"] == 5 || info["disciplineId"] == 6); } return info; } diff --git a/quickshow/src/cellrenderer.cpp b/quickshow/src/cellrenderer.cpp index 9525c0711..5dc9635c1 100644 --- a/quickshow/src/cellrenderer.cpp +++ b/quickshow/src/cellrenderer.cpp @@ -1,7 +1,8 @@ #include "cellrenderer.h" - +#include "application.h" #include #include +#include "src/appclioptions.h" #include #include @@ -199,6 +200,8 @@ ResultsCellRenderer::ResultsCellRenderer(const QSize &size, QWidget *widget) QString ResultsCellRenderer::columnText(int col, const QVariantMap &data) { QString ret; + Application *app = Application::instance(); + bool is_relay = app->eventInfo().value("isRelay").toBool(); switch(col) { case Position: { bool disq = data.value(QStringLiteral("disqualified")).toBool(); @@ -208,14 +211,30 @@ QString ResultsCellRenderer::columnText(int col, const QVariantMap &data) break; } case Name: ret = QStringLiteral("{{lastname}} {{firstname}}"); break; - case Registration: ret = QStringLiteral("{{registration}}"); break; + case Registration: + if (is_relay) { + ret = data.value(QStringLiteral("relayname")).toString(); + } else { //individual + ret = QStringLiteral("{{registration}}"); + } + break; case Time: { - int sec = data.value(QStringLiteral("timems")).toInt() / 1000; + int sec; + if (is_relay) { + sec = data.value(QStringLiteral("legfinishtimems")).toInt() / 1000; + } else { //individual + sec = data.value(QStringLiteral("timems")).toInt() / 1000; + } ret = QString("%1.%2").arg(sec / 60).arg(sec % 60, 2, 10, QChar('0')); return ret; } case Status: { - bool disq = data.value(QStringLiteral("disqualified")).toBool(); + bool disq; + if (is_relay) { + disq = data.value(QStringLiteral("relaydisqualified")).toBool(); + } else { + disq = data.value(QStringLiteral("disqualified")).toBool(); + } return disq? tr("DISQ"): QString(); } default: diff --git a/quickshow/src/model.cpp b/quickshow/src/model.cpp index 2dc94f6c6..efc024059 100644 --- a/quickshow/src/model.cpp +++ b/quickshow/src/model.cpp @@ -81,75 +81,157 @@ bool Model::addCategoryToStorage() return false; } Application *app = Application::instance(); + bool is_relay = app->eventInfo().value("isRelay").toBool(); int cat_id_to_load = m_categoriesToProceed.takeFirst().toInt(); - QVariantMap category_map; - { + if (is_relay) { qf::core::sql::QueryBuilder qb; - qb.select2("classes", "name") - //.select2("classdefs", "") - .select2("courses", "length, climb") - .from("classes") - .joinRestricted("classes.id", "classdefs.classId", "classdefs.stageId={{stage_id}}") - .join("classdefs.courseId", "courses.id") - .where("classes.id={{class_id}}"); - QString qs = qb.toString(); + QString qs = "select cd.relaylegcount as leg_count from classdefs as cd where cd.classid = {{class_id}} and cd.stageid = {{stage_id}}"; + qfDebug() << "Get leg count for category:" << qs; qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); qs.replace("{{class_id}}", QString::number(cat_id_to_load)); - if(first_run) - qfInfo() << "classes:" << qs; qf::core::sql::Query q = app->execSql(qs); - if(q.next()) { - QVariantMap m; - category_map = q.values(); - m["type"] = "classInfo"; - m["record"] = category_map; - m_storage << m; + q.next(); + int leg_count_from_class = q.value("leg_count").toInt(); + for (int leg_num = 1; leg_num <= leg_count_from_class; leg_num++) { + QVariantMap category_map; + { + qf::core::sql::QueryBuilder qb; + QString qs = "select c.name || '-' || '{{leg_num}}' as name, 0 as length, 0 as climb from classes as c where c.id = {{class_id}}"; + qfInfo() << "Get category:" << qs; + qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); + qs.replace("{{class_id}}", QString::number(cat_id_to_load)); + qs.replace("{{leg_num}}", QString::number(leg_num)); + if(first_run) + qfInfo() << "classes:" << qs; + qf::core::sql::Query q = app->execSql(qs); + if(q.next()) { + QVariantMap m; + category_map = q.values(); + m["type"] = "classInfo"; + m["record"] = category_map; + m_storage << m; + } + else { + qfError() << "Entry for classname" << cat_id_to_load << "does not exist !!!"; + } + } + { + QString qs; + qf::core::sql::QueryBuilder qb; + if(app->cliOptions()->profile() == QLatin1String("results")) { + qs = "SELECT c.registration, c.lastName, c.firstName, r.*, (finishTimeMs - starttimemin*60*1000) as legFinishTimeMs, " + "relay.disqualified as relaydisqualified, " + "rel.club || ' ' || rel.name as relayname " + "FROM competitors as c join runs as r on r.competitorId = c.id " + "join relays as rel on r.relayid = rel.id " + "join classdefs as cd on cd.classid = rel.classId " + "join (select relayid, bool_or(disqualified) as disqualified from runs r group by relayid) relay on r.relayid = relay.relayid " + "where r.isRunning and r.finishTimeMs>0 and rel.classId = {{class_id}} and r.leg = {{leg_num}} " + "order by r.notCompeting, relaydisqualified, r.finishtimeMs"; + if(first_run) + qfInfo() << "results:" << qs; + } + else { + qb.select2("competitors", "registration, lastName, firstName") + //.select("COALESCE(competitors.lastName, '') || ' ' || COALESCE(competitors.firstName, '') AS competitorName") + .select2("runs", "*") + .from("competitors") + .joinRestricted("competitors.id", "runs.competitorId", "runs.stageId={{stage_id}} AND runs.isRunning", "JOIN") + .where("competitors.classId={{class_id}}") + .orderBy("runs.startTimeMs"); + qs = qb.toString(); + if(first_run) + qfInfo() << "startlist:" << qs; + } + qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); + qs.replace("{{class_id}}", QString::number(cat_id_to_load)); + qs.replace("{{leg_num}}", QString::number(leg_num)); + qf::core::sql::Query q = app->execSql(qs); + int pos = 0; + while(q.next()) { + QVariantMap m; + //QVariantMap detail_map = app->sqlRecordToMap(rec); + QVariantMap detail_map = q.values(); + detail_map["pos"] = ++pos; + m["type"] = app->cliOptions()->profile(); + m["record"] = detail_map; + /// pridej k detailu i kategorii, protoze na prvnim miste listu se zobrazuje vzdy zahlavi aktualni kategorie kvuli prehlednosti + //m["category"] = category_map; + m_storage << m; + } + } } - else { - qfError() << "Entry for classname" << cat_id_to_load << "does not exist !!!"; - } - } - { - QString qs; - qf::core::sql::QueryBuilder qb; - if(app->cliOptions()->profile() == QLatin1String("results")) { - qb.select2("competitors", "registration, lastName, firstName") - //.select("COALESCE(competitors.lastName, '') || ' ' || COALESCE(competitors.firstName, '') AS competitorName") - .select2("runs", "*") - .from("competitors") - .joinRestricted("competitors.id", "runs.competitorId", "runs.stageId={{stage_id}} AND runs.isRunning AND runs.finishTimeMs>0", "JOIN") - .where("competitors.classId={{class_id}}") - .orderBy("runs.notCompeting, runs.disqualified, runs.timeMs"); - qs = qb.toString(); - if(first_run) - qfInfo() << "results:" << qs; - } - else { - qb.select2("competitors", "registration, lastName, firstName") - //.select("COALESCE(competitors.lastName, '') || ' ' || COALESCE(competitors.firstName, '') AS competitorName") - .select2("runs", "*") - .from("competitors") - .joinRestricted("competitors.id", "runs.competitorId", "runs.stageId={{stage_id}} AND runs.isRunning", "JOIN") - .where("competitors.classId={{class_id}}") - .orderBy("runs.startTimeMs"); - qs = qb.toString(); + } else { //event type 'individual' + QVariantMap category_map; + { + qf::core::sql::QueryBuilder qb; + qb.select2("classes", "name") + //.select2("classdefs", "") + .select2("courses", "length, climb") + .from("classes") + .joinRestricted("classes.id", "classdefs.classId", "classdefs.stageId={{stage_id}}") + .join("classdefs.courseId", "courses.id") + .where("classes.id={{class_id}}"); + QString qs = qb.toString(); + qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); + qs.replace("{{class_id}}", QString::number(cat_id_to_load)); if(first_run) - qfInfo() << "startlist:" << qs; + qfInfo() << "classes:" << qs; + qf::core::sql::Query q = app->execSql(qs); + if(q.next()) { + QVariantMap m; + category_map = q.values(); + m["type"] = "classInfo"; + m["record"] = category_map; + m_storage << m; + } + else { + qfError() << "Entry for classname" << cat_id_to_load << "does not exist !!!"; + } } - qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); - qs.replace("{{class_id}}", QString::number(cat_id_to_load)); - qf::core::sql::Query q = app->execSql(qs); - int pos = 0; - while(q.next()) { - QVariantMap m; - //QVariantMap detail_map = app->sqlRecordToMap(rec); - QVariantMap detail_map = q.values(); - detail_map["pos"] = ++pos; - m["type"] = app->cliOptions()->profile(); - m["record"] = detail_map; - /// pridej k detailu i kategorii, protoze na prvnim miste listu se zobrazuje vzdy zahlavi aktualni kategorie kvuli prehlednosti - //m["category"] = category_map; - m_storage << m; + { + QString qs; + qf::core::sql::QueryBuilder qb; + if(app->cliOptions()->profile() == QLatin1String("results")) { + qfInfo() << "vytazeni zavodniku pro kategorii" << qs; + qb.select2("competitors", "registration, lastName, firstName") + //.select("COALESCE(competitors.lastName, '') || ' ' || COALESCE(competitors.firstName, '') AS competitorName") + .select2("runs", "*") + .from("competitors") + .joinRestricted("competitors.id", "runs.competitorId", "runs.stageId={{stage_id}} AND runs.isRunning AND runs.finishTimeMs>0", "JOIN") + .where("competitors.classId={{class_id}}") + .orderBy("runs.notCompeting, runs.disqualified, runs.timeMs"); + qs = qb.toString(); + if(first_run) + qfInfo() << "results:" << qs; + } + else { + qb.select2("competitors", "registration, lastName, firstName") + //.select("COALESCE(competitors.lastName, '') || ' ' || COALESCE(competitors.firstName, '') AS competitorName") + .select2("runs", "*") + .from("competitors") + .joinRestricted("competitors.id", "runs.competitorId", "runs.stageId={{stage_id}} AND runs.isRunning", "JOIN") + .where("competitors.classId={{class_id}}") + .orderBy("runs.startTimeMs"); + qs = qb.toString(); + if(first_run) + qfInfo() << "startlist:" << qs; + } + qs.replace("{{stage_id}}", QString::number(app->cliOptions()->stage())); + qs.replace("{{class_id}}", QString::number(cat_id_to_load)); + qf::core::sql::Query q = app->execSql(qs); + int pos = 0; + while(q.next()) { + QVariantMap m; + //QVariantMap detail_map = app->sqlRecordToMap(rec); + QVariantMap detail_map = q.values(); + detail_map["pos"] = ++pos; + m["type"] = app->cliOptions()->profile(); + m["record"] = detail_map; + /// pridej k detailu i kategorii, protoze na prvnim miste listu se zobrazuje vzdy zahlavi aktualni kategorie kvuli prehlednosti + //m["category"] = category_map; + m_storage << m; + } } } first_run = false;