-
Notifications
You must be signed in to change notification settings - Fork 3
/
model.go
102 lines (81 loc) · 2.26 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
97
98
99
100
101
102
// Package coal provides a mini ORM for mongoDB.
package coal
import (
"fmt"
"reflect"
"github.com/globalsign/mgo/bson"
)
// Model is the main interface implemented by every coal model embedding Base.
type Model interface {
ID() bson.ObjectId
Meta() *Meta
MustGet(string) interface{}
MustSet(string, interface{})
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 coal model.
type Base struct {
DocID bson.ObjectId `json:"-" bson:"_id"`
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. MustGet will panic if no field
// has been found.
func (b *Base) MustGet(name string) interface{} {
// find field
field := b.meta.Fields[name]
if field == nil {
panic(fmt.Sprintf(`coal: field "%s" not found on "%s"`, name, b.meta.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. MustSet will panic
// if no field has been found.
func (b *Base) MustSet(name string, value interface{}) {
// find field
field := b.meta.Fields[name]
if field == nil {
panic(fmt.Sprintf(`coal: field "%s" not found on "%s"`, name, b.meta.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)
}