Fix proposal preparation derivation transaction
This commit is contained in:
parent
a856451875
commit
f57682790d
2 changed files with 41 additions and 8 deletions
|
|
@ -923,18 +923,14 @@ TrainlogStatus trainlog_web_sessions_save_json(TrainlogDatabase *database,
|
||||||
if ((preparation_id == NULL || preparation_id[0] == '\0') && source_proposal != NULL) {
|
if ((preparation_id == NULL || preparation_id[0] == '\0') && source_proposal != NULL) {
|
||||||
if (sqlite3_prepare_v2(
|
if (sqlite3_prepare_v2(
|
||||||
database->connection,
|
database->connection,
|
||||||
"UPDATE session_preparations SET source_proposal_id=?1,source_payload_sha256=?2 "
|
"SELECT 1 FROM ai_session_draft_imports WHERE draft_id=?1 AND payload_sha256=?2",
|
||||||
"WHERE preparation_id=?3 AND EXISTS(SELECT 1 FROM ai_session_draft_imports i WHERE "
|
|
||||||
"i.draft_id=?1 AND i.payload_sha256=?2)",
|
|
||||||
-1,
|
-1,
|
||||||
&statement,
|
&statement,
|
||||||
NULL) != SQLITE_OK ||
|
NULL) != SQLITE_OK ||
|
||||||
sqlite3_bind_text(statement, 1, source_proposal, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
sqlite3_bind_text(statement, 1, source_proposal, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
||||||
sqlite3_bind_text(statement, 2, source_fingerprint, -1, SQLITE_TRANSIENT) !=
|
sqlite3_bind_text(statement, 2, source_fingerprint, -1, SQLITE_TRANSIENT) !=
|
||||||
SQLITE_OK ||
|
SQLITE_OK ||
|
||||||
sqlite3_bind_text(statement, 3, actual_preparation, -1, SQLITE_TRANSIENT) !=
|
sqlite3_step(statement) != SQLITE_ROW) {
|
||||||
SQLITE_OK ||
|
|
||||||
sqlite3_step(statement) != SQLITE_DONE || sqlite3_changes(database->connection) != 1) {
|
|
||||||
status = TRAINLOG_STATUS_CONFLICT;
|
status = TRAINLOG_STATUS_CONFLICT;
|
||||||
goto rollback;
|
goto rollback;
|
||||||
}
|
}
|
||||||
|
|
@ -964,7 +960,7 @@ TrainlogStatus trainlog_web_sessions_save_json(TrainlogDatabase *database,
|
||||||
statement = NULL;
|
statement = NULL;
|
||||||
} else if (sqlite3_prepare_v2(
|
} else if (sqlite3_prepare_v2(
|
||||||
database->connection,
|
database->connection,
|
||||||
"INSERT INTO session_preparations VALUES(?1,?2,?3,?3,?4,'local',NULL,NULL)",
|
"INSERT INTO session_preparations VALUES(?1,?2,?3,?3,?4,'local',?5,?6)",
|
||||||
-1,
|
-1,
|
||||||
&statement,
|
&statement,
|
||||||
NULL) != SQLITE_OK ||
|
NULL) != SQLITE_OK ||
|
||||||
|
|
@ -973,6 +969,14 @@ TrainlogStatus trainlog_web_sessions_save_json(TrainlogDatabase *database,
|
||||||
sqlite3_bind_text(statement, 2, revision, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
sqlite3_bind_text(statement, 2, revision, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
||||||
sqlite3_bind_text(statement, 3, now, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
sqlite3_bind_text(statement, 3, now, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
||||||
sqlite3_bind_text(statement, 4, editing_state, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
sqlite3_bind_text(statement, 4, editing_state, -1, SQLITE_TRANSIENT) != SQLITE_OK ||
|
||||||
|
(source_proposal == NULL
|
||||||
|
? sqlite3_bind_null(statement, 5)
|
||||||
|
: sqlite3_bind_text(statement, 5, source_proposal, -1, SQLITE_TRANSIENT)) !=
|
||||||
|
SQLITE_OK ||
|
||||||
|
(source_fingerprint == NULL
|
||||||
|
? sqlite3_bind_null(statement, 6)
|
||||||
|
: sqlite3_bind_text(statement, 6, source_fingerprint, -1, SQLITE_TRANSIENT)) !=
|
||||||
|
SQLITE_OK ||
|
||||||
sqlite3_step(statement) != SQLITE_DONE) {
|
sqlite3_step(statement) != SQLITE_DONE) {
|
||||||
status = TRAINLOG_STATUS_DATABASE_ERROR;
|
status = TRAINLOG_STATUS_DATABASE_ERROR;
|
||||||
goto rollback;
|
goto rollback;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,13 @@ static bool creation_replay_revision_and_pagination(void) {
|
||||||
"{\"title\":\"Réordonnée\",\"session_type\":\"training\","
|
"{\"title\":\"Réordonnée\",\"session_type\":\"training\","
|
||||||
"\"planned_for\":null,\"notes\":null,\"editing_state\":\"draft\","
|
"\"planned_for\":null,\"notes\":null,\"editing_state\":\"draft\","
|
||||||
"\"occurrences\":[]}";
|
"\"occurrences\":[]}";
|
||||||
|
static const char DERIVED_BODY[] =
|
||||||
|
"{\"title\":\"Derived\",\"session_type\":\"training\","
|
||||||
|
"\"planned_for\":null,\"notes\":null,\"editing_state\":\"draft\","
|
||||||
|
"\"occurrences\":[],\"source_proposal_id\":"
|
||||||
|
"\"aid_11111111-1111-4111-8111-111111111111\","
|
||||||
|
"\"source_payload_sha256\":"
|
||||||
|
"\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}";
|
||||||
TrainlogDatabase *database = NULL;
|
TrainlogDatabase *database = NULL;
|
||||||
TrainlogWebSessionsPageQuery query = {TRAINLOG_WEB_SESSION_PREPARATIONS, 0U, 1U, "échappée"};
|
TrainlogWebSessionsPageQuery query = {TRAINLOG_WEB_SESSION_PREPARATIONS, 0U, 1U, "échappée"};
|
||||||
char *created = NULL;
|
char *created = NULL;
|
||||||
|
|
@ -70,6 +77,17 @@ static bool creation_replay_revision_and_pagination(void) {
|
||||||
TRAINLOG_TRACKING_REPS,
|
TRAINLOG_TRACKING_REPS,
|
||||||
TRAINLOG_RECORDING_SETS,
|
TRAINLOG_RECORDING_SETS,
|
||||||
0U) == TRAINLOG_STATUS_OK);
|
0U) == TRAINLOG_STATUS_OK);
|
||||||
|
CHECK(sqlite3_exec(database->connection,
|
||||||
|
"INSERT INTO ai_session_drafts(draft_id,created_at,session_type,title) "
|
||||||
|
"VALUES('aid_11111111-1111-4111-8111-111111111111','2026-09-18T00:00:00Z',"
|
||||||
|
"'training','Source');"
|
||||||
|
"INSERT INTO ai_session_draft_imports VALUES("
|
||||||
|
"last_insert_rowid(),'aid_11111111-1111-4111-8111-111111111111',"
|
||||||
|
"'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"
|
||||||
|
"'2026-09-18T00:00:00Z');",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL) == SQLITE_OK);
|
||||||
CHECK(trainlog_web_sessions_save_json(database,
|
CHECK(trainlog_web_sessions_save_json(database,
|
||||||
NULL,
|
NULL,
|
||||||
"",
|
"",
|
||||||
|
|
@ -122,6 +140,17 @@ static bool creation_replay_revision_and_pagination(void) {
|
||||||
&updated_size) == TRAINLOG_STATUS_OK);
|
&updated_size) == TRAINLOG_STATUS_OK);
|
||||||
CHECK(updated_size > 0U);
|
CHECK(updated_size > 0U);
|
||||||
CHECK(scalar(database, "SELECT COUNT(*) FROM session_preparation_revisions") == 2);
|
CHECK(scalar(database, "SELECT COUNT(*) FROM session_preparation_revisions") == 2);
|
||||||
|
CHECK(trainlog_web_sessions_save_json(database,
|
||||||
|
NULL,
|
||||||
|
"",
|
||||||
|
"request-derived-1",
|
||||||
|
DERIVED_BODY,
|
||||||
|
strlen(DERIVED_BODY),
|
||||||
|
&detail,
|
||||||
|
&detail_size) == TRAINLOG_STATUS_OK);
|
||||||
|
CHECK(scalar(database,
|
||||||
|
"SELECT COUNT(*) FROM session_preparations WHERE source_proposal_id="
|
||||||
|
"'aid_11111111-1111-4111-8111-111111111111'") == 1);
|
||||||
free(detail);
|
free(detail);
|
||||||
detail = NULL;
|
detail = NULL;
|
||||||
detail_size = 0U;
|
detail_size = 0U;
|
||||||
|
|
@ -133,7 +162,7 @@ static bool creation_replay_revision_and_pagination(void) {
|
||||||
strlen(UPDATE_BODY),
|
strlen(UPDATE_BODY),
|
||||||
&detail,
|
&detail,
|
||||||
&detail_size) == TRAINLOG_STATUS_CONFLICT);
|
&detail_size) == TRAINLOG_STATUS_CONFLICT);
|
||||||
CHECK(scalar(database, "SELECT COUNT(*) FROM session_preparation_revisions") == 2);
|
CHECK(scalar(database, "SELECT COUNT(*) FROM session_preparation_revisions") == 3);
|
||||||
free(created);
|
free(created);
|
||||||
free(replayed);
|
free(replayed);
|
||||||
free(detail);
|
free(detail);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue