forked from cory/tildefriends
Add missing .clang-format, and fix some spaces that slipped through.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4856 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
1958623a7a
commit
d0e11bc68b
20
.clang-format
Normal file
20
.clang-format
Normal file
@ -0,0 +1,20 @@
|
||||
# Format Style Options - Created with Clang Power Tools
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: DontAlign
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Allman
|
||||
ColumnLimit: 180
|
||||
ContinuationIndentWidth: 4
|
||||
IndentCaseBlocks: true
|
||||
IndentWidth: 4
|
||||
MaxEmptyLinesToKeep: 1
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: false
|
||||
SortIncludes: false
|
||||
TabWidth: 4
|
||||
UseTab: Always
|
||||
...
|
@ -105,7 +105,7 @@ static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc
|
||||
size_t length;
|
||||
const char* keyString = JS_ToCStringLen(context, &length, argv[0]);
|
||||
if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, length, NULL) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_ROW)
|
||||
sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
entry = JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0));
|
||||
}
|
||||
@ -132,7 +132,7 @@ static JSValue _database_set(JSContext* context, JSValueConst this_val, int argc
|
||||
size_t valueLength;
|
||||
const char* valueString = JS_ToCStringLen(context, &valueLength, argv[1]);
|
||||
if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, keyLength, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, valueString, valueLength, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 3, valueString, valueLength, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_OK)
|
||||
{
|
||||
}
|
||||
JS_FreeCString(context, keyString);
|
||||
@ -162,7 +162,7 @@ static JSValue _database_exchange(JSContext* context, JSValueConst this_val, int
|
||||
const char* key = JS_ToCStringLen(context, &key_length, argv[0]);
|
||||
const char* set = JS_ToCStringLen(context, &set_length, argv[2]);
|
||||
if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, key, key_length, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, set, set_length, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_DONE)
|
||||
sqlite3_bind_text(statement, 3, set, set_length, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_DONE)
|
||||
{
|
||||
exchanged = sqlite3_changes(db) != 0 ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
@ -180,8 +180,8 @@ static JSValue _database_exchange(JSContext* context, JSValueConst this_val, int
|
||||
const char* expected = JS_ToCStringLen(context, &expected_length, argv[1]);
|
||||
const char* set = JS_ToCStringLen(context, &set_length, argv[2]);
|
||||
if (sqlite3_bind_text(statement, 1, set, set_length, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, database->id, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, key, key_length, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 4, expected, expected_length, NULL) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_DONE)
|
||||
sqlite3_bind_text(statement, 3, key, key_length, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 4, expected, expected_length, NULL) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_DONE)
|
||||
{
|
||||
exchanged = sqlite3_changes(db) != 0 ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
@ -208,7 +208,7 @@ static JSValue _database_remove(JSContext* context, JSValueConst this_val, int a
|
||||
size_t keyLength;
|
||||
const char* keyString = JS_ToCStringLen(context, &keyLength, argv[0]);
|
||||
if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, keyLength, NULL) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_OK)
|
||||
sqlite3_step(statement) == SQLITE_OK)
|
||||
{
|
||||
}
|
||||
JS_FreeCString(context, keyString);
|
||||
@ -236,8 +236,7 @@ static JSValue _database_get_all(JSContext* context, JSValueConst this_val, int
|
||||
uint32_t index = 0;
|
||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
JS_SetPropertyUint32(
|
||||
context, array, index++, JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)));
|
||||
JS_SetPropertyUint32(context, array, index++, JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)));
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
@ -265,7 +264,7 @@ static JSValue _database_get_like(JSContext* context, JSValueConst this_val, int
|
||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
JS_SetPropertyStr(context, result, (const char*)sqlite3_column_text(statement, 0),
|
||||
JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1)));
|
||||
JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1)));
|
||||
}
|
||||
}
|
||||
JS_FreeCString(context, pattern);
|
||||
@ -292,8 +291,7 @@ static JSValue _databases_list(JSContext* context, JSValueConst this_val, int ar
|
||||
uint32_t index = 0;
|
||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
JS_SetPropertyUint32(
|
||||
context, array, index++, JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)));
|
||||
JS_SetPropertyUint32(context, array, index++, JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)));
|
||||
}
|
||||
}
|
||||
JS_FreeCString(context, pattern);
|
||||
|
14
src/http.c
14
src/http.c
@ -132,8 +132,7 @@ static bool _http_find_handler(tf_http_t* http, const char* path, tf_http_callba
|
||||
for (int i = 0; i < http->handlers_count; i++)
|
||||
{
|
||||
if (!http->handlers[i].pattern || !*http->handlers[i].pattern || strcmp(path, http->handlers[i].pattern) == 0 ||
|
||||
(*http->handlers[i].pattern && strncmp(path, http->handlers[i].pattern, strlen(http->handlers[i].pattern)) == 0 &&
|
||||
path[strlen(http->handlers[i].pattern) - 1] == '/'))
|
||||
(*http->handlers[i].pattern && strncmp(path, http->handlers[i].pattern, strlen(http->handlers[i].pattern)) == 0 && path[strlen(http->handlers[i].pattern) - 1] == '/'))
|
||||
{
|
||||
*out_callback = http->handlers[i].callback;
|
||||
*out_trace_name = http->handlers[i].pattern;
|
||||
@ -301,8 +300,7 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d
|
||||
size_t total_length = mask_start + 4 + length;
|
||||
if (connection->body_length >= total_length)
|
||||
{
|
||||
uint32_t mask =
|
||||
(uint32_t)p[mask_start + 0] | (uint32_t)p[mask_start + 1] << 8 | (uint32_t)p[mask_start + 2] << 16 | (uint32_t)p[mask_start + 3] << 24;
|
||||
uint32_t mask = (uint32_t)p[mask_start + 0] | (uint32_t)p[mask_start + 1] << 8 | (uint32_t)p[mask_start + 2] << 16 | (uint32_t)p[mask_start + 3] << 24;
|
||||
uint8_t* message = p + mask_start + 4;
|
||||
_http_websocket_mask_in_place(message, mask, length);
|
||||
|
||||
@ -324,8 +322,7 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d
|
||||
{
|
||||
tf_trace_begin(connection->http->trace, connection->trace_name ? connection->trace_name : "websocket");
|
||||
connection->request->on_message(connection->request, connection->fragment_length ? connection->fragment_op_code : op_code,
|
||||
connection->fragment_length ? connection->fragment : message,
|
||||
connection->fragment_length ? connection->fragment_length : length);
|
||||
connection->fragment_length ? connection->fragment : message, connection->fragment_length ? connection->fragment_length : length);
|
||||
tf_trace_end(connection->http->trace);
|
||||
}
|
||||
connection->fragment_length = 0;
|
||||
@ -397,7 +394,7 @@ static size_t _http_on_read_plain_internal(tf_http_connection_t* connection, con
|
||||
size_t header_count = sizeof(connection->headers) / sizeof(*connection->headers);
|
||||
|
||||
int parse_result = phr_parse_request(connection->headers_buffer, connection->headers_buffer_length, &method, &method_length, &path, &path_length,
|
||||
&connection->minor_version, connection->headers, &header_count, connection->parsed_length);
|
||||
&connection->minor_version, connection->headers, &header_count, connection->parsed_length);
|
||||
connection->parsed_length = connection->headers_buffer_length;
|
||||
if (parse_result > 0)
|
||||
{
|
||||
@ -445,8 +442,7 @@ static size_t _http_on_read_plain_internal(tf_http_connection_t* connection, con
|
||||
connection->body = tf_realloc(connection->body, connection->content_length);
|
||||
}
|
||||
|
||||
if (!_http_find_handler(connection->http, connection->path, &connection->callback, &connection->trace_name, &connection->user_data) ||
|
||||
!connection->callback)
|
||||
if (!_http_find_handler(connection->http, connection->path, &connection->callback, &connection->trace_name, &connection->user_data) || !connection->callback)
|
||||
{
|
||||
connection->callback = _http_builtin_404_handler;
|
||||
connection->trace_name = "404";
|
||||
|
@ -305,8 +305,7 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va
|
||||
headers[headers_count * 2 + 1] = key;
|
||||
headers_count++;
|
||||
|
||||
bool send_version =
|
||||
!tf_http_request_get_header(request, "sec-websocket-version") || strcmp(tf_http_request_get_header(request, "sec-websocket-version"), "13") != 0;
|
||||
bool send_version = !tf_http_request_get_header(request, "sec-websocket-version") || strcmp(tf_http_request_get_header(request, "sec-websocket-version"), "13") != 0;
|
||||
if (send_version)
|
||||
{
|
||||
headers[headers_count * 2 + 0] = "Sec-WebSocket-Accept";
|
||||
@ -697,8 +696,8 @@ static void _httpd_endpoint_robots_txt(tf_http_request_t* request)
|
||||
return;
|
||||
}
|
||||
char* response = "User-Agent: *\n"
|
||||
"Disallow: /*/*/edit\n"
|
||||
"Allow: /\n";
|
||||
"Disallow: /*/*/edit\n"
|
||||
"Allow: /\n";
|
||||
const char* headers[] = { "Content-Type", "text/plain; charset=utf-8" };
|
||||
tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, response ? strlen(response) : 0);
|
||||
}
|
||||
|
29
src/ios.m
29
src/ios.m
@ -46,9 +46,9 @@ static void _start_initial_load(WKWebView* web_view)
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView*)webView
|
||||
runJavaScriptConfirmPanelWithMessage:(NSString*)message
|
||||
initiatedByFrame:(WKFrameInfo*)frame
|
||||
completionHandler:(void (^)(BOOL result))completionHandler
|
||||
runJavaScriptConfirmPanelWithMessage:(NSString*)message
|
||||
initiatedByFrame:(WKFrameInfo*)frame
|
||||
completionHandler:(void (^)(BOOL result))completionHandler
|
||||
{
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) { completionHandler(true); }]];
|
||||
@ -63,26 +63,23 @@ static void _start_initial_load(WKWebView* web_view)
|
||||
[self presentViewController:alertController animated:YES completion:^ {}];
|
||||
}
|
||||
|
||||
|
||||
- (void)webView:(WKWebView*)webView
|
||||
runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
|
||||
defaultText:(NSString*)defaultText
|
||||
initiatedByFrame:(WKFrameInfo*)frame
|
||||
completionHandler:(void (^)(NSString*))completionHandler
|
||||
runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
|
||||
defaultText:(NSString*)defaultText
|
||||
initiatedByFrame:(WKFrameInfo*)frame
|
||||
completionHandler:(void (^)(NSString*))completionHandler
|
||||
{
|
||||
NSString* sender = [NSString stringWithFormat:@"%@", self.web_view.URL.host];
|
||||
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:prompt message:sender preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField* textField) {
|
||||
textField.placeholder = defaultText;
|
||||
textField.text = defaultText;
|
||||
textField.placeholder = defaultText;
|
||||
textField.text = defaultText;
|
||||
}];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction* action) {
|
||||
NSString* input = ((UITextField*)alertController.textFields.firstObject).text;
|
||||
completionHandler(input);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) {
|
||||
NSString* input = ((UITextField*)alertController.textFields.firstObject).text;
|
||||
completionHandler(input);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action) { completionHandler(nil); }]];
|
||||
[self presentViewController:alertController animated:YES completion:^ {}];
|
||||
}
|
||||
|
17
src/main.c
17
src/main.c
@ -42,7 +42,7 @@ struct backtrace_state* g_backtrace_state;
|
||||
const char* k_db_path_default = "db.sqlite";
|
||||
|
||||
#define XOPT_PARSE( \
|
||||
name, flags, options, config_ptr, argc, argv, extrac_ptr, extrav_ptr, err_ptr, autohelp_file, autohelp_usage, autohelp_prefix, autohelp_suffix, autohelp_spacer) \
|
||||
name, flags, options, config_ptr, argc, argv, extrac_ptr, extrav_ptr, err_ptr, autohelp_file, autohelp_usage, autohelp_prefix, autohelp_suffix, autohelp_spacer) \
|
||||
do \
|
||||
{ \
|
||||
xoptContext* _xopt_ctx; \
|
||||
@ -117,8 +117,7 @@ static int _tf_command_test(const char* file, int argc, char* argv[])
|
||||
const char** extras = NULL;
|
||||
int extra_count = 0;
|
||||
const char* err = NULL;
|
||||
XOPT_PARSE(
|
||||
file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "test [options]", "options:", NULL, 15);
|
||||
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "test [options]", "options:", NULL, 15);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", err);
|
||||
@ -165,7 +164,7 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
|
||||
int extra_count = 0;
|
||||
const char* err = NULL;
|
||||
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr,
|
||||
"import [options] [paths] ...", "options:", NULL, 15);
|
||||
"import [options] [paths] ...", "options:", NULL, 15);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", err);
|
||||
@ -223,7 +222,7 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
|
||||
int extra_count = 0;
|
||||
const char* err = NULL;
|
||||
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr,
|
||||
"export [options] [paths] ...", "options:", NULL, 15);
|
||||
"export [options] [paths] ...", "options:", NULL, 15);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", err);
|
||||
@ -440,7 +439,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
||||
int extra_count = 0;
|
||||
const char* err = NULL;
|
||||
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr,
|
||||
"run [options] [paths] ...", "options:", NULL, 15);
|
||||
"run [options] [paths] ...", "options:", NULL, 15);
|
||||
|
||||
if (err)
|
||||
{
|
||||
@ -513,7 +512,7 @@ static int _tf_command_sandbox(const char* file, int argc, char* argv[])
|
||||
int extra_count = 0;
|
||||
const char* err = NULL;
|
||||
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr,
|
||||
"sandbox [options]", "options:", NULL, 15);
|
||||
"sandbox [options]", "options:", NULL, 15);
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", err);
|
||||
@ -614,9 +613,9 @@ static void _startup(int argc, char* argv[])
|
||||
{
|
||||
if (
|
||||
#if !defined(_WIN32)
|
||||
signal(SIGSYS, _error_handler) == SIG_ERR ||
|
||||
signal(SIGSYS, _error_handler) == SIG_ERR ||
|
||||
#endif
|
||||
signal(SIGSEGV, _error_handler) == SIG_ERR)
|
||||
signal(SIGSEGV, _error_handler) == SIG_ERR)
|
||||
{
|
||||
perror("signal");
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ static void _tf_mem_summarize(void* ptr, size_t size, int frames_count, void* co
|
||||
|
||||
int index = tf_util_insert_index(&allocation, summary->allocations, summary->count, sizeof(tf_mem_allocation_t), _tf_mem_hash_stack_compare);
|
||||
if (index < summary->count && allocation.stack_hash == summary->allocations[index].stack_hash && allocation.frames_count == summary->allocations[index].frames_count &&
|
||||
memcmp(frames, summary->allocations[index].frames, sizeof(void*) * frames_count) == 0)
|
||||
memcmp(frames, summary->allocations[index].frames, sizeof(void*) * frames_count) == 0)
|
||||
{
|
||||
summary->allocations[index].count++;
|
||||
summary->allocations[index].size += size;
|
||||
|
@ -451,16 +451,14 @@ static void _socket_onResolvedForBind(uv_getaddrinfo_t* resolver, int status, st
|
||||
socket_resolve_data_t* data = (socket_resolve_data_t*)resolver->data;
|
||||
if (status != 0)
|
||||
{
|
||||
tf_task_reject_promise(
|
||||
data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "uv_getaddrinfo: %s", uv_strerror(status)));
|
||||
tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "uv_getaddrinfo: %s", uv_strerror(status)));
|
||||
}
|
||||
else
|
||||
{
|
||||
int bindResult = uv_tcp_bind(&data->socket->_socket, result->ai_addr, 0);
|
||||
if (bindResult != 0)
|
||||
{
|
||||
tf_task_reject_promise(
|
||||
data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "uv_tcp_bind: %s", uv_strerror(bindResult)));
|
||||
tf_task_reject_promise(data->socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(data->socket->_task), "uv_tcp_bind: %s", uv_strerror(bindResult)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
74
src/ssb.c
74
src/ssb.c
@ -482,8 +482,7 @@ static void _tf_ssb_write(tf_ssb_connection_t* connection, void* data, size_t si
|
||||
}
|
||||
else if (connection->tunnel_connection)
|
||||
{
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection->tunnel_connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, -connection->tunnel_request_number, data, size, NULL, NULL, NULL);
|
||||
tf_ssb_connection_rpc_send(connection->tunnel_connection, k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream, -connection->tunnel_request_number, data, size, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +555,6 @@ static void _tf_ssb_connection_send_identity(tf_ssb_connection_t* connection, ui
|
||||
connection->state = k_tf_ssb_state_sent_identity;
|
||||
}
|
||||
|
||||
|
||||
static void _tf_ssb_nonce_inc(uint8_t* nonce)
|
||||
{
|
||||
int i = 23;
|
||||
@ -643,10 +641,10 @@ static bool _tf_ssb_connection_get_request_callback(tf_ssb_connection_t* connect
|
||||
}
|
||||
|
||||
void tf_ssb_connection_add_request(tf_ssb_connection_t* connection, int32_t request_number, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data,
|
||||
tf_ssb_connection_t* dependent_connection)
|
||||
tf_ssb_connection_t* dependent_connection)
|
||||
{
|
||||
tf_ssb_request_t* existing =
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
if (existing)
|
||||
{
|
||||
assert(!existing->callback);
|
||||
@ -691,7 +689,7 @@ static int _message_request_compare(const void* a, const void* b)
|
||||
void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection, const char* author, int32_t request_number, bool keys)
|
||||
{
|
||||
int index =
|
||||
tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (index < connection->message_requests_count && strcmp(author, connection->message_requests[index].author) == 0)
|
||||
{
|
||||
connection->message_requests[index].request_number = request_number;
|
||||
@ -702,7 +700,7 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
if (connection->message_requests_count - index)
|
||||
{
|
||||
memmove(connection->message_requests + index + 1, connection->message_requests + index,
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index));
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index));
|
||||
}
|
||||
connection->message_requests[index] = (tf_ssb_connection_message_request_t) {
|
||||
.request_number = request_number,
|
||||
@ -715,11 +713,11 @@ void tf_ssb_connection_add_new_message_request(tf_ssb_connection_t* connection,
|
||||
void tf_ssb_connection_remove_new_message_request(tf_ssb_connection_t* connection, const char* author)
|
||||
{
|
||||
int index =
|
||||
tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
tf_util_insert_index(author, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (index < connection->message_requests_count && strcmp(author, connection->message_requests[index].author) == 0)
|
||||
{
|
||||
memmove(connection->message_requests + index, connection->message_requests + index + 1,
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index - 1));
|
||||
sizeof(tf_ssb_connection_message_request_t) * (connection->message_requests_count - index - 1));
|
||||
connection->message_requests_count--;
|
||||
}
|
||||
}
|
||||
@ -727,7 +725,7 @@ void tf_ssb_connection_remove_new_message_request(tf_ssb_connection_t* connectio
|
||||
void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t request_number)
|
||||
{
|
||||
tf_ssb_request_t* request =
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
connection->requests_count ? bsearch(&request_number, connection->requests, connection->requests_count, sizeof(tf_ssb_request_t), _request_compare) : NULL;
|
||||
if (request)
|
||||
{
|
||||
if (request->cleanup)
|
||||
@ -743,7 +741,7 @@ void tf_ssb_connection_remove_request(tf_ssb_connection_t* connection, int32_t r
|
||||
}
|
||||
|
||||
void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const uint8_t* message, size_t size, tf_ssb_rpc_callback_t* callback,
|
||||
tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
{
|
||||
if (!connection)
|
||||
{
|
||||
@ -773,9 +771,9 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags,
|
||||
memcpy(combined + 1 + 2 * sizeof(uint32_t), message, size);
|
||||
if (connection->ssb->verbose)
|
||||
{
|
||||
tf_printf(MAGENTA "%s RPC SEND" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type],
|
||||
request_number, size, (flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary ? 0 : (int)size, message);
|
||||
tf_printf(MAGENTA "%s RPC SEND" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name, (flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size,
|
||||
(flags & k_ssb_rpc_mask_type) == k_ssb_rpc_flag_binary ? 0 : (int)size, message);
|
||||
}
|
||||
_tf_ssb_connection_add_debug_message(connection, true, flags & k_ssb_rpc_mask_send, request_number, message, size);
|
||||
_tf_ssb_connection_box_stream_send(connection, combined, 1 + 2 * sizeof(uint32_t) + size);
|
||||
@ -792,14 +790,13 @@ void tf_ssb_connection_rpc_send(tf_ssb_connection_t* connection, uint8_t flags,
|
||||
}
|
||||
|
||||
void tf_ssb_connection_rpc_send_json(
|
||||
tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue message, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue message, tf_ssb_rpc_callback_t* callback, tf_ssb_callback_cleanup_t* cleanup, void* user_data)
|
||||
{
|
||||
JSContext* context = connection->ssb->context;
|
||||
JSValue json = JS_JSONStringify(context, message, JS_NULL, JS_NULL);
|
||||
size_t size = 0;
|
||||
const char* json_string = JS_ToCStringLen(context, &size, json);
|
||||
tf_ssb_connection_rpc_send(
|
||||
connection, k_ssb_rpc_flag_json | (flags & ~k_ssb_rpc_mask_type), request_number, (const uint8_t*)json_string, size, callback, cleanup, user_data);
|
||||
tf_ssb_connection_rpc_send(connection, k_ssb_rpc_flag_json | (flags & ~k_ssb_rpc_mask_type), request_number, (const uint8_t*)json_string, size, callback, cleanup, user_data);
|
||||
JS_FreeCString(context, json_string);
|
||||
JS_FreeValue(context, json);
|
||||
}
|
||||
@ -813,7 +810,7 @@ void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t f
|
||||
JS_SetPropertyStr(context, message, "stack", JS_NewString(context, stack ? stack : "stack unavailable"));
|
||||
JS_SetPropertyStr(context, message, "message", JS_NewString(context, error));
|
||||
tf_ssb_connection_rpc_send_json(
|
||||
connection, ((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream) : 0) | k_ssb_rpc_flag_end_error, request_number, message, NULL, NULL, NULL);
|
||||
connection, ((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream) : 0) | k_ssb_rpc_flag_end_error, request_number, message, NULL, NULL, NULL);
|
||||
JS_FreeValue(context, message);
|
||||
tf_free((void*)stack);
|
||||
}
|
||||
@ -1006,7 +1003,7 @@ static bool _tf_ssb_verify_and_strip_signature_internal(JSContext* context, JSVa
|
||||
}
|
||||
|
||||
bool tf_ssb_verify_and_strip_signature(
|
||||
JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size, bool* out_sequence_before_author)
|
||||
JSContext* context, JSValue val, char* out_id, size_t out_id_size, char* out_signature, size_t out_signature_size, bool* out_sequence_before_author)
|
||||
{
|
||||
if (_tf_ssb_verify_and_strip_signature_internal(context, val, out_id, out_id_size, out_signature, out_signature_size))
|
||||
{
|
||||
@ -1528,9 +1525,8 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
|
||||
tf_ssb_id_bin_to_str(id, sizeof(id), connection->serverpub);
|
||||
if (connection->ssb->verbose)
|
||||
{
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size, (int)size, message);
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B] %.*s\n", connection->name, (flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size, (int)size, message);
|
||||
}
|
||||
JSContext* context = connection->ssb->context;
|
||||
JSValue val = JS_ParseJSON(context, (const char*)message, size, NULL);
|
||||
@ -1589,9 +1585,8 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t
|
||||
{
|
||||
if (connection->ssb->verbose)
|
||||
{
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B]\n", connection->name,
|
||||
(flags & k_ssb_rpc_flag_end_error) ? "true" : "false", (flags & k_ssb_rpc_flag_stream) ? "true" : "false",
|
||||
k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size);
|
||||
tf_printf(CYAN "%s RPC RECV" RESET " end/error=%s stream=%s type=%s RN=%d: [%zd B]\n", connection->name, (flags & k_ssb_rpc_flag_end_error) ? "true" : "false",
|
||||
(flags & k_ssb_rpc_flag_stream) ? "true" : "false", k_ssb_type_names[flags & k_ssb_rpc_mask_type], request_number, size);
|
||||
}
|
||||
tf_ssb_rpc_callback_t* callback = NULL;
|
||||
void* user_data = NULL;
|
||||
@ -1627,7 +1622,7 @@ static void _tf_ssb_connection_rpc_recv_push(tf_ssb_connection_t* connection, co
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t copy_size =
|
||||
(connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
|
||||
(connection->rpc_recv_size + size_left > sizeof(connection->rpc_recv_buffer)) ? sizeof(connection->rpc_recv_buffer) - connection->rpc_recv_size : size_left;
|
||||
if (copy_size == 0)
|
||||
{
|
||||
_tf_ssb_connection_close(connection, "recv buffer overflow");
|
||||
@ -1700,8 +1695,7 @@ static bool _tf_ssb_connection_box_stream_recv(tf_ssb_connection_t* connection)
|
||||
memcpy(connection->box_stream_buf, connection->body_auth_tag, sizeof(connection->body_auth_tag));
|
||||
if (_tf_ssb_connection_recv_pop(connection, connection->box_stream_buf + 16, connection->body_len))
|
||||
{
|
||||
if (crypto_secretbox_open_easy(
|
||||
connection->secretbox_buf, connection->box_stream_buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0)
|
||||
if (crypto_secretbox_open_easy(connection->secretbox_buf, connection->box_stream_buf, 16 + connection->body_len, connection->nonce, connection->s_to_c_box_key) != 0)
|
||||
{
|
||||
_tf_ssb_connection_close(connection, "failed to open secret box");
|
||||
return false;
|
||||
@ -2377,7 +2371,7 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
||||
tf_printf("Waiting for closes.\n");
|
||||
|
||||
while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || ssb->broadcast_cleanup_timer.data || ssb->trace_timer.data ||
|
||||
ssb->server.data || ssb->ref_count)
|
||||
ssb->server.data || ssb->ref_count)
|
||||
{
|
||||
uv_run(ssb->loop, UV_RUN_ONCE);
|
||||
}
|
||||
@ -2605,7 +2599,7 @@ tf_ssb_connection_t* tf_ssb_connection_create(tf_ssb_t* ssb, const char* host, c
|
||||
}
|
||||
|
||||
static void _tf_ssb_connection_tunnel_callback(
|
||||
tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
tf_ssb_connection_t* tunnel = user_data;
|
||||
if (flags & k_ssb_rpc_flag_end_error)
|
||||
@ -2949,7 +2943,7 @@ static void _tf_ssb_add_broadcast(tf_ssb_t* ssb, const tf_ssb_broadcast_t* broad
|
||||
for (tf_ssb_broadcast_t* node = ssb->broadcasts; node; node = node->next)
|
||||
{
|
||||
if (node->addr.sin_family == broadcast->addr.sin_family && node->addr.sin_port == broadcast->addr.sin_port &&
|
||||
node->addr.sin_addr.s_addr == broadcast->addr.sin_addr.s_addr && memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
node->addr.sin_addr.s_addr == broadcast->addr.sin_addr.s_addr && memcmp(node->pub, broadcast->pub, sizeof(node->pub)) == 0)
|
||||
{
|
||||
node->mtime = time(NULL);
|
||||
return;
|
||||
@ -3001,7 +2995,7 @@ static void _tf_ssb_on_broadcast_listener_recv(uv_udp_t* handle, ssize_t nread,
|
||||
}
|
||||
|
||||
void tf_ssb_visit_broadcasts(
|
||||
tf_ssb_t* ssb, void (*callback)(const char* host, const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data), void* user_data)
|
||||
tf_ssb_t* ssb, void (*callback)(const char* host, const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data), void* user_data)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
tf_ssb_broadcast_t* next = NULL;
|
||||
@ -3304,7 +3298,7 @@ JSValue tf_ssb_connection_get_object(tf_ssb_connection_t* connection)
|
||||
}
|
||||
|
||||
void tf_ssb_add_message_added_callback(
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
{
|
||||
tf_ssb_message_added_callback_node_t* node = tf_malloc(sizeof(tf_ssb_message_added_callback_node_t));
|
||||
*node = (tf_ssb_message_added_callback_node_t) {
|
||||
@ -3370,12 +3364,12 @@ void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* id, JSValue message_
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tf_ssb_connection_message_request_t* message_request = bsearch(
|
||||
author_string, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
tf_ssb_connection_message_request_t* message_request =
|
||||
bsearch(author_string, connection->message_requests, connection->message_requests_count, sizeof(tf_ssb_connection_message_request_t), _message_request_compare);
|
||||
if (message_request)
|
||||
{
|
||||
tf_ssb_connection_rpc_send_json(
|
||||
connection, k_ssb_rpc_flag_stream, message_request->request_number, message_request->keys ? message_keys : message, NULL, NULL, NULL);
|
||||
connection, k_ssb_rpc_flag_stream, message_request->request_number, message_request->keys ? message_keys : message, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3386,7 +3380,7 @@ void tf_ssb_notify_message_added(tf_ssb_t* ssb, const char* id, JSValue message_
|
||||
}
|
||||
|
||||
void tf_ssb_add_blob_want_added_callback(
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
tf_ssb_t* ssb, void (*callback)(tf_ssb_t* ssb, const char* id, void* user_data), void (*cleanup)(tf_ssb_t* ssb, void* user_data), void* user_data)
|
||||
{
|
||||
tf_ssb_blob_want_added_callback_node_t* node = tf_malloc(sizeof(tf_ssb_blob_want_added_callback_node_t));
|
||||
*node = (tf_ssb_blob_want_added_callback_node_t) {
|
||||
@ -3625,8 +3619,8 @@ JSValue tf_ssb_get_disconnection_debug(tf_ssb_t* ssb, JSContext* context)
|
||||
JS_SetPropertyStr(context, message, "flags", JS_NewInt32(context, ssb->debug_close[i].messages[j]->flags));
|
||||
JS_SetPropertyStr(context, message, "request_number", JS_NewInt32(context, ssb->debug_close[i].messages[j]->request_number));
|
||||
JS_SetPropertyStr(context, message, "timestamp", JS_NewFloat64(context, ssb->debug_close[i].messages[j]->timestamp));
|
||||
JS_SetPropertyStr(context, message, "payload",
|
||||
JS_NewStringLen(context, (const char*)ssb->debug_close[i].messages[j]->data, ssb->debug_close[i].messages[j]->size));
|
||||
JS_SetPropertyStr(
|
||||
context, message, "payload", JS_NewStringLen(context, (const char*)ssb->debug_close[i].messages[j]->data, ssb->debug_close[i].messages[j]->size));
|
||||
JS_SetPropertyUint32(context, messages, j, message);
|
||||
}
|
||||
}
|
||||
@ -3720,7 +3714,7 @@ static void _tf_ssb_connection_after_work_callback(uv_work_t* work, int status)
|
||||
}
|
||||
|
||||
void tf_ssb_connection_run_work(tf_ssb_connection_t* connection, void (*work_callback)(tf_ssb_connection_t* connection, void* user_data),
|
||||
void (*after_work_callback)(tf_ssb_connection_t* connection, int result, void* user_data), void* user_data)
|
||||
void (*after_work_callback)(tf_ssb_connection_t* connection, int result, void* user_data), void* user_data)
|
||||
{
|
||||
connection_work_t* work = tf_malloc(sizeof(connection_work_t));
|
||||
*work = (connection_work_t)
|
||||
|
@ -28,7 +28,7 @@ static void _tf_ssb_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_change_t
|
||||
{
|
||||
char key[k_id_base64_len];
|
||||
if (tf_ssb_connection_get_host(connection) && *tf_ssb_connection_get_host(connection) && tf_ssb_connection_get_port(connection) &&
|
||||
tf_ssb_connection_get_id(connection, key, sizeof(key)))
|
||||
tf_ssb_connection_get_id(connection, key, sizeof(key)))
|
||||
{
|
||||
tf_ssb_connections_set_attempted(connections, tf_ssb_connection_get_host(connection), tf_ssb_connection_get_port(connection), key);
|
||||
}
|
||||
@ -53,8 +53,8 @@ static bool _tf_ssb_connections_get_next_connection(tf_ssb_connections_t* connec
|
||||
bool result = false;
|
||||
sqlite3_stmt* statement;
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(connections->ssb);
|
||||
if (sqlite3_prepare(db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > ?1) ORDER BY last_attempt LIMIT 1",
|
||||
-1, &statement, NULL) == SQLITE_OK)
|
||||
if (sqlite3_prepare(db, "SELECT host, port, key FROM connections WHERE last_attempt IS NULL OR (strftime('%s', 'now') - last_attempt > ?1) ORDER BY last_attempt LIMIT 1", -1,
|
||||
&statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_int(statement, 1, 60000) == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
@ -179,11 +179,10 @@ static void _tf_ssb_connections_update_work(uv_work_t* work)
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(update->ssb);
|
||||
if (update->attempted)
|
||||
{
|
||||
if (sqlite3_prepare(db, "UPDATE connections SET last_attempt = strftime('%s', 'now') WHERE host = ?1 AND port = ?2 AND key = ?3", -1, &statement, NULL) ==
|
||||
SQLITE_OK)
|
||||
if (sqlite3_prepare(db, "UPDATE connections SET last_attempt = strftime('%s', 'now') WHERE host = ?1 AND port = ?2 AND key = ?3", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) != SQLITE_DONE)
|
||||
{
|
||||
@ -195,11 +194,10 @@ static void _tf_ssb_connections_update_work(uv_work_t* work)
|
||||
}
|
||||
else if (update->succeeded)
|
||||
{
|
||||
if (sqlite3_prepare(db, "UPDATE connections SET last_success = strftime('%s', 'now') WHERE host = ?1 AND port = ?2 AND key = ?3", -1, &statement, NULL) ==
|
||||
SQLITE_OK)
|
||||
if (sqlite3_prepare(db, "UPDATE connections SET last_success = strftime('%s', 'now') WHERE host = ?1 AND port = ?2 AND key = ?3", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) != SQLITE_DONE)
|
||||
{
|
||||
@ -214,7 +212,7 @@ static void _tf_ssb_connections_update_work(uv_work_t* work)
|
||||
if (sqlite3_prepare(db, "INSERT INTO connections (host, port, key) VALUES (?1, ?2, ?3) ON CONFLICT DO NOTHING", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
int r = sqlite3_step(statement);
|
||||
if (r != SQLITE_DONE)
|
||||
|
202
src/ssb.db.c
202
src/ssb.db.c
@ -94,51 +94,51 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
|
||||
}
|
||||
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS messages ("
|
||||
" author TEXT,"
|
||||
" id TEXT PRIMARY KEY,"
|
||||
" sequence INTEGER,"
|
||||
" timestamp REAL,"
|
||||
" previous TEXT,"
|
||||
" hash TEXT,"
|
||||
" content TEXT,"
|
||||
" signature TEXT,"
|
||||
" sequence_before_author INTEGER,"
|
||||
" UNIQUE(author, sequence)"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS messages ("
|
||||
" author TEXT,"
|
||||
" id TEXT PRIMARY KEY,"
|
||||
" sequence INTEGER,"
|
||||
" timestamp REAL,"
|
||||
" previous TEXT,"
|
||||
" hash TEXT,"
|
||||
" content TEXT,"
|
||||
" signature TEXT,"
|
||||
" sequence_before_author INTEGER,"
|
||||
" UNIQUE(author, sequence)"
|
||||
")");
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_id_index ON messages (author, id)");
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)");
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)");
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS blobs ("
|
||||
" id TEXT PRIMARY KEY,"
|
||||
" content BLOB,"
|
||||
" created INTEGER"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS blobs ("
|
||||
" id TEXT PRIMARY KEY,"
|
||||
" content BLOB,"
|
||||
" created INTEGER"
|
||||
")");
|
||||
_tf_ssb_db_exec(db, "DROP TABLE IF EXISTS blob_wants");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS properties ("
|
||||
" id TEXT,"
|
||||
" key TEXT,"
|
||||
" value TEXT,"
|
||||
" UNIQUE(id, key)"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS properties ("
|
||||
" id TEXT,"
|
||||
" key TEXT,"
|
||||
" value TEXT,"
|
||||
" UNIQUE(id, key)"
|
||||
")");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS connections ("
|
||||
" host TEXT,"
|
||||
" port INTEGER,"
|
||||
" key TEXT,"
|
||||
" last_attempt INTEGER,"
|
||||
" last_success INTEGER,"
|
||||
" UNIQUE(host, port, key)"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS connections ("
|
||||
" host TEXT,"
|
||||
" port INTEGER,"
|
||||
" key TEXT,"
|
||||
" last_attempt INTEGER,"
|
||||
" last_success INTEGER,"
|
||||
" UNIQUE(host, port, key)"
|
||||
")");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS identities ("
|
||||
" user TEXT,"
|
||||
" public_key TEXT UNIQUE,"
|
||||
" private_key TEXT UNIQUE"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS identities ("
|
||||
" user TEXT,"
|
||||
" public_key TEXT UNIQUE,"
|
||||
" private_key TEXT UNIQUE"
|
||||
")");
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS identities_user ON identities (user, public_key)");
|
||||
|
||||
bool populate_fts = false;
|
||||
@ -165,40 +165,39 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
|
||||
tf_printf("Done.\n");
|
||||
}
|
||||
|
||||
_tf_ssb_db_exec(
|
||||
db, "CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content); END");
|
||||
_tf_ssb_db_exec(db, "CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content); END");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN INSERT INTO messages_fts(messages_fts, rowid, content) VALUES ('delete', old.rowid, "
|
||||
"old.content); END");
|
||||
"CREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN INSERT INTO messages_fts(messages_fts, rowid, content) VALUES ('delete', old.rowid, "
|
||||
"old.content); END");
|
||||
|
||||
if (!_tf_ssb_db_has_rows(db, "PRAGMA table_list('messages_refs')"))
|
||||
{
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TABLE IF NOT EXISTS messages_refs ("
|
||||
" message TEXT, "
|
||||
" ref TEXT, "
|
||||
" UNIQUE(message, ref)"
|
||||
")");
|
||||
"CREATE TABLE IF NOT EXISTS messages_refs ("
|
||||
" message TEXT, "
|
||||
" ref TEXT, "
|
||||
" UNIQUE(message, ref)"
|
||||
")");
|
||||
tf_printf("Populating messages_refs...\n");
|
||||
_tf_ssb_db_exec(db,
|
||||
"INSERT INTO messages_refs(message, ref) "
|
||||
"SELECT messages.id, j.value FROM messages, json_tree(messages.content) as j WHERE "
|
||||
"j.value LIKE '&%.sha256' OR "
|
||||
"j.value LIKE '%%%.sha256' OR "
|
||||
"j.value LIKE '@%.ed25519' "
|
||||
"ON CONFLICT DO NOTHING");
|
||||
"INSERT INTO messages_refs(message, ref) "
|
||||
"SELECT messages.id, j.value FROM messages, json_tree(messages.content) as j WHERE "
|
||||
"j.value LIKE '&%.sha256' OR "
|
||||
"j.value LIKE '%%%.sha256' OR "
|
||||
"j.value LIKE '@%.ed25519' "
|
||||
"ON CONFLICT DO NOTHING");
|
||||
tf_printf("Done.\n");
|
||||
}
|
||||
|
||||
_tf_ssb_db_exec(db, "DROP TRIGGER IF EXISTS messages_ai_refs");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE TRIGGER IF NOT EXISTS messages_ai_refs AFTER INSERT ON messages BEGIN "
|
||||
"INSERT INTO messages_refs(message, ref) "
|
||||
"SELECT DISTINCT new.id, j.value FROM json_tree(new.content) as j WHERE "
|
||||
"j.value LIKE '&%.sha256' OR "
|
||||
"j.value LIKE '%%%.sha256' OR "
|
||||
"j.value LIKE '@%.ed25519' "
|
||||
"ON CONFLICT DO NOTHING; END");
|
||||
"CREATE TRIGGER IF NOT EXISTS messages_ai_refs AFTER INSERT ON messages BEGIN "
|
||||
"INSERT INTO messages_refs(message, ref) "
|
||||
"SELECT DISTINCT new.id, j.value FROM json_tree(new.content) as j WHERE "
|
||||
"j.value LIKE '&%.sha256' OR "
|
||||
"j.value LIKE '%%%.sha256' OR "
|
||||
"j.value LIKE '@%.ed25519' "
|
||||
"ON CONFLICT DO NOTHING; END");
|
||||
_tf_ssb_db_exec(db, "DROP TRIGGER IF EXISTS messages_ad_refs");
|
||||
_tf_ssb_db_exec(db, "CREATE TRIGGER IF NOT EXISTS messages_ad_refs AFTER DELETE ON messages BEGIN DELETE FROM messages_refs WHERE messages_refs.message = old.id; END");
|
||||
|
||||
@ -206,14 +205,14 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
|
||||
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_refs_ref_idx ON messages_refs (ref)");
|
||||
_tf_ssb_db_exec(db, "DROP VIEW IF EXISTS blob_wants_view");
|
||||
_tf_ssb_db_exec(db,
|
||||
"CREATE VIEW IF NOT EXISTS blob_wants_view (id, timestamp) AS "
|
||||
" SELECT messages_refs.ref AS id, messages.timestamp AS timestamp "
|
||||
" FROM messages_refs "
|
||||
" JOIN messages ON messages.id = messages_refs.message "
|
||||
" LEFT OUTER JOIN blobs ON messages_refs.ref = blobs.id "
|
||||
" WHERE blobs.id IS NULL "
|
||||
" AND LENGTH(messages_refs.ref) = 52 "
|
||||
" AND messages_refs.ref LIKE '&%.sha256'");
|
||||
"CREATE VIEW IF NOT EXISTS blob_wants_view (id, timestamp) AS "
|
||||
" SELECT messages_refs.ref AS id, messages.timestamp AS timestamp "
|
||||
" FROM messages_refs "
|
||||
" JOIN messages ON messages.id = messages_refs.message "
|
||||
" LEFT OUTER JOIN blobs ON messages_refs.ref = blobs.id "
|
||||
" WHERE blobs.id IS NULL "
|
||||
" AND LENGTH(messages_refs.ref) = 52 "
|
||||
" AND messages_refs.ref LIKE '&%.sha256'");
|
||||
|
||||
bool need_add_sequence_before_author = true;
|
||||
bool need_convert_timestamp_to_real = false;
|
||||
@ -270,7 +269,7 @@ static bool _tf_ssb_db_previous_message_exists(sqlite3* db, const char* author,
|
||||
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)
|
||||
sqlite3_bind_text(statement, 3, previous, -1, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
exists = sqlite3_column_int(statement, 0) != 0;
|
||||
}
|
||||
@ -281,7 +280,7 @@ static bool _tf_ssb_db_previous_message_exists(sqlite3* db, const char* author,
|
||||
}
|
||||
|
||||
static int64_t _tf_ssb_db_store_message_raw(tf_ssb_t* ssb, const char* id, const char* previous, const char* author, int64_t sequence, double timestamp, const char* content,
|
||||
size_t content_len, const char* signature, bool sequence_before_author)
|
||||
size_t content_len, const char* signature, bool sequence_before_author)
|
||||
{
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
int64_t last_row_id = -1;
|
||||
@ -289,16 +288,16 @@ static int64_t _tf_ssb_db_store_message_raw(tf_ssb_t* ssb, const char* id, const
|
||||
if (_tf_ssb_db_previous_message_exists(db, author, sequence, previous))
|
||||
{
|
||||
const char* query = "INSERT INTO messages (id, previous, author, sequence, timestamp, content, hash, signature, sequence_before_author) VALUES (?, ?, ?, ?, ?, ?, "
|
||||
"?, ?, ?) ON CONFLICT DO NOTHING";
|
||||
"?, ?, ?) ON CONFLICT DO NOTHING";
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
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_double(statement, 5, timestamp) == SQLITE_OK && sqlite3_bind_text(statement, 6, content, 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)
|
||||
(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_double(statement, 5, timestamp) == SQLITE_OK && sqlite3_bind_text(statement, 6, content, 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)
|
||||
{
|
||||
int r = sqlite3_step(statement);
|
||||
if (r != SQLITE_DONE)
|
||||
@ -337,9 +336,9 @@ static char* _tf_ssb_db_get_message_blob_wants(tf_ssb_t* ssb, int64_t rowid)
|
||||
size_t size = 0;
|
||||
|
||||
if (sqlite3_prepare(db,
|
||||
"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",
|
||||
-1, &statement, NULL) == SQLITE_OK)
|
||||
"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",
|
||||
-1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_int64(statement, 1, rowid) == SQLITE_OK && sqlite3_bind_int(statement, 2, k_blob_id_len - 1) == SQLITE_OK)
|
||||
{
|
||||
@ -404,7 +403,7 @@ static void _tf_ssb_db_store_message_work(uv_work_t* work)
|
||||
tf_trace_t* trace = tf_ssb_get_trace(store->ssb);
|
||||
tf_trace_begin(trace, "message_store_work");
|
||||
int64_t last_row_id = _tf_ssb_db_store_message_raw(store->ssb, store->id, *store->previous ? store->previous : NULL, store->author, store->sequence, store->timestamp,
|
||||
store->content, store->length, store->signature, store->sequence_before_author);
|
||||
store->content, store->length, store->signature, store->sequence_before_author);
|
||||
if (last_row_id != -1)
|
||||
{
|
||||
store->out_stored = true;
|
||||
@ -461,7 +460,7 @@ static void _tf_ssb_db_store_message_after_work(uv_work_t* work, int status)
|
||||
tf_trace_begin(trace, "notify_message_added");
|
||||
JSContext* context = tf_ssb_get_context(store->ssb);
|
||||
JSValue formatted = tf_ssb_format_message(
|
||||
context, store->previous, store->author, store->sequence, store->timestamp, "sha256", store->content, store->signature, store->sequence_before_author);
|
||||
context, store->previous, store->author, store->sequence, store->timestamp, "sha256", store->content, store->signature, store->sequence_before_author);
|
||||
JSValue message = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, message, "key", JS_NewString(context, store->id));
|
||||
JS_SetPropertyStr(context, message, "value", formatted);
|
||||
@ -487,7 +486,7 @@ static void _tf_ssb_db_store_message_after_work(uv_work_t* work, int status)
|
||||
}
|
||||
|
||||
void tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, JSValue val, const char* signature, bool sequence_before_author,
|
||||
tf_ssb_db_store_message_callback_t* callback, void* user_data)
|
||||
tf_ssb_db_store_message_callback_t* callback, void* user_data)
|
||||
{
|
||||
JSValue previousval = JS_GetPropertyStr(context, val, "previous");
|
||||
const char* previous = JS_IsNull(previousval) ? NULL : JS_ToCString(context, previousval);
|
||||
@ -722,8 +721,7 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char*
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_writer(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "INSERT INTO blobs (id, content, created) VALUES (?1, ?2, CAST(strftime('%s') AS INTEGER)) ON CONFLICT DO NOTHING", -1, &statement, NULL) ==
|
||||
SQLITE_OK)
|
||||
if (sqlite3_prepare(db, "INSERT INTO blobs (id, content, created) VALUES (?1, ?2, CAST(strftime('%s') AS INTEGER)) ON CONFLICT DO NOTHING", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_blob(statement, 2, blob, size, NULL) == SQLITE_OK)
|
||||
{
|
||||
@ -762,7 +760,7 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char*
|
||||
}
|
||||
|
||||
bool tf_ssb_db_get_message_by_author_and_sequence(
|
||||
tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content)
|
||||
tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content)
|
||||
{
|
||||
bool found = false;
|
||||
sqlite3_stmt* statement;
|
||||
@ -770,8 +768,7 @@ bool tf_ssb_db_get_message_by_author_and_sequence(
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, author, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, sequence) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_ROW)
|
||||
if (sqlite3_bind_text(statement, 1, author, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, sequence) == SQLITE_OK && sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
if (out_message_id)
|
||||
{
|
||||
@ -927,11 +924,10 @@ int tf_ssb_sqlite_authorizer(void* user_data, int action_code, const char* arg0,
|
||||
break;
|
||||
case SQLITE_READ:
|
||||
result = (strcmp(arg0, "blob_wants_view") == 0 || strcmp(arg0, "json_each") == 0 || strcmp(arg0, "json_tree") == 0 || strcmp(arg0, "messages") == 0 ||
|
||||
strcmp(arg0, "messages_fts") == 0 || strcmp(arg0, "messages_fts_idx") == 0 || strcmp(arg0, "messages_fts_config") == 0 ||
|
||||
strcmp(arg0, "messages_refs") == 0 || strcmp(arg0, "messages_refs_message_idx") == 0 || strcmp(arg0, "messages_refs_ref_idx") == 0 ||
|
||||
strcmp(arg0, "sqlite_master") == 0 || false)
|
||||
? SQLITE_OK
|
||||
: SQLITE_DENY;
|
||||
strcmp(arg0, "messages_fts") == 0 || strcmp(arg0, "messages_fts_idx") == 0 || strcmp(arg0, "messages_fts_config") == 0 || strcmp(arg0, "messages_refs") == 0 ||
|
||||
strcmp(arg0, "messages_refs_message_idx") == 0 || strcmp(arg0, "messages_refs_ref_idx") == 0 || strcmp(arg0, "sqlite_master") == 0 || false)
|
||||
? SQLITE_OK
|
||||
: SQLITE_DENY;
|
||||
break;
|
||||
case SQLITE_PRAGMA:
|
||||
result = strcmp(arg0, "data_version") == 0 ? SQLITE_OK : SQLITE_DENY;
|
||||
@ -989,7 +985,7 @@ JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue bi
|
||||
}
|
||||
|
||||
JSValue tf_ssb_format_message(JSContext* context, const char* previous, const char* author, int64_t sequence, double timestamp, const char* hash, const char* content,
|
||||
const char* signature, bool sequence_before_author)
|
||||
const char* signature, bool sequence_before_author)
|
||||
{
|
||||
JSValue value = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, value, "previous", (previous && *previous) ? JS_NewString(context, previous) : JS_NULL);
|
||||
@ -1056,7 +1052,7 @@ bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_
|
||||
if (sqlite3_prepare(db, "INSERT INTO identities (user, public_key, private_key) VALUES (?, ?, ?) ON CONFLICT DO NOTHING", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, public_key, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 3, private_key, -1, NULL) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 3, private_key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
added = sqlite3_step(statement) == SQLITE_DONE && sqlite3_changes(db) != 0;
|
||||
if (!added)
|
||||
@ -1137,7 +1133,7 @@ bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const c
|
||||
if (sqlite3_prepare(db, "SELECT private_key FROM identities WHERE user = ? AND public_key = ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 2, (public_key && *public_key == '@') ? public_key + 1 : public_key, -1, NULL) == SQLITE_OK)
|
||||
sqlite3_bind_text(statement, 2, (public_key && *public_key == '@') ? public_key + 1 : public_key, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
@ -1273,11 +1269,11 @@ static void _populate_follows_and_blocks(tf_ssb_t* ssb, following_t* entry, foll
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db,
|
||||
"SELECT json_extract(content, '$.contact') AS contact, json_extract(content, '$.following'), json_extract(content, '$.blocking') "
|
||||
"FROM messages "
|
||||
"WHERE contact IS NOT NULL AND author = ? AND json_extract(content, '$.type') = 'contact' "
|
||||
"ORDER BY sequence",
|
||||
-1, &statement, NULL) == SQLITE_OK)
|
||||
"SELECT json_extract(content, '$.contact') AS contact, json_extract(content, '$.following'), json_extract(content, '$.blocking') "
|
||||
"FROM messages "
|
||||
"WHERE contact IS NOT NULL AND author = ? AND json_extract(content, '$.type') = 'contact' "
|
||||
"ORDER BY sequence",
|
||||
-1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, entry->id, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
@ -1485,8 +1481,8 @@ JSValue tf_ssb_db_get_message_by_id(tf_ssb_t* ssb, const char* id, bool is_keys)
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(db, "SELECT previous, author, id, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages WHERE id = ?", -1, &statement,
|
||||
NULL) == SQLITE_OK)
|
||||
if (sqlite3_prepare(
|
||||
db, "SELECT previous, author, id, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages WHERE id = ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
@ -1494,8 +1490,8 @@ JSValue tf_ssb_db_get_message_by_id(tf_ssb_t* ssb, const char* id, bool is_keys)
|
||||
{
|
||||
JSValue message = JS_UNDEFINED;
|
||||
JSValue formatted = tf_ssb_format_message(context, (const char*)sqlite3_column_text(statement, 0), (const char*)sqlite3_column_text(statement, 1),
|
||||
sqlite3_column_int64(statement, 3), sqlite3_column_double(statement, 4), (const char*)sqlite3_column_text(statement, 5),
|
||||
(const char*)sqlite3_column_text(statement, 6), (const char*)sqlite3_column_text(statement, 7), sqlite3_column_int(statement, 8));
|
||||
sqlite3_column_int64(statement, 3), sqlite3_column_double(statement, 4), (const char*)sqlite3_column_text(statement, 5),
|
||||
(const char*)sqlite3_column_text(statement, 6), (const char*)sqlite3_column_text(statement, 7), sqlite3_column_int(statement, 8));
|
||||
if (is_keys)
|
||||
{
|
||||
message = JS_NewObject(context);
|
||||
@ -1550,7 +1546,7 @@ void tf_ssb_db_forget_stored_connection(tf_ssb_t* ssb, const char* address, int
|
||||
if (sqlite3_prepare(db, "DELETE FROM connections WHERE host = ? AND port = ? AND key = ?", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, address, -1, NULL) != SQLITE_OK || sqlite3_bind_int(statement, 2, port) != SQLITE_OK ||
|
||||
sqlite3_bind_text(statement, 3, pubkey, -1, NULL) != SQLITE_OK || sqlite3_step(statement) != SQLITE_DONE)
|
||||
sqlite3_bind_text(statement, 3, pubkey, -1, NULL) != SQLITE_OK || sqlite3_step(statement) != SQLITE_DONE)
|
||||
{
|
||||
tf_printf("Delete stored connection: %s.\n", sqlite3_errmsg(db));
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ bool tf_ssb_db_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_
|
||||
|
||||
typedef void(tf_ssb_db_store_message_callback_t)(const char* id, bool stored, void* user_data);
|
||||
void tf_ssb_db_store_message(tf_ssb_t* ssb, JSContext* context, const char* id, JSValue val, const char* signature, bool sequence_before_author,
|
||||
tf_ssb_db_store_message_callback_t* callback, void* user_data);
|
||||
tf_ssb_db_store_message_callback_t* callback, void* user_data);
|
||||
|
||||