Use dbutil for mass insert query building

This commit is contained in:
Tulir Asokan 2024-02-25 01:31:53 +02:00
parent 2aaed5fc9f
commit 2d02241fc4
4 changed files with 17 additions and 46 deletions

View file

@ -18,7 +18,6 @@ package database
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"time" "time"
@ -62,10 +61,6 @@ const (
INSERT INTO message (conv_id, conv_receiver, id, mxid, mx_room, sender, timestamp, status) INSERT INTO message (conv_id, conv_receiver, id, mxid, mx_room, sender, timestamp, status)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
` `
massInsertMessageQueryPrefix = `
INSERT INTO message (conv_id, conv_receiver, id, mxid, mx_room, sender, timestamp, status)
VALUES
`
updateMessageQuery = ` updateMessageQuery = `
UPDATE message UPDATE message
SET conv_id=$1, mxid=$4, mx_room=$5, sender=$6, timestamp=$7, status=$8 SET conv_id=$1, mxid=$4, mx_room=$5, sender=$6, timestamp=$7, status=$8
@ -75,6 +70,8 @@ const (
deleteMessageQuery = "DELETE FROM message WHERE conv_id=$1 AND conv_receiver=$2 AND id=$3" deleteMessageQuery = "DELETE FROM message WHERE conv_id=$1 AND conv_receiver=$2 AND id=$3"
) )
var massInsertMessageBuilder = dbutil.NewMassInsertBuilder[*Message, [3]any](insertMessageQuery, "($1, $2, $%d, $%d, $3, $%d, $%d, $%d)")
func (mq *MessageQuery) GetByID(ctx context.Context, receiver int, messageID string) (*Message, error) { func (mq *MessageQuery) GetByID(ctx context.Context, receiver int, messageID string) (*Message, error) {
return mq.QueryOne(ctx, getMessageByIDQuery, receiver, messageID) return mq.QueryOne(ctx, getMessageByIDQuery, receiver, messageID)
} }
@ -154,26 +151,12 @@ func (msg *Message) Insert(ctx context.Context) error {
return msg.qh.Exec(ctx, insertMessageQuery, msg.sqlVariables()...) return msg.qh.Exec(ctx, insertMessageQuery, msg.sqlVariables()...)
} }
func (msg *Message) GetMassInsertValues() [5]any {
return [...]any{msg.ID, msg.MXID, msg.Sender, msg.Timestamp.UnixMicro(), dbutil.JSON{Data: &msg.Status}}
}
func (mq *MessageQuery) MassInsert(ctx context.Context, messages []*Message) error { func (mq *MessageQuery) MassInsert(ctx context.Context, messages []*Message) error {
valueStringFormat := "($1, $2, $%d, $%d, $3, $%d, $%d, $%d)" query, params := massInsertMessageBuilder.Build([3]any{messages[0].Chat.ID, messages[0].Chat.Receiver, messages[0].RoomID}, messages)
if mq.GetDB().Dialect == dbutil.SQLite {
valueStringFormat = strings.ReplaceAll(valueStringFormat, "$", "?")
}
placeholders := make([]string, len(messages))
params := make([]any, 3+len(messages)*5)
params[0] = messages[0].Chat.ID
params[1] = messages[0].Chat.Receiver
params[2] = messages[0].RoomID
for i, msg := range messages {
baseIndex := 3 + i*5
params[baseIndex] = msg.ID
params[baseIndex+1] = msg.MXID
params[baseIndex+2] = msg.Sender
params[baseIndex+3] = msg.Timestamp.UnixMicro()
params[baseIndex+4] = dbutil.JSON{Data: &msg.Status}
placeholders[i] = fmt.Sprintf(valueStringFormat, baseIndex+1, baseIndex+2, baseIndex+3, baseIndex+4, baseIndex+5)
}
query := massInsertMessageQueryPrefix + strings.Join(placeholders, ",")
return mq.Exec(ctx, query, params...) return mq.Exec(ctx, query, params...)
} }

View file

