Files
m8sh/database/leveldb/users.go
T
2026-06-06 19:20:38 +03:00

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
}