package main import ( "encoding/json" "errors" "fmt" "github.com/xujiajun/nutsdb" ) func ReadUser(username string) (*UserData, error) { data, err := DbRead(bucketUsers, username) if err != nil { return nil, err } var user UserData err = json.Unmarshal(data, &user) return &user, err } func SaveUser(user *UserData) error { data, err := json.Marshal(user) if err != nil { return err } if user.Username == "" { return errors.New("user empty") } err = DbSave(bucketUsers, user.Username, data) return err } func AddUserToAnime(username string, userId, animeId int64) (*AnimeUser, error) { var anime AnimeUser err := db.Update( func(tx *nutsdb.Tx) error { keyBytes := Int64ToByte(animeId) e, err := tx.Get(bucketAnime, keyBytes) var users []WatchUser if err != nil { users = make([]WatchUser, 0) } else { // parse user list users, err = parseUserList(e.Value) if err != nil { return err } } // check if user already part for _, u := range users { if u.MalID == userId { // early terminate anime = AnimeUser{ Anime: animeId, Users: users, } return err } } // add user users = append(users, WatchUser{ Username: username, MalID: userId, }) anime = AnimeUser{ Anime: animeId, Users: users, } newData, err := json.Marshal(users) if err != nil { return err } return tx.Put(bucketAnime, keyBytes, newData, nutsdb.Persistent) }) return &anime, err } func DeleteUserFromAnime(username string, userId, animeId int64) (*AnimeUser, error) { var anime AnimeUser err := db.Update( func(tx *nutsdb.Tx) error { keyBytes := Int64ToByte(animeId) e, err := tx.Get(bucketAnime, keyBytes) var users []WatchUser if err != nil { users = make([]WatchUser, 0) } else { // parse user list users, err = parseUserList(e.Value) if err != nil { return err } } // check if user already part for i, u := range users { // early terminate if u.MalID == userId { // delete user from list users[i] = users[len(users)-1] users = users[:len(users)-1] // check if anime needs recycling anime = AnimeUser{ Anime: animeId, Users: users, } if len(users) == 0 { return tx.Delete(bucketAnime, keyBytes) } newData, err := json.Marshal(users) if err != nil { return err } return tx.Put(bucketAnime, keyBytes, newData, nutsdb.Persistent) } } return fmt.Errorf("%s %d schaut nicht %d", username, userId, animeId) }) return &anime, err } func DeleteUserFromAnimes(userId int64) error { return db.Update( func(tx *nutsdb.Tx) error { entries, err := tx.GetAll(bucketAnime) if err != nil { return err } // iterate entries for _, e := range entries { // parse user list users, err := parseUserList(e.Value) if err != nil { return err } // check if user is part for i, u := range users { if u.MalID == userId { // delete user from list users[i] = users[len(users)-1] users = users[:len(users)-1] // check if anime needs recycling if len(users) == 0 { err = tx.Delete(bucketAnime, e.Key) if err != nil { return err } } else { newData, err := json.Marshal(users) if err != nil { return err } err = tx.Put(bucketAnime, e.Key, newData, nutsdb.Persistent) if err != nil { return err } } break } } } return nil }) } func ReadAnimeUsers() ([]AnimeUser, error) { var animes []AnimeUser err := db.View( func(tx *nutsdb.Tx) error { entries, err := tx.GetAll(bucketAnime) if err != nil { return err } animes = make([]AnimeUser, 0) // iterate entries for _, e := range entries { // decode anime list animeId, err := BytesToInt64(e.Key) if err != nil { return err } // parse user list users, err := parseUserList(e.Value) if err != nil { return err } anime := AnimeUser{ Anime: animeId, Users: users, } animes = append(animes, anime) } return nil }) return animes, err } func DbClean() error { return db.Update( func(tx *nutsdb.Tx) error { return db.Merge() }) } func DbSave(bucket, key string, val []byte) error { return db.Update( func(tx *nutsdb.Tx) error { keyBytes := []byte(key) return tx.Put(bucket, keyBytes, val, nutsdb.Persistent) }) } func DbRead(bucket, key string) ([]byte, error) { var val []byte err := db.View( func(tx *nutsdb.Tx) error { keyBytes := []byte(key) e, err := tx.Get(bucket, keyBytes) if err != nil { return err } val = make([]byte, len(e.Value)) copy(val, e.Value) return err }) return val, err } func DbDelete(bucket, key string) error { return db.Update( func(tx *nutsdb.Tx) error { keyBytes := []byte(key) return tx.Delete(bucket, keyBytes) }) } func parseUserList(data []byte) ([]WatchUser, error) { var users []WatchUser err := json.Unmarshal(data, &users) return users, err }