Propagate better sqlite errors.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3971 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2022-09-04 01:58:11 +00:00
parent c3fb80a1c8
commit 97b7643049

View File

@ -435,24 +435,46 @@ bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, i
return found; return found;
} }
static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds) static JSValue _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds)
{ {
if (JS_IsUndefined(binds)) if (JS_IsUndefined(binds))
{ {
return true; return JS_UNDEFINED;
} }
if (!JS_IsArray(context, binds)) if (!JS_IsArray(context, binds))
{ {
printf("Expected bind parameters to be an array.\n"); return JS_ThrowTypeError(context, "Expected bind parameters to be an array.");
return false;
} }
bool all_bound = true; JSValue result = JS_UNDEFINED;
int32_t length = tf_util_get_length(context, binds); int32_t length = tf_util_get_length(context, binds);
for (int i = 0; i < length; i++) for (int i = 0; i < length && JS_IsUndefined(result); i++)
{ {
JSValue value = JS_GetPropertyUint32(context, binds, i); JSValue value = JS_GetPropertyUint32(context, binds, i);
if (JS_IsString(value)) if (JS_IsNumber(value))
{
int64_t number = 0;
JS_ToInt64(context, &number, value);
if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK)
{
result = JS_ThrowInternalError(context, "Failed to bind: %s.", sqlite3_errmsg(db));
}
}
else if (JS_IsBool(value))
{
if (sqlite3_bind_int(statement, i + 1, JS_ToBool(context, value) ? 1 : 0) != SQLITE_OK)
{
result = JS_ThrowInternalError(context, "Failed to bind: %s.", sqlite3_errmsg(db));
}
}
else if (JS_IsNull(value))
{
if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK)
{
result = JS_ThrowInternalError(context, "Failed to bind: %s.", sqlite3_errmsg(db));
}
}
else
{ {
size_t str_len = 0; size_t str_len = 0;
const char* str = JS_ToCStringLen(context, &str_len, value); const char* str = JS_ToCStringLen(context, &str_len, value);
@ -460,43 +482,18 @@ static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_st
{ {
if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK) if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK)
{ {
printf("failed to bind: %s\n", sqlite3_errmsg(db)); result = JS_ThrowInternalError(context, "Failed to bind: %s.", sqlite3_errmsg(db));
all_bound = false;
} }
JS_FreeCString(context, str); JS_FreeCString(context, str);
} }
else else
{ {
printf("expected cstring\n"); result = JS_ThrowInternalError(context, "Could not convert bind argument %d to string.", i);
} }
} }
else if (JS_IsNumber(value))
{
int64_t number = 0;
JS_ToInt64(context, &number, value);
if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
}
else if (JS_IsNull(value))
{
if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
}
else
{
const char* str = JS_ToCString(context, value);
printf("expected string: %s\n", str);
JS_FreeCString(context, str);
}
JS_FreeValue(context, value); JS_FreeValue(context, value);
} }
return all_bound; return result;
} }
static JSValue _tf_ssb_sqlite_row_to_json(JSContext* context, sqlite3_stmt* row) static JSValue _tf_ssb_sqlite_row_to_json(JSContext* context, sqlite3_stmt* row)
@ -558,7 +555,8 @@ JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue bi
sqlite3_set_authorizer(db, _tf_ssb_sqlite_authorizer, ssb); sqlite3_set_authorizer(db, _tf_ssb_sqlite_authorizer, ssb);
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK) if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
{ {
if (_tf_ssb_sqlite_bind_json(context, db, statement, binds)) JSValue bind_result = _tf_ssb_sqlite_bind_json(context, db, statement, binds);
if (JS_IsUndefined(bind_result))
{ {
int r = SQLITE_OK; int r = SQLITE_OK;
while ((r = sqlite3_step(statement)) == SQLITE_ROW) while ((r = sqlite3_step(statement)) == SQLITE_ROW)
@ -575,6 +573,10 @@ JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue bi
result = JS_ThrowInternalError(context, "SQL Error %s: running \"%s\".", sqlite3_errmsg(db), query); result = JS_ThrowInternalError(context, "SQL Error %s: running \"%s\".", sqlite3_errmsg(db), query);
} }
} }
else
{
result = bind_result;
}
sqlite3_finalize(statement); sqlite3_finalize(statement);
} }
else else