feat: now simple users can only occupy one seat at a time
This commit is contained in:
+38
-16
@@ -6,6 +6,9 @@ package db
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"git.phc.dm.unipi.it/aziis98/posti-dm/server/util"
|
||||
)
|
||||
|
||||
// ErrAlreadyExists is the error thrown from Store functions when an entity already exists.
|
||||
@@ -14,6 +17,11 @@ var ErrAlreadyExists = errors.New(`object already exists in database`)
|
||||
// ErrDoesntExist is the error thrown from Store functions when an entity doesn't exist.
|
||||
var ErrDoesntExist = errors.New(`object doesn't exist in database`)
|
||||
|
||||
const (
|
||||
PermissionAdmin = "admin"
|
||||
PermissionModerator = "moderator"
|
||||
)
|
||||
|
||||
// Entities
|
||||
|
||||
// type FrontendUser struct {
|
||||
@@ -24,23 +32,12 @@ var ErrDoesntExist = errors.New(`object doesn't exist in database`)
|
||||
|
||||
// User represents a user in the database.
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Permissions []string `json:"permissions"`
|
||||
ID string `json:"id"`
|
||||
Permissions util.StringSet `json:"permissions"`
|
||||
|
||||
// passwordSaltHash string
|
||||
}
|
||||
|
||||
// HasPermission checks if the user has a specific permission.
|
||||
func (user User) HasPermission(neededPerm string) bool {
|
||||
for _, perm := range user.Permissions {
|
||||
if perm == neededPerm {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Room represents a room in the database, a room has an id, a name and a collection of seatIDs of this room.
|
||||
type Room struct {
|
||||
ID string `json:"id"`
|
||||
@@ -49,6 +46,26 @@ type Room struct {
|
||||
// gridRows, gridCols int
|
||||
}
|
||||
|
||||
// Version 1:
|
||||
//
|
||||
// type SeatState struct {
|
||||
// Occupied bool
|
||||
// Anonymous bool
|
||||
// UserID string
|
||||
// }
|
||||
|
||||
// Version 2:
|
||||
//
|
||||
// type SeatState interface{ isSeatState() }
|
||||
//
|
||||
// type SeatNotOccupied struct{}
|
||||
// type SeatOccupiedByUser struct{ UserID string }
|
||||
// type SeatOccupiedByAnonymous struct{}
|
||||
//
|
||||
// func (s SeatNotOccupied) isSeatState()
|
||||
// func (s SeatOccupiedByUser) isSeatState()
|
||||
// func (s SeatOccupiedByAnonymous) isSeatState()
|
||||
|
||||
// Seat represents a seat in the database, it belongs to a single room and can be free or occupied by some user (referenced by userID).
|
||||
type Seat struct {
|
||||
ID string `json:"id"`
|
||||
@@ -81,6 +98,9 @@ type Seat struct {
|
||||
|
||||
// Store is the main interface for interacting with database implementations, for now the only implementation is "memDB".
|
||||
type Store interface {
|
||||
BeginTransaction()
|
||||
EndTransaction()
|
||||
|
||||
CreateUser(user *User) error
|
||||
CreateRoom(room *Room) error
|
||||
CreateSeat(seat *Seat) error
|
||||
@@ -98,7 +118,7 @@ type Store interface {
|
||||
GetRoomOccupiedSeats(roomID string) ([]string, error)
|
||||
GetRoomFreeSeats(roomID string) ([]string, error)
|
||||
|
||||
GetUserSeat(userID string) ([]string, error)
|
||||
GetUserSeats(userID string) (util.StringSet, error)
|
||||
|
||||
OccupySeat(seatID, userID string) error
|
||||
FreeSeat(seatID string) error
|
||||
@@ -109,6 +129,8 @@ type Store interface {
|
||||
// NewInMemoryStore creates an instance of memDB hidden behind the Store interface.
|
||||
func NewInMemoryStore() Store {
|
||||
db := &memDB{
|
||||
&sync.Mutex{},
|
||||
|
||||
make(map[string]*User),
|
||||
make(map[string]*Room),
|
||||
make(map[string]*Seat),
|
||||
@@ -135,12 +157,12 @@ func NewInMemoryStore() Store {
|
||||
|
||||
db.users["aziis98"] = &User{
|
||||
ID: "aziis98",
|
||||
Permissions: []string{"admin"},
|
||||
Permissions: util.NewStringSet(PermissionAdmin),
|
||||
}
|
||||
|
||||
db.users["bachoseven"] = &User{
|
||||
ID: "bachoseven",
|
||||
Permissions: []string{"admin"},
|
||||
Permissions: util.NewStringSet(PermissionAdmin),
|
||||
}
|
||||
|
||||
return db
|
||||
|
||||
+18
-6
@@ -1,17 +1,29 @@
|
||||
package db
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"git.phc.dm.unipi.it/aziis98/posti-dm/server/util"
|
||||
)
|
||||
|
||||
// memDB is the first Store implementation used for testing.
|
||||
type memDB struct {
|
||||
// FIXME: Giusto per la cronaca fare le modifiche in questo modo alle mappe non è per niente thread safe, servirebbe come minimo usare un mutex per quando si scrive su una di queste variabili
|
||||
// mutex *sync.Mutex
|
||||
mutex *sync.Mutex
|
||||
|
||||
users map[string]*User
|
||||
rooms map[string]*Room
|
||||
seats map[string]*Seat
|
||||
}
|
||||
|
||||
func (db *memDB) BeginTransaction() {
|
||||
db.mutex.Lock()
|
||||
}
|
||||
|
||||
func (db *memDB) EndTransaction() {
|
||||
db.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (db *memDB) CreateUser(user *User) error {
|
||||
if _, present := db.users[user.ID]; present {
|
||||
return ErrAlreadyExists
|
||||
@@ -134,14 +146,14 @@ func (db *memDB) GetRoomFreeSeats(roomID string) ([]string, error) {
|
||||
return seats, nil
|
||||
}
|
||||
|
||||
func (db *memDB) GetUserSeat(userID string) ([]string, error) {
|
||||
func (db *memDB) GetUserSeats(userID string) (util.StringSet, error) {
|
||||
for _, seat := range db.seats {
|
||||
if len(seat.OccupiedBy) > 0 && seat.OccupiedBy[0] == userID {
|
||||
return []string{userID}, nil
|
||||
return util.NewStringSet(seat.ID), nil
|
||||
}
|
||||
}
|
||||
|
||||
return []string{}, nil
|
||||
return util.NewStringSet(), nil
|
||||
}
|
||||
|
||||
func (db *memDB) OccupySeat(seatID, userID string) error {
|
||||
|
||||
Reference in New Issue
Block a user