From 9a75af81469d0f81dd4acaa5dbc911bf29e71bb8 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 6 Feb 2022 03:51:25 +0000 Subject: [PATCH] Don't add a message until its previous message exists. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3830 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- src/ssb.db.c | 77 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/src/ssb.db.c b/src/ssb.db.c index b1faf30e..1257907f 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -63,6 +63,31 @@ void tf_ssb_db_init(tf_ssb_t* ssb) NULL, NULL, NULL); } +static bool _tf_ssb_db_previous_message_exists(sqlite3* db, const char* author, int64_t sequence, const char* previous) +{ + bool exists = false; + if (sequence == 1) + { + exists = true; + } + else + { + sqlite3_stmt* statement; + if (sqlite3_prepare(db, "SELECT COUNT(*) FROM messages WHERE author = ?1 AND sequence = ?2 AND id = ?3", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, author, -1, NULL) == SQLITE_OK && + sqlite3_bind_int64(statement, 2, sequence - 1) == SQLITE_OK && + sqlite3_bind_text(statement, 3, previous, -1, NULL) == SQLITE_OK && + sqlite3_step(statement) == SQLITE_ROW) + { + exists = sqlite3_column_int(statement, 0) != 0; + } + sqlite3_finalize(statement); + } + } + return exists; +} + bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, JSValue val, const char* signature, bool sequence_before_author) { bool stored = false; @@ -84,40 +109,48 @@ bool tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, sqlite3* db = tf_ssb_get_db(ssb); sqlite3_stmt* statement; int64_t last_row_id = -1; - const char* query = "INSERT INTO messages (id, previous, author, sequence, timestamp, content, hash, signature, sequence_before_author) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING"; - if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) + + if (_tf_ssb_db_previous_message_exists(db, author, sequence, previous)) { - if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && - (previous ? sqlite3_bind_text(statement, 2, previous, -1, NULL) : sqlite3_bind_null(statement, 2)) == SQLITE_OK && - sqlite3_bind_text(statement, 3, author, -1, NULL) == SQLITE_OK && - sqlite3_bind_int64(statement, 4, sequence) == SQLITE_OK && - sqlite3_bind_int64(statement, 5, timestamp) == SQLITE_OK && - sqlite3_bind_text(statement, 6, contentstr, content_len, NULL) == SQLITE_OK && - sqlite3_bind_text(statement, 7, "sha256", 6, NULL) == SQLITE_OK && - sqlite3_bind_text(statement, 8, signature, -1, NULL) == SQLITE_OK && - sqlite3_bind_int(statement, 9, sequence_before_author) == SQLITE_OK) + const char* query = "INSERT INTO messages (id, previous, author, sequence, timestamp, content, hash, signature, sequence_before_author) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING"; + if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { - int r = sqlite3_step(statement); - if (r != SQLITE_DONE) + if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && + (previous ? sqlite3_bind_text(statement, 2, previous, -1, NULL) : sqlite3_bind_null(statement, 2)) == SQLITE_OK && + sqlite3_bind_text(statement, 3, author, -1, NULL) == SQLITE_OK && + sqlite3_bind_int64(statement, 4, sequence) == SQLITE_OK && + sqlite3_bind_int64(statement, 5, timestamp) == SQLITE_OK && + sqlite3_bind_text(statement, 6, contentstr, content_len, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 7, "sha256", 6, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 8, signature, -1, NULL) == SQLITE_OK && + sqlite3_bind_int(statement, 9, sequence_before_author) == SQLITE_OK) { - printf("%s\n", sqlite3_errmsg(db)); - } - stored = r == SQLITE_DONE && sqlite3_changes(db) != 0; - if (stored) - { - last_row_id = sqlite3_last_insert_rowid(db); + int r = sqlite3_step(statement); + if (r != SQLITE_DONE) + { + printf("%s\n", sqlite3_errmsg(db)); + } + stored = r == SQLITE_DONE && sqlite3_changes(db) != 0; + if (stored) + { + last_row_id = sqlite3_last_insert_rowid(db); + } } + sqlite3_finalize(statement); + } + else + { + printf("prepare failed: %s\n", sqlite3_errmsg(db)); } - sqlite3_finalize(statement); } else { - printf("prepare failed: %s\n", sqlite3_errmsg(db)); + printf("Previous message doesn't exist.\n"); } if (last_row_id != -1) { - query = "INSERT INTO blob_wants (id) SELECT DISTINCT json.value FROM messages, json_tree(messages.content) AS json LEFT OUTER JOIN blobs ON json.value = blobs.id WHERE messages.rowid = ?1 AND json.value LIKE '&%%.sha256' AND length(json.value) = ?2 AND blobs.content IS NULL ON CONFLICT DO NOTHING RETURNING id"; + const char* query = "INSERT INTO blob_wants (id) SELECT DISTINCT json.value FROM messages, json_tree(messages.content) AS json LEFT OUTER JOIN blobs ON json.value = blobs.id WHERE messages.rowid = ?1 AND json.value LIKE '&%%.sha256' AND length(json.value) = ?2 AND blobs.content IS NULL ON CONFLICT DO NOTHING RETURNING id"; if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) { if (sqlite3_bind_int64(statement, 1, last_row_id) == SQLITE_OK &&