101 lines
3.2 KiB
Go
101 lines
3.2 KiB
Go
package mysql
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
roomv1 "hyapp.local/api/proto/room/v1"
|
|
"hyapp/pkg/appcode"
|
|
roomservice "hyapp/services/room-service/internal/room/service"
|
|
)
|
|
|
|
const ownerCountryRoomExtKey = "owner_country_code"
|
|
|
|
type ownerCountrySnapshotUpdate struct {
|
|
roomID string
|
|
roomVersion int64
|
|
payload []byte
|
|
}
|
|
|
|
// RenameOwnerCountryCode 同事务刷新房间当前列表投影和最新快照中的房主国家码。
|
|
// command_log 保留房间发生时事实,因此这里明确只碰当前读模型,供后台国家码重命名任务收敛线上展示态。
|
|
func (r *Repository) RenameOwnerCountryCode(ctx context.Context, oldCountryCode string, newCountryCode string, nowMS int64) (roomservice.OwnerCountryCodeRenameResult, error) {
|
|
app := appcode.FromContext(ctx)
|
|
var result roomservice.OwnerCountryCodeRenameResult
|
|
tx, err := r.db.BeginTx(ctx, &sql.TxOptions{})
|
|
if err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
rows, err := tx.QueryContext(ctx, `
|
|
SELECT room_id, room_version, payload
|
|
FROM room_snapshots
|
|
WHERE app_code = ?
|
|
FOR UPDATE
|
|
`, app)
|
|
if err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
|
|
updates := []ownerCountrySnapshotUpdate{}
|
|
for rows.Next() {
|
|
var update ownerCountrySnapshotUpdate
|
|
if err := rows.Scan(&update.roomID, &update.roomVersion, &update.payload); err != nil {
|
|
_ = rows.Close()
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
var snapshot roomv1.RoomSnapshot
|
|
if err := proto.Unmarshal(update.payload, &snapshot); err != nil {
|
|
_ = rows.Close()
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
if snapshot.RoomExt == nil || snapshot.RoomExt[ownerCountryRoomExtKey] != oldCountryCode {
|
|
continue
|
|
}
|
|
snapshot.RoomExt[ownerCountryRoomExtKey] = newCountryCode
|
|
body, err := proto.Marshal(&snapshot)
|
|
if err != nil {
|
|
_ = rows.Close()
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
update.payload = body
|
|
updates = append(updates, update)
|
|
}
|
|
if err := rows.Close(); err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
|
|
listResult, err := tx.ExecContext(ctx, `
|
|
UPDATE room_list_entries
|
|
SET owner_country_code = ?, updated_at_ms = ?
|
|
WHERE app_code = ? AND owner_country_code = ?
|
|
`, newCountryCode, nowMS, app, oldCountryCode)
|
|
if err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
result.RoomListEntries, _ = listResult.RowsAffected()
|
|
|
|
for _, update := range updates {
|
|
// room_version 不递增,避免把低频后台投影修复伪装成 Room Cell 状态版本推进。
|
|
affected, err := tx.ExecContext(ctx, `
|
|
UPDATE room_snapshots
|
|
SET payload = ?, updated_at_ms = ?
|
|
WHERE app_code = ? AND room_id = ? AND room_version = ?
|
|
`, update.payload, nowMS, app, update.roomID, update.roomVersion)
|
|
if err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
rowsAffected, _ := affected.RowsAffected()
|
|
result.RoomSnapshots += rowsAffected
|
|
}
|
|
if err := tx.Commit(); err != nil {
|
|
return roomservice.OwnerCountryCodeRenameResult{}, err
|
|
}
|
|
return result, nil
|
|
}
|