diff options
author | Kevin Keuning <kkeuning@gmail.com> | 2017-03-05 22:11:42 -0600 |
---|---|---|
committer | Kevin Keuning <kkeuning@gmail.com> | 2017-03-05 22:11:42 -0600 |
commit | 92a96fe470b39ae5c16f66fce8023f04ad3a37ae (patch) | |
tree | fd9a03089b1a6ba1a45bcc733858851a394fa718 /system/db/content.go | |
parent | 266b7834c586f3c6be20d6772b36347d1f2a6b35 (diff) |
consolidate UpdateContent into SetContent
Diffstat (limited to 'system/db/content.go')
-rw-r--r-- | system/db/content.go | 125 |
1 files changed, 47 insertions, 78 deletions
diff --git a/system/db/content.go b/system/db/content.go index 8064b03..4517fbe 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -3,6 +3,7 @@ package db import ( "bytes" "encoding/json" + "errors" "fmt" "log" "net/url" @@ -17,29 +18,18 @@ import ( uuid "github.com/satori/go.uuid" ) -// SetContent inserts or updates values in the database. -// The `target` argument is a string made up of namespace:id (string:int) -func SetContent(target string, data url.Values) (int, error) { - t := strings.Split(target, ":") - ns, id := t[0], t[1] - - // check if content id == -1 (indicating new post). - // if so, run an insert which will assign the next auto incremented int. - // this is done because boltdb begins its bucket auto increment value at 0, - // which is the zero-value of an int in the Item struct field for ID. - // this is a problem when the original first post (with auto ID = 0) gets - // overwritten by any new post, originally having no ID, defauting to 0. - if id == "-1" { - return insert(ns, data) +func IsValidID(id string) bool { + // ID should be a non-negative integer. + // ID of -1 is special for new posts, not updates. + if i, err := strconv.Atoi(id); err != nil || i < 0 { + return false } - - return update(ns, id, data) + return true } -// UpdateContent inserts or updates values in the database. -// Updated content will be merged into existing values from the database. +// SetContent inserts or updates values in the database. // The `target` argument is a string made up of namespace:id (string:int) -func UpdateContent(target string, data url.Values) (int, error) { +func SetContent(target string, data url.Values) (int, error) { t := strings.Split(target, ":") ns, id := t[0], t[1] @@ -58,16 +48,11 @@ func UpdateContent(target string, data url.Values) (int, error) { if err != nil { return 0, err } + return update(ns, id, data, &existingContent) +} - // Unmarsal the existing values - s := item.Types[ns]() - - err = json.Unmarshal(existingContent, &s) - if err != nil { - log.Println("Error decoding json while updating", ns, ":", err) - return 0, err - } - +// update can support merge or replace behavior +func update(ns, id string, data url.Values, existingContent *[]byte) (int, error) { var specifier string // i.e. __pending, __sorted, etc. if strings.Contains(ns, "__") { spec := strings.Split(ns, "__") @@ -80,22 +65,17 @@ func UpdateContent(target string, data url.Values) (int, error) { return 0, err } - // Don't allow the Item fields to be updated from form values - data.Del("id") - data.Del("uuid") - data.Del("slug") - - dec := schema.NewDecoder() - dec.SetAliasTag("json") // allows simpler struct tagging when creating a content type - dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct - err = dec.Decode(s, data) - if err != nil { - return 0, err - } - - j, err := json.Marshal(s) - if err != nil { - return 0, err + var j []byte + if existingContent == nil { + j, err = postToJSON(ns, data) + if err != nil { + return 0, err + } + } else { + j, err = mergeData(ns, data, *existingContent) + if err != nil { + return 0, err + } } err = store.Update(func(tx *bolt.Tx) error { @@ -128,52 +108,41 @@ func UpdateContent(target string, data url.Values) (int, error) { return cid, nil } -func update(ns, id string, data url.Values) (int, error) { - var specifier string // i.e. __pending, __sorted, etc. - if strings.Contains(ns, "__") { - spec := strings.Split(ns, "__") - ns = spec[0] - specifier = "__" + spec[1] - } - - cid, err := strconv.Atoi(id) - if err != nil { - return 0, err +func mergeData(ns string, data url.Values, existingContent []byte) ([]byte, error) { + var j []byte + t, ok := item.Types[ns] + if !ok { + return j, errors.New("Invalid type.") + // handle } - j, err := postToJSON(ns, data) + // Unmarsal the existing values + s := t() + err := json.Unmarshal(existingContent, &s) if err != nil { - return 0, err + log.Println("Error decoding json while updating", ns, ":", err) + return j, err } - err = store.Update(func(tx *bolt.Tx) error { - b, err := tx.CreateBucketIfNotExists([]byte(ns + specifier)) - if err != nil { - return err - } - - err = b.Put([]byte(fmt.Sprintf("%d", cid)), j) - if err != nil { - return err - } + // Don't allow the Item fields to be updated from form values + data.Del("id") + data.Del("uuid") + data.Del("slug") - return nil - }) + dec := schema.NewDecoder() + dec.SetAliasTag("json") // allows simpler struct tagging when creating a content type + dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct + err = dec.Decode(s, data) if err != nil { - return 0, nil - } - - if specifier == "" { - go SortContent(ns) + return j, err } - // update changes data, so invalidate client caching - err = InvalidateCache() + j, err = json.Marshal(s) if err != nil { - return 0, err + return j, err } - return cid, nil + return j, nil } func insert(ns string, data url.Values) (int, error) { |