diff --git a/store/db/sqlite/memo.go b/store/db/sqlite/memo.go index c5c65321..3f8e290e 100644 --- a/store/db/sqlite/memo.go +++ b/store/db/sqlite/memo.go @@ -113,7 +113,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo if err != nil { return nil, err } - where = append(where, condition) + where = append(where, fmt.Sprintf("(%s)", condition)) } if find.ExcludeComments { where = append(where, "`parent_id` IS NULL") diff --git a/store/db/sqlite/memo_filter.go b/store/db/sqlite/memo_filter.go index f77f3475..f4954db2 100644 --- a/store/db/sqlite/memo_filter.go +++ b/store/db/sqlite/memo_filter.go @@ -18,21 +18,22 @@ func RestoreExprToSQL(expr *exprv1.Expr) (string, error) { case *exprv1.Expr_CallExpr: switch v.CallExpr.Function { case "_||_", "_&&_": - for _, arg := range v.CallExpr.Args { - left, err := RestoreExprToSQL(arg) - if err != nil { - return "", err - } - right, err := RestoreExprToSQL(arg) - if err != nil { - return "", err - } - operator := "AND" - if v.CallExpr.Function == "_||_" { - operator = "OR" - } - condition = fmt.Sprintf("(%s %s %s)", left, operator, right) + if len(v.CallExpr.Args) != 2 { + return "", errors.Errorf("invalid number of arguments for %s", v.CallExpr.Function) } + left, err := RestoreExprToSQL(v.CallExpr.Args[0]) + if err != nil { + return "", err + } + right, err := RestoreExprToSQL(v.CallExpr.Args[1]) + if err != nil { + return "", err + } + operator := "AND" + if v.CallExpr.Function == "_||_" { + operator = "OR" + } + condition = fmt.Sprintf("(%s %s %s)", left, operator, right) case "_==_", "_!=_", "_<_", "_>_", "_<=_", "_>=_": if len(v.CallExpr.Args) != 2 { return "", errors.Errorf("invalid number of arguments for %s", v.CallExpr.Function) @@ -130,7 +131,7 @@ func RestoreExprToSQL(expr *exprv1.Expr) (string, error) { if err != nil { return "", err } - condition = fmt.Sprintf("`memo`.`content` LIKE %s", fmt.Sprintf(`%%"%s"%%`, arg)) + condition = fmt.Sprintf("`memo`.`content` LIKE %s", fmt.Sprintf(`'%%%s%%'`, arg)) case "!_": if len(v.CallExpr.Args) != 1 { return "", errors.Errorf("invalid number of arguments for %s", v.CallExpr.Function) diff --git a/store/db/sqlite/memo_filter_test.go b/store/db/sqlite/memo_filter_test.go index 40577210..6cd56635 100644 --- a/store/db/sqlite/memo_filter_test.go +++ b/store/db/sqlite/memo_filter_test.go @@ -23,11 +23,11 @@ func TestRestoreExprToSQL(t *testing.T) { }, { filter: `tag in ["tag1", "tag2"] || tag in ["tag3", "tag4"]`, - want: "((JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag3\"%' OR JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag4\"%') OR (JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag3\"%' OR JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag4\"%'))", + want: "((JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag1\"%' OR JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag2\"%') OR (JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag3\"%' OR JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag4\"%'))", }, { filter: `content.contains("memos")`, - want: "`memo`.`content` LIKE %\"memos\"%", + want: "`memo`.`content` LIKE '%memos%'", }, { filter: `visibility in ["PUBLIC"]`, @@ -41,6 +41,10 @@ func TestRestoreExprToSQL(t *testing.T) { filter: `create_time == "2006-01-02T15:04:05+07:00"`, want: "`memo`.`created_ts` = 1136189045", }, + { + filter: `tag in ['tag1'] || content.contains('hello')`, + want: "(JSON_EXTRACT(`memo`.`payload`, '$.tags') LIKE '%\"tag1\"%' OR `memo`.`content` LIKE '%hello%')", + }, } for _, tt := range tests {