diff options
Diffstat (limited to 'system/db')
-rw-r--r-- | system/db/config.go | 4 | ||||
-rw-r--r-- | system/db/content.go | 73 | ||||
-rw-r--r-- | system/db/init.go | 8 | ||||
-rw-r--r-- | system/db/user.go | 25 |
4 files changed, 75 insertions, 35 deletions
diff --git a/system/db/config.go b/system/db/config.go index 6855081..ab1c720 100644 --- a/system/db/config.go +++ b/system/db/config.go @@ -24,7 +24,7 @@ func init() { // SetConfig sets key:value pairs in the db for configuration settings func SetConfig(data url.Values) error { err := store.Update(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_config")) + b := tx.Bucket([]byte("__config")) // check for any multi-value fields (ex. checkbox fields) // and correctly format for db storage. Essentially, we need @@ -108,7 +108,7 @@ func Config(key string) ([]byte, error) { func ConfigAll() ([]byte, error) { val := &bytes.Buffer{} err := store.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_config")) + b := tx.Bucket([]byte("__config")) val.Write(b.Get([]byte("settings"))) return nil diff --git a/system/db/content.go b/system/db/content.go index 0cfadf4..74a77ec 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -39,11 +39,11 @@ func SetContent(target string, data url.Values) (int, error) { } 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, "_") + var specifier string // i.e. __pending, __sorted, etc. + if strings.Contains(ns, "__") { + spec := strings.Split(ns, "__") ns = spec[0] - specifier = "_" + spec[1] + specifier = "__" + spec[1] } cid, err := strconv.Atoi(id) @@ -82,11 +82,11 @@ func update(ns, id string, data url.Values) (int, error) { func insert(ns string, data url.Values) (int, error) { var effectedID int - var specifier string // i.e. _pending, _sorted, etc. - if strings.Contains(ns, "_") { - spec := strings.Split(ns, "_") + var specifier string // i.e. __pending, __sorted, etc. + if strings.Contains(ns, "__") { + spec := strings.Split(ns, "__") ns = spec[0] - specifier = "_" + spec[1] + specifier = "__" + spec[1] } err := store.Update(func(tx *bolt.Tx) error { @@ -215,8 +215,21 @@ type QueryOptions struct { } // Query retrieves a set of content from the db based on options -func Query(namespace string, opts QueryOptions) [][]byte { +// and returns the total number of content in the namespace and the content +func Query(namespace string, opts QueryOptions) (int, [][]byte) { var posts [][]byte + var total int + + // correct bad input rather than return nil or error + // similar to default case for opts.Order switch below + if opts.Count < 0 { + opts.Count = 0 + } + + if opts.Offset < 0 { + opts.Offset = 0 + } + store.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(namespace)) if b == nil { @@ -225,6 +238,12 @@ func Query(namespace string, opts QueryOptions) [][]byte { c := b.Cursor() n := b.Stats().KeyN + total = n + + // return nil if no content + if n == 0 { + return nil + } var start, end int switch opts.Count { @@ -279,12 +298,29 @@ func Query(namespace string, opts QueryOptions) [][]byte { i++ cur++ } + + default: + // results for DESC order + for k, v := c.First(); k != nil; k, v = c.Next() { + if cur < start { + cur++ + continue + } + + if cur >= end { + break + } + + posts = append(posts, v) + i++ + cur++ + } } return nil }) - return posts + return total, posts } // SortContent sorts all content of the type supplied as the namespace by time, @@ -292,13 +328,13 @@ func Query(namespace string, opts QueryOptions) [][]byte { // Should be called from a goroutine after SetContent is successful func SortContent(namespace string) { // only sort main content types i.e. Post - if strings.Contains(namespace, "_") { + if strings.Contains(namespace, "__") { return } all := ContentAll(namespace) - var posts sortablePosts + var posts sortableContent // decode each (json) into type to then sort for i := range all { j := all[i] @@ -318,7 +354,7 @@ func SortContent(namespace string) { // store in <namespace>_sorted bucket, first delete existing err := store.Update(func(tx *bolt.Tx) error { - bname := []byte(namespace + "_sorted") + bname := []byte(namespace + "__sorted") err := tx.DeleteBucket(bname) if err != nil { return err @@ -351,23 +387,22 @@ func SortContent(namespace string) { } -type sortablePosts []editor.Sortable +type sortableContent []editor.Sortable -func (s sortablePosts) Len() int { +func (s sortableContent) Len() int { return len(s) } -func (s sortablePosts) Less(i, j int) bool { +func (s sortableContent) Less(i, j int) bool { return s[i].Time() > s[j].Time() } -func (s sortablePosts) Swap(i, j int) { +func (s sortableContent) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func postToJSON(ns string, data url.Values) ([]byte, error) { // find the content type and decode values into it - ns = strings.TrimSuffix(ns, "_external") t, ok := content.Types[ns] if !ok { return nil, fmt.Errorf(content.ErrTypeNotRegistered, ns) @@ -382,7 +417,7 @@ func postToJSON(ns string, data url.Values) ([]byte, error) { return nil, err } - slug, err := manager.Slug(post.(editor.Editable)) + slug, err := manager.Slug(post.(content.Identifiable)) if err != nil { return nil, err } diff --git a/system/db/init.go b/system/db/init.go index 63804e1..967eed1 100644 --- a/system/db/init.go +++ b/system/db/init.go @@ -38,14 +38,14 @@ func Init() { return err } - _, err = tx.CreateBucketIfNotExists([]byte(t + "_sorted")) + _, err = tx.CreateBucketIfNotExists([]byte(t + "__sorted")) if err != nil { return err } } // init db with other buckets as needed - buckets := []string{"_config", "_users"} + buckets := []string{"__config", "__users"} for _, name := range buckets { _, err := tx.CreateBucketIfNotExists([]byte(name)) if err != nil { @@ -54,7 +54,7 @@ func Init() { } // seed db with configs structure if not present - b := tx.Bucket([]byte("_config")) + b := tx.Bucket([]byte("__config")) if b.Get([]byte("settings")) == nil { j, err := json.Marshal(&config.Config{}) if err != nil { @@ -93,7 +93,7 @@ func SystemInitComplete() bool { complete := false err := store.View(func(tx *bolt.Tx) error { - users := tx.Bucket([]byte("_users")) + users := tx.Bucket([]byte("__users")) err := users.ForEach(func(k, v []byte) error { complete = true diff --git a/system/db/user.go b/system/db/user.go index 3386dc2..b92a62a 100644 --- a/system/db/user.go +++ b/system/db/user.go @@ -24,7 +24,7 @@ var ErrNoUserExists = errors.New("Error. No user exists.") func SetUser(usr *user.User) (int, error) { err := store.Update(func(tx *bolt.Tx) error { email := []byte(usr.Email) - users := tx.Bucket([]byte("_users")) + users := tx.Bucket([]byte("__users")) // check if user is found by email, fail if nil exists := users.Get(email) @@ -61,8 +61,13 @@ func SetUser(usr *user.User) (int, error) { // UpdateUser sets key:value pairs in the db for existing user settings func UpdateUser(usr, updatedUsr *user.User) error { + // ensure user ID remains the same + if updatedUsr.ID != usr.ID { + updatedUsr.ID = usr.ID + } + err := store.Update(func(tx *bolt.Tx) error { - users := tx.Bucket([]byte("_users")) + users := tx.Bucket([]byte("__users")) // check if user is found by email, fail if nil exists := users.Get([]byte(usr.Email)) @@ -103,7 +108,7 @@ func UpdateUser(usr, updatedUsr *user.User) error { // DeleteUser deletes a user from the db by email func DeleteUser(email string) error { err := store.Update(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_users")) + b := tx.Bucket([]byte("__users")) err := b.Delete([]byte(email)) if err != nil { return err @@ -122,7 +127,7 @@ func DeleteUser(email string) error { func User(email string) ([]byte, error) { val := &bytes.Buffer{} err := store.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_users")) + b := tx.Bucket([]byte("__users")) usr := b.Get([]byte(email)) _, err := val.Write(usr) @@ -147,7 +152,7 @@ func User(email string) ([]byte, error) { func UserAll() ([][]byte, error) { var users [][]byte err := store.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_users")) + b := tx.Bucket([]byte("__users")) err := b.ForEach(func(k, v []byte) error { users = append(users, v) return nil @@ -196,7 +201,7 @@ func SetRecoveryKey(email string) (string, error) { key := fmt.Sprintf("%d", rand.Int63()) err := store.Update(func(tx *bolt.Tx) error { - b, err := tx.CreateBucketIfNotExists([]byte("_recoveryKeys")) + b, err := tx.CreateBucketIfNotExists([]byte("__recoveryKeys")) if err != nil { return err } @@ -215,18 +220,18 @@ func SetRecoveryKey(email string) (string, error) { return key, nil } -// RecoveryKey generates and saves a random secret key to verify an email -// address submitted in order to recover/reset an account password +// RecoveryKey gets a previously set recovery key to verify an email address +// submitted in order to recover/reset an account password func RecoveryKey(email string) (string, error) { key := &bytes.Buffer{} err := store.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte("_recoveryKeys")) + b := tx.Bucket([]byte("__recoveryKeys")) if b == nil { return errors.New("No database found for checking keys.") } - _, err := key.Write(b.Get([]byte("email"))) + _, err := key.Write(b.Get([]byte(email))) if err != nil { return err } |