@ -18,8 +18,6 @@ package database
import ( import (
"context" "context"
"fmt"
"strings"
"go.mau.fi/util/dbutil" "go.mau.fi/util/dbutil"
"maunium.net/go/mautrix/id" "maunium.net/go/mautrix/id"
@ -59,6 +57,8 @@ const (
deleteReactionQuery = "DELETE FROM reaction WHERE conv_id=$1 AND conv_receiver=$2 AND msg_id=$3 AND sender=$4" deleteReactionQuery = "DELETE FROM reaction WHERE conv_id=$1 AND conv_receiver=$2 AND msg_id=$3 AND sender=$4"
) )
var massInsertReactionBuilder = dbutil.NewMassInsertBuilder[*Reaction, [2]any](insertReactionQuery, "($1, $2, $%d, $%d, $%d, $%d)")
func (rq *ReactionQuery) GetByID(ctx context.Context, receiver int, messageID, sender string) (*Reaction, error) { func (rq *ReactionQuery) GetByID(ctx context.Context, receiver int, messageID, sender string) (*Reaction, error) {
return rq.QueryOne(ctx, getReactionByIDQuery, receiver, messageID, sender) return rq.QueryOne(ctx, getReactionByIDQuery, receiver, messageID, sender)
} }
@ -93,24 +93,12 @@ func (r *Reaction) Insert(ctx context.Context) error {
return r.qh.Exec(ctx, insertReactionQuery, r.Chat.ID, r.Chat.Receiver, r.MessageID, r.Sender, r.Reaction, r.MXID) return r.qh.Exec(ctx, insertReactionQuery, r.Chat.ID, r.Chat.Receiver, r.MessageID, r.Sender, r.Reaction, r.MXID)
} }
func (r *Reaction) GetMassInsertValues() [4]any {
return [...]any{r.MessageID, r.Sender, r.Reaction, r.MXID}
}
func (rq *ReactionQuery) MassInsert(ctx context.Context, reactions []*Reaction) error { func (rq *ReactionQuery) MassInsert(ctx context.Context, reactions []*Reaction) error {
valueStringFormat := "($1, $2, $%d, $%d, $%d, $%d)" query, params := massInsertReactionBuilder.Build([2]any{reactions[0].Chat.ID, reactions[0].Chat.Receiver}, reactions)
if rq.GetDB().Dialect == dbutil.SQLite {
valueStringFormat = strings.ReplaceAll(valueStringFormat, "$", "?")
}
placeholders := make([]string, len(reactions))
params := make([]any, 2+len(reactions)*4)
params[0] = reactions[0].Chat.ID
params[1] = reactions[0].Chat.Receiver
for i, msg := range reactions {
baseIndex := 2 + i*4
params[baseIndex] = msg.MessageID
params[baseIndex+1] = msg.Sender
params[baseIndex+2] = msg.Reaction
params[baseIndex+3] = msg.MXID
placeholders[i] = fmt.Sprintf(valueStringFormat, baseIndex+1, baseIndex+2, baseIndex+3, baseIndex+4)
}
query := strings.Replace(insertReactionQuery, "($1, $2, $3, $4, $5, $6)", strings.Join(placeholders, ","), 1)
return rq.Exec(ctx, query, params...) return rq.Exec(ctx, query, params...)
} }

2
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/rs/zerolog v1.32.0 github.com/rs/zerolog v1.32.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
go.mau.fi/mautrix-gmessages/libgm v0.3.0 go.mau.fi/mautrix-gmessages/libgm v0.3.0
go.mau.fi/util v0.4.1 go.mau.fi/util v0.4.2-0.20240317181036-e3ab4975c61c
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f
google.golang.org/protobuf v1.33.0 google.golang.org/protobuf v1.33.0
maunium.net/go/mautrix v0.18.0 maunium.net/go/mautrix v0.18.0

4
go.sum
View file

@ -60,8 +60,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
go.mau.fi/util v0.4.1 h1:3EC9KxIXo5+h869zDGf5OOZklRd/FjeVnimTwtm3owg= go.mau.fi/util v0.4.2-0.20240317181036-e3ab4975c61c h1:LnkEFlUnKcvCNzMDCT2sEuFOYi7zjF/HXvE4SnVrTZU=
go.mau.fi/util v0.4.1/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY= go.mau.fi/util v0.4.2-0.20240317181036-e3ab4975c61c/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY=
go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto=
go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=