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)
|
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
|
add_executable(shipheart_api
|
||||||
main.cpp
|
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
|
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 <QPair>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "_version.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// shipheart_api - Phase 4 : première tranche verticale, domaine "circuit"
|
// 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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
qInfo() << "shipheart_api version" << VERSION;
|
||||||
|
|
||||||
// --- Connexion MariaDB locale ---
|
// --- Connexion MariaDB locale ---
|
||||||
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
|
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
|
||||||
|
|||||||
Binary file not shown.
@@ -164,6 +164,32 @@ static QHttpServerResponse withCors(QHttpServerResponse &&resp)
|
|||||||
return std::move(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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
@@ -196,6 +222,7 @@ int main(int argc, char *argv[])
|
|||||||
// requêtes onglets de mise_a_jour_onglets_circuits()).
|
// requêtes onglets de mise_a_jour_onglets_circuits()).
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
server.route("/elements/familles", [](const QHttpServerRequest &request) {
|
server.route("/elements/familles", [](const QHttpServerRequest &request) {
|
||||||
|
assurer_connexion_bdd();
|
||||||
QUrlQuery query(request.query());
|
QUrlQuery query(request.query());
|
||||||
const QString type = query.queryItemValue("type");
|
const QString type = query.queryItemValue("type");
|
||||||
|
|
||||||
@@ -352,6 +379,7 @@ int main(int argc, char *argv[])
|
|||||||
// différents, mais un seul, appelé deux fois).
|
// différents, mais un seul, appelé deux fois).
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
server.route("/elements", [](const QHttpServerRequest &request) {
|
server.route("/elements", [](const QHttpServerRequest &request) {
|
||||||
|
assurer_connexion_bdd();
|
||||||
QUrlQuery query(request.query());
|
QUrlQuery query(request.query());
|
||||||
const QString type = query.queryItemValue("type");
|
const QString type = query.queryItemValue("type");
|
||||||
const QString familleStr = query.queryItemValue("famille");
|
const QString familleStr = query.queryItemValue("famille");
|
||||||
@@ -610,6 +638,7 @@ int main(int argc, char *argv[])
|
|||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
server.route("/elements/circuit/<arg>", QHttpServerRequest::Method::Patch,
|
server.route("/elements/circuit/<arg>", QHttpServerRequest::Method::Patch,
|
||||||
[](int idCircuit, const QHttpServerRequest &request) {
|
[](int idCircuit, const QHttpServerRequest &request) {
|
||||||
|
assurer_connexion_bdd();
|
||||||
const QJsonDocument body = QJsonDocument::fromJson(request.body());
|
const QJsonDocument body = QJsonDocument::fromJson(request.body());
|
||||||
if (!body.isObject()) {
|
if (!body.isObject()) {
|
||||||
QJsonObject err;
|
QJsonObject err;
|
||||||
@@ -686,6 +715,7 @@ int main(int argc, char *argv[])
|
|||||||
// Circuits/batteries (sélection de variable côté client) à venir.
|
// Circuits/batteries (sélection de variable côté client) à venir.
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
server.route("/mesures", [](const QHttpServerRequest &request) {
|
server.route("/mesures", [](const QHttpServerRequest &request) {
|
||||||
|
assurer_connexion_bdd();
|
||||||
QUrlQuery query(request.query());
|
QUrlQuery query(request.query());
|
||||||
const QString type = query.queryItemValue("type");
|
const QString type = query.queryItemValue("type");
|
||||||
const QString idStr = query.queryItemValue("id");
|
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).
|
// 90% du temps de traitement natif pour un gain marginal).
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
server.route("/energie", [](const QHttpServerRequest &request) {
|
server.route("/energie", [](const QHttpServerRequest &request) {
|
||||||
|
assurer_connexion_bdd();
|
||||||
QUrlQuery query(request.query());
|
QUrlQuery query(request.query());
|
||||||
const QString type = query.queryItemValue("type");
|
const QString type = query.queryItemValue("type");
|
||||||
const QString idStr = query.queryItemValue("id");
|
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