refactor: update filter constants and improve type handling in filter functions

- Renamed filter operation constants for clarity and consistency.
- Introduced short forms for certain filter operations.
- Updated test cases to reflect changes in filter operation handling.
- Enhanced type handling in filter functions to support int64 values for conditions.
- Improved query generation logic to accommodate new constant names and types.
This commit is contained in:
Marvin Zhang
2025-03-16 20:30:52 +08:00
parent ce0143ca06
commit 700c263cfe
4 changed files with 51 additions and 23 deletions

View File

@@ -8,8 +8,10 @@ const (
const (
FilterOpNotSet = "ns"
FilterOpContains = "c"
FilterOpNotContains = "nc"
FilterOpContains = "contains"
FilterOpContainsShort = "c"
FilterOpNotContainsShort = "nc"
FilterOpNotContains = "not-contains"
FilterOpRegex = "r"
FilterOpEqual = "eq"
FilterOpNotEqual = "ne"
@@ -19,5 +21,6 @@ const (
FilterOpLessThan = "lt"
FilterOpGreaterThanEqual = "gte"
FilterOpLessThanEqual = "lte"
FilterOpSearch = "s"
FilterOpSearchShort = "s"
FilterOpSearch = "search"
)

View File

@@ -2,7 +2,9 @@ package controllers
import (
"encoding/json"
"errors"
"net/http"
"reflect"
"github.com/crawlab-team/crawlab/core/constants"
"github.com/crawlab-team/crawlab/core/entity"
"github.com/crawlab-team/crawlab/core/models/models"
@@ -12,8 +14,6 @@ import (
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"net/http"
"reflect"
)
var logger = utils.NewLogger("Controllers")
@@ -67,30 +67,55 @@ func GetFilterFromConditionString(condStr string) (f *entity.Filter, err error)
} else {
conditions[i].Value = item
}
case reflect.Float64:
// JSON numbers are decoded as float64 by default
switch cond.Value.(type) {
case float64:
num := cond.Value.(float64)
// Check if it's a whole number
if num == float64(int64(num)) {
conditions[i].Value = int64(num)
} else {
conditions[i].Value = num
}
case int:
num := cond.Value.(int)
conditions[i].Value = int64(num)
case int64:
num := cond.Value.(int64)
conditions[i].Value = num
}
case reflect.Bool:
conditions[i].Value = cond.Value.(bool)
case reflect.Slice, reflect.Array:
var items []interface{}
for i := 0; i < v.Len(); i++ {
vItem := v.Index(i)
item := vItem.Interface()
// string
stringItem, ok := item.(string)
if ok {
id, err := primitive.ObjectIDFromHex(stringItem)
if err == nil {
switch typedItem := item.(type) {
case string:
// Try to convert to ObjectID first
if id, err := primitive.ObjectIDFromHex(typedItem); err == nil {
items = append(items, id)
} else {
items = append(items, stringItem)
items = append(items, typedItem)
}
continue
case float64:
if typedItem == float64(int64(typedItem)) {
items = append(items, int64(typedItem))
} else {
items = append(items, typedItem)
}
case bool:
items = append(items, typedItem)
default:
items = append(items, item)
}
// default
items = append(items, item)
}
conditions[i].Value = items
default:
return nil, errors.New("invalid type")
conditions[i].Value = cond.Value
}
}

View File

@@ -34,7 +34,7 @@ func TestGetFilterFromConditionString(t *testing.T) {
assert.Equal(t, "test", filter.Conditions[0].Value)
assert.Equal(t, "priority", filter.Conditions[1].Key)
assert.Equal(t, "gt", filter.Conditions[1].Op)
assert.Equal(t, float64(5), filter.Conditions[1].Value) // JSON parses numbers as float64
assert.Equal(t, int64(5), filter.Conditions[1].Value)
// Invalid JSON should return error
condStr = `[{"key":"name","op":"eq","value":"test"`
@@ -56,7 +56,7 @@ func TestGetFilterQueryFromConditionString(t *testing.T) {
query, err = controllers.GetFilterQueryFromConditionString(condStr)
require.NoError(t, err)
require.NotNil(t, query)
expected = bson.M{"priority": bson.M{"$gt": float64(5)}}
expected = bson.M{"priority": bson.M{"$gt": int64(5)}}
assert.Equal(t, expected, query)
// Multiple conditions
@@ -64,11 +64,11 @@ func TestGetFilterQueryFromConditionString(t *testing.T) {
query, err = controllers.GetFilterQueryFromConditionString(condStr)
require.NoError(t, err)
require.NotNil(t, query)
expected = bson.M{"name": "test", "priority": bson.M{"$gt": float64(5)}}
expected = bson.M{"name": "test", "priority": bson.M{"$gt": int64(5)}}
assert.Equal(t, expected, query)
// Contains operator
condStr = `[{"key":"name","op":"contains","value":"test"}]`
condStr = `[{"key":"name","op":"c","value":"test"}]`
query, err = controllers.GetFilterQueryFromConditionString(condStr)
require.NoError(t, err)
require.NotNil(t, query)

View File

@@ -25,9 +25,9 @@ func FilterToQuery(f interfaces.Filter) (q bson.M, err error) {
q[key] = cond.GetValue()
case constants.FilterOpNotEqual:
q[key] = bson.M{"$ne": value}
case constants.FilterOpContains, constants.FilterOpRegex, constants.FilterOpSearch:
case constants.FilterOpContains, constants.FilterOpContainsShort, constants.FilterOpRegex, constants.FilterOpSearch, constants.FilterOpSearchShort:
q[key] = bson.M{"$regex": value, "$options": "i"}
case constants.FilterOpNotContains:
case constants.FilterOpNotContains, constants.FilterOpNotContainsShort:
q[key] = bson.M{"$not": bson.M{"$regex": value}}
case constants.FilterOpIn:
q[key] = bson.M{"$in": value}