diff --git a/dice/ext_log.go b/dice/ext_log.go index 3b629fc2f..14d6c7c85 100644 --- a/dice/ext_log.go +++ b/dice/ext_log.go @@ -196,7 +196,7 @@ func RegisterBuiltinExtLog(self *Dice) { } if name != "" { - lines, exists := model.LogLinesCountGet(ctx.Dice.DBLogs, group.GroupID, name) + lineCount, lastLine, exists := model.LogGetCountAndLastLine(ctx.Dice.DBLogs, group.GroupID, name) if exists { if groupNotActiveCheck() { @@ -208,15 +208,9 @@ func RegisterBuiltinExtLog(self *Dice) { group.UpdatedAtTime = time.Now().Unix() VarSetValueStr(ctx, "$t记录名称", name) - VarSetValueInt64(ctx, "$t当前记录条数", lines) - - logEnabledPrompt := DiceFormatTmpl(ctx, "日志:记录_开启_成功") - // TODO: 到这里相当于全文 query 了两遍日志。可以优化吗? - lastRecord, err := model.LogGetLastLine(ctx.Dice.DBLogs, group.GroupID, name) - if err == nil { - logEnabledPrompt = fmt.Sprintf("[CQ:reply,id=%v] %s", lastRecord.RawMsgID, logEnabledPrompt) - } + VarSetValueInt64(ctx, "$t当前记录条数", lineCount) + logEnabledPrompt := fmt.Sprintf("[CQ:reply,id=%v] %s", lastLine.RawMsgID, DiceFormatTmpl(ctx, "日志:记录_开启_成功")) ReplyToSender(ctx, msg, logEnabledPrompt) } else { VarSetValueStr(ctx, "$t记录名称", name) diff --git a/dice/model/log.go b/dice/model/log.go index fc7e350a1..cbcd3b36c 100644 --- a/dice/model/log.go +++ b/dice/model/log.go @@ -532,3 +532,34 @@ LIMIT 1` } return &record, nil } + +// LogGetCountAndLastLine performs a specialised union search. +func LogGetCountAndLastLine(db *sqlx.DB, groupID, logName string) (lineCount int64, lastLine *LogOneItem, exists bool) { + logID, err := LogGetIDByGroupIDAndName(db, groupID, logName) + if err != nil { + return + } + + const filterQuery = ` +WITH filtered AS ( + SELECT id, nickname, im_userid, time, message, is_dice, command_id, command_info, raw_msg_id, user_uniform_id + FROM log_items + WHERE log_id=$1 AND removed IS NULL +) +SELECT COUNT(*) OVER () AS line_count, * +FROM filtered +ORDER BY time DESC +LIMIT 1` + + type QueryResult struct { + LineCount int64 `db:"line_count"` + LogOneItem + } + + var result QueryResult + if err = db.Get(&result, filterQuery, logID); err != nil { + return + } + + return result.LineCount, &result.LogOneItem, true +}