Sync profile source and message topic seq
This commit is contained in:
+82
-12
@@ -1055,6 +1055,9 @@ func (a *adapter) UpgradeDb() error {
|
||||
if err := a.ensureMessageTopicSeqIndex(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.ensureTopicSeqMatchesMessages(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if a.version == adpVersion {
|
||||
return nil
|
||||
@@ -1080,6 +1083,61 @@ func (a *adapter) ensureMessageTopicSeqIndex() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *adapter) ensureTopicSeqMatchesMessages() error {
|
||||
ctx := context.Background()
|
||||
conn, err := a.db.Connx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
topicsScoped, err := identityColumnExists(ctx, conn, "im_topics", "tenant_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
messagesScoped, err := identityColumnExists(ctx, conn, "im_messages", "tenant_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if topicsScoped && messagesScoped {
|
||||
if _, err = conn.ExecContext(ctx, `UPDATE im_topics AS t
|
||||
JOIN (SELECT tenant_id,topic,MAX(seqid) AS max_seq FROM im_messages GROUP BY tenant_id,topic) AS m
|
||||
ON m.tenant_id=t.tenant_id AND m.topic COLLATE utf8mb4_unicode_ci=t.name
|
||||
SET t.seqid=GREATEST(t.seqid,m.max_seq)
|
||||
WHERE t.seqid<m.max_seq`); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err = conn.ExecContext(ctx, `UPDATE im_topics AS t
|
||||
JOIN (SELECT topic,MAX(seqid) AS max_seq FROM im_messages GROUP BY topic) AS m ON m.topic COLLATE utf8mb4_unicode_ci=t.name
|
||||
SET t.seqid=GREATEST(t.seqid,m.max_seq)
|
||||
WHERE t.seqid<m.max_seq`); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
groupMessagesExist, err := identityTableExists(ctx, conn, "im_group_messages")
|
||||
if err != nil || !groupMessagesExist {
|
||||
return err
|
||||
}
|
||||
groupMessagesScoped, err := identityColumnExists(ctx, conn, "im_group_messages", "tenant_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if topicsScoped && groupMessagesScoped {
|
||||
_, err = conn.ExecContext(ctx, `UPDATE im_topics AS t
|
||||
JOIN (SELECT tenant_id,topic,MAX(seqid) AS max_seq FROM im_group_messages GROUP BY tenant_id,topic) AS m
|
||||
ON m.tenant_id=t.tenant_id AND m.topic COLLATE utf8mb4_unicode_ci=t.name
|
||||
SET t.seqid=GREATEST(t.seqid,m.max_seq)
|
||||
WHERE t.seqid<m.max_seq`)
|
||||
return err
|
||||
}
|
||||
_, err = conn.ExecContext(ctx, `UPDATE im_topics AS t
|
||||
JOIN (SELECT topic,MAX(seqid) AS max_seq FROM im_group_messages GROUP BY topic) AS m ON m.topic COLLATE utf8mb4_unicode_ci=t.name
|
||||
SET t.seqid=GREATEST(t.seqid,m.max_seq)
|
||||
WHERE t.seqid<m.max_seq`)
|
||||
return err
|
||||
}
|
||||
|
||||
func createIMNotificationTables(tx *sql.Tx) error {
|
||||
_, err := tx.Exec(
|
||||
`CREATE TABLE im_system_notifications(
|
||||
@@ -2019,6 +2077,10 @@ func (a *adapter) UserCreate(user *t.User) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
profileID, err := nextSnowflakeID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var phone any
|
||||
if strings.TrimSpace(user.Phone) != "" {
|
||||
canonicalPhone, err := normalizeUserPhone(user.Phone)
|
||||
@@ -2048,6 +2110,11 @@ func (a *adapter) UserCreate(user *t.User) error {
|
||||
securityID, decoded_uid, 1, user.CreatedAt, user.UpdatedAt); err != nil {
|
||||
return err
|
||||
}
|
||||
nickname, avatarFileID := profileSeedFromPublic(user.Public)
|
||||
if _, err = tx.Exec(`INSERT IGNORE INTO im_user_profiles(id,user_id,avatar_file_id,nickname,public_account,created_at,updated_at)
|
||||
VALUES(?,?,?,?,?,?,?)`, profileID, decoded_uid, avatarFileID, nickname, user.Uid().UserId(), user.CreatedAt, user.UpdatedAt); err != nil {
|
||||
return err
|
||||
}
|
||||
user.Tags = nil
|
||||
|
||||
return tx.Commit()
|
||||
@@ -2316,13 +2383,15 @@ func (a *adapter) UserGet(uid t.Uid) (*t.User, error) {
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
var user t.User
|
||||
err := a.db.GetContext(ctx, &user, `SELECT id,username,createdat,updatedat,state,stateat,access,lastseen,useragent,
|
||||
COALESCE(phone,'') AS phone,public,trusted FROM im_users WHERE id=? AND state!=?`, store.DecodeUid(uid), t.StateDeleted)
|
||||
var row profileUserRow
|
||||
err := a.db.GetContext(ctx, &row, `SELECT u.id,u.username,u.createdat,u.updatedat,u.state,u.stateat,u.access,u.lastseen,u.useragent,
|
||||
COALESCE(u.phone,'') AS phone,u.public,u.trusted,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.updated_at AS profile_updated_at
|
||||
FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id
|
||||
WHERE u.id=? AND u.state!=?`, store.DecodeUid(uid), t.StateDeleted)
|
||||
if err == nil {
|
||||
user := profileUserFromRow(row)
|
||||
user.SetUid(uid)
|
||||
user.Public = common.FromJSON(user.Public)
|
||||
user.Trusted = common.FromJSON(user.Trusted)
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
@@ -2348,8 +2417,11 @@ func (a *adapter) UserGetAll(ids ...t.Uid) ([]t.User, error) {
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
q, uids, _ := sqlx.In(`SELECT id,username,createdat,updatedat,state,stateat,access,lastseen,useragent,
|
||||
COALESCE(phone,'') AS phone,public,trusted FROM im_users WHERE id IN (?) AND state!=?`, uids, t.StateDeleted)
|
||||
q, uids, _ := sqlx.In(`SELECT u.id,u.username,u.createdat,u.updatedat,u.state,u.stateat,u.access,u.lastseen,u.useragent,
|
||||
COALESCE(u.phone,'') AS phone,u.public,u.trusted,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.updated_at AS profile_updated_at
|
||||
FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id
|
||||
WHERE u.id IN (?) AND u.state!=?`, uids, t.StateDeleted)
|
||||
rows, err := a.db.QueryxContext(ctx, a.db.Rebind(q), uids...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -2357,14 +2429,12 @@ func (a *adapter) UserGetAll(ids ...t.Uid) ([]t.User, error) {
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var user t.User
|
||||
if err = rows.StructScan(&user); err != nil {
|
||||
var row profileUserRow
|
||||
if err = rows.StructScan(&row); err != nil {
|
||||
users = nil
|
||||
break
|
||||
}
|
||||
user.SetUid(common.EncodeUidString(user.Id))
|
||||
user.Public = common.FromJSON(user.Public)
|
||||
user.Trusted = common.FromJSON(user.Trusted)
|
||||
user := profileUserFromRow(row)
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user