111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
package leveldb
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"encoding/gob"
|
|
"fmt"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb"
|
|
"m8sh.su/x/m8sh/database"
|
|
)
|
|
|
|
type users struct {
|
|
db *leveldb.DB
|
|
}
|
|
|
|
func (u *users) Create(user database.User) error {
|
|
k := key(user.Name, prefixUsers)
|
|
|
|
_, err := u.db.Get(k, nil)
|
|
if err == nil {
|
|
return database.ErrAlreadyExists
|
|
}
|
|
if err != leveldb.ErrNotFound {
|
|
return fmt.Errorf("check user %q: %w", user.Name, err)
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
if err = gob.NewEncoder(&buf).Encode(user); err != nil {
|
|
return fmt.Errorf("encode user %q: %w", user.Name, err)
|
|
}
|
|
|
|
if err = u.db.Put(k, buf.Bytes(), woSync); err != nil {
|
|
return fmt.Errorf("store user %q: %w", user.Name, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (u *users) Get(name string) (database.User, error) {
|
|
k := key(name, prefixUsers)
|
|
data, err := u.db.Get(k, nil)
|
|
if err != nil {
|
|
if err == leveldb.ErrNotFound {
|
|
return database.User{}, database.ErrNotFound
|
|
}
|
|
return database.User{}, fmt.Errorf("read user %q: %w", name, err)
|
|
}
|
|
|
|
var user database.User
|
|
if err = gob.NewDecoder(bytes.NewReader(data)).Decode(&user); err != nil {
|
|
return database.User{}, fmt.Errorf("decode user %q: %w", name, err)
|
|
}
|
|
|
|
totalKey := key(name, prefixSubsTotal)
|
|
if data, err = u.db.Get(totalKey, nil); err == nil {
|
|
user.Subscribers = binary.LittleEndian.Uint64(data)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (u *users) Update(name string, user database.User) error {
|
|
k := key(name, prefixUsers)
|
|
|
|
_, err := u.db.Get(k, nil)
|
|
if err != nil {
|
|
if err == leveldb.ErrNotFound {
|
|
return database.ErrNotFound
|
|
}
|
|
return fmt.Errorf("check user %q before update: %w", name, err)
|
|
}
|
|
|
|
user.Name = name
|
|
|
|
var buf bytes.Buffer
|
|
if err = gob.NewEncoder(&buf).Encode(user); err != nil {
|
|
return fmt.Errorf("encode user %q: %w", name, err)
|
|
}
|
|
|
|
if err = u.db.Put(k, buf.Bytes(), woSync); err != nil {
|
|
return fmt.Errorf("store user %q: %w", name, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (u *users) Delete(name string) error {
|
|
k := key(name, prefixUsers)
|
|
|
|
_, err := u.db.Get(k, nil)
|
|
if err != nil {
|
|
if err == leveldb.ErrNotFound {
|
|
return database.ErrNotFound
|
|
}
|
|
return fmt.Errorf("check user %q before delete: %w", name, err)
|
|
}
|
|
|
|
if err = u.db.Delete(k, woSync); err != nil {
|
|
return fmt.Errorf("delete user %q: %w", name, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (u *users) CheckExists(name string) bool {
|
|
k := key(name, prefixUsers)
|
|
_, err := u.db.Get(k, nil)
|
|
return err == nil
|
|
}
|