🎨 Parameterized label query statements and escaping LIKE wildcards (#17416)

This commit is contained in:
Jeffrey Chen
2026-04-06 09:30:04 +08:00
committed by GitHub
parent b62273eb00
commit f9c5c482b8

View File

@@ -25,6 +25,18 @@ import (
"github.com/siyuan-note/logging"
)
func escapeLikePattern(s string) string {
var b strings.Builder
b.Grow(len(s))
for _, r := range s {
if r == '%' || r == '_' || r == '\\' {
b.WriteRune('\\')
}
b.WriteRune(r)
}
return b.String()
}
type Span struct {
ID string
BlockID string
@@ -82,12 +94,14 @@ func SelectSpansRawStmt(stmt string, limit int) (ret []*Span) {
func QueryTagSpansByLabel(label string) (ret []*Span) {
var stmt string
var args []any
if "" != label {
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND content LIKE '%" + label + "%' GROUP BY block_id"
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND content LIKE ? ESCAPE '\\' GROUP BY block_id"
args = append(args, "%"+escapeLikePattern(label)+"%")
} else {
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND content = '' GROUP BY block_id"
}
rows, err := query(stmt)
rows, err := query(stmt, args...)
if err != nil {
logging.LogErrorf("sql query failed: %s", err)
return
@@ -104,19 +118,18 @@ func QueryTagSpansByKeyword(keyword string, limit int) (ret []*Span) {
// 标签搜索支持空格分隔关键字 Tag search supports space-separated keywords https://github.com/siyuan-note/siyuan/issues/14580
keywords := strings.Fields(keyword)
var stmt string
var args []any
if len(keywords) == 0 {
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND content != '' GROUP BY markdown LIMIT " + strconv.Itoa(limit)
} else {
contentLikes := ""
var likes []string
for _, k := range keywords {
if contentLikes != "" {
contentLikes += " AND "
}
contentLikes += "content LIKE '%" + k + "%'"
likes = append(likes, "content LIKE ? ESCAPE '\\'")
args = append(args, "%"+escapeLikePattern(k)+"%")
}
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND (" + contentLikes + ") GROUP BY markdown LIMIT " + strconv.Itoa(limit)
stmt = "SELECT * FROM spans WHERE type LIKE '%tag%' AND (" + strings.Join(likes, " AND ") + ") GROUP BY markdown LIMIT " + strconv.Itoa(limit)
}
rows, err := query(stmt)
rows, err := query(stmt, args...)
if err != nil {
logging.LogErrorf("sql query failed: %s", err)
return
@@ -131,10 +144,12 @@ func QueryTagSpansByKeyword(keyword string, limit int) (ret []*Span) {
func QueryTagSpans(p string) (ret []*Span) {
stmt := "SELECT * FROM spans WHERE type LIKE '%tag%'"
var args []any
if "" != p {
stmt += " AND path = '" + p + "'"
stmt += " AND path = ?"
args = append(args, p)
}
rows, err := query(stmt)
rows, err := query(stmt, args...)
if err != nil {
logging.LogErrorf("sql query failed: %s", err)
return