mautrix-go/sqlstatestore/v06-displayname-disambiguat...

56 lines
1.7 KiB
Go

// Copyright (c) 2024 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package sqlstatestore
import (
"context"
"go.mau.fi/util/confusable"
"go.mau.fi/util/dbutil"
"maunium.net/go/mautrix/id"
)
type roomUserName struct {
RoomID id.RoomID
UserID id.UserID
Name string
}
func init() {
UpgradeTable.Register(-1, 6, 3, "Add disambiguation column for user profiles", dbutil.TxnModeOn, func(ctx context.Context, db *dbutil.Database) error {
_, err := db.Exec(ctx, `
ALTER TABLE mx_user_profile ADD COLUMN name_skeleton bytea;
CREATE INDEX mx_user_profile_membership_idx ON mx_user_profile (room_id, membership);
CREATE INDEX mx_user_profile_name_skeleton_idx ON mx_user_profile (room_id, name_skeleton);
`)
if err != nil {
return err
}
const ChunkSize = 1000
const GetEntriesChunkQuery = "SELECT room_id, user_id, displayname FROM mx_user_profile WHERE displayname<>'' LIMIT $1 OFFSET $2"
const SetSkeletonHashQuery = `UPDATE mx_user_profile SET name_skeleton = $3 WHERE room_id = $1 AND user_id = $2`
for offset := 0; ; offset += ChunkSize {
entries, err := dbutil.NewSimpleReflectRowIter[roomUserName](db.Query(ctx, GetEntriesChunkQuery, ChunkSize, offset)).AsList()
if err != nil {
return err
}
for _, entry := range entries {
skel := confusable.SkeletonHash(entry.Name)
_, err = db.Exec(ctx, SetSkeletonHashQuery, entry.RoomID, entry.UserID, skel[:])
if err != nil {
return err
}
}
if len(entries) < ChunkSize {
break
}
}
return nil
})
}