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;
}
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))
{
return true;
return JS_UNDEFINED;
}
if (!JS_IsArray(context, binds))
{
printf("Expected bind parameters to be an array.\n");
return false;
return JS_ThrowTypeError(context, "Expected bind parameters to be an array.");
}
bool all_bound = true;
JSValue result = JS_UNDEFINED;
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);
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;
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)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
result = JS_ThrowInternalError(context, "Failed to bind: %s.", sqlite3_errmsg(db));
}
JS_FreeCString(context, str);
}
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);
}
return all_bound;
return result;
}
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);
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;
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);
}
}
else
{
result = bind_result;
}
sqlite3_finalize(statement);
}
else