Mise en place du versionnement horodaté (même mécanisme que shipheart_qt) : génération de _version.h à chaque build, archivage automatique d'une copie horodatée de l'exécutable dans versions/, affichage de la version au démarrage
This commit is contained in:
@@ -0,0 +1 @@
|
||||
260924_084534
|
||||
@@ -7,8 +7,35 @@ set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core HttpServer Sql)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Version dynamique, injectée dans _version.h à CHAQUE build - même mécanisme
|
||||
# que shipheart_qt (cf synthèse, format yymmdd_HHMMSS, ex: 260924_080910) :
|
||||
# une cible personnalisée sans suivi de fichier est toujours considérée
|
||||
# périmée par Ninja/Make et se ré-exécute avant chaque build, contrairement à
|
||||
# string(TIMESTAMP ...) seul qui ne s'évalue qu'à la configuration du projet.
|
||||
# ---------------------------------------------------------------------------
|
||||
add_custom_target(generate_version ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DOUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/_version.h
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/generate_version.cmake
|
||||
COMMENT "Régénération de _version.h (horodatage)"
|
||||
BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/_version.h
|
||||
)
|
||||
|
||||
add_executable(shipheart_api
|
||||
main.cpp
|
||||
# Header listé pour visibilité dans l'IDE (non obligatoire pour la compilation) :
|
||||
_version.h
|
||||
)
|
||||
|
||||
add_dependencies(shipheart_api generate_version)
|
||||
|
||||
add_custom_command(TARGET shipheart_api POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DEXE_PATH=$<TARGET_FILE:shipheart_api>
|
||||
-DSRC_DIR=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/archive_version.cmake
|
||||
COMMENT "Archivage d'une copie horodatée de l'exécutable"
|
||||
)
|
||||
|
||||
target_link_libraries(shipheart_api PRIVATE
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
#ifndef _VERSION_H
|
||||
#define _VERSION_H
|
||||
|
||||
#define VERSION "260924_084534"
|
||||
|
||||
#endif // _VERSION_H
|
||||
@@ -0,0 +1,8 @@
|
||||
file(READ "${SRC_DIR}/.current_version" APP_VERSION)
|
||||
string(STRIP "${APP_VERSION}" APP_VERSION)
|
||||
|
||||
file(MAKE_DIRECTORY "${SRC_DIR}/versions")
|
||||
file(COPY "${EXE_PATH}" DESTINATION "${SRC_DIR}/versions")
|
||||
file(RENAME "${SRC_DIR}/versions/shipheart_api" "${SRC_DIR}/versions/shipheart_api_${APP_VERSION}")
|
||||
|
||||
message(STATUS "Exécutable archivé : versions/shipheart_api_${APP_VERSION}")
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
# Exécuté à CHAQUE build (pas seulement à chaque reconfiguration CMake) via
|
||||
# la cible "generate_version" dans CMakeLists.txt, qui n'a aucun suivi de
|
||||
# fichier et est donc toujours considérée périmée par Ninja/Make.
|
||||
#
|
||||
# Même mécanisme que shipheart_qt (cf synthèse) : deux exécutables différents
|
||||
# (même par une modification infime du code) obtiennent systématiquement un
|
||||
# horodatage différent, garantissant l'unicité recherchée.
|
||||
|
||||
string(TIMESTAMP APP_VERSION "%y%m%d_%H%M%S")
|
||||
|
||||
file(WRITE "${OUTPUT_FILE}"
|
||||
"#ifndef _VERSION_H
|
||||
#define _VERSION_H
|
||||
|
||||
#define VERSION \"${APP_VERSION}\"
|
||||
|
||||
#endif // _VERSION_H
|
||||
")
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_LIST_DIR}/.current_version" "${APP_VERSION}")
|
||||
|
||||
message(STATUS "Version ShipHeart API régénérée : ${APP_VERSION}")
|
||||
Binary file not shown.
@@ -15,6 +15,8 @@
|
||||
#include <QPair>
|
||||
#include <QDebug>
|
||||
|
||||
#include "_version.h"
|
||||
|
||||
// ============================================================================
|
||||
// shipheart_api - Phase 4 : première tranche verticale, domaine "circuit"
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -193,6 +195,7 @@ static void assurer_connexion_bdd()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
qInfo() << "shipheart_api version" << VERSION;
|
||||
|
||||
// --- Connexion MariaDB locale ---
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
|
||||
|
||||
Binary file not shown.
@@ -164,6 +164,32 @@ static QHttpServerResponse withCors(QHttpServerResponse &&resp)
|
||||
return std::move(resp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Vérifie que la connexion MariaDB (ouverte une seule fois au démarrage) est
|
||||
// toujours active, et la rétablit sinon. isOpen() peut rester vrai même après
|
||||
// une coupure réseau ou un dépassement de wait_timeout côté serveur - un test
|
||||
// léger (SELECT 1) confirme que la connexion répond réellement. Sans ce
|
||||
// contrôle, l'API reste "vivante" indéfiniment mais chaque requête SQL échoue
|
||||
// silencieusement après une longue période d'inactivité (constaté après
|
||||
// plusieurs semaines d'exécution continue, cf synthèse).
|
||||
// À appeler en tout premier dans chaque route qui touche la base.
|
||||
// ----------------------------------------------------------------------------
|
||||
static void assurer_connexion_bdd()
|
||||
{
|
||||
QSqlDatabase db = QSqlDatabase::database();
|
||||
if (db.isOpen()) {
|
||||
QSqlQuery test(db);
|
||||
if (test.exec("SELECT 1")) return;
|
||||
}
|
||||
qWarning() << "Connexion MariaDB perdue, tentative de reconnexion...";
|
||||
db.close();
|
||||
if (db.open()) {
|
||||
qInfo() << "Reconnexion MariaDB réussie.";
|
||||
} else {
|
||||
qCritical() << "Reconnexion MariaDB échouée :" << db.lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
@@ -196,6 +222,7 @@ int main(int argc, char *argv[])
|
||||
// requêtes onglets de mise_a_jour_onglets_circuits()).
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/elements/familles", [](const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
QUrlQuery query(request.query());
|
||||
const QString type = query.queryItemValue("type");
|
||||
|
||||
@@ -352,6 +379,7 @@ int main(int argc, char *argv[])
|
||||
// différents, mais un seul, appelé deux fois).
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/elements", [](const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
QUrlQuery query(request.query());
|
||||
const QString type = query.queryItemValue("type");
|
||||
const QString familleStr = query.queryItemValue("famille");
|
||||
@@ -610,6 +638,7 @@ int main(int argc, char *argv[])
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/elements/circuit/<arg>", QHttpServerRequest::Method::Patch,
|
||||
[](int idCircuit, const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
const QJsonDocument body = QJsonDocument::fromJson(request.body());
|
||||
if (!body.isObject()) {
|
||||
QJsonObject err;
|
||||
@@ -686,6 +715,7 @@ int main(int argc, char *argv[])
|
||||
// Circuits/batteries (sélection de variable côté client) à venir.
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/mesures", [](const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
QUrlQuery query(request.query());
|
||||
const QString type = query.queryItemValue("type");
|
||||
const QString idStr = query.queryItemValue("id");
|
||||
@@ -1037,6 +1067,7 @@ int main(int argc, char *argv[])
|
||||
// 90% du temps de traitement natif pour un gain marginal).
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/energie", [](const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
QUrlQuery query(request.query());
|
||||
const QString type = query.queryItemValue("type");
|
||||
const QString idStr = query.queryItemValue("id");
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user