diff --git a/database/message.go b/database/message.go index c67f80b..e55c40a 100644 --- a/database/message.go +++ b/database/message.go @@ -18,7 +18,6 @@ package database import ( "context" - "fmt" "strings" "time" @@ -62,10 +61,6 @@ const ( INSERT INTO message (conv_id, conv_receiver, id, mxid, mx_room, sender, timestamp, status) 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 = ` UPDATE message 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" ) +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) { 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()...) } +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 { - valueStringFormat := "($1, $2, $%d, $%d, $3, $%d, $%d, $%d)" - 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, ",") + query, params := massInsertMessageBuilder.Build([3]any{messages[0].Chat.ID, messages[0].Chat.Receiver, messages[0].RoomID}, messages) return mq.Exec(ctx, query, params...) } diff --git a/database/reaction.go b/database/reaction.go index 643b7fd..09c935c 100644 --- a/database/reaction.go +++ b/database/reaction.go @@ -18,8 +18,6 @@ package database import ( "context" - "fmt" - "strings" "go.mau.fi/util/dbutil" "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" ) +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) { 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) } +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 { - valueStringFormat := "($1, $2, $%d, $%d, $%d, $%d)" - 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) + query, params := massInsertReactionBuilder.Build([2]any{reactions[0].Chat.ID, reactions[0].Chat.Receiver}, reactions) return rq.Exec(ctx, query, params...) } diff --git a/go.mod b/go.mod index f008d2a..f3bc0fd 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/rs/zerolog v1.32.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e 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 google.golang.org/protobuf v1.33.0 maunium.net/go/mautrix v0.18.0 diff --git a/go.sum b/go.sum index 1089590..026e3ae 100644 --- a/go.sum +++ b/go.sum @@ -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/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= 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.1/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY= +go.mau.fi/util v0.4.2-0.20240317181036-e3ab4975c61c h1:LnkEFlUnKcvCNzMDCT2sEuFOYi7zjF/HXvE4SnVrTZU= +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/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=