func (d *Database) UpdateLinkSlug(slug string, l *model.Link, u *model.User) error {
	var (
		i  int
		ok bool
	)
	err := d.db.Update(func(tx *bolt.Tx) error {
		if slug == l.Slug {
			return d.update(tx, "link", linksBucket, []byte(l.Slug), l)
		}
		if err := d.delete(tx, "link", linksBucket, []byte(slug)); err != nil {
			return err
		}
		if err := d.create(tx, "link", linksBucket, []byte(l.Slug), l); err != nil {
			return err
		}
		var ok bool
		i, ok := u.FindLinkSlug(slug)
		if !ok {
			return errors.Error{
				Type:    errors.Unauthorized,
				Message: "bolt: failed to find link in user",
			}
		}
		u.LinkSlugs[i] = l.Slug
		return d.update(tx, "user", usersBucket, []byte(u.Username), u)
	})
	if err != nil && ok {
		u.LinkSlugs[i] = slug
	}
	return err
}
UpdateLinkSlug updates the given link, including changes to the slug.
package bolt
import (
	"github.com/boltdb/bolt"
	"github.com/ravern/jabba/errors"
	"github.com/ravern/jabba/model"
)
func (d *Database) CreateLink(l *model.Link, u *model.User) error {
	err := d.db.Update(func(tx *bolt.Tx) error {
		if err := d.create(tx, "link", linksBucket, []byte(l.Slug), l); err != nil {
			return err
		}
		u.LinkSlugs = append(u.LinkSlugs, l.Slug)
		return d.update(tx, "user", usersBucket, []byte(u.Username), u)
	})
	if err != nil {
		if i, ok := u.FindLinkSlug(l.Slug); ok {
			u.LinkSlugs = append(u.LinkSlugs[:i], u.LinkSlugs[i+1:]...)
		}
	}
	return err
}
func (d *Database) DeleteLink(l *model.Link, u *model.User) error {
	var (
		i  int
		ok bool
	)
	err := d.db.Update(func(tx *bolt.Tx) error {
		if err := d.delete(tx, "links", linksBucket, []byte(l.Slug)); err != nil {
			return err
		}
		i, ok = u.FindLinkSlug(l.Slug)
		if !ok {
			return errors.Error{
				Type:    errors.Unauthorized,
				Message: "bolt: failed to find link in user",
			}
		}
		u.LinkSlugs = append(u.LinkSlugs[:i], u.LinkSlugs[i+1:]...)
		return d.update(tx, "user", usersBucket, []byte(u.Username), u)
	})
	if err != nil && ok {
		u.LinkSlugs = append(u.LinkSlugs[:i], append([]string{l.Slug}, u.LinkSlugs[i:]...)...)
	}
	return err
}
func (d *Database) IncrementLinkCount(l *model.Link) {
	d.visitCountsMu.Lock()
	defer d.visitCountsMu.Unlock()
	_, ok := d.visitCounts[l.Slug]
	if !ok {
		d.visitCounts[l.Slug] = 0
	}
	d.visitCounts[l.Slug]++
	l.Count++
}
func (d *Database) updateLinkCounts() {
	d.visitCountsMu.Lock()
	defer d.visitCountsMu.Unlock()
	d.db.Update(func(tx *bolt.Tx) error {
		for slug, count := range d.visitCounts {
			var l *model.Link
			if err := d.get(tx, "link", linksBucket, []byte(slug), &l); err != nil {
				continue
			}
			l.Count += count
			d.put(tx, "link", linksBucket, []byte(slug), l)
		}
		return nil
	})
	d.visitCounts = make(map[string]int)
}