diff --git a/crud.go b/crud.go index 2cb3afc..1151e1c 100644 --- a/crud.go +++ b/crud.go @@ -37,6 +37,84 @@ func ReadDocument(db *mgo.Database, m ModelInterface, selector bson.M) error { // PipelineModifierFunction is a function to modify mongodb query type PipelineModifierFunction func(pipeline []bson.M) []bson.M +func convertIDValue(v reflect.Value) reflect.Value { + v = reflect.ValueOf(v.Interface()) + vKind := v.Kind() // mapVal.Kind() does not work, no idea why ;( + spew.Dump(v.Interface()) + spew.Dump(vKind) + + switch vKind { + case reflect.String: + return reflect.ValueOf(bson.ObjectIdHex(v.Interface().(string))) + case reflect.Map: + for _, key := range v.MapKeys() { + v.SetMapIndex(key, convertIDValue(v.MapIndex(key))) + } + case reflect.Slice: + for i := 0; i < v.Len(); i++ { + v.Index(i).Set(convertIDValue(v.Index(i))) + } + } + + return v +} + +func idToObjectID(filter interface{}) { + spew.Dump(filter) + val := reflect.ValueOf(filter) + switch reflect.TypeOf(filter).Kind() { + case reflect.Slice: + for i := 0; i < val.Len(); i++ { + idToObjectID(val.Index(i).Interface()) + } + case reflect.Ptr: + idToObjectID(reflect.Indirect(val).Interface()) + case reflect.Map: + for _, key := range val.MapKeys() { + if k, ok := key.Interface().(string); ok { + mapVal := val.MapIndex(key) + if mapVal.Type().Kind() == reflect.Ptr { + mapVal = reflect.Indirect(mapVal) + } + if k == "_id" { + val.SetMapIndex(key, convertIDValue(mapVal)) + } else { + idToObjectID(mapVal.Interface()) + } + } + } + } + + /* + for key, data := range filter { + if key == "_id" { + if hex, ok := data.(string); ok { + filter[key] = bson.ObjectIdHex(hex) + } + } else { + switch d := data.(type) { + case map[string]interface{}: + idToObjectID(d) + case bson.M: + idToObjectID(d) + case []map[string]interface{}: + for _, s := range d { + idToObjectID(s) + } + case []bson.M: + for _, s := range d { + idToObjectID(s) + } + case []interface{}: + for _, s := range d { + isToObjectID(s) + } + } + } + } + */ +} + // ReadCollection gets the filtered collection of the model func ReadCollection(db *mgo.Database, results interface{}, filter bson.M, selector bson.M, offset int, limit int, sort []string, pipelineModifier PipelineModifierFunction) (err error) { defer func() { @@ -116,6 +194,10 @@ func ReadCollection(db *mgo.Database, results interface{}, filter bson.M, select } else { // search without pipe is faster + idToObjectID(filter) + + spew.Dump(filter) + q := c.Find(filter) if selector != nil { q = q.Select(selector)