package db import ( "errors" "fmt" ) var ErrAlreadyExists = errors.New(`object already exists in database`) var ErrDoesntExist = errors.New(`object doesn't exist in database`) // Entities type User struct { ID string `json:"id"` Permissions []string `json:"permissions"` } type Room struct { ID string `json:"id"` SeatIDs []string `json:"seatIds"` // gridRows, gridCols int } type Seat struct { ID string `json:"id"` RoomID string `json:"roomId"` // OccupiedBy is an empty list or a singleton of a userID OccupiedBy []string `json:"occupiedBy"` // x, y, w, h int } // Database Interfaces type Store interface { CreateUser(user *User) error CreateRoom(room *Room) error CreateSeat(seat *Seat) error DeleteUser(user *User) error DeleteRoom(room *Room) error DeleteSeat(seat *Seat) error GetUser(userID string) (*User, error) GetRoom(roomID string) (*Room, error) GetSeat(seatID string) (*Seat, error) GetRooms() ([]string, error) GetRoomOccupiedSeats(roomID string) ([]string, error) GetRoomFreeSeats(roomID string) ([]string, error) GetUserSeat(userID string) ([]string, error) OccupySeat(seatID, userID string) error FreeSeat(seatID string) error } // TODO: Create an SQLite implementation type memDB struct { users map[string]*User rooms map[string]*Room seats map[string]*Seat } func NewInMemoryStore() Store { db := &memDB{ make(map[string]*User), make(map[string]*Room), make(map[string]*Seat), } db.rooms["aula-stud"] = &Room{ ID: "aula-stud", SeatIDs: []string{}, } for i := 1; i <= 11; i++ { seatID := fmt.Sprintf(`aula-stud/posto-%d`, i) db.rooms["aula-stud"].SeatIDs = append(db.rooms["aula-stud"].SeatIDs, seatID) db.seats[seatID] = &Seat{ ID: seatID, RoomID: "aula-stud", OccupiedBy: []string{}, } } db.seats["aula-stud/posto-7"].OccupiedBy = []string{"aziis98"} db.seats["aula-stud/posto-8"].OccupiedBy = []string{"jack"} db.users["aziis98"] = &User{ ID: "aziis98", Permissions: []string{"admin"}, } db.users["bachoseven"] = &User{ ID: "bachoseven", Permissions: []string{"admin"}, } return db } func (db *memDB) CreateUser(user *User) error { if _, present := db.users[user.ID]; present { return ErrAlreadyExists } db.users[user.ID] = user return nil } func (db *memDB) CreateRoom(room *Room) error { if _, present := db.rooms[room.ID]; present { return ErrAlreadyExists } db.rooms[room.ID] = room return nil } func (db *memDB) CreateSeat(seat *Seat) error { if _, present := db.seats[seat.ID]; present { return ErrAlreadyExists } db.seats[seat.ID] = seat return nil } func (db *memDB) DeleteUser(user *User) error { if _, present := db.users[user.ID]; !present { return ErrDoesntExist } delete(db.users, user.ID) return nil } func (db *memDB) DeleteRoom(room *Room) error { if _, present := db.rooms[room.ID]; !present { return ErrDoesntExist } delete(db.rooms, room.ID) return nil } func (db *memDB) DeleteSeat(seat *Seat) error { if _, present := db.seats[seat.ID]; !present { return ErrDoesntExist } delete(db.seats, seat.ID) return nil } func (db *memDB) GetUser(userID string) (*User, error) { user, present := db.users[userID] if !present { return nil, fmt.Errorf(`no such user "%s"`, userID) } return user, nil } func (db *memDB) GetRoom(roomID string) (*Room, error) { room, present := db.rooms[roomID] if !present { return nil, fmt.Errorf(`no such room "%s"`, roomID) } return room, nil } func (db *memDB) GetSeat(seatID string) (*Seat, error) { seat, present := db.seats[seatID] if !present { return nil, fmt.Errorf(`no such seat "%s"`, seatID) } return seat, nil } func (db *memDB) GetRooms() ([]string, error) { roomIDs := []string{} for roomID := range db.rooms { roomIDs = append(roomIDs, roomID) } return roomIDs, nil } func (db *memDB) GetRoomOccupiedSeats(roomID string) ([]string, error) { room, err := db.GetRoom(roomID) if err != nil { return nil, err } seats := []string{} for _, seatID := range room.SeatIDs { seat := db.seats[seatID] if len(seat.OccupiedBy) == 1 { seats = append(seats, seatID) } } return seats, nil } func (db *memDB) GetRoomFreeSeats(roomID string) ([]string, error) { room, err := db.GetRoom(roomID) if err != nil { return nil, err } seats := []string{} for _, seatID := range room.SeatIDs { seat := db.seats[seatID] if len(seat.OccupiedBy) == 0 { seats = append(seats, seatID) } } return seats, nil } func (db *memDB) GetUserSeat(userID string) ([]string, error) { for _, seat := range db.seats { if len(seat.OccupiedBy) > 0 && seat.OccupiedBy[0] == userID { return []string{userID}, nil } } return []string{}, nil } func (db *memDB) OccupySeat(seatID, userID string) error { db.seats[seatID].OccupiedBy = []string{userID} return nil } func (db *memDB) FreeSeat(seatID string) error { db.seats[seatID].OccupiedBy = []string{} return nil }