fix: handle nullable recalled_by in mysql messages
This commit is contained in:
@@ -12,11 +12,17 @@ func TestEnsureIMHTTPInfrastructureTablesUsesSelectedTenantDatabase(t *testing.T
|
|||||||
if err := ensureIMHTTPInfrastructureTables(exec); err != nil {
|
if err := ensureIMHTTPInfrastructureTables(exec); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if len(exec.statements) != 2 {
|
if len(exec.statements) != 5 {
|
||||||
t.Fatalf("created %d infrastructure tables, want 2", len(exec.statements))
|
t.Fatalf("created %d infrastructure tables, want 5", len(exec.statements))
|
||||||
}
|
}
|
||||||
joined := strings.ToLower(strings.Join(exec.statements, "\n"))
|
joined := strings.ToLower(strings.Join(exec.statements, "\n"))
|
||||||
for _, table := range []string{"im_http_idempotency", "im_business_events_outbox"} {
|
for _, table := range []string{
|
||||||
|
"im_http_idempotency",
|
||||||
|
"im_business_events_outbox",
|
||||||
|
"im_realname_appeals",
|
||||||
|
"im_conversation_settings",
|
||||||
|
"im_topic_drafts",
|
||||||
|
} {
|
||||||
if !strings.Contains(joined, table) {
|
if !strings.Contains(joined, table) {
|
||||||
t.Fatalf("missing table %s", table)
|
t.Fatalf("missing table %s", table)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,16 @@ func stampTenantMessage(id t.TenantID, msg *t.Message) *t.Message {
|
|||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func finalizeTenantMessage(id t.TenantID, msg t.Message, recalledBy sql.NullInt64) t.Message {
|
||||||
|
msg.TenantID = id
|
||||||
|
msg.From = common.EncodeUidString(msg.From).String()
|
||||||
|
if recalledBy.Valid {
|
||||||
|
msg.RecalledBy = common.EncodeUidString(strconv.FormatInt(recalledBy.Int64, 10)).String()
|
||||||
|
}
|
||||||
|
msg.Content = common.FromJSON(msg.Content)
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
func stampTenantFile(id t.TenantID, file *t.FileDef) *t.FileDef {
|
func stampTenantFile(id t.TenantID, file *t.FileDef) *t.FileDef {
|
||||||
if file != nil {
|
if file != nil {
|
||||||
file.TenantID = id
|
file.TenantID = id
|
||||||
@@ -1659,20 +1669,21 @@ func (a *adapter) TenantMessageGetByClientID(id t.TenantID, from t.Uid, clientMs
|
|||||||
if cancel != nil {
|
if cancel != nil {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
var msg t.Message
|
row := struct {
|
||||||
|
t.Message
|
||||||
|
RecalledBy sql.NullInt64 `db:"recalled_by"`
|
||||||
|
}{}
|
||||||
err := a.db.QueryRowxContext(ctx,
|
err := a.db.QueryRowxContext(ctx,
|
||||||
"SELECT id,createdat,updatedat,deletedat,delid,seqid,topic,`from`,client_msg_id,version,recalled_at,recalled_by,head,content "+
|
"SELECT id,createdat,updatedat,deletedat,delid,seqid,topic,`from`,client_msg_id,version,recalled_at,recalled_by,head,content "+
|
||||||
"FROM im_messages WHERE `from`=? AND client_msg_id=?",
|
"FROM im_messages WHERE `from`=? AND client_msg_id=?",
|
||||||
decodeUID(from), clientMsgID).StructScan(&msg)
|
decodeUID(from), clientMsgID).StructScan(&row)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msg.From = common.EncodeUidString(msg.From).String()
|
msg := finalizeTenantMessage(id, row.Message, row.RecalledBy)
|
||||||
msg.Content = common.FromJSON(msg.Content)
|
|
||||||
msg.TenantID = id
|
|
||||||
return &msg, nil
|
return &msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1865,13 +1876,14 @@ func (a *adapter) TenantMessageGetAll(id t.TenantID, topic string, uid t.Uid, op
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
msgs := make([]t.Message, 0, limit)
|
msgs := make([]t.Message, 0, limit)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var msg t.Message
|
row := struct {
|
||||||
if err = rows.StructScan(&msg); err != nil {
|
t.Message
|
||||||
|
RecalledBy sql.NullInt64 `db:"recalled_by"`
|
||||||
|
}{}
|
||||||
|
if err = rows.StructScan(&row); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msg.From = common.EncodeUidString(msg.From).String()
|
msgs = append(msgs, finalizeTenantMessage(id, row.Message, row.RecalledBy))
|
||||||
msg.Content = common.FromJSON(msg.Content)
|
|
||||||
msgs = append(msgs, msg)
|
|
||||||
}
|
}
|
||||||
return msgs, rows.Err()
|
return msgs, rows.Err()
|
||||||
}
|
}
|
||||||
@@ -1929,14 +1941,15 @@ func (a *adapter) TenantMessageSearch(id t.TenantID, topic string, uid t.Uid, qu
|
|||||||
msgs := make([]t.Message, 0, limit)
|
msgs := make([]t.Message, 0, limit)
|
||||||
nextCursor := ""
|
nextCursor := ""
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var msg t.Message
|
row := struct {
|
||||||
if err = rows.StructScan(&msg); err != nil {
|
t.Message
|
||||||
|
RecalledBy sql.NullInt64 `db:"recalled_by"`
|
||||||
|
}{}
|
||||||
|
if err = rows.StructScan(&row); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
msg.From = common.EncodeUidString(msg.From).String()
|
msg := finalizeTenantMessage(id, row.Message, row.RecalledBy)
|
||||||
msg.Head = kvMapFromJSON(msg.Head)
|
msg.Head = kvMapFromJSON(msg.Head)
|
||||||
msg.Content = common.FromJSON(msg.Content)
|
|
||||||
msg.TenantID = id
|
|
||||||
if len(msgs) == limit {
|
if len(msgs) == limit {
|
||||||
nextCursor = strconv.Itoa(msg.SeqId)
|
nextCursor = strconv.Itoa(msg.SeqId)
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user