|
|
package bolt
import ( "context" "github.com/gisle/stufflog/database/repositories" "github.com/gisle/stufflog/models" "github.com/gisle/stufflog/slerrors" "github.com/vmihailenco/msgpack/v4" "go.etcd.io/bbolt" )
var bnUserSessions = []byte("UserSession")
type userSessionRepository struct { userIdIdx *index db *bbolt.DB }
func (r *userSessionRepository) FindID(ctx context.Context, id string) (*models.UserSession, error) { session := new(models.UserSession) err := r.db.View(func(tx *bbolt.Tx) error { value := tx.Bucket(bnUserSessions).Get(unsafeStringToBytes(id)) if value == nil { return slerrors.NotFound("Session") } err := msgpack.Unmarshal(value, session) if err != nil { return err } return nil }) if err != nil { return nil, err }
return session, nil }
func (r *userSessionRepository) List(ctx context.Context) ([]*models.UserSession, error) { sessions := make([]*models.UserSession, 0, 16) err := r.db.View(func(tx *bbolt.Tx) error { cursor := tx.Bucket(bnUserSessions).Cursor()
for key, value := cursor.First(); key != nil; key, value = cursor.Next() { session := new(models.UserSession) err := msgpack.Unmarshal(value, session) if err != nil { return err }
sessions = append(sessions, session) }
return nil }) if err != nil { return nil, err }
return sessions, nil }
func (r *userSessionRepository) ListUser(ctx context.Context, user models.User) ([]*models.UserSession, error) { var sessions []*models.UserSession err := r.db.View(func(tx *bbolt.Tx) error { bucket := tx.Bucket(bnUserSessions)
ids, err := r.userIdIdx.WithTx(tx).Get(user.ID) if err != nil { return err } sessions = make([]*models.UserSession, len(ids))
for i, id := range ids { value := bucket.Get(id)
session := new(models.UserSession) err := msgpack.Unmarshal(value, session) if err != nil { return err }
sessions[i] = session }
return nil }) if err != nil { return nil, err }
return sessions, nil }
func (r *userSessionRepository) Save(ctx context.Context, session models.UserSession) error { value, err := msgpack.Marshal(&session) if err != nil { return err }
return r.db.Update(func(tx *bbolt.Tx) error { err := tx.Bucket(bnUserSessions).Put(unsafeStringToBytes(session.ID), value) if err != nil { return err }
err = r.userIdIdx.WithTx(tx).Set(unsafeStringToBytes(session.ID), session.UserID) if err != nil { return err }
return nil }) }
func (r *userSessionRepository) Remove(ctx context.Context, session models.UserSession) error { return r.db.Update(func(tx *bbolt.Tx) error { err := tx.Bucket(bnUserSessions).Delete(unsafeStringToBytes(session.ID)) if err != nil { return err }
err = r.userIdIdx.WithTx(tx).Set(unsafeStringToBytes(session.ID)) if err != nil { return err }
return nil }) }
func (r *userSessionRepository) RemoveUser(ctx context.Context, user models.User) error { return r.db.Update(func(tx *bbolt.Tx) error { bucket := tx.Bucket(bnUserSessions)
ids, err := r.userIdIdx.WithTx(tx).Get(user.ID) if err != nil { return err }
for _, id := range ids { err := bucket.Delete(id) if err != nil { return err } }
return nil }) }
func (r *userSessionRepository) reindex() error { return r.db.Update(func(tx *bbolt.Tx) error { cursor := tx.Bucket(bnUserSessions).Cursor()
err := r.userIdIdx.Reset(tx) if err != nil { return err } userIdIdxTx := r.userIdIdx.WithTx(tx)
for key, value := cursor.First(); key != nil; key, value = cursor.Next() { session := new(models.UserSession) err := msgpack.Unmarshal(value, session) if err != nil { return err }
err = userIdIdxTx.Set(unsafeStringToBytes(session.ID), session.UserID) if err != nil { return err } }
return nil }) }
func newUserSessionRepository(db *bbolt.DB) (repositories.UserSessionRepository, error) { err := db.Update(func(tx *bbolt.Tx) error { _, err := tx.CreateBucketIfNotExists(bnUserSessions) return err }) if err != nil { return nil, err }
idx, err := newModelIndex(db, "UserSession", "UserID") if err != nil { return nil, err }
return &userSessionRepository{ db: db, userIdIdx: idx, }, nil }
|