Created
February 25, 2019 11:43
-
-
Save ogerardin/5aa272f69563475ba9d7b3194b12ae57 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package poly | |
import ( | |
"b2b-go/lib/typeregistry" | |
"fmt" | |
"github.com/globalsign/mgo" | |
"github.com/globalsign/mgo/bson" | |
"github.com/globalsign/mgo/dbtest" | |
"io/ioutil" | |
"os" | |
"reflect" | |
"testing" | |
) | |
type I interface { | |
f1() | |
} | |
type S1 struct { | |
X int | |
} | |
type S2 struct { | |
S1 | |
Y int | |
} | |
func (*S1) f1() { | |
fmt.Println("f1") | |
} | |
/*func (*S2) f1() { | |
fmt.Println("S2") | |
} | |
*/ | |
type Wrapper struct { | |
Id bson.ObjectId `bson:"_id"` | |
TypeKey string | |
Val interface{} | |
} | |
func save(coll *mgo.Collection, s I) (bson.ObjectId, error) { | |
t := reflect.TypeOf(s) | |
wrapper := Wrapper{ | |
Id: bson.NewObjectId(), | |
TypeKey: typeregistry.GetKey(t), | |
Val: s, | |
} | |
return wrapper.Id, coll.Insert(wrapper) | |
} | |
func getById(coll *mgo.Collection, id interface{}) (*I, error) { | |
// read wrapper | |
wrapper := Wrapper{} | |
err := coll.Find(bson.M{"_id": id}).One(&wrapper) | |
if err != nil { | |
return nil, err | |
} | |
// obtain Type from registry | |
t := typeregistry.GetType(wrapper.TypeKey) | |
// get a pointer to a new value of this type | |
pt := reflect.New(t) | |
// FIXME populate value using wrapper.Val (type bson.M) | |
/* | |
m := wrapper.Val.(bson.M) | |
bsonBytes, _ := bson.Marshal(m) | |
bson.Unmarshal(bsonBytes, pt) | |
*/ | |
// return the value as *I | |
i := pt.Elem().Interface().(I) | |
return &i, nil | |
} | |
func TestPoly(t *testing.T) { | |
d, _ := ioutil.TempDir(os.TempDir(), "mongotools-test") | |
server := dbtest.DBServer{} | |
server.SetPath(d) | |
//server.SetPort(27017) | |
defer server.Stop() | |
session := server.Session() | |
defer session.Close() | |
coll := session.DB("").C("polytest") | |
saveAndRetrieve(coll, t) | |
//time.Sleep(time.Hour) | |
} | |
func saveAndRetrieve(coll *mgo.Collection, t *testing.T) { | |
typeregistry.Register(reflect.TypeOf((*S1)(nil)).Elem()) | |
typeregistry.Register(reflect.TypeOf((*S2)(nil)).Elem()) | |
s1 := S1{ | |
1, | |
} | |
s2 := S2{ | |
S1{ | |
2, | |
}, | |
3, | |
} | |
id1, _ := save(coll, &s1) | |
t.Logf("object 1 saved %v", id1) | |
id2, _ := save(coll, &s2) | |
t.Logf("object 2 saved %v", id2) | |
r1, _ := getById(coll, id1) | |
t.Logf("object 1 retrieved %v", r1) | |
r2, _ := getById(coll, id2) | |
t.Logf("object 2 retrieved %v", r2) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package typeregistry | |
import "reflect" | |
var types map[string]reflect.Type | |
func init() { | |
types = make(map[string]reflect.Type) | |
} | |
func Register(t reflect.Type) { | |
key := GetKey(t) | |
types[key] = t | |
} | |
func GetKey(t reflect.Type) string { | |
key := t.PkgPath() + "." + t.Name() | |
return key | |
} | |
func GetType(key string) reflect.Type { | |
t := types[key] | |
return t | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment