ssb: Fix and test the messages_stats trigger.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m59s
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m59s
This commit is contained in:
parent
3f4738e593
commit
8104f6f228
11
src/ssb.db.c
11
src/ssb.db.c
@ -150,9 +150,16 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
|
|||||||
"CREATE TRIGGER IF NOT EXISTS messages_ai_stats AFTER INSERT ON messages BEGIN INSERT INTO messages_stats(author, max_sequence, max_timestamp) VALUES (new.author, "
|
"CREATE TRIGGER IF NOT EXISTS messages_ai_stats AFTER INSERT ON messages BEGIN INSERT INTO messages_stats(author, max_sequence, max_timestamp) VALUES (new.author, "
|
||||||
"new.sequence, new.timestamp) ON CONFLICT DO UPDATE SET max_sequence = MAX(max_sequence, new.sequence), max_timestamp = MAX(max_timestamp, "
|
"new.sequence, new.timestamp) ON CONFLICT DO UPDATE SET max_sequence = MAX(max_sequence, new.sequence), max_timestamp = MAX(max_timestamp, "
|
||||||
"new.timestamp); END");
|
"new.timestamp); END");
|
||||||
|
_tf_ssb_db_exec(db, "DROP TRIGGER IF EXISTS messages_ad_stats");
|
||||||
_tf_ssb_db_exec(db,
|
_tf_ssb_db_exec(db,
|
||||||
"CREATE TRIGGER IF NOT EXISTS messages_ad_stats AFTER DELETE ON messages BEGIN UPDATE messages_stats SET max_sequence = (SELECT MAX(messages.sequence) FROM messages WHERE "
|
"CREATE TRIGGER IF NOT EXISTS messages_ad_stats AFTER DELETE ON messages BEGIN "
|
||||||
"messages.author = old.author), max_timestamp = (SELECT MAX(messages.timestamp) FROM messages WHERE messages.author = old.author); END");
|
"UPDATE messages_stats SET max_sequence = updated.sequence, max_timestamp = updated.timestamp "
|
||||||
|
"FROM ("
|
||||||
|
" SELECT COALESCE(MAX(messages.sequence), 0) AS sequence, COALESCE(MAX(messages.timestamp), 0) AS timestamp "
|
||||||
|
" FROM messages WHERE messages.author = old.author) AS updated "
|
||||||
|
"WHERE messages_stats.author = old.author; "
|
||||||
|
"DELETE FROM messages_stats WHERE messages_stats.author = old.author AND messages_stats.max_sequence = 0; "
|
||||||
|
"END");
|
||||||
|
|
||||||
if (_tf_ssb_db_has_rows(db, "SELECT name FROM pragma_table_info('messages') WHERE name = 'content' AND type == 'TEXT'"))
|
if (_tf_ssb_db_has_rows(db, "SELECT name FROM pragma_table_info('messages') WHERE name = 'content' AND type == 'TEXT'"))
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include "sodium/crypto_sign.h"
|
#include "sodium/crypto_sign.h"
|
||||||
|
|
||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
@ -659,7 +661,7 @@ void tf_ssb_test_following(const tf_test_options_t* options)
|
|||||||
|
|
||||||
void tf_ssb_test_bench(const tf_test_options_t* options)
|
void tf_ssb_test_bench(const tf_test_options_t* options)
|
||||||
{
|
{
|
||||||
tf_printf("Testing following.\n");
|
tf_printf("Testing bench.\n");
|
||||||
|
|
||||||
uv_loop_t loop = { 0 };
|
uv_loop_t loop = { 0 };
|
||||||
uv_loop_init(&loop);
|
uv_loop_init(&loop);
|
||||||
@ -1393,4 +1395,87 @@ void tf_ssb_test_invite(const tf_test_options_t* options)
|
|||||||
uv_loop_close(&loop);
|
uv_loop_close(&loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tf_ssb_test_triggers(const tf_test_options_t* options)
|
||||||
|
{
|
||||||
|
tf_printf("Testing triggers.\n");
|
||||||
|
|
||||||
|
uv_loop_t loop = { 0 };
|
||||||
|
uv_loop_init(&loop);
|
||||||
|
|
||||||
|
tf_trace_t* trace = tf_trace_create();
|
||||||
|
|
||||||
|
unlink("out/test_db0.sqlite");
|
||||||
|
tf_ssb_t* ssb0 = tf_ssb_create(&loop, NULL, "file:out/test_db0.sqlite", NULL);
|
||||||
|
tf_ssb_set_trace(ssb0, trace);
|
||||||
|
tf_ssb_generate_keys(ssb0);
|
||||||
|
|
||||||
|
char id0[k_id_base64_len] = { 0 };
|
||||||
|
tf_ssb_whoami(ssb0, id0, sizeof(id0));
|
||||||
|
|
||||||
|
uint8_t priv0[512];
|
||||||
|
tf_ssb_get_private_key(ssb0, priv0, sizeof(priv0));
|
||||||
|
|
||||||
|
struct timespec start_time = { 0 };
|
||||||
|
struct timespec end_time = { 0 };
|
||||||
|
clock_gettime(CLOCK_REALTIME, &start_time);
|
||||||
|
const int k_messages = 5;
|
||||||
|
JSValue obj = JS_NewObject(tf_ssb_get_context(ssb0));
|
||||||
|
JS_SetPropertyStr(tf_ssb_get_context(ssb0), obj, "type", JS_NewString(tf_ssb_get_context(ssb0), "post"));
|
||||||
|
JS_SetPropertyStr(tf_ssb_get_context(ssb0), obj, "text", JS_NewString(tf_ssb_get_context(ssb0), "Hello, world!"));
|
||||||
|
for (int i = 0; i < k_messages; i++)
|
||||||
|
{
|
||||||
|
bool stored = false;
|
||||||
|
JSValue signed_message = tf_ssb_sign_message(ssb0, id0, priv0, obj, NULL, 0);
|
||||||
|
tf_ssb_verify_strip_and_store_message(ssb0, signed_message, _message_stored, &stored);
|
||||||
|
JS_FreeValue(tf_ssb_get_context(ssb0), signed_message);
|
||||||
|
_wait_stored(ssb0, &stored);
|
||||||
|
}
|
||||||
|
JS_FreeValue(tf_ssb_get_context(ssb0), obj);
|
||||||
|
clock_gettime(CLOCK_REALTIME, &end_time);
|
||||||
|
tf_printf("insert = %f seconds\n", (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec - start_time.tv_nsec) / 1e9);
|
||||||
|
|
||||||
|
int64_t max_sequence = 0;
|
||||||
|
tf_ssb_db_get_latest_message_by_author(ssb0, id0, &max_sequence, NULL, 0);
|
||||||
|
tf_printf("max_sequence=%" PRId64 "\n", max_sequence);
|
||||||
|
assert(max_sequence == 5);
|
||||||
|
|
||||||
|
sqlite3* db = tf_ssb_acquire_db_writer(ssb0);
|
||||||
|
sqlite3_exec(db, "DELETE FROM messages WHERE sequence = 5", NULL, NULL, NULL);
|
||||||
|
tf_ssb_release_db_writer(ssb0, db);
|
||||||
|
|
||||||
|
max_sequence = 0;
|
||||||
|
tf_ssb_db_get_latest_message_by_author(ssb0, id0, &max_sequence, NULL, 0);
|
||||||
|
tf_printf("max_sequence=%" PRId64 "\n", max_sequence);
|
||||||
|
assert(max_sequence == 4);
|
||||||
|
|
||||||
|
tf_ssb_acquire_db_writer(ssb0);
|
||||||
|
sqlite3_exec(db, "DELETE FROM messages", NULL, NULL, NULL);
|
||||||
|
tf_ssb_release_db_writer(ssb0, db);
|
||||||
|
|
||||||
|
max_sequence = 0;
|
||||||
|
tf_ssb_db_get_latest_message_by_author(ssb0, id0, &max_sequence, NULL, 0);
|
||||||
|
tf_printf("max_sequence=%" PRId64 "\n", max_sequence);
|
||||||
|
assert(max_sequence == 0);
|
||||||
|
|
||||||
|
uv_run(&loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
char* trace_data = tf_trace_export(trace);
|
||||||
|
if (trace_data)
|
||||||
|
{
|
||||||
|
FILE* file = fopen("out/trace.json", "wb");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
fwrite(trace_data, 1, strlen(trace_data), file);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
tf_free(trace_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
tf_ssb_destroy(ssb0);
|
||||||
|
|
||||||
|
tf_trace_destroy(trace);
|
||||||
|
|
||||||
|
uv_loop_close(&loop);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,4 +83,10 @@ void tf_ssb_test_connect_str(const tf_test_options_t* options);
|
|||||||
*/
|
*/
|
||||||
void tf_ssb_test_invite(const tf_test_options_t* options);
|
void tf_ssb_test_invite(const tf_test_options_t* options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Test triggers.
|
||||||
|
** @param options The test options.
|
||||||
|
*/
|
||||||
|
void tf_ssb_test_triggers(const tf_test_options_t* options);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1078,6 +1078,7 @@ void tf_tests(const tf_test_options_t* options)
|
|||||||
_tf_test_run(options, "replicate", tf_ssb_test_replicate, false);
|
_tf_test_run(options, "replicate", tf_ssb_test_replicate, false);
|
||||||
_tf_test_run(options, "connect_str", tf_ssb_test_connect_str, false);
|
_tf_test_run(options, "connect_str", tf_ssb_test_connect_str, false);
|
||||||
_tf_test_run(options, "invite", tf_ssb_test_invite, false);
|
_tf_test_run(options, "invite", tf_ssb_test_invite, false);
|
||||||
|
_tf_test_run(options, "triggers", tf_ssb_test_triggers, false);
|
||||||
tf_printf("Tests completed.\n");
|
tf_printf("Tests completed.\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user