2024-02-25 00:25:51 +02:00
|
|
|
package memoryexecutor
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
|
2024-02-27 22:38:59 +02:00
|
|
|
"github.com/pikami/cosmium/internal/logger"
|
2024-02-25 00:25:51 +02:00
|
|
|
"github.com/pikami/cosmium/parsers"
|
|
|
|
)
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) array_Concat(arguments []interface{}) []interface{} {
|
2024-02-25 00:25:51 +02:00
|
|
|
var result []interface{}
|
|
|
|
for _, arg := range arguments {
|
2024-12-07 22:29:26 +02:00
|
|
|
array := r.parseArray(arg)
|
2024-02-25 00:25:51 +02:00
|
|
|
result = append(result, array...)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2024-12-26 20:27:59 +02:00
|
|
|
func (r rowContext) array_Contains(arguments []interface{}) bool {
|
|
|
|
array := r.parseArray(arguments[0])
|
|
|
|
if array == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
exprToSearch := r.resolveSelectItem(arguments[1].(parsers.SelectItem))
|
|
|
|
|
|
|
|
partialSearch := false
|
|
|
|
if len(arguments) > 2 {
|
|
|
|
boolExpr := r.resolveSelectItem(arguments[2].(parsers.SelectItem))
|
|
|
|
if boolValue, ok := boolExpr.(bool); ok {
|
|
|
|
partialSearch = boolValue
|
|
|
|
} else {
|
|
|
|
logger.Error("array_Contains - got parameters of wrong type")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, item := range array {
|
|
|
|
if partialSearch {
|
|
|
|
if r.partialMatch(item, exprToSearch) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if reflect.DeepEqual(item, exprToSearch) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r rowContext) array_Contains_Any(arguments []interface{}) bool {
|
|
|
|
array := r.parseArray(arguments[0])
|
|
|
|
if array == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
valueSelectItems := arguments[1:]
|
|
|
|
|
|
|
|
for _, valueSelectItem := range valueSelectItems {
|
|
|
|
value := r.resolveSelectItem(valueSelectItem.(parsers.SelectItem))
|
|
|
|
for _, item := range array {
|
|
|
|
if reflect.DeepEqual(item, value) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r rowContext) array_Contains_All(arguments []interface{}) bool {
|
|
|
|
array := r.parseArray(arguments[0])
|
|
|
|
if array == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
valueSelectItems := arguments[1:]
|
|
|
|
|
|
|
|
for _, valueSelectItem := range valueSelectItems {
|
|
|
|
value := r.resolveSelectItem(valueSelectItem.(parsers.SelectItem))
|
|
|
|
|
|
|
|
found := false
|
|
|
|
for _, item := range array {
|
|
|
|
if reflect.DeepEqual(item, value) {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) array_Length(arguments []interface{}) int {
|
|
|
|
array := r.parseArray(arguments[0])
|
2024-02-25 00:25:51 +02:00
|
|
|
if array == nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
return len(array)
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) array_Slice(arguments []interface{}) []interface{} {
|
2024-02-25 00:25:51 +02:00
|
|
|
var ok bool
|
|
|
|
var start int
|
|
|
|
var length int
|
2024-12-07 22:29:26 +02:00
|
|
|
array := r.parseArray(arguments[0])
|
|
|
|
startEx := r.resolveSelectItem(arguments[1].(parsers.SelectItem))
|
2024-02-25 00:25:51 +02:00
|
|
|
|
|
|
|
if arguments[2] != nil {
|
2024-12-07 22:29:26 +02:00
|
|
|
lengthEx := r.resolveSelectItem(arguments[2].(parsers.SelectItem))
|
2024-02-25 00:25:51 +02:00
|
|
|
|
|
|
|
if length, ok = lengthEx.(int); !ok {
|
2024-02-27 22:38:59 +02:00
|
|
|
logger.Error("array_Slice - got length parameters of wrong type")
|
2024-02-25 00:25:51 +02:00
|
|
|
return []interface{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if start, ok = startEx.(int); !ok {
|
2024-02-27 22:38:59 +02:00
|
|
|
logger.Error("array_Slice - got start parameters of wrong type")
|
2024-02-25 00:25:51 +02:00
|
|
|
return []interface{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
if start < 0 {
|
|
|
|
start = len(array) + start
|
|
|
|
}
|
|
|
|
|
|
|
|
if start < 0 {
|
|
|
|
start = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if array == nil || start >= len(array) {
|
|
|
|
return []interface{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
end := start + length
|
|
|
|
if end > len(array) {
|
|
|
|
end = len(array)
|
|
|
|
}
|
|
|
|
return array[start:end]
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) set_Intersect(arguments []interface{}) []interface{} {
|
|
|
|
set1 := r.parseArray(arguments[0])
|
|
|
|
set2 := r.parseArray(arguments[1])
|
2024-02-25 00:25:51 +02:00
|
|
|
|
|
|
|
intersection := make(map[interface{}]struct{})
|
|
|
|
if set1 == nil || set2 == nil {
|
|
|
|
return []interface{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, item := range set1 {
|
|
|
|
intersection[item] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
var result []interface{}
|
|
|
|
for _, item := range set2 {
|
|
|
|
if _, exists := intersection[item]; exists {
|
|
|
|
result = append(result, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) set_Union(arguments []interface{}) []interface{} {
|
|
|
|
set1 := r.parseArray(arguments[0])
|
|
|
|
set2 := r.parseArray(arguments[1])
|
2024-02-25 00:25:51 +02:00
|
|
|
|
|
|
|
var result []interface{}
|
|
|
|
union := make(map[interface{}]struct{})
|
|
|
|
for _, item := range set1 {
|
|
|
|
if _, ok := union[item]; !ok {
|
|
|
|
union[item] = struct{}{}
|
|
|
|
result = append(result, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, item := range set2 {
|
|
|
|
if _, ok := union[item]; !ok {
|
|
|
|
union[item] = struct{}{}
|
|
|
|
result = append(result, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2024-12-07 22:29:26 +02:00
|
|
|
func (r rowContext) parseArray(argument interface{}) []interface{} {
|
2024-02-25 00:25:51 +02:00
|
|
|
exItem := argument.(parsers.SelectItem)
|
2024-12-07 22:29:26 +02:00
|
|
|
ex := r.resolveSelectItem(exItem)
|
2024-02-25 00:25:51 +02:00
|
|
|
|
|
|
|
arrValue := reflect.ValueOf(ex)
|
|
|
|
if arrValue.Kind() != reflect.Slice {
|
2024-02-27 22:38:59 +02:00
|
|
|
logger.Error("parseArray got parameters of wrong type")
|
2024-02-25 00:25:51 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
result := make([]interface{}, arrValue.Len())
|
|
|
|
|
|
|
|
for i := 0; i < arrValue.Len(); i++ {
|
|
|
|
result[i] = arrValue.Index(i).Interface()
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
2024-12-26 20:27:59 +02:00
|
|
|
|
|
|
|
func (r rowContext) partialMatch(item interface{}, exprToSearch interface{}) bool {
|
|
|
|
itemValue := reflect.ValueOf(item)
|
|
|
|
exprValue := reflect.ValueOf(exprToSearch)
|
|
|
|
|
|
|
|
if itemValue.Kind() != reflect.Map || exprValue.Kind() != reflect.Map {
|
|
|
|
logger.Error("partialMatch got parameters of wrong type")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, key := range exprValue.MapKeys() {
|
|
|
|
if itemValue.MapIndex(key).Interface() != exprValue.MapIndex(key).Interface() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|