-
Notifications
You must be signed in to change notification settings - Fork 3
/
model.go
96 lines (76 loc) · 2.29 KB
/
model.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package fire
import (
"reflect"
"gopkg.in/mgo.v2/bson"
)
// Model is the main interface implemented by every fire model embedding Base.
type Model interface {
ID() bson.ObjectId
MustGet(string) interface{}
MustSet(string, interface{})
Meta() *Meta
initialize(Model)
}
// Init initializes the internals of a model and should be called before using
// a newly created Model.
func Init(model Model) Model {
model.initialize(model)
return model
}
// InitSlice initializes all models in a slice of the form *[]*Post and returns
// a new slice that contains all initialized models.
func InitSlice(ptr interface{}) []Model {
// get slice
slice := reflect.ValueOf(ptr).Elem()
// make model slice
models := make([]Model, slice.Len())
// iterate over entries
for i := 0; i < slice.Len(); i++ {
m := Init(slice.Index(i).Interface().(Model))
models[i] = m
}
return models
}
// Base is the base for every fire model.
type Base struct {
DocID bson.ObjectId `json:"-" bson:"_id,omitempty"`
model interface{}
meta *Meta
}
// ID returns the models id.
func (b *Base) ID() bson.ObjectId {
return b.DocID
}
// MustGet returns the value of the given field.
//
// Note: MustGet will return the value of the first field that has a matching
// Name, JSONName, or BSONName and will panic if no field can be found.
func (b *Base) MustGet(name string) interface{} {
field := b.meta.MustFindField(name)
// read value from model struct
structField := reflect.ValueOf(b.model).Elem().Field(field.index)
return structField.Interface()
}
// MustSet will set the given field to the the passed valued.
//
// Note: MustSet will set the value of the first field that has a matching Name,
// JSONName, or BSONName and will panic if no field can been found. The method
// will also panic if the type of the field and the passed value do not match.
func (b *Base) MustSet(name string, value interface{}) {
field := b.meta.MustFindField(name)
// set the value on model struct
reflect.ValueOf(b.model).Elem().Field(field.index).Set(reflect.ValueOf(value))
}
// Meta returns the models Meta structure.
func (b *Base) Meta() *Meta {
return b.meta
}
func (b *Base) initialize(model Model) {
b.model = model
// set id if missing
if !b.DocID.Valid() {
b.DocID = bson.NewObjectId()
}
// assign meta
b.meta = NewMeta(model)
}