improve Save
api
add a `SaveWith` function that accepts `SaveOptions` as a parameter, letting you tweak things like whether timestamps will be set before an insert or update operation
This commit is contained in:
parent
bb37212be7
commit
11d31fbbc1
27
document.go
27
document.go
@ -21,6 +21,7 @@ type IDocument interface {
|
|||||||
Delete() error
|
Delete() error
|
||||||
Remove() error
|
Remove() error
|
||||||
Save() error
|
Save() error
|
||||||
|
SaveWith(opts *SaveOptions) error
|
||||||
setSelf(arg interface{})
|
setSelf(arg interface{})
|
||||||
getExists() bool
|
getExists() bool
|
||||||
setExists(n bool)
|
setExists(n bool)
|
||||||
@ -33,6 +34,10 @@ type IDocument interface {
|
|||||||
setModel(m Model)
|
setModel(m Model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SaveOptions struct {
|
||||||
|
SetTimestamps bool
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Document) getCreated() time.Time {
|
func (d *Document) getCreated() time.Time {
|
||||||
return d.Created
|
return d.Created
|
||||||
}
|
}
|
||||||
@ -89,25 +94,33 @@ func (d *Document) Remove() error {
|
|||||||
return d.Delete()
|
return d.Delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save - updates this Model in the database,
|
// SaveWith - updates this Model in the database,
|
||||||
// or inserts it if it doesn't exist
|
// or inserts it if it doesn't exist, using the provided
|
||||||
func (d *Document) Save() error {
|
// SaveOptions
|
||||||
|
func (d *Document) SaveWith(opts *SaveOptions) error {
|
||||||
val := valueOf(d.self)
|
val := valueOf(d.self)
|
||||||
if val.Kind() == reflect.Slice {
|
if val.Kind() == reflect.Slice {
|
||||||
for i := 0; i < val.Len(); i++ {
|
for i := 0; i < val.Len(); i++ {
|
||||||
cur := val.Index(i)
|
cur := val.Index(i)
|
||||||
asHId := asId(cur.Interface())
|
if err := doSave(d.model.getColl(), !d.exists, opts, cur.Interface()); err != nil {
|
||||||
if err := doSave(d.model.getColl(), !d.exists && reflect.ValueOf(asHId.Id()).IsZero(), cur.Interface()); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
asHId := asId(val.Interface())
|
return doSave(d.model.getColl(), !d.exists, opts, d.self)
|
||||||
return doSave(d.model.getColl(), !d.exists && reflect.ValueOf(asHId.Id()).IsZero(), d.self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save - updates this Model in the database,
|
||||||
|
// or inserts it if it doesn't exist, using
|
||||||
|
// default SaveOptions
|
||||||
|
func (d *Document) Save() error {
|
||||||
|
return d.SaveWith(&SaveOptions{
|
||||||
|
SetTimestamps: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Document) serializeToStore() any {
|
func (d *Document) serializeToStore() any {
|
||||||
return serializeIDs((d).self)
|
return serializeIDs((d).self)
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func serializeIDs(input interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
func doSave(c *mongo.Collection, isNew bool, arg interface{}) error {
|
func doSave(c *mongo.Collection, isNew bool, opts *SaveOptions, arg interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
d, ok := arg.(IDocument)
|
d, ok := arg.(IDocument)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -118,10 +118,12 @@ func doSave(c *mongo.Collection, isNew bool, arg interface{}) error {
|
|||||||
}
|
}
|
||||||
var asHasId = vp.Interface().(HasID)
|
var asHasId = vp.Interface().(HasID)
|
||||||
var asModel = vp.Interface().(IDocument)
|
var asModel = vp.Interface().(IDocument)
|
||||||
if isNew {
|
if isNew && opts.SetTimestamps {
|
||||||
d.setCreated(now)
|
d.setCreated(now)
|
||||||
}
|
}
|
||||||
|
if opts.SetTimestamps {
|
||||||
d.setModified(now)
|
d.setModified(now)
|
||||||
|
}
|
||||||
idxs := d.getModel().getIdxs()
|
idxs := d.getModel().getIdxs()
|
||||||
for _, i := range idxs {
|
for _, i := range idxs {
|
||||||
_, err = c.Indexes().CreateOne(context.TODO(), *i)
|
_, err = c.Indexes().CreateOne(context.TODO(), *i)
|
||||||
|
7
util.go
7
util.go
@ -45,7 +45,12 @@ func asId(i interface{}) HasID {
|
|||||||
var ok bool
|
var ok bool
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
v = reflect.New(reflect.PointerTo(v.Type()))
|
asHasId, ok = v.Interface().(HasID)
|
||||||
|
if ok {
|
||||||
|
return asHasId
|
||||||
|
}
|
||||||
|
v = reflect.New(v.Type())
|
||||||
|
v.Elem().Set(reflect.ValueOf(i))
|
||||||
fallthrough
|
fallthrough
|
||||||
case reflect.Pointer:
|
case reflect.Pointer:
|
||||||
asHasId, ok = v.Interface().(HasID)
|
asHasId, ok = v.Interface().(HasID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user