This repository has been archived by the owner on Apr 2, 2024. It is now read-only.
generated from mrz1836/go-template
-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
model_save.go
115 lines (99 loc) · 3.05 KB
/
model_save.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
103
104
105
106
107
108
109
110
111
112
113
114
115
package bux
import (
"context"
"fmt"
"time"
"github.com/BuxOrg/bux/datastore"
"github.com/pkg/errors"
)
// Save will Save the model(s) into the Datastore
func Save(ctx context.Context, model ModelInterface) (err error) {
// Create new Datastore transaction
// @siggi: we need this to be in a callback context for Mongo
// NOTE: a DB error is not being returned from here
return model.Client().Datastore().NewTx(ctx, func(tx *datastore.Transaction) (err error) {
// Fire the before hooks (parent model)
if model.IsNew() {
if err = model.BeforeCreating(ctx); err != nil {
return
}
} else {
if err = model.BeforeUpdating(ctx); err != nil {
return
}
}
// Set the record's timestamps
model.SetRecordTime(model.IsNew())
// Start the list of models to Save
modelsToSave := append(make([]ModelInterface, 0), model)
// Add any child models (fire before hooks)
if children := model.ChildModels(); len(children) > 0 {
for _, child := range children {
if child.IsNew() {
if err = child.BeforeCreating(ctx); err != nil {
return
}
} else {
if err = child.BeforeUpdating(ctx); err != nil {
return
}
}
// Set the record's timestamps
child.SetRecordTime(child.IsNew())
}
// Add to list for saving
modelsToSave = append(modelsToSave, children...)
}
// Logs for saving models
model.DebugLog(fmt.Sprintf("saving %d models...", len(modelsToSave)))
// Save all models (or fail!)
for _, modelToSave := range modelsToSave {
modelToSave.DebugLog("starting to save model: " + modelToSave.Name() + " id: " + modelToSave.GetID())
if err = modelToSave.Client().Datastore().SaveModel(
ctx, modelToSave, tx, modelToSave.IsNew(), false,
); err != nil {
return
}
}
// Commit all the model(s) if needed
if tx.CanCommit() {
model.DebugLog("committing db transaction...")
if err = tx.Commit(); err != nil {
return
}
}
// Fire after hooks (only on commit success)
var afterErr error
for _, modelToSave := range modelsToSave {
if modelToSave.IsNew() {
modelToSave.NotNew() // NOTE: calling it before this method... after created assumes its been saved already
afterErr = modelToSave.AfterCreated(ctx)
} else {
afterErr = modelToSave.AfterUpdated(ctx)
}
if afterErr != nil {
if err == nil { // First error - set the error
err = afterErr
} else { // Got more than one error, wrap it!
err = errors.Wrap(err, afterErr.Error())
}
}
// modelToSave.NotNew() // NOTE: moved to above from here
}
return
})
}
// saveToCache will Save the model to the cache using the given key
//
// ttl of 0 will cache forever
func saveToCache(ctx context.Context, key string, model ModelInterface, ttl time.Duration) error {
// NOTE: this check is in place in-case a model does not load it's Parent Client
if model.Client() != nil {
c := model.Client().Cachestore()
if c != nil && !c.Engine().IsEmpty() {
return c.SetModel(ctx, key, model, ttl)
}
}
model.DebugLog("ignoring SetModel: client or cachestore is missing")
return nil
}