package repositories import ( "errors" "fmt" "log" "strconv" "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" ) type RoomRepository interface { CreateRoom(r *model.Room) (*model.Room, error) UpdateRoom(r *model.Room) GetRoom(document interface{}) (room *model.Room, err error) GetAllRooms() []model.Room ConnectTo(c *mongo.Collection) *Repository } func (repo *Repository) findByRoomNumber(roomNumber int) (*model.Room, error) { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() // Find result, err := repo.Col.Find(ctx, bson.M{"number": roomNumber}) if err != nil { return &model.Room{}, err } // Decode var r model.Room err = result.Decode(&r) if err != nil { return &model.Room{}, err } return &r, nil } func (repo *Repository) findByID(id primitive.ObjectID) (*model.Room, error) { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() // Find result, err := repo.Col.Find(ctx, bson.M{"_id": id}) if err != nil { return &model.Room{}, err } // Decode var r model.Room err = result.Decode(&r) if err != nil { return &model.Room{}, err } return &r, nil } func (repo *Repository) insertOne(document interface{}) (*model.Room, error) { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() // Insert result, err := repo.Col.InsertOne(ctx, document) if err != nil { return &model.Room{}, err } // Return created entity return repo.findByID(result.InsertedID.(primitive.ObjectID)) } func (repo *Repository) updateOne(document interface{}) { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() _, err := repo.Col.UpdateOne(ctx, document, document) if err != nil { fmt.Println(err) } } func (repo *Repository) findOne(document interface{}) (*model.Room, error) { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() result := repo.Col.FindOne(ctx, document) var room model.Room err := result.Decode(&room) return &room, err } func (repo *Repository) deleteByID(id primitive.ObjectID) error { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() _, err := repo.Col.DeleteOne(ctx, bson.M{"_id": id}) return err } func (repo *Repository) CreateRoom(r *model.Room) (*model.Room, error) { log.Print("Create room ", r.Number) //Check if room with same room number exists existingRoom, err := repo.GetRoom(bson.M{"number": r.Number}) if err == nil { t := strconv.Itoa(r.Number) return existingRoom, errors.New("Room with number " + t + " already exists") } room, err := repo.insertOne(bson.M{ "number": r.Number, "capacity": r.Capacity, }) if err != nil { log.Fatal(err) return &model.Room{}, err } log.Print("created new room", room.Number) return room, err } func (repo *Repository) UpdateRoom(r *model.Room) { repo.updateOne(r) } func (repo *Repository) GetRoom(document interface{}) (room *model.Room, err error) { log.Print("Finding room by ", document) return repo.findOne(document) } func (repo *Repository) GetAllRooms() []model.Room { ctx, cancel := utils.CreateTimeoutCTX(5 * time.Second) defer cancel() cursor, err := repo.Col.Find(ctx, bson.M{}) if err != nil { log.Fatal("[MONGODB] roomRepository", err) } var rooms []model.Room if err = cursor.All(ctx, &rooms); err != nil { log.Fatal(err) } return rooms }