mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Add search string parsing (#1982)
* Add search string parsing * Add manual page
This commit is contained in:
@@ -237,9 +237,7 @@ func (qb *galleryQueryBuilder) makeQuery(galleryFilter *models.GalleryFilterType
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"galleries.title", "galleries.path", "galleries.checksum"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(galleryFilter); err != nil {
|
||||
|
||||
@@ -265,9 +265,7 @@ func (qb *imageQueryBuilder) makeQuery(imageFilter *models.ImageFilterType, find
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"images.title", "images.path", "images.checksum"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(imageFilter); err != nil {
|
||||
|
||||
@@ -145,9 +145,7 @@ func (qb *movieQueryBuilder) Query(movieFilter *models.MovieFilterType, findFilt
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"movies.name"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
filter := qb.makeFilter(movieFilter)
|
||||
|
||||
@@ -308,9 +308,7 @@ func (qb *performerQueryBuilder) Query(performerFilter *models.PerformerFilterTy
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"performers.name", "performers.aliases"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(performerFilter); err != nil {
|
||||
|
||||
@@ -3,6 +3,9 @@ package sqlite
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
"github.com/stashapp/stash/pkg/models"
|
||||
)
|
||||
|
||||
type queryBuilder struct {
|
||||
@@ -53,7 +56,9 @@ func (qb queryBuilder) toSQL(includeSortPagination bool) string {
|
||||
|
||||
func (qb queryBuilder) findIDs() ([]int, error) {
|
||||
const includeSortPagination = true
|
||||
return qb.repository.runIdsQuery(qb.toSQL(includeSortPagination), qb.args)
|
||||
sql := qb.toSQL(includeSortPagination)
|
||||
logger.Tracef("SQL: %s, args: %v", sql, qb.args)
|
||||
return qb.repository.runIdsQuery(sql, qb.args)
|
||||
}
|
||||
|
||||
func (qb queryBuilder) executeFind() ([]int, int, error) {
|
||||
@@ -168,3 +173,38 @@ func (qb *queryBuilder) addFilter(f *filterBuilder) {
|
||||
|
||||
qb.addJoins(f.getAllJoins()...)
|
||||
}
|
||||
|
||||
func (qb *queryBuilder) parseQueryString(columns []string, q string) {
|
||||
specs := models.ParseSearchString(q)
|
||||
|
||||
for _, t := range specs.MustHave {
|
||||
var clauses []string
|
||||
|
||||
for _, column := range columns {
|
||||
clauses = append(clauses, column+" LIKE ?")
|
||||
qb.addArg(like(t))
|
||||
}
|
||||
|
||||
qb.addWhere("(" + strings.Join(clauses, " OR ") + ")")
|
||||
}
|
||||
|
||||
for _, t := range specs.MustNot {
|
||||
for _, column := range columns {
|
||||
qb.addWhere(coalesce(column) + " NOT LIKE ?")
|
||||
qb.addArg(like(t))
|
||||
}
|
||||
}
|
||||
|
||||
for _, set := range specs.AnySets {
|
||||
var clauses []string
|
||||
|
||||
for _, column := range columns {
|
||||
for _, v := range set {
|
||||
clauses = append(clauses, column+" LIKE ?")
|
||||
qb.addArg(like(v))
|
||||
}
|
||||
}
|
||||
|
||||
qb.addWhere("(" + strings.Join(clauses, " OR ") + ")")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,9 +412,7 @@ func (qb *sceneQueryBuilder) Query(options models.SceneQueryOptions) (*models.Sc
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
query.join("scene_markers", "", "scene_markers.scene_id = scenes.id")
|
||||
searchColumns := []string{"scenes.title", "scenes.details", "scenes.path", "scenes.oshash", "scenes.checksum", "scene_markers.title"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(sceneFilter); err != nil {
|
||||
|
||||
@@ -151,9 +151,7 @@ func (qb *sceneMarkerQueryBuilder) Query(sceneMarkerFilter *models.SceneMarkerFi
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"scene_markers.title", "scenes.title"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
filter := qb.makeFilter(sceneMarkerFilter)
|
||||
|
||||
@@ -249,3 +249,11 @@ func getImage(tx dbi, query string, args ...interface{}) ([]byte, error) {
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func coalesce(column string) string {
|
||||
return fmt.Sprintf("COALESCE(%s, '')", column)
|
||||
}
|
||||
|
||||
func like(v string) string {
|
||||
return "%" + v + "%"
|
||||
}
|
||||
|
||||
@@ -244,9 +244,7 @@ func (qb *studioQueryBuilder) Query(studioFilter *models.StudioFilterType, findF
|
||||
query.join(studioAliasesTable, "", "studio_aliases.studio_id = studios.id")
|
||||
searchColumns := []string{"studios.name", "studio_aliases.alias"}
|
||||
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(studioFilter); err != nil {
|
||||
|
||||
@@ -329,9 +329,7 @@ func (qb *tagQueryBuilder) Query(tagFilter *models.TagFilterType, findFilter *mo
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
query.join(tagAliasesTable, "", "tag_aliases.tag_id = tags.id")
|
||||
searchColumns := []string{"tags.name", "tag_aliases.alias"}
|
||||
clause, thisArgs := getSearchBinding(searchColumns, *q, false)
|
||||
query.addWhere(clause)
|
||||
query.addArg(thisArgs...)
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
if err := qb.validateFilter(tagFilter); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user