full filter interpretation
This commit is contained in:
+43
-14
@@ -165,7 +165,7 @@ func FiltersFromFlatMap(flatMap map[string]interface{}, target interface{}) *Fil
|
||||
And: make(map[string][]Filter),
|
||||
Or: make(map[string][]Filter),
|
||||
}
|
||||
paths := jsonToBsonPaths(reflect.TypeOf(target), "")
|
||||
paths := jsonToBsonPaths(reflect.TypeOf(target), "", "")
|
||||
resolve := func(jsonKey string) string {
|
||||
if p, ok := paths[jsonKey]; ok {
|
||||
return p
|
||||
@@ -215,11 +215,22 @@ func FiltersFromFlatMap(flatMap map[string]interface{}, target interface{}) *Fil
|
||||
//
|
||||
// Anonymous embedded fields without any tag follow the BSON convention of this
|
||||
// codebase: they are stored as a nested sub-document whose key is the lowercased
|
||||
// struct type name (e.g. utils.AbstractObject → "abstractobject").
|
||||
func jsonToBsonPaths(t reflect.Type, prefix string) map[string]string {
|
||||
// struct type name (e.g. utils.AbstractObject → "abstractobject"). Their JSON
|
||||
// fields are promoted (flat), so bsonPrefix advances but jsonPrefix does not.
|
||||
//
|
||||
// For fields inside slices or maps, both the leaf json name and the full dotted
|
||||
// json path (e.g. "instances.access_protocol") are registered as keys so callers
|
||||
// can use either form unambiguously.
|
||||
func jsonToBsonPaths(t reflect.Type, bsonPrefix string, jsonPrefix string) map[string]string {
|
||||
for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() == reflect.Map {
|
||||
t = t.Elem()
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
}
|
||||
result := make(map[string]string)
|
||||
if t.Kind() != reflect.Struct {
|
||||
return result
|
||||
@@ -233,20 +244,21 @@ func jsonToBsonPaths(t reflect.Type, prefix string) map[string]string {
|
||||
bsonName := strings.Split(bsonTag, ",")[0]
|
||||
|
||||
// Anonymous embedded struct with no tags: use lowercase type name as BSON prefix.
|
||||
// JSON fields are promoted so jsonPrefix stays the same.
|
||||
if field.Anonymous && jsonName == "" && bsonName == "" {
|
||||
ft := field.Type
|
||||
for ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
if ft.Kind() == reflect.Struct {
|
||||
embedPrefix := strings.ToLower(ft.Name())
|
||||
embedBsonPrefix := strings.ToLower(ft.Name())
|
||||
re := regexp.MustCompile(`\[[^\]]*\]`)
|
||||
embedPrefix = re.ReplaceAllString(embedPrefix, "")
|
||||
embedPrefix = strings.ReplaceAll(embedPrefix, "*", "")
|
||||
if prefix != "" {
|
||||
embedPrefix = prefix + "." + embedPrefix
|
||||
embedBsonPrefix = re.ReplaceAllString(embedBsonPrefix, "")
|
||||
embedBsonPrefix = strings.ReplaceAll(embedBsonPrefix, "*", "")
|
||||
if bsonPrefix != "" {
|
||||
embedBsonPrefix = bsonPrefix + "." + embedBsonPrefix
|
||||
}
|
||||
for k, v := range jsonToBsonPaths(ft, embedPrefix) {
|
||||
for k, v := range jsonToBsonPaths(ft, embedBsonPrefix, jsonPrefix) {
|
||||
if _, exists := result[k]; !exists {
|
||||
result[k] = v
|
||||
}
|
||||
@@ -262,19 +274,36 @@ func jsonToBsonPaths(t reflect.Type, prefix string) map[string]string {
|
||||
bsonName = jsonName
|
||||
}
|
||||
|
||||
fullPath := bsonName
|
||||
if prefix != "" {
|
||||
fullPath = prefix + "." + bsonName
|
||||
fullBsonPath := bsonName
|
||||
if bsonPrefix != "" {
|
||||
fullBsonPath = bsonPrefix + "." + bsonName
|
||||
}
|
||||
fullJsonPath := jsonName
|
||||
if jsonPrefix != "" {
|
||||
fullJsonPath = jsonPrefix + "." + jsonName
|
||||
}
|
||||
|
||||
result[jsonName] = fullPath
|
||||
result[jsonName] = fullBsonPath
|
||||
// Also register the full dotted JSON path so callers can use
|
||||
// "instances.access_protocol" instead of just "access_protocol".
|
||||
if fullJsonPath != jsonName {
|
||||
if _, exists := result[fullJsonPath]; !exists {
|
||||
result[fullJsonPath] = fullBsonPath
|
||||
}
|
||||
}
|
||||
|
||||
ft := field.Type
|
||||
for ft.Kind() == reflect.Ptr || ft.Kind() == reflect.Slice {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
if ft.Kind() == reflect.Map {
|
||||
ft = ft.Elem()
|
||||
for ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
}
|
||||
if ft.Kind() == reflect.Struct {
|
||||
for k, v := range jsonToBsonPaths(ft, fullPath) {
|
||||
for k, v := range jsonToBsonPaths(ft, fullBsonPath, fullJsonPath) {
|
||||
if _, exists := result[k]; !exists {
|
||||
result[k] = v
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user