package repository import ( "codeword/internal/models" "context" "errors" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "time" ) var ErrDuplicateCodeword = errors.New("duplicate codeword") type PromoCodeRepository struct { mdb *mongo.Collection } func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository { indexModel := mongo.IndexModel{ Keys: bson.D{ {"codeword", 1}, {"delete", 1}, }, Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"delete": false}), } _, err := mdb.Indexes().CreateOne(context.Background(), indexModel) if err != nil { panic(err) } return &PromoCodeRepository{mdb: mdb} } func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) { promoCode.CreatedAt = time.Now() promoCode.ID = primitive.NewObjectID() _, err := r.mdb.InsertOne(ctx, promoCode) if err != nil { if writeErr, ok := err.(mongo.WriteException); ok { for _, writeError := range writeErr.WriteErrors { if writeError.Code == 11000 { return nil, ErrDuplicateCodeword } } } return nil, err } return promoCode, nil }