diff --git a/document.go b/document.go index b76d561..67335ba 100644 --- a/document.go +++ b/document.go @@ -21,6 +21,7 @@ type IDocument interface { Delete() error Remove() error Save() error + SaveWith(opts *SaveOptions) error setSelf(arg interface{}) getExists() bool setExists(n bool) @@ -33,6 +34,10 @@ type IDocument interface { setModel(m Model) } +type SaveOptions struct { + SetTimestamps bool +} + func (d *Document) getCreated() time.Time { return d.Created } @@ -89,25 +94,33 @@ func (d *Document) Remove() error { return d.Delete() } -// Save - updates this Model in the database, -// or inserts it if it doesn't exist -func (d *Document) Save() error { +// SaveWith - updates this Model in the database, +// or inserts it if it doesn't exist, using the provided +// SaveOptions +func (d *Document) SaveWith(opts *SaveOptions) error { val := valueOf(d.self) if val.Kind() == reflect.Slice { for i := 0; i < val.Len(); i++ { cur := val.Index(i) - asHId := asId(cur.Interface()) - if err := doSave(d.model.getColl(), !d.exists && reflect.ValueOf(asHId.Id()).IsZero(), cur.Interface()); err != nil { + if err := doSave(d.model.getColl(), !d.exists, opts, cur.Interface()); err != nil { return err } } return nil } else { - asHId := asId(val.Interface()) - return doSave(d.model.getColl(), !d.exists && reflect.ValueOf(asHId.Id()).IsZero(), d.self) + return doSave(d.model.getColl(), !d.exists, opts, 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 { return serializeIDs((d).self) } diff --git a/document_internals.go b/document_internals.go index 51a96cf..0b353ba 100644 --- a/document_internals.go +++ b/document_internals.go @@ -102,7 +102,7 @@ func serializeIDs(input interface{}) interface{} { } 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 d, ok := arg.(IDocument) if !ok { @@ -118,10 +118,12 @@ func doSave(c *mongo.Collection, isNew bool, arg interface{}) error { } var asHasId = vp.Interface().(HasID) var asModel = vp.Interface().(IDocument) - if isNew { + if isNew && opts.SetTimestamps { d.setCreated(now) } - d.setModified(now) + if opts.SetTimestamps { + d.setModified(now) + } idxs := d.getModel().getIdxs() for _, i := range idxs { _, err = c.Indexes().CreateOne(context.TODO(), *i) diff --git a/util.go b/util.go index fff292d..b03567d 100644 --- a/util.go +++ b/util.go @@ -45,7 +45,12 @@ func asId(i interface{}) HasID { var ok bool switch v.Kind() { 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 case reflect.Pointer: asHasId, ok = v.Interface().(HasID)