diff --git a/src/ssb.c b/src/ssb.c index 3b7c42bc3..6946086de 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -4222,63 +4222,19 @@ typedef struct _update_settings_t char room_name[1024]; } update_settings_t; -static bool _get_global_setting_string(tf_ssb_t* ssb, const char* name, char* out_value, size_t size) -{ - bool result = false; - sqlite3* db = tf_ssb_acquire_db_reader(ssb); - sqlite3_stmt* statement; - if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) - { - if (sqlite3_step(statement) == SQLITE_ROW) - { - snprintf(out_value, size, "%s", sqlite3_column_text(statement, 0)); - result = true; - } - } - sqlite3_finalize(statement); - } - else - { - tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); - } - tf_ssb_release_db_reader(ssb, db); - return result; -} - -static bool _get_global_setting_bool(tf_ssb_t* ssb, const char* name, bool default_value) -{ - bool result = default_value; - sqlite3* db = tf_ssb_acquire_db_reader(ssb); - sqlite3_stmt* statement; - if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) - { - if (sqlite3_step(statement) == SQLITE_ROW) - { - result = sqlite3_column_int(statement, 0) != 0; - } - } - sqlite3_finalize(statement); - } - else - { - tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); - } - tf_ssb_release_db_reader(ssb, db); - return result; -} - static void _tf_ssb_update_settings_work(tf_ssb_t* ssb, void* user_data) { update_settings_t* update = user_data; - update->is_room = _get_global_setting_bool(ssb, "room", true); - update->is_replicator = _get_global_setting_bool(ssb, "replicator", true); - update->is_peer_exchange = _get_global_setting_bool(ssb, "peer_exchange", true); - _get_global_setting_string(ssb, "room_name", update->room_name, sizeof(update->room_name)); - _get_global_setting_string(ssb, "seeds_host", update->seeds_host, sizeof(update->seeds_host)); + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + update->is_room = true; + update->is_replicator = true; + update->is_peer_exchange = true; + tf_ssb_db_get_global_setting_bool(db, "room", &update->is_room); + tf_ssb_db_get_global_setting_bool(db, "replicator", &update->is_replicator); + tf_ssb_db_get_global_setting_bool(db, "peer_exchange", &update->is_peer_exchange); + tf_ssb_db_get_global_setting_string(db, "room_name", update->room_name, sizeof(update->room_name)); + tf_ssb_db_get_global_setting_string(db, "seeds_host", update->seeds_host, sizeof(update->seeds_host)); + tf_ssb_release_db_reader(ssb, db); } static void _tf_ssb_update_settings_after_work(tf_ssb_t* ssb, int result, void* user_data) diff --git a/src/ssb.db.c b/src/ssb.db.c index 0f670c2a9..cac4a60e3 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -1681,34 +1681,13 @@ bool tf_ssb_db_set_account_password(uv_loop_t* loop, sqlite3* db, JSContext* con return result; } -static bool _tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool default_value) -{ - bool result = default_value; - sqlite3_stmt* statement; - if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) - { - if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL) - { - result = sqlite3_column_int(statement, 0) != 0; - } - } - sqlite3_finalize(statement); - } - else - { - tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); - } - return result; -} - bool tf_ssb_db_register_account(uv_loop_t* loop, sqlite3* db, JSContext* context, const char* name, const char* password) { bool result = false; JSValue users_array = JS_UNDEFINED; - bool registration_allowed = _tf_ssb_db_get_global_setting_bool(db, "account_registration", true); + bool registration_allowed = true; + tf_ssb_db_get_global_setting_bool(db, "account_registration", ®istration_allowed); if (registration_allowed) { sqlite3_stmt* statement = NULL; @@ -2030,3 +2009,72 @@ bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, sqlite3* db, const char* id, c } return has_permission; } + +bool tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool* out_value) +{ + bool result = false; + sqlite3_stmt* statement; + if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) == SQLITE_ROW) + { + *out_value = sqlite3_column_int(statement, 0) != 0; + result = true; + } + } + sqlite3_finalize(statement); + } + else + { + tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); + } + return result; +} + +bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t* out_value) +{ + bool result = false; + sqlite3_stmt* statement; + if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL) + { + *out_value = sqlite3_column_int64(statement, 0); + result = true; + } + } + sqlite3_finalize(statement); + } + else + { + tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); + } + return result; +} + +bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size) +{ + bool result = false; + sqlite3_stmt* statement; + if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) == SQLITE_ROW) + { + snprintf(out_value, size, "%s", sqlite3_column_text(statement, 0)); + result = true; + } + } + sqlite3_finalize(statement); + } + else + { + tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); + } + return result; +} diff --git a/src/ssb.db.h b/src/ssb.db.h index 53045bc35..f47775d22 100644 --- a/src/ssb.db.h +++ b/src/ssb.db.h @@ -455,6 +455,34 @@ bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id); */ bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, sqlite3* db, const char* id, const char* permission); +/** +** Get a boolean global setting value. +** @param db The database. +** @param name The setting name. +** @param out_value Populated with the value. +** @return true if the setting was found. +*/ +bool tf_ssb_db_get_global_setting_bool(sqlite3* db, const char* name, bool* out_value); + +/** +** Get an int64_t global setting value. +** @param db The database. +** @param name The setting name. +** @param out_value Populated with the value. +** @return true if the setting was found. +*/ +bool tf_ssb_db_get_global_setting_int64(sqlite3* db, const char* name, int64_t* out_value); + +/** +** Get a string global setting value. +** @param db The database. +** @param name The setting name. +** @param out_value Populated with the value. +** @param size The size of the out_value buffer. +** @return true if the setting was found. +*/ +bool tf_ssb_db_get_global_setting_string(sqlite3* db, const char* name, char* out_value, size_t size); + /** ** An SQLite authorizer callback. See https://www.sqlite.org/c3ref/set_authorizer.html for use. ** @param user_data User data registered with the authorizer. diff --git a/src/ssb.rpc.c b/src/ssb.rpc.c index f549db29d..817017ba9 100644 --- a/src/ssb.rpc.c +++ b/src/ssb.rpc.c @@ -20,30 +20,6 @@ static void _tf_ssb_rpc_send_peers_exchange(tf_ssb_connection_t* connection); static void _tf_ssb_rpc_start_delete_blobs(tf_ssb_t* ssb, int delay_ms); static void _tf_ssb_rpc_start_delete_feeds(tf_ssb_t* ssb, int delay_ms); -static int64_t _get_global_setting_int64(tf_ssb_t* ssb, const char* name, int64_t default_value) -{ - int64_t result = default_value; - sqlite3* db = tf_ssb_acquire_db_reader(ssb); - sqlite3_stmt* statement; - if (sqlite3_prepare(db, "SELECT json_extract(value, '$.' || ?) FROM properties WHERE id = 'core' AND key = 'settings'", -1, &statement, NULL) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK) - { - if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_type(statement, 0) != SQLITE_NULL) - { - result = sqlite3_column_int64(statement, 0); - } - } - sqlite3_finalize(statement); - } - else - { - tf_printf("prepare failed: %s\n", sqlite3_errmsg(db)); - } - tf_ssb_release_db_reader(ssb, db); - return result; -} - static bool _get_global_setting_bool(tf_ssb_t* ssb, const char* name, bool default_value) { bool result = default_value; @@ -243,7 +219,10 @@ static void _tf_ssb_request_blob_wants_work(tf_ssb_connection_t* connection, voi blob_wants_work_t* work = user_data; tf_ssb_blob_wants_t* blob_wants = tf_ssb_connection_get_blob_wants_state(connection); tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection); - int64_t age = _get_global_setting_int64(ssb, "blob_fetch_age_seconds", -1); + int64_t age = -1; + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + tf_ssb_db_get_global_setting_int64(db, "blob_fetch_age_seconds", &age); + tf_ssb_release_db_reader(ssb, db); int64_t timestamp = -1; if (age == 0) { @@ -256,7 +235,7 @@ static void _tf_ssb_request_blob_wants_work(tf_ssb_connection_t* connection, voi timestamp = now - age * 1000ULL; } - sqlite3* db = tf_ssb_acquire_db_reader(ssb); + db = tf_ssb_acquire_db_reader(ssb); sqlite3_stmt* statement; if (sqlite3_prepare(db, "SELECT id FROM blob_wants_view WHERE id > ? AND timestamp > ? ORDER BY id LIMIT ?", -1, &statement, NULL) == SQLITE_OK) { @@ -1003,7 +982,10 @@ static void _tf_ssb_rpc_ebt_replicate_send_clock_work(tf_ssb_connection_t* conne tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection); JSValue full_clock = JS_NewObject(context); - int64_t depth = _get_global_setting_int64(ssb, "replication_hops", 2); + int64_t depth = 2; + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + tf_ssb_db_get_global_setting_int64(db, "replication_hops", &depth); + tf_ssb_release_db_reader(ssb, db); /* Ask for every identity we know is being followed from local accounts. */ const char** visible = tf_ssb_db_get_all_visible_identities(ssb, depth); @@ -1400,14 +1382,17 @@ typedef struct _delete_t static void _tf_ssb_rpc_delete_blobs_work(tf_ssb_t* ssb, void* user_data) { delete_t* delete = user_data; - int64_t age = _get_global_setting_int64(ssb, "blob_expire_age_seconds", -1); + int64_t age = -1; + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + tf_ssb_db_get_global_setting_int64(db, "blob_expire_age_seconds", &age); + tf_ssb_release_db_reader(ssb, db); if (age <= 0) { _tf_ssb_rpc_checkpoint(ssb); return; } int64_t start_ns = uv_hrtime(); - sqlite3* db = tf_ssb_acquire_db_writer(ssb); + db = tf_ssb_acquire_db_writer(ssb); sqlite3_stmt* statement; int64_t now = (int64_t)time(NULL) * 1000ULL; int64_t timestamp = now - age * 1000ULL; @@ -1474,7 +1459,10 @@ static void _tf_ssb_rpc_delete_feeds_work(tf_ssb_t* ssb, void* user_data) return; } int64_t start_ns = uv_hrtime(); - int replication_hops = (int)_get_global_setting_int64(ssb, "replication_hops", 2); + int64_t replication_hops = 2; + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + tf_ssb_db_get_global_setting_int64(db, "replication_hops", &replication_hops); + tf_ssb_release_db_reader(ssb, db); const char** identities = tf_ssb_db_get_all_visible_identities(ssb, replication_hops); JSMallocFunctions funcs = { 0 }; @@ -1493,7 +1481,7 @@ static void _tf_ssb_rpc_delete_feeds_work(tf_ssb_t* ssb, void* user_data) JS_FreeValue(context, json); JS_FreeValue(context, array); - sqlite3* db = tf_ssb_acquire_db_writer(ssb); + db = tf_ssb_acquire_db_writer(ssb); sqlite3_stmt* statement; if (sqlite3_prepare(db, "DELETE FROM messages WHERE author IN ("