mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Whitespace is not trimmed from the end of query strings (#1263)
* fixed whitespace not trimmed query string * fixed whitespace trimming on backend * added query trim tests and fixed double space
This commit is contained in:
@@ -1164,7 +1164,7 @@ func TestSceneQuerySorting(t *testing.T) {
|
|||||||
lastScene := scenes[len(scenes)-1]
|
lastScene := scenes[len(scenes)-1]
|
||||||
|
|
||||||
assert.Equal(t, sceneIDs[0], firstScene.ID)
|
assert.Equal(t, sceneIDs[0], firstScene.ID)
|
||||||
assert.Equal(t, sceneIDs[len(sceneIDs)-1], lastScene.ID)
|
assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], lastScene.ID)
|
||||||
|
|
||||||
// sort in descending order
|
// sort in descending order
|
||||||
direction = models.SortDirectionEnumDesc
|
direction = models.SortDirectionEnumDesc
|
||||||
@@ -1173,7 +1173,7 @@ func TestSceneQuerySorting(t *testing.T) {
|
|||||||
firstScene = scenes[0]
|
firstScene = scenes[0]
|
||||||
lastScene = scenes[len(scenes)-1]
|
lastScene = scenes[len(scenes)-1]
|
||||||
|
|
||||||
assert.Equal(t, sceneIDs[len(sceneIDs)-1], firstScene.ID)
|
assert.Equal(t, sceneIDs[sceneIdxWithSpacedName], firstScene.ID)
|
||||||
assert.Equal(t, sceneIDs[0], lastScene.ID)
|
assert.Equal(t, sceneIDs[0], lastScene.ID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -1519,6 +1519,49 @@ func TestSceneStashIDs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSceneQueryQTrim(t *testing.T) {
|
||||||
|
if err := withTxn(func(r models.Repository) error {
|
||||||
|
qb := r.Scene()
|
||||||
|
|
||||||
|
expectedID := sceneIDs[sceneIdxWithSpacedName]
|
||||||
|
|
||||||
|
type test struct {
|
||||||
|
query string
|
||||||
|
id int
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
tests := []test{
|
||||||
|
{query: " zzz yyy ", id: expectedID, count: 1},
|
||||||
|
{query: " \"zzz yyy xxx\" ", id: expectedID, count: 1},
|
||||||
|
{query: "zzz", id: expectedID, count: 1},
|
||||||
|
{query: "\" zzz yyy \"", count: 0},
|
||||||
|
{query: "\"zzz yyy\"", count: 0},
|
||||||
|
{query: "\" zzz yyy\"", count: 0},
|
||||||
|
{query: "\"zzz yyy \"", count: 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tst := range tests {
|
||||||
|
f := models.FindFilterType{
|
||||||
|
Q: &tst.query,
|
||||||
|
}
|
||||||
|
scenes := queryScene(t, qb, nil, &f)
|
||||||
|
|
||||||
|
assert.Len(t, scenes, tst.count)
|
||||||
|
if len(scenes) > 0 {
|
||||||
|
assert.Equal(t, tst.id, scenes[0].ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findFilter := models.FindFilterType{}
|
||||||
|
scenes := queryScene(t, qb, nil, &findFilter)
|
||||||
|
assert.NotEqual(t, 0, len(scenes))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
t.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Update
|
// TODO Update
|
||||||
// TODO IncrementOCounter
|
// TODO IncrementOCounter
|
||||||
// TODO DecrementOCounter
|
// TODO DecrementOCounter
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ import (
|
|||||||
"github.com/stashapp/stash/pkg/utils"
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
spacedSceneTitle = "zzz yyy xxx"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sceneIdxWithMovie = iota
|
sceneIdxWithMovie = iota
|
||||||
sceneIdxWithGallery
|
sceneIdxWithGallery
|
||||||
@@ -33,6 +37,7 @@ const (
|
|||||||
sceneIdxWithMarker
|
sceneIdxWithMarker
|
||||||
sceneIdxWithPerformerTag
|
sceneIdxWithPerformerTag
|
||||||
sceneIdxWithPerformerTwoTags
|
sceneIdxWithPerformerTwoTags
|
||||||
|
sceneIdxWithSpacedName
|
||||||
// new indexes above
|
// new indexes above
|
||||||
lastSceneIdx
|
lastSceneIdx
|
||||||
|
|
||||||
@@ -452,6 +457,15 @@ func getSceneNullStringValue(index int, field string) sql.NullString {
|
|||||||
return getPrefixedNullStringValue("scene", index, field)
|
return getPrefixedNullStringValue("scene", index, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSceneTitle(index int) string {
|
||||||
|
switch index {
|
||||||
|
case sceneIdxWithSpacedName:
|
||||||
|
return spacedSceneTitle
|
||||||
|
default:
|
||||||
|
return getSceneStringValue(index, titleField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getRating(index int) sql.NullInt64 {
|
func getRating(index int) sql.NullInt64 {
|
||||||
rating := index % 6
|
rating := index % 6
|
||||||
return sql.NullInt64{Int64: int64(rating), Valid: rating > 0}
|
return sql.NullInt64{Int64: int64(rating), Valid: rating > 0}
|
||||||
@@ -493,7 +507,7 @@ func createScenes(sqb models.SceneReaderWriter, n int) error {
|
|||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
scene := models.Scene{
|
scene := models.Scene{
|
||||||
Path: getSceneStringValue(i, pathField),
|
Path: getSceneStringValue(i, pathField),
|
||||||
Title: sql.NullString{String: getSceneStringValue(i, titleField), Valid: true},
|
Title: sql.NullString{String: getSceneTitle(i), Valid: true},
|
||||||
Checksum: sql.NullString{String: getSceneStringValue(i, checksumField), Valid: true},
|
Checksum: sql.NullString{String: getSceneStringValue(i, checksumField), Valid: true},
|
||||||
Details: sql.NullString{String: getSceneStringValue(i, "Details"), Valid: true},
|
Details: sql.NullString{String: getSceneStringValue(i, "Details"), Valid: true},
|
||||||
URL: getSceneNullStringValue(i, urlField),
|
URL: getSceneNullStringValue(i, urlField),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -116,10 +117,12 @@ func getSearchBinding(columns []string, q string, not bool) (string, []interface
|
|||||||
notStr = " NOT"
|
notStr = " NOT"
|
||||||
binaryType = " AND "
|
binaryType = " AND "
|
||||||
}
|
}
|
||||||
|
q = strings.TrimSpace(q)
|
||||||
queryWords := strings.Split(q, " ")
|
|
||||||
trimmedQuery := strings.Trim(q, "\"")
|
trimmedQuery := strings.Trim(q, "\"")
|
||||||
|
|
||||||
if trimmedQuery == q {
|
if trimmedQuery == q {
|
||||||
|
q = regexp.MustCompile(`\s+`).ReplaceAllString(q, " ")
|
||||||
|
queryWords := strings.Split(q, " ")
|
||||||
// Search for any word
|
// Search for any word
|
||||||
for _, word := range queryWords {
|
for _, word := range queryWords {
|
||||||
for _, column := range columns {
|
for _, column := range columns {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
* Change performer text query to search by name and alias only.
|
* Change performer text query to search by name and alias only.
|
||||||
|
|
||||||
### 🐛 Bug fixes
|
### 🐛 Bug fixes
|
||||||
|
* Fix whitespace in query string returning all objects.
|
||||||
* Fix hang on Login page when not connected to internet.
|
* Fix hang on Login page when not connected to internet.
|
||||||
* Fix `Clear Image` button not updating image preview.
|
* Fix `Clear Image` button not updating image preview.
|
||||||
* Fix processing some webp files.
|
* Fix processing some webp files.
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ export class ListFilterModel {
|
|||||||
this.displayMode = Number.parseInt(params.disp, 10);
|
this.displayMode = Number.parseInt(params.disp, 10);
|
||||||
}
|
}
|
||||||
if (params.q) {
|
if (params.q) {
|
||||||
this.searchTerm = params.q;
|
this.searchTerm = params.q.trim();
|
||||||
}
|
}
|
||||||
if (params.p) {
|
if (params.p) {
|
||||||
this.currentPage = Number.parseInt(params.p, 10);
|
this.currentPage = Number.parseInt(params.p, 10);
|
||||||
|
|||||||
Reference in New Issue
Block a user