Improve valueQry function and filters validation

This commit is contained in:
arberkatellari
2025-07-01 16:43:14 +02:00
committed by Dan Christian Bogos
parent 644661b778
commit 7872d2f33b
5 changed files with 71 additions and 19 deletions

View File

@@ -836,6 +836,12 @@ func CheckFilter(fltr *Filter) (err error) {
return fmt.Errorf("%s for filter <%v>", err, fltr) //encapsulated error
}
for _, val := range rls.Values {
if rls.Type == utils.MetaEmpty || rls.Type == utils.MetaNotEmpty ||
rls.Type == utils.MetaExists || rls.Type == utils.MetaNotExists &&
val != utils.EmptyString {
return fmt.Errorf("value of filter <%s> is not empty <%s>",
fltr.ID, val)
}
if err = valFunc(val); err != nil {
return fmt.Errorf("%s for filter <%v>", err, fltr) //encapsulated error
}

View File

@@ -2230,7 +2230,6 @@ func TestFilterRulePassRegexParseErr(t *testing.T) {
}
}
func TestCheckFilterErrValFuncElement(t *testing.T) {
fltr := &Filter{
Tenant: utils.CGRateSorg,
ID: "FLTR_CP_1",
@@ -2243,13 +2242,12 @@ func TestCheckFilterErrValFuncElement(t *testing.T) {
},
}
expErr := `Path is missing for filter <{"Tenant":"cgrates.org","ID":"FLTR_CP_1","Rules":[{"Type":"*string","Element":"~missing path","Values":["ChargerProfile1"]}]}>`
if err := CheckFilter(fltr); err.Error() != expErr {
if err := CheckFilter(fltr); err == nil || err.Error() != expErr {
t.Error(err)
}
}
func TestCheckFilterErrValFuncValues(t *testing.T) {
fltr := &Filter{
Tenant: utils.CGRateSorg,
ID: "FLTR_CP_1",
@@ -2262,7 +2260,25 @@ func TestCheckFilterErrValFuncValues(t *testing.T) {
},
}
expErr := `Path is missing for filter <{"Tenant":"cgrates.org","ID":"FLTR_CP_1","Rules":[{"Type":"*string","Element":"~*req.Charger","Values":["~missing path"]}]}>`
if err := CheckFilter(fltr); err.Error() != expErr {
if err := CheckFilter(fltr); err == nil || err.Error() != expErr {
t.Error(err)
}
}
func TestCheckFilterErrNotEmpty(t *testing.T) {
fltr := &Filter{
Tenant: utils.CGRateSorg,
ID: "FLTR_CP_1",
Rules: []*FilterRule{
{
Type: utils.MetaNotEmpty,
Element: "~*req.Charger",
Values: []string{"''"},
},
},
}
expErr := `value of filter <FLTR_CP_1> is not empty <''>`
if err := CheckFilter(fltr); err == nil || err.Error() != expErr {
t.Error(err)
}
}

View File

@@ -136,7 +136,7 @@ func (msqlS *MySQLStorage) valueQry(ruleType, elem, field string, values []strin
conditions = append(conditions, fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') != ''", elem, field))
return
}
conditions = append(conditions, fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') != ''", elem, field))
conditions = append(conditions, fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') == ''", elem, field))
}
return
}
@@ -153,13 +153,14 @@ func (msqlS *MySQLStorage) valueQry(ruleType, elem, field string, values []strin
}
singleCond = fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') = '%s'", elem, field, value)
case utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual:
if ruleType == utils.MetaGreaterOrEqual {
switch ruleType {
case utils.MetaGreaterOrEqual:
singleCond = fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') >= %s", elem, field, value)
} else if ruleType == utils.MetaGreaterThan {
case utils.MetaGreaterThan:
singleCond = fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') > %s", elem, field, value)
} else if ruleType == utils.MetaLessOrEqual {
case utils.MetaLessOrEqual:
singleCond = fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') <= %s", elem, field, value)
} else if ruleType == utils.MetaLessThan {
case utils.MetaLessThan:
singleCond = fmt.Sprintf(" JSON_VALUE(%s, '$.\"%s\"') < %s", elem, field, value)
}
case utils.MetaPrefix, utils.MetaNotPrefix:

View File

@@ -161,13 +161,14 @@ func (poS *PostgresStorage) valueQry(ruleType, elem, field string, values []stri
}
singleCond = fmt.Sprintf(" (%s ->> '%s') = '%s'", elem, field, value)
case utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual:
if ruleType == utils.MetaGreaterOrEqual {
switch ruleType {
case utils.MetaGreaterOrEqual:
singleCond = fmt.Sprintf(" (%s ->> '%s')::numeric >= '%s'", elem, field, value)
} else if ruleType == utils.MetaGreaterThan {
case utils.MetaGreaterThan:
singleCond = fmt.Sprintf(" (%s ->> '%s')::numeric > '%s'", elem, field, value)
} else if ruleType == utils.MetaLessOrEqual {
case utils.MetaLessOrEqual:
singleCond = fmt.Sprintf(" (%s ->> '%s')::numeric <= '%s'", elem, field, value)
} else if ruleType == utils.MetaLessThan {
case utils.MetaLessThan:
singleCond = fmt.Sprintf(" (%s ->> '%s')::numeric < '%s'", elem, field, value)
}
case utils.MetaPrefix, utils.MetaNotPrefix:

View File

@@ -30,10 +30,17 @@ import (
)
func TestSessionBasics(t *testing.T) {
var dbcfg engine.DBCfg
switch *utils.DBType {
case utils.MetaInternal:
case utils.MetaMySQL, utils.MetaMongo, utils.MetaPostgres:
t.SkipNow()
dbcfg = engine.InternalDBCfg
case utils.MetaMySQL:
case utils.MetaMongo:
t.SkipNow() // unfinished look into errors
dbcfg = engine.MongoDBCfg
case utils.MetaPostgres:
t.SkipNow() // unfinished look into postgres flush
dbcfg = engine.PostgresDBCfg
default:
t.Fatal("unsupported dbtype value")
}
@@ -72,7 +79,7 @@ cgrates.org,RP_STANDARD,,;10,,,,RT_STANDARD,*string:~*req.Destination:1002,"* *
cgrates.org,RP_STANDARD,,,,,,RT_STANDARD,,,,,1m,0,0.6,1m,1s
cgrates.org,RP_FALLBACK,,;0,,,,RT_FALLBACK,*string:~*req.Destination:1002,"* * * * *",;0,false,0s,0,0.01,1s,1s`,
},
DBCfg: engine.InternalDBCfg,
DBCfg: dbcfg,
Encoding: *utils.Encoding,
// LogBuffer: new(bytes.Buffer),
}
@@ -157,6 +164,9 @@ cgrates.org,RP_FALLBACK,,;0,,,,RT_FALLBACK,*string:~*req.Destination:1002,"* * *
&utils.CDRFilters{
FilterIDs: []string{
fmt.Sprintf("*string:~*opts.*originID:%s", originID),
"*exists:~*opts.*originID:",
"*notexists:~*req.NonExistentField:",
"*notempty:~*opts.*originID:",
},
}, &cdrs); err != nil {
t.Fatal(err)
@@ -187,12 +197,30 @@ cgrates.org,RP_FALLBACK,,;0,,,,RT_FALLBACK,*string:~*req.Destination:1002,"* * *
switch costKey {
case utils.Abstracts, utils.Concretes:
cd := getCostDetails(t, cdr, utils.MetaAccountSCost)
got = cd[costKey].(float64)
if cd == nil {
t.Fatalf("Nil costDetails")
}
var canCast bool
got, canCast = cd[costKey].(float64)
if !canCast {
t.Fatalf("Could not cast cdr.Opts[utils.MetaCost] to float64")
}
case utils.Cost:
cd := getCostDetails(t, cdr, utils.MetaRateSCost)
got = cd[costKey].(float64)
if cd == nil {
t.Fatalf("Nil costDetails")
}
var canCast bool
got, canCast = cd[costKey].(float64)
if !canCast {
t.Fatalf("Could not cast cdr.Opts[utils.MetaCost] to float64")
}
case utils.MetaCost:
got = cdr.Opts[utils.MetaCost].(float64)
var canCast bool
got, canCast = cdr.Opts[utils.MetaCost].(float64)
if !canCast {
t.Fatalf("Could not cast cdr.Opts[utils.MetaCost] to float64")
}
default:
t.Fatalf("invalid cdr cost key: %q", costKey)
}