mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Add sqlite filter builder. Add AND, OR, NOT filters to scene filter (#1115)
* Add resolution enum extension * Add filter builder * Use filterBuilder for scene query * Optimise joins * Add binary operators to scene query * Use Query for auto-tag
This commit is contained in:
@@ -139,6 +139,7 @@ func TestSceneQueryQ(t *testing.T) {
|
||||
}
|
||||
|
||||
func queryScene(t *testing.T, sqb models.SceneReader, sceneFilter *models.SceneFilterType, findFilter *models.FindFilterType) []*models.Scene {
|
||||
t.Helper()
|
||||
scenes, _, err := sqb.Query(sceneFilter, findFilter)
|
||||
if err != nil {
|
||||
t.Errorf("Error querying scene: %s", err.Error())
|
||||
@@ -186,6 +187,143 @@ func TestSceneQueryPath(t *testing.T) {
|
||||
verifyScenesPath(t, pathCriterion)
|
||||
}
|
||||
|
||||
func TestSceneQueryPathOr(t *testing.T) {
|
||||
const scene1Idx = 1
|
||||
const scene2Idx = 2
|
||||
|
||||
scene1Path := getSceneStringValue(scene1Idx, "Path")
|
||||
scene2Path := getSceneStringValue(scene2Idx, "Path")
|
||||
|
||||
sceneFilter := models.SceneFilterType{
|
||||
Path: &models.StringCriterionInput{
|
||||
Value: scene1Path,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
},
|
||||
Or: &models.SceneFilterType{
|
||||
Path: &models.StringCriterionInput{
|
||||
Value: scene2Path,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
withTxn(func(r models.Repository) error {
|
||||
sqb := r.Scene()
|
||||
|
||||
scenes := queryScene(t, sqb, &sceneFilter, nil)
|
||||
|
||||
assert.Len(t, scenes, 2)
|
||||
assert.Equal(t, scene1Path, scenes[0].Path)
|
||||
assert.Equal(t, scene2Path, scenes[1].Path)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestSceneQueryPathAndRating(t *testing.T) {
|
||||
const sceneIdx = 1
|
||||
scenePath := getSceneStringValue(sceneIdx, "Path")
|
||||
sceneRating := getRating(sceneIdx)
|
||||
|
||||
sceneFilter := models.SceneFilterType{
|
||||
Path: &models.StringCriterionInput{
|
||||
Value: scenePath,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
},
|
||||
And: &models.SceneFilterType{
|
||||
Rating: &models.IntCriterionInput{
|
||||
Value: int(sceneRating.Int64),
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
withTxn(func(r models.Repository) error {
|
||||
sqb := r.Scene()
|
||||
|
||||
scenes := queryScene(t, sqb, &sceneFilter, nil)
|
||||
|
||||
assert.Len(t, scenes, 1)
|
||||
assert.Equal(t, scenePath, scenes[0].Path)
|
||||
assert.Equal(t, sceneRating.Int64, scenes[0].Rating.Int64)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestSceneQueryPathNotRating(t *testing.T) {
|
||||
const sceneIdx = 1
|
||||
|
||||
sceneRating := getRating(sceneIdx)
|
||||
|
||||
pathCriterion := models.StringCriterionInput{
|
||||
Value: "scene_.*1_Path",
|
||||
Modifier: models.CriterionModifierMatchesRegex,
|
||||
}
|
||||
|
||||
ratingCriterion := models.IntCriterionInput{
|
||||
Value: int(sceneRating.Int64),
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
}
|
||||
|
||||
sceneFilter := models.SceneFilterType{
|
||||
Path: &pathCriterion,
|
||||
Not: &models.SceneFilterType{
|
||||
Rating: &ratingCriterion,
|
||||
},
|
||||
}
|
||||
|
||||
withTxn(func(r models.Repository) error {
|
||||
sqb := r.Scene()
|
||||
|
||||
scenes := queryScene(t, sqb, &sceneFilter, nil)
|
||||
|
||||
for _, scene := range scenes {
|
||||
verifyString(t, scene.Path, pathCriterion)
|
||||
ratingCriterion.Modifier = models.CriterionModifierNotEquals
|
||||
verifyInt64(t, scene.Rating, ratingCriterion)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestSceneIllegalQuery(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
const sceneIdx = 1
|
||||
subFilter := models.SceneFilterType{
|
||||
Path: &models.StringCriterionInput{
|
||||
Value: getSceneStringValue(sceneIdx, "Path"),
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
},
|
||||
}
|
||||
|
||||
sceneFilter := &models.SceneFilterType{
|
||||
And: &subFilter,
|
||||
Or: &subFilter,
|
||||
}
|
||||
|
||||
withTxn(func(r models.Repository) error {
|
||||
sqb := r.Scene()
|
||||
|
||||
_, _, err := sqb.Query(sceneFilter, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
sceneFilter.Or = nil
|
||||
sceneFilter.Not = &subFilter
|
||||
_, _, err = sqb.Query(sceneFilter, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
sceneFilter.And = nil
|
||||
sceneFilter.Or = &subFilter
|
||||
_, _, err = sqb.Query(sceneFilter, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func verifyScenesPath(t *testing.T, pathCriterion models.StringCriterionInput) {
|
||||
withTxn(func(r models.Repository) error {
|
||||
sqb := r.Scene()
|
||||
|
||||
Reference in New Issue
Block a user