fix: resolve P1 backend consistency issues

This commit is contained in:
richjohnrambo
2026-09-08 16:23:21 +08:00
parent 06945a4050
commit 0b3c0b1c78
13 changed files with 587 additions and 57 deletions
+4
View File
@@ -167,6 +167,10 @@ func ensureIMGroupBusinessTables(exec sqlExecutor) error {
PRIMARY KEY(id), UNIQUE INDEX uk_im_group_events_outbox_event(event_id),
INDEX idx_im_group_events_outbox_pending(status, next_retry_at, id), INDEX idx_im_group_events_outbox_topic(topic, id DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci`,
`UPDATE im_topics SET public=JSON_SET(public, '$.fn', JSON_UNQUOTE(JSON_EXTRACT(public, '$.name')))
WHERE name LIKE 'grp%' AND JSON_VALID(public)
AND COALESCE(JSON_UNQUOTE(JSON_EXTRACT(public, '$.fn')), '') = ''
AND COALESCE(JSON_UNQUOTE(JSON_EXTRACT(public, '$.name')), '') <> ''`,
}
for _, statement := range statements {
if _, err := exec.Exec(statement); err != nil {
+5 -2
View File
@@ -22,8 +22,8 @@ func TestEnsureIMGroupBusinessTablesUsesSelectedTenantDatabase(t *testing.T) {
if err := ensureIMGroupBusinessTables(exec); err != nil {
t.Fatal(err)
}
if len(exec.statements) != 13 {
t.Fatalf("created %d group tables, want 13", len(exec.statements))
if len(exec.statements) != 14 {
t.Fatalf("executed %d group schema statements, want 14", len(exec.statements))
}
for _, statement := range exec.statements {
if strings.Contains(strings.ToLower(statement), "tinode.") || strings.Contains(strings.ToLower(statement), "create database") {
@@ -40,4 +40,7 @@ func TestEnsureIMGroupBusinessTablesUsesSelectedTenantDatabase(t *testing.T) {
t.Fatalf("group schema is missing snowflake primary-key definition %q", expected)
}
}
if !strings.Contains(joined, "json_set(public, '$.fn'") {
t.Fatal("group schema is missing historical public.fn backfill")
}
}
+12 -3
View File
@@ -7051,15 +7051,17 @@ func (a *adapter) TenantTopicDraftPut(id t.TenantID, uid t.Uid, topic, content s
return nil, err
}
now := t.TimeNow()
_, err = a.db.ExecContext(ctx, `INSERT INTO im_topic_drafts
res, err := a.db.ExecContext(ctx, `INSERT INTO im_topic_drafts
(id,user_id,topic,content,entities_json,version,created_at,updated_at)
VALUES(?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE content=VALUES(content),entities_json=VALUES(entities_json),
version=version+1,updated_at=VALUES(updated_at)`,
ON DUPLICATE KEY UPDATE id=id`,
draftID, decodeUID(uid), strings.TrimSpace(topic), content, entities, 1, now, now)
if err != nil {
return nil, err
}
if affected, _ := res.RowsAffected(); affected == 0 {
return nil, t.ErrInvalidResponse
}
return a.topicDraftByKey(ctx, uid, strings.TrimSpace(topic))
}
res, err := a.db.ExecContext(ctx, `UPDATE im_topic_drafts
@@ -9210,6 +9212,13 @@ func (a *adapter) TenantFriendRequestAccept(id t.TenantID, requestID string, act
row.HandledAt = &handledAt
row.UpdatedAt = handledAt
}
if _, err = tx.ExecContext(ctx, `UPDATE im_friend_requests SET status=?,handled_at=?,updated_at=?
WHERE request_id<>? AND status=? AND
((applicant_id=? AND target_id=?) OR (applicant_id=? AND target_id=?))`,
t.FriendRequestExpired, handledAt, handledAt, requestID, t.FriendRequestPending,
decodeUID(applicant), decodeUID(target), decodeUID(target), decodeUID(applicant)); err != nil {
return nil, err
}
for _, pair := range [][2]t.Uid{{applicant, target}, {target, applicant}} {
friendshipID, idErr := nextSnowflakeID()
if idErr != nil {
+30 -2
View File
@@ -936,11 +936,16 @@ func (a *adapter) TenantGroupFileCreate(id t.TenantID, file *t.GroupFile) (*t.Gr
}
a.enrichGroupFileFromUpload(id, file)
now := t.TimeNow()
ctx, cancel := a.getContext()
ctx, cancel := a.getContextForTx()
if cancel != nil {
defer cancel()
}
_, err := a.db.ExecContext(ctx, `INSERT INTO im_group_files
tx, err := a.db.BeginTxx(ctx, nil)
if err != nil {
return nil, err
}
defer tx.Rollback()
_, err = tx.ExecContext(ctx, `INSERT INTO im_group_files
(group_file_id,topic,file_id,source_topic,source_seq,uploader_id,file_name,mime_type,file_type,file_size,status,idempotency_key,created_at,updated_at)
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE
@@ -954,6 +959,29 @@ func (a *adapter) TenantGroupFileCreate(id t.TenantID, file *t.GroupFile) (*t.Gr
if err != nil && !isDupe(err) {
return nil, err
}
uploadID := strings.TrimSpace(file.FileID)
if dot := strings.IndexByte(uploadID, '.'); dot > 0 {
uploadID = uploadID[:dot]
}
if fid := t.ParseUid(uploadID); !fid.IsZero() {
if a.tenantScopedDB {
_, err = tx.ExecContext(ctx, `INSERT INTO im_filemsglinks(createdat,fileid,topic)
SELECT ?,?,? WHERE NOT EXISTS (
SELECT 1 FROM im_filemsglinks WHERE fileid=? AND topic=?)`,
now, decodeUID(fid), file.Topic, decodeUID(fid), file.Topic)
} else {
_, err = tx.ExecContext(ctx, `INSERT INTO im_filemsglinks(tenant_id,createdat,fileid,topic)
SELECT ?,?,?,? WHERE NOT EXISTS (
SELECT 1 FROM im_filemsglinks WHERE tenant_id=? AND fileid=? AND topic=?)`,
id, now, decodeUID(fid), file.Topic, id, decodeUID(fid), file.Topic)
}
if err != nil {
return nil, err
}
}
if err = tx.Commit(); err != nil {
return nil, err
}
created, err := a.groupFileByQuery(ctx, "SELECT * FROM im_group_files WHERE topic=? AND file_id=?", file.Topic, file.FileID)
if err != nil {
return nil, err