Implement STARTSWITH, ENDSWITH functions

This commit is contained in:
Pijus Kamandulis
2024-02-21 20:46:08 +02:00
parent 9bf3dc22ed
commit 790192bf5a
7 changed files with 460 additions and 203 deletions

View File

@@ -180,6 +180,10 @@ func getFieldValue(field parsers.SelectItem, queryParameters map[string]interfac
return strings_StringEquals(typedValue.Arguments, queryParameters, row)
case parsers.FunctionCallContains:
return strings_Contains(typedValue.Arguments, queryParameters, row)
case parsers.FunctionCallEndsWith:
return strings_EndsWith(typedValue.Arguments, queryParameters, row)
case parsers.FunctionCallStartsWith:
return strings_StartsWith(typedValue.Arguments, queryParameters, row)
case parsers.FunctionCallConcat:
return strings_Concat(typedValue.Arguments, queryParameters, row)
case parsers.FunctionCallIsDefined:

View File

@@ -199,4 +199,100 @@ func Test_Execute_StringFunctions(t *testing.T) {
},
)
})
t.Run("Should execute function ENDSWITH()", func(t *testing.T) {
testQueryExecute(
t,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Path: []string{"c", "id"},
Type: parsers.SelectItemTypeField,
},
{
Alias: "ends",
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallEndsWith,
Arguments: []interface{}{
parsers.SelectItem{
Path: []string{"c", "id"},
Type: parsers.SelectItemTypeField,
},
parsers.SelectItem{
Type: parsers.SelectItemTypeConstant,
Value: parsers.Constant{
Type: parsers.ConstantTypeString,
Value: "3",
},
},
parsers.SelectItem{
Type: parsers.SelectItemTypeConstant,
Value: parsers.Constant{
Type: parsers.ConstantTypeBoolean,
Value: true,
},
},
},
},
},
},
Table: parsers.Table{Value: "c"},
},
mockData,
[]memoryexecutor.RowType{
map[string]interface{}{"id": "123", "ends": true},
map[string]interface{}{"id": "456", "ends": false},
map[string]interface{}{"id": "789", "ends": false},
},
)
})
t.Run("Should execute function STARTSWITH()", func(t *testing.T) {
testQueryExecute(
t,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Path: []string{"c", "id"},
Type: parsers.SelectItemTypeField,
},
{
Alias: "starts",
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallStartsWith,
Arguments: []interface{}{
parsers.SelectItem{
Path: []string{"c", "id"},
Type: parsers.SelectItemTypeField,
},
parsers.SelectItem{
Type: parsers.SelectItemTypeConstant,
Value: parsers.Constant{
Type: parsers.ConstantTypeString,
Value: "1",
},
},
parsers.SelectItem{
Type: parsers.SelectItemTypeConstant,
Value: parsers.Constant{
Type: parsers.ConstantTypeBoolean,
Value: true,
},
},
},
},
},
},
Table: parsers.Table{Value: "c"},
},
mockData,
[]memoryexecutor.RowType{
map[string]interface{}{"id": "123", "starts": true},
map[string]interface{}{"id": "456", "starts": false},
map[string]interface{}{"id": "789", "starts": false},
},
)
})
}

View File

@@ -8,30 +8,9 @@ import (
)
func strings_StringEquals(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
ignoreCase := false
if len(arguments) > 2 && arguments[2] != nil {
ignoreCaseItem := arguments[2].(parsers.SelectItem)
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
ignoreCase = value
}
}
ex1Item := arguments[0].(parsers.SelectItem)
ex2Item := arguments[1].(parsers.SelectItem)
ex1 := getFieldValue(ex1Item, queryParameters, row)
ex2 := getFieldValue(ex2Item, queryParameters, row)
var ok bool
var str1 string
var str2 string
if str1, ok = ex1.(string); !ok {
fmt.Println("StringEquals got parameters of wrong type")
}
if str2, ok = ex2.(string); !ok {
fmt.Println("StringEquals got parameters of wrong type")
}
str1 := parseString(arguments[0], queryParameters, row)
str2 := parseString(arguments[1], queryParameters, row)
ignoreCase := getBoolFlag(arguments, queryParameters, row)
if ignoreCase {
return strings.EqualFold(str1, str2)
@@ -41,30 +20,9 @@ func strings_StringEquals(arguments []interface{}, queryParameters map[string]in
}
func strings_Contains(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
ignoreCase := false
if len(arguments) > 2 && arguments[2] != nil {
ignoreCaseItem := arguments[2].(parsers.SelectItem)
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
ignoreCase = value
}
}
ex1Item := arguments[0].(parsers.SelectItem)
ex2Item := arguments[1].(parsers.SelectItem)
ex1 := getFieldValue(ex1Item, queryParameters, row)
ex2 := getFieldValue(ex2Item, queryParameters, row)
var ok bool
var str1 string
var str2 string
if str1, ok = ex1.(string); !ok {
fmt.Println("StringEquals got parameters of wrong type")
}
if str2, ok = ex2.(string); !ok {
fmt.Println("StringEquals got parameters of wrong type")
}
str1 := parseString(arguments[0], queryParameters, row)
str2 := parseString(arguments[1], queryParameters, row)
ignoreCase := getBoolFlag(arguments, queryParameters, row)
if ignoreCase {
str1 = strings.ToLower(str1)
@@ -74,6 +32,32 @@ func strings_Contains(arguments []interface{}, queryParameters map[string]interf
return strings.Contains(str1, str2)
}
func strings_EndsWith(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
str1 := parseString(arguments[0], queryParameters, row)
str2 := parseString(arguments[1], queryParameters, row)
ignoreCase := getBoolFlag(arguments, queryParameters, row)
if ignoreCase {
str1 = strings.ToLower(str1)
str2 = strings.ToLower(str2)
}
return strings.HasSuffix(str1, str2)
}
func strings_StartsWith(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
str1 := parseString(arguments[0], queryParameters, row)
str2 := parseString(arguments[1], queryParameters, row)
ignoreCase := getBoolFlag(arguments, queryParameters, row)
if ignoreCase {
str1 = strings.ToLower(str1)
str2 = strings.ToLower(str2)
}
return strings.HasPrefix(str1, str2)
}
func strings_Concat(arguments []interface{}, queryParameters map[string]interface{}, row RowType) string {
result := ""
@@ -87,6 +71,29 @@ func strings_Concat(arguments []interface{}, queryParameters map[string]interfac
return result
}
func getBoolFlag(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
ignoreCase := false
if len(arguments) > 2 && arguments[2] != nil {
ignoreCaseItem := arguments[2].(parsers.SelectItem)
if value, ok := getFieldValue(ignoreCaseItem, queryParameters, row).(bool); ok {
ignoreCase = value
}
}
return ignoreCase
}
func parseString(argument interface{}, queryParameters map[string]interface{}, row RowType) string {
exItem := argument.(parsers.SelectItem)
ex := getFieldValue(exItem, queryParameters, row)
if str1, ok := ex.(string); ok {
fmt.Println("StringEquals got parameters of wrong type")
return str1
}
return ""
}
func convertToString(value interface{}) string {
switch v := value.(type) {
case string: