Changeset 0.25.4 (#164)
This commit is contained in:
@@ -171,8 +171,11 @@ func (h *SettingsHandler) GetSettings(c *gin.Context) {
|
||||
userID := getUserID(c)
|
||||
|
||||
var settingsRaw string
|
||||
// Handle three states: SQL NULL, JSON null, or valid JSON object.
|
||||
// NULLIF(settings, 'null') converts JSON null to SQL NULL,
|
||||
// then COALESCE handles both SQL NULL cases.
|
||||
err := database.DB.QueryRow(
|
||||
database.Q(`SELECT settings::text FROM users WHERE id = $1`), userID,
|
||||
database.Q(`SELECT COALESCE(NULLIF(settings::text, 'null'), '{}') FROM users WHERE id = $1`), userID,
|
||||
).Scan(&settingsRaw)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to load settings"})
|
||||
@@ -202,12 +205,25 @@ func (h *SettingsHandler) UpdateSettings(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// JSONB merge — existing keys preserved, incoming keys overwrite
|
||||
// JSONB merge — existing keys preserved, incoming keys overwrite.
|
||||
// Must handle three column states:
|
||||
// 1. SQL NULL (never saved)
|
||||
// 2. JSON literal null (corrupted by earlier bug)
|
||||
// 3. JSON array (corrupted by repeated appends to null)
|
||||
// 4. Valid JSON object (normal)
|
||||
// NULLIF converts JSON null → SQL NULL, then COALESCE → '{}',
|
||||
// and we enforce jsonb_typeof = 'object' to catch array corruption.
|
||||
var mergeQuery string
|
||||
if database.IsSQLite() {
|
||||
mergeQuery = `UPDATE users SET settings = json_patch(settings, ?), updated_at = datetime('now') WHERE id = ?`
|
||||
mergeQuery = `UPDATE users SET settings = json_patch(
|
||||
CASE WHEN settings IS NULL OR settings = 'null' OR json_type(settings) != 'object'
|
||||
THEN '{}' ELSE settings END,
|
||||
?), updated_at = datetime('now') WHERE id = ?`
|
||||
} else {
|
||||
mergeQuery = `UPDATE users SET settings = settings || $1::jsonb, updated_at = NOW() WHERE id = $2`
|
||||
mergeQuery = `UPDATE users SET settings = (
|
||||
CASE WHEN settings IS NULL OR settings = 'null'::jsonb OR jsonb_typeof(settings) != 'object'
|
||||
THEN '{}'::jsonb ELSE settings END
|
||||
) || $1::jsonb, updated_at = NOW() WHERE id = $2`
|
||||
}
|
||||
_, err = database.DB.Exec(mergeQuery, string(patch), userID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user