package db import ( "bytes" "git.giftfish.de/ston1th/gowiki/pkg/render" "github.com/boltdb/bolt" "html/template" "strings" ) type Snippet struct { Title string `json:"title"` LinkTitle string `json:"-"` Index template.HTML `json:"index"` Text template.HTML `json:"text"` MD string `json:"md"` Created string `json:"created"` Updated string `json:"updated"` Permission int `json:"permission"` } func copyBuf(buf []byte) (b []byte) { b = make([]byte, len(buf)) copy(b, buf) return } var ( errSnippetNotExists = dbErr("snippet does not exist") errSnippetExists = dbErr("snippet already exist") ) func (bs *BoltStore) GetSnippets(username string) (snip []Snippet, err error) { user := []byte(username) var buf [][]byte err = bs.db.View(func(tx *bolt.Tx) error { return tx.Bucket([]byte(snippetTable)).ForEach(func(k, v []byte) error { if !bytes.HasPrefix(k, user) { return nil } buf = append(buf, copyBuf(v)) return nil }) }) if err != nil { return } for _, b := range buf { s := new(Snippet) if err = bs.Unmarshal(b, s); err != nil { return } snip = append(snip, *s) } return } func (bs *BoltStore) GetSnippet(username, title string, perm int) (*Snippet, error) { s := new(Snippet) err := bs.db.View(func(tx *bolt.Tx) error { v := tx.Bucket([]byte(snippetTable)).Get([]byte(title)) if v == nil { return errSnippetNotExists } return bs.Unmarshal(v, s) }) if err != nil { return nil, err } switch s.Permission { case 0: return s, nil case 1: if username != "" { return s, nil } case 2: if strings.HasPrefix(title, username) { return s, nil } } return nil, errSnippetNotExists } func (bs *BoltStore) snippetExists(username, title string, perm int) (err error) { _, err = bs.GetSnippet(username, title, perm) return } func makeKey(username, title string) string { return username + title } func checkPerm(p int) error { switch p { case 0, 1, 2: return nil } return errInvalidPermission } func (bs *BoltStore) CreateSnippet(username, title, text string, perm int) (newTitle string, err error) { //newTitle, title = makeLinkTitle(title) err = checkPerm(perm) if err != nil { return } err = bs.snippetExists(username, title, perm) if err == nil { err = errSnippetExists return } err = bs.db.Update(func(tx *bolt.Tx) error { snip := render.Render(text).Snippet() snip.Title = title snip.Created = username + " " + now() snip.Permission = perm v, err := bs.Marshal(snip) if err != nil { return err } return tx.Bucket([]byte(snippetTable)).Put([]byte(makeKey(username, title)), v) }) return } func (bs *BoltStore) EditSnippet(username, title, text string, perm int) (err error) { err = checkPerm(perm) if err != nil { return } err = bs.snippetExists(username, title, perm) if err != nil { return } err = bs.db.Update(func(tx *bolt.Tx) error { snip := render.Render(text).Snippet() snip.Title = title snip.Created = username + " " + now() snip.Permission = perm v, err := bs.Marshal(snip) if err != nil { return err } return tx.Bucket([]byte(snippetTable)).Put([]byte(makeKey(username, title)), v) }) return }