Commit 29e426ed authored by Max Richter's avatar Max Richter
Browse files

feat: some small changes

parent acdb00aa
......@@ -31,7 +31,7 @@ func Init() {
r.Use(m.SentryHandler)
// Register all the Routers
h.RoomRouter.AttachRouter(r)
h.BuildingRouter.AttachRouter(r)
h.AppointmentRouter.AttachRouter(r)
h.HomeRouter.AttachRouter(r)
......
package restapi
import (
"encoding/json"
"fmt"
"log"
"net/http"
u "git.coco.study/fvitt/good2go/api/rest/utils"
"git.coco.study/fvitt/good2go/internal/model"
s "git.coco.study/fvitt/good2go/internal/services"
"github.com/gorilla/mux"
)
type buildingRouter struct{}
var (
// BuildingRouter Handles requests to /building
BuildingRouter = &buildingRouter{}
)
func createBuilding(res http.ResponseWriter, req *http.Request) {
var buildingDTO model.Building
err := json.NewDecoder(req.Body).Decode(&model.Building{})
if err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
building, err := s.BuildingService.CreateBuilding(&buildingDTO)
if err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
err = u.SendJSON(res).Encode(building)
if err != nil {
fmt.Println(err)
}
}
func getBuilding(res http.ResponseWriter, req *http.Request) {
buildingID := mux.Vars(req)["buildingID"]
building, buildingErr := s.BuildingService.GetBuilding(buildingID)
if buildingErr == nil {
u.SendJSON(res).Encode(building)
} else {
http.Error(res, buildingErr.Error(), http.StatusNotFound)
}
}
func getAllBuildings(res http.ResponseWriter, req *http.Request) {
buildings, err := s.BuildingService.GetAllBuildings()
if err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
err = u.SendJSON(res).Encode(buildings)
if err != nil {
fmt.Println(err)
}
}
func deleteBuilding(res http.ResponseWriter, req *http.Request) {
buildingID := mux.Vars(req)["buildingID"]
err := s.BuildingService.DeleteBuilding(buildingID)
if err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
log.Fatal(err)
}
res.WriteHeader(http.StatusOK)
}
// AttachRouter initialize Router
func (a buildingRouter) AttachRouter(router *mux.Router) {
r := router.PathPrefix("/buildings/").Subrouter()
// CREATE
r.HandleFunc("/", createBuilding).Methods("POST")
// // READ
r.HandleFunc("/{buildingID}", getBuilding).Methods("GET")
r.HandleFunc("/", getAllBuildings).Methods("GET")
// // DELETE
r.HandleFunc("/{buildingID}", deleteBuilding).Methods("DELETE")
}
......@@ -7,6 +7,7 @@ import (
"net/http"
u "git.coco.study/fvitt/good2go/api/rest/utils"
"git.coco.study/fvitt/good2go/internal/model"
s "git.coco.study/fvitt/good2go/internal/services"
"github.com/gorilla/mux"
)
......@@ -15,23 +16,23 @@ type roomRouter struct{}
var (
// RoomRouter Handles requests to /room
RoomRouter = &roomRouter{}
RoomRouter = &buildingRouter{}
)
type roomDTO struct {
Building int `json:"building"`
Number int `json:"number"`
Capacity int `json:"capacity"`
}
func createRoom(res http.ResponseWriter, req *http.Request) {
type roomDTO struct {
buildingID string
room model.Room
}
var r roomDTO
err := json.NewDecoder(req.Body).Decode(&roomDTO{})
if err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
room, err := s.BuildingService.AddRoom(r.Building, r.Number, r.Capacity)
room, err := s.BuildingService.CreateRoom(r.buildingID, &r.room)
err = u.SendJSON(res).Encode(room)
if err != nil {
......@@ -54,7 +55,7 @@ func getRoom(res http.ResponseWriter, req *http.Request) {
func getAllRooms(res http.ResponseWriter, req *http.Request) {
rooms := s.BuildingService.GetRooms()
rooms := s.BuildingService.GetAllRooms()
err := u.SendJSON(res).Encode(rooms)
if err != nil {
......@@ -66,14 +67,14 @@ func updateRoom(res http.ResponseWriter, req *http.Request) {
roomID := mux.Vars(req)["roomID"]
var r roomDTO
var r model.Room
parseBodyErr := json.NewDecoder(req.Body).Decode(&r)
if parseBodyErr != nil {
http.Error(res, parseBodyErr.Error(), http.StatusBadRequest)
return
}
room, err := s.BuildingService.UpdateRoomCapacity(roomID, r.Number, r.Capacity)
room, err := s.BuildingService.UpdateRoomCapacity(roomID, r.Capacity)
if err == nil {
err := u.SendJSON(res).Encode(room)
......
File added
......@@ -29,14 +29,22 @@ func main() {
// Create sample objects in memory for playing around
func initSampleData() {
//"08:00", "10h", []string{"mon", "tue", "wed", "thu", "fri", "sat"}
// Add Building
services.BuildingService.AddBuilding("08:00", "10h", []string{"mon", "tue", "wed", "thu", "fri", "sat"})
// Add Rooms
_, err := services.BuildingService.AddRoom(0, 310, 20)
building1 := &model.Building{}
building1.New("08:00", "10h", []string{"mon", "tue", "wed", "thu", "fri", "sat"})
building, _ := services.BuildingService.CreateBuilding(building1)
_, err := services.BuildingService.CreateRoom(building.ID.String(), &model.Room{
Number: 320,
Capacity: 10,
})
if err != nil {
log.Fatal(err)
}
//model.Building.AddRoom(520, 50)
//model.Building.CreateRoom(520, 50)
// Add sample Appointments
a1, _ := model.Appointment{}.New("27-11-2016 10:00", "2h")
......
......@@ -9,9 +9,9 @@ import (
)
var (
// RoomRepository does crud stuff
RoomRepo *repositories.Repository
BuildingRepo *repositories.Repository
RoomRepo *repositories.Repository
BuildingRepo *repositories.Repository
AppointmentRepo *repositories.Repository
)
// Init initializes connection to a database
......@@ -39,4 +39,8 @@ func Init() {
Col: db.Collection("buildings"),
}
AppointmentRepo = &repositories.Repository{
Col: db.Collection("appointments"),
}
}
package repositories
import (
"git.coco.study/fvitt/good2go/internal/model"
"go.mongodb.org/mongo-driver/mongo"
)
type AppointmentRepository interface {
CreateRoom(r *model.Appointment) (*model.Appointment, error)
UpdateRoom(r *model.Appointment)
GetRoom(document interface{}) (room *model.Appointment, err error)
GetAllRooms() []model.Room
ConnectTo(c *mongo.Collection) *Repository
}
// func (repo *Repository) findAppointmentByID(roomID string) (*model.Appointment, error) {
// }
package repositories
import (
"log"
"time"
"git.coco.study/fvitt/good2go/database/mongo/utils"
"git.coco.study/fvitt/good2go/internal/model"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
......@@ -16,14 +18,55 @@ type BuildingRepository interface {
UpdateBuilding(id interface{}, building *model.Building) (*mongo.UpdateResult, error)
}
func (repo *Repository) CreateBuilding(building *model.Building) (*mongo.InsertOneResult, error) {
func (repo *Repository) findBuildingByID(buildingID string) (*model.Building, error) {
ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
defer cancel()
id, err := primitive.ObjectIDFromHex(buildingID)
if err != nil {
return nil, err
}
res, err := repo.Col.Find(ctx, bson.M{"_id": id})
if err != nil {
return nil, err
}
building := model.Building{}
err = res.Decode(&building)
if err != nil {
return nil, err
}
return &building, err
}
func (repo *Repository) CreateBuilding(building *model.Building) (*model.Building, error) {
ctx, cancel := utils.CreateTimeoutCTX(time.Second * 10)
defer cancel()
res, err := repo.Col.InsertOne(ctx, &building)
// Create
insertedRes, err := repo.Col.InsertOne(ctx, &building)
if err != nil {
return nil, err
}
return res, nil
// Get
res, err := repo.Col.Find(ctx, bson.M{"_id": insertedRes.InsertedID})
if err != nil {
return nil, err
}
// Decode
result := model.Building{}
err = res.Decode(&result)
if err != nil {
return nil, err
}
return &result, nil
}
func (repo *Repository) UpdateBuilding(id interface{}, building *model.Building) (*mongo.UpdateResult, error) {
......@@ -36,8 +79,8 @@ func (repo *Repository) UpdateBuilding(id interface{}, building *model.Building)
return res, nil
}
func (repo *Repository) GetBuildingById(id interface{}) (*model.Building, error) {
return repo.GetBuilding(&bson.M{"_id": id})
func (repo *Repository) GetBuildingById(id string) (*model.Building, error) {
return repo.findBuildingByID(id)
}
func (repo *Repository) GetBuilding(filter *bson.M) (*model.Building, error) {
......@@ -52,3 +95,37 @@ func (repo *Repository) GetBuilding(filter *bson.M) (*model.Building, error) {
}
return &building, nil
}
func (repo *Repository) GetAllBuildings() ([]*model.Building, error) {
ctx, cancel := utils.CreateTimeoutCTX(time.Second * 10)
defer cancel()
res, err := repo.Col.Find(ctx, bson.M{})
if err != nil {
return nil, err
}
var buildings []*model.Building
if err = res.All(ctx, &buildings); err != nil {
log.Fatal(err)
}
return buildings, nil
}
func (repo *Repository) DeleteBuilding(buildingID string) error {
ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
defer cancel()
id, err := primitive.ObjectIDFromHex(buildingID)
if err != nil {
return err
}
_, err = repo.Col.DeleteOne(ctx, bson.M{"_id": id})
return err
}
......@@ -44,7 +44,12 @@ func (repo *Repository) findByRoomNumber(roomNumber int) (*model.Room, error) {
}
func (repo *Repository) findByID(id primitive.ObjectID) (*model.Room, error) {
func (repo *Repository) findByID(roomID string) (*model.Room, error) {
id, err := primitive.ObjectIDFromHex(roomID)
if err != nil {
return nil, err
}
ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
defer cancel()
......@@ -71,24 +76,54 @@ func (repo *Repository) insertOne(document interface{}) (*model.Room, error) {
defer cancel()
// Insert
result, err := repo.Col.InsertOne(ctx, document)
insertResult, err := repo.Col.InsertOne(ctx, document)
if err != nil {
return &model.Room{}, err
}
// Find
result, err := repo.Col.Find(ctx, bson.M{"_id": insertResult.InsertedID})
if err != nil {
return &model.Room{}, err
}
// Decode
var r model.Room
err = result.Decode(&r)
if err != nil {
return nil, err
}
// Return created entity
return repo.findByID(result.InsertedID.(primitive.ObjectID))
return &r, err
}
func (repo *Repository) updateOne(document interface{}) {
func (repo *Repository) updateOne(document interface{}) (*model.Room, error) {
ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
defer cancel()
_, err := repo.Col.UpdateOne(ctx, document, document)
insertedResult, err := repo.Col.UpdateOne(ctx, document, document)
if err != nil {
fmt.Println(err)
}
// Find
result, err := repo.Col.Find(ctx, bson.M{"_id": insertedResult.UpsertedID})
if err != nil {
return &model.Room{}, err
}
// Decode
var r model.Room
err = result.Decode(&r)
if err != nil {
return nil, err
}
// Return created entity
return &r, err
}
func (repo *Repository) findOne(document interface{}) (*model.Room, error) {
......@@ -112,6 +147,10 @@ func (repo *Repository) deleteByID(id primitive.ObjectID) error {
return err
}
func (repo *Repository) GetRoomByID(id string) (*model.Room, error) {
return repo.findByID(id)
}
func (repo *Repository) CreateRoom(r *model.Room) (*model.Room, error) {
log.Print("Create room ", r.Number)
......@@ -138,8 +177,8 @@ func (repo *Repository) CreateRoom(r *model.Room) (*model.Room, error) {
return room, err
}
func (repo *Repository) UpdateRoom(r *model.Room) {
repo.updateOne(r)
func (repo *Repository) UpdateRoom(r *model.Room) (*model.Room, error) {
return repo.updateOne(r)
}
func (repo *Repository) GetRoom(document interface{}) (room *model.Room, err error) {
......@@ -147,7 +186,11 @@ func (repo *Repository) GetRoom(document interface{}) (room *model.Room, err err
return repo.findOne(document)
}
func (repo *Repository) GetAllRooms() []model.Room {
func (repo *Repository) DeleteRoom(roomID string) (room *model.Room, err error) {
return repo.findByID(roomID)
}
func (repo *Repository) GetAllRooms() []*model.Room {
ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second)
defer cancel()
......@@ -157,7 +200,7 @@ func (repo *Repository) GetAllRooms() []model.Room {
log.Fatal("[MONGODB] roomRepository", err)
}
var rooms []model.Room
var rooms []*model.Room
if err = cursor.All(ctx, &rooms); err != nil {
log.Fatal(err)
}
......
......@@ -6,11 +6,12 @@ import (
"time"
"git.coco.study/fvitt/good2go/internal/utils"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// singleton for now
type Building struct {
Id int
ID primitive.ObjectID
OpeningHour time.Time
ClosingHour time.Time
Workdays []time.Weekday
......@@ -32,9 +33,9 @@ func (b *Building) New(openFrom string, openDuration string, workdays []string)
return b
}
// AddRoom adds rooms to building.
// CreateRoom adds rooms to building.
// takes number and capacity
func (b *Building) AddRoom(roomNumber int, capacity int) (room *Room, err error) {
func (b *Building) CreateRoom(roomNumber int, capacity int) (room *Room, err error) {
room, err = b.GetRoomByNo(roomNumber)
if err != nil {
......
......@@ -20,11 +20,11 @@ func TestBuilding_New(t *testing.T) {
}
}
func TestBuilding_AddRoom(t *testing.T) {
func TestBuilding_CreateRoom(t *testing.T) {
building1 := newBuilding()
const roomNumber int = 520
const capacity int = 35
building1.AddRoom(roomNumber, capacity)
building1.CreateRoom(roomNumber, capacity)
if len(building1.Rooms) != 1 {
t.Error("\n\nRooms slice still empty\nDid not add room to slide\nlen: ", len(building1.Rooms))
}
......@@ -41,7 +41,7 @@ func TestBuilding_AddRoom(t *testing.T) {
func TestBuilding_DeleteRoom(t *testing.T) {
building1 := newBuilding()
// Add one – remove one
building1.AddRoom(200, 50)
building1.CreateRoom(200, 50)
building1.DeleteRoom(200)
if len(building1.Rooms) > 0 {
......@@ -49,9 +49,9 @@ func TestBuilding_DeleteRoom(t *testing.T) {
}
// Add three – remove one
building1.AddRoom(200, 50)
building1.AddRoom(250, 40)
building1.AddRoom(260, 30)
building1.CreateRoom(200, 50)
building1.CreateRoom(250, 40)
building1.CreateRoom(260, 30)
building1.DeleteRoom(250)
for _, room := range building1.Rooms {
......@@ -63,8 +63,8 @@ func TestBuilding_DeleteRoom(t *testing.T) {
func TestBuilding_GetRooms(t *testing.T) {
building1 := newBuilding()
_, err := building1.AddRoom(200, 20)
_, err = building1.AddRoom(210, 40)
_, err := building1.CreateRoom(200, 20)
_, err = building1.CreateRoom(210, 40)
if err != nil {
t.Error(err)
}
......@@ -78,8 +78,8 @@ func TestBuilding_GetRooms(t *testing.T) {
func TestBuilding_GetRoomByNo(t *testing.T) {
building1 := newBuilding()
_, err := building1.AddRoom(200, 50)
_, err = building1.AddRoom(250, 40)
_, err := building1.CreateRoom(200, 50)
_, err = building1.CreateRoom(250, 40)
room, err := building1.GetRoomByNo(200)
if err != nil {
......@@ -98,7 +98,7 @@ func TestBuilding_GetRoomByNo(t *testing.T) {
func TestBuilding_UpdateRoomCapacity(t *testing.T) {
building1 := newBuilding()
_, err := building1.AddRoom(200, 20)
_, err := building1.CreateRoom(200, 20)
_, err = building1.UpdateRoomCapacity(200, 50)
if err != nil {
......@@ -111,7 +111,7 @@ func TestBuilding_UpdateRoomCapacity(t *testing.T) {
func TestBuilding_FindFreeRooms(t *testing.T) {
building1 := newBuilding()
_, err := building1.AddRoom(520, 35)
_, err := building1.CreateRoom(520, 35)
requestedAppoint, _ := Appointment{}.New("30-05-2020 10:00", "2h")
rooms, err := building1.FindAvailableRooms(requestedAppoint)
if err != nil {
......@@ -126,7 +126,7 @@ func TestBuilding_FindFreeRooms(t *testing.T) {
}
// should book the new room instead
_, err = building1.AddRoom(200, 40)
_, err = building1.CreateRoom(200, 40)
ap, _ := Appointment{}.New("29-05-2020 10:00", "2h")
building1.Rooms[1].Appointments = append(building1.Rooms[0].Appointments, ap)
......
package services
import (
"git.coco.study/fvitt/good2go/internal/model"
"log"
r "git.coco.study/fvitt/good2go/database/mongo"
"git.coco.study/fvitt/good2go/internal/model"
)
type appointmentService struct {
......@@ -26,8 +28,8 @@ func (a *appointmentService) AddAppointment(reqAppoint model.Appointment) (room
// DeleteAppointment deletes an appointment on higher level.
// Takes room number and start date, finds room and deletes appointment.