Просмотр исходного кода

add support for mysql and postgres unique index error codes

bergquist 7 лет назад
Родитель
Сommit
c5278af6c4

+ 7 - 3
pkg/models/alert_notifications.go

@@ -11,7 +11,7 @@ var (
 	ErrNotificationFrequencyNotFound         = errors.New("Notification frequency not specified")
 	ErrAlertNotificationStateNotFound        = errors.New("alert notification state not found")
 	ErrAlertNotificationStateVersionConflict = errors.New("alert notification state update version conflict")
-	ErrAlertNotificationStateAllreadyExist   = errors.New("alert notification state allready exists.")
+	ErrAlertNotificationStateAlreadyExist    = errors.New("alert notification state already exists.")
 )
 
 type AlertNotificationStateType string
@@ -95,13 +95,17 @@ type AlertNotificationState struct {
 	Version    int64
 }
 
-type UpdateAlertNotificationStateCommand struct {
+type SetAlertNotificationStateToPendingCommand struct {
 	Id      int64
 	SentAt  int64
-	State   AlertNotificationStateType
 	Version int64
 }
 
+type SetAlertNotificationStateToCompleteCommand struct {
+	Id     int64
+	SentAt int64
+}
+
 type GetNotificationStateQuery struct {
 	OrgId      int64
 	AlertId    int64

+ 2 - 0
pkg/services/alerting/notifier.go

@@ -64,6 +64,8 @@ func (n *notificationService) sendNotifications(evalContext *EvalContext, notifi
 		err := bus.InTransaction(evalContext.Ctx, func(ctx context.Context) error {
 			n.log.Debug("trying to send notification", "id", not.GetNotifierId())
 
+			// insert if needed
+
 			// Verify that we can send the notification again
 			// but this time within the same transaction.
 			// if !evalContext.IsTestRun && !not.ShouldNotify(ctx, evalContext) {

+ 37 - 6
pkg/services/sqlstore/alert_notification.go

@@ -20,6 +20,8 @@ func init() {
 	bus.AddHandler("sql", GetAllAlertNotifications)
 	bus.AddHandlerCtx("sql", InsertAlertNotificationState)
 	bus.AddHandlerCtx("sql", GetAlertNotificationState)
+	bus.AddHandlerCtx("sql", SetAlertNotificationStateToCompleteCommand)
+	bus.AddHandlerCtx("sql", SetAlertNotificationStateToPendingCommand)
 }
 
 func DeleteAlertNotification(cmd *m.DeleteAlertNotificationCommand) error {
@@ -244,25 +246,54 @@ func InsertAlertNotificationState(ctx context.Context, cmd *m.InsertAlertNotific
 			return nil
 		}
 
-		if strings.HasPrefix(err.Error(), "UNIQUE constraint failed") {
-			return m.ErrAlertNotificationStateAllreadyExist
+		uniqenessIndexFailureCodes := []string{
+			"UNIQUE constraint failed",
+			"pq: duplicate key value violates unique constraint",
+			"Error 1062: Duplicate entry ",
+		}
+
+		for _, code := range uniqenessIndexFailureCodes {
+			if strings.HasPrefix(err.Error(), code) {
+				return m.ErrAlertNotificationStateAlreadyExist
+			}
 		}
 
 		return err
 	})
 }
 
-func UpdateAlertNotificationState(ctx context.Context, cmd *m.UpdateAlertNotificationStateCommand) error {
+func SetAlertNotificationStateToCompleteCommand(ctx context.Context, cmd *m.SetAlertNotificationStateToCompleteCommand) error {
+	return withDbSession(ctx, func(sess *DBSession) error {
+		sql := `UPDATE alert_notification_state SET 
+			state= ?
+		WHERE
+			id = ?`
+
+		res, err := sess.Exec(sql, m.AlertNotificationStateCompleted, cmd.Id)
+		if err != nil {
+			return err
+		}
+
+		affected, _ := res.RowsAffected()
+
+		if affected == 0 {
+			return m.ErrAlertNotificationStateVersionConflict
+		}
+
+		return nil
+	})
+}
+
+func SetAlertNotificationStateToPendingCommand(ctx context.Context, cmd *m.SetAlertNotificationStateToPendingCommand) error {
 	return withDbSession(ctx, func(sess *DBSession) error {
 		sql := `UPDATE alert_notification_state SET 
 			state= ?,  
 			version = ?
 		WHERE
 			id = ? AND
-			version = ?
-		`
+			version = ?`
 
-		res, err := sess.Exec(sql, cmd.State, cmd.Version+1, cmd.Id, cmd.Version)
+		res, err := sess.Exec(sql, m.AlertNotificationStatePending, cmd.Version+1, cmd.Id, cmd.Version)
 		if err != nil {
 			return err
 		}

+ 11 - 6
pkg/services/sqlstore/alert_notification_test.go

@@ -38,23 +38,28 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 				So(err, ShouldBeNil)
 
 				err = InsertAlertNotificationState(context.Background(), createCmd)
-				So(err, ShouldEqual, models.ErrAlertNotificationStateAllreadyExist)
+				So(err, ShouldEqual, models.ErrAlertNotificationStateAlreadyExist)
 
 				Convey("should be able to update alert notifier state", func() {
-					updateCmd := &models.UpdateAlertNotificationStateCommand{
+					updateCmd := &models.SetAlertNotificationStateToPendingCommand{
 						Id:      1,
 						SentAt:  1,
-						State:   models.AlertNotificationStatePending,
 						Version: 0,
 					}
 
-					err := UpdateAlertNotificationState(context.Background(), updateCmd)
+					err := SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
 					So(err, ShouldBeNil)
 
-					Convey("should not be able to update older versions", func() {
-						err = UpdateAlertNotificationState(context.Background(), updateCmd)
+					Convey("should not be able to set pending on old version", func() {
+						err = SetAlertNotificationStateToPendingCommand(context.Background(), updateCmd)
 						So(err, ShouldEqual, models.ErrAlertNotificationStateVersionConflict)
 					})
+
+					Convey("should be able to set state to completed", func() {
+						cmd := &models.SetAlertNotificationStateToCompleteCommand{Id: 1}
+						err = SetAlertNotificationStateToCompleteCommand(context.Background(), cmd)
+						So(err, ShouldBeNil)
+					})
 				})
 			})
 		})