2016-06-13 22:39:00 +08:00
package sqlstore
import (
"bytes"
2018-06-15 21:30:17 +08:00
"context"
2016-06-14 14:33:50 +08:00
"fmt"
2016-07-26 18:29:52 +08:00
"strings"
2016-06-14 14:33:50 +08:00
"time"
2016-06-13 22:39:00 +08:00
"github.com/grafana/grafana/pkg/bus"
m "github.com/grafana/grafana/pkg/models"
)
func init ( ) {
2016-08-01 20:34:58 +08:00
bus . AddHandler ( "sql" , GetAlertNotifications )
2016-06-14 14:33:50 +08:00
bus . AddHandler ( "sql" , CreateAlertNotificationCommand )
bus . AddHandler ( "sql" , UpdateAlertNotification )
2016-06-16 21:21:44 +08:00
bus . AddHandler ( "sql" , DeleteAlertNotification )
2016-09-06 14:42:35 +08:00
bus . AddHandler ( "sql" , GetAlertNotificationsToSend )
bus . AddHandler ( "sql" , GetAllAlertNotifications )
2018-06-15 21:30:17 +08:00
bus . AddHandlerCtx ( "sql" , RecordNotificationJournal )
bus . AddHandlerCtx ( "sql" , GetLatestNotification )
bus . AddHandlerCtx ( "sql" , CleanNotificationJournal )
2016-06-16 21:21:44 +08:00
}
func DeleteAlertNotification ( cmd * m . DeleteAlertNotificationCommand ) error {
2017-05-23 16:56:23 +08:00
return inTransaction ( func ( sess * DBSession ) error {
2016-06-16 21:21:44 +08:00
sql := "DELETE FROM alert_notification WHERE alert_notification.org_id = ? AND alert_notification.id = ?"
_ , err := sess . Exec ( sql , cmd . OrgId , cmd . Id )
2018-04-17 01:54:23 +08:00
return err
2016-06-16 21:21:44 +08:00
} )
2016-06-13 22:39:00 +08:00
}
2016-08-01 20:34:58 +08:00
func GetAlertNotifications ( query * m . GetAlertNotificationsQuery ) error {
2017-05-23 16:56:23 +08:00
return getAlertNotificationInternal ( query , newSession ( ) )
2016-06-14 14:33:50 +08:00
}
2016-09-06 14:42:35 +08:00
func GetAllAlertNotifications ( query * m . GetAllAlertNotificationsQuery ) error {
results := make ( [ ] * m . AlertNotification , 0 )
if err := x . Where ( "org_id = ?" , query . OrgId ) . Find ( & results ) ; err != nil {
return err
}
query . Result = results
return nil
}
func GetAlertNotificationsToSend ( query * m . GetAlertNotificationsToSendQuery ) error {
var sql bytes . Buffer
params := make ( [ ] interface { } , 0 )
sql . WriteString ( ` SELECT
alert_notification . id ,
alert_notification . org_id ,
alert_notification . name ,
alert_notification . type ,
alert_notification . created ,
alert_notification . updated ,
alert_notification . settings ,
2018-05-21 00:12:10 +08:00
alert_notification . is_default ,
2018-06-05 16:27:29 +08:00
alert_notification . send_reminder ,
2018-05-21 00:12:10 +08:00
alert_notification . frequency
2016-09-06 14:42:35 +08:00
FROM alert_notification
` )
sql . WriteString ( ` WHERE alert_notification.org_id = ? ` )
params = append ( params , query . OrgId )
2016-09-23 14:07:14 +08:00
sql . WriteString ( ` AND ((alert_notification.is_default = ?) ` )
params = append ( params , dialect . BooleanStr ( true ) )
2016-09-06 14:42:35 +08:00
if len ( query . Ids ) > 0 {
sql . WriteString ( ` OR alert_notification.id IN (? ` + strings . Repeat ( ",?" , len ( query . Ids ) - 1 ) + ")" )
for _ , v := range query . Ids {
params = append ( params , v )
}
}
sql . WriteString ( ` ) ` )
results := make ( [ ] * m . AlertNotification , 0 )
2018-01-24 05:30:45 +08:00
if err := x . SQL ( sql . String ( ) , params ... ) . Find ( & results ) ; err != nil {
2016-09-06 14:42:35 +08:00
return err
}
query . Result = results
return nil
}
2017-05-23 16:56:23 +08:00
func getAlertNotificationInternal ( query * m . GetAlertNotificationsQuery , sess * DBSession ) error {
2016-06-13 22:39:00 +08:00
var sql bytes . Buffer
params := make ( [ ] interface { } , 0 )
sql . WriteString ( ` SELECT
2016-09-06 03:33:05 +08:00
alert_notification . id ,
alert_notification . org_id ,
alert_notification . name ,
alert_notification . type ,
alert_notification . created ,
alert_notification . updated ,
alert_notification . settings ,
2018-05-21 00:12:10 +08:00
alert_notification . is_default ,
2018-06-05 16:27:29 +08:00
alert_notification . send_reminder ,
2018-05-21 00:12:10 +08:00
alert_notification . frequency
2016-09-06 03:33:05 +08:00
FROM alert_notification
` )
2016-06-13 22:39:00 +08:00
sql . WriteString ( ` WHERE alert_notification.org_id = ? ` )
2016-07-22 22:45:17 +08:00
params = append ( params , query . OrgId )
2016-06-13 22:39:00 +08:00
2016-09-06 14:42:35 +08:00
if query . Name != "" || query . Id != 0 {
2016-09-06 03:33:05 +08:00
if query . Name != "" {
sql . WriteString ( ` AND alert_notification.name = ? ` )
params = append ( params , query . Name )
}
2016-06-13 22:39:00 +08:00
2016-09-06 03:33:05 +08:00
if query . Id != 0 {
sql . WriteString ( ` AND alert_notification.id = ? ` )
params = append ( params , query . Id )
}
2016-06-14 22:56:14 +08:00
}
2016-07-22 22:45:17 +08:00
results := make ( [ ] * m . AlertNotification , 0 )
2018-09-16 18:26:05 +08:00
if err := sess . SQL ( sql . String ( ) , params ... ) . Find ( & results ) ; err != nil {
2016-06-13 22:39:00 +08:00
return err
}
2016-09-06 14:42:35 +08:00
if len ( results ) == 0 {
query . Result = nil
} else {
query . Result = results [ 0 ]
}
2016-06-13 22:39:00 +08:00
return nil
}
2016-06-14 14:33:50 +08:00
func CreateAlertNotificationCommand ( cmd * m . CreateAlertNotificationCommand ) error {
2017-05-23 16:56:23 +08:00
return inTransaction ( func ( sess * DBSession ) error {
2016-07-22 22:45:17 +08:00
existingQuery := & m . GetAlertNotificationsQuery { OrgId : cmd . OrgId , Name : cmd . Name }
2016-09-06 14:42:35 +08:00
err := getAlertNotificationInternal ( existingQuery , sess )
2016-06-14 14:33:50 +08:00
if err != nil {
return err
}
2016-09-06 14:42:35 +08:00
if existingQuery . Result != nil {
2016-06-14 14:33:50 +08:00
return fmt . Errorf ( "Alert notification name %s already exists" , cmd . Name )
}
2016-06-13 22:39:00 +08:00
2018-05-26 02:14:33 +08:00
var frequency time . Duration
2018-06-05 16:27:29 +08:00
if cmd . SendReminder {
2018-06-05 04:19:27 +08:00
if cmd . Frequency == "" {
return m . ErrNotificationFrequencyNotFound
}
frequency , err = time . ParseDuration ( cmd . Frequency )
if err != nil {
return err
}
2018-05-21 00:12:10 +08:00
}
2016-06-14 14:33:50 +08:00
alertNotification := & m . AlertNotification {
2018-06-05 16:27:29 +08:00
OrgId : cmd . OrgId ,
Name : cmd . Name ,
Type : cmd . Type ,
Settings : cmd . Settings ,
SendReminder : cmd . SendReminder ,
Frequency : frequency ,
Created : time . Now ( ) ,
Updated : time . Now ( ) ,
IsDefault : cmd . IsDefault ,
2016-06-14 14:33:50 +08:00
}
2016-06-13 22:39:00 +08:00
2018-06-05 16:27:29 +08:00
if _ , err = sess . MustCols ( "send_reminder" ) . Insert ( alertNotification ) ; err != nil {
2016-06-14 14:33:50 +08:00
return err
}
cmd . Result = alertNotification
return nil
2016-06-13 22:39:00 +08:00
} )
}
func UpdateAlertNotification ( cmd * m . UpdateAlertNotificationCommand ) error {
2017-05-23 16:56:23 +08:00
return inTransaction ( func ( sess * DBSession ) ( err error ) {
2016-07-22 22:45:17 +08:00
current := m . AlertNotification { }
2016-06-13 22:39:00 +08:00
2018-01-24 05:30:45 +08:00
if _ , err = sess . ID ( cmd . Id ) . Get ( & current ) ; err != nil {
2016-06-14 14:33:50 +08:00
return err
}
2016-07-22 22:45:17 +08:00
// check if name exists
sameNameQuery := & m . GetAlertNotificationsQuery { OrgId : cmd . OrgId , Name : cmd . Name }
2016-09-06 14:42:35 +08:00
if err := getAlertNotificationInternal ( sameNameQuery , sess ) ; err != nil {
2016-07-22 22:45:17 +08:00
return err
2016-06-20 22:19:15 +08:00
}
2016-09-06 14:42:35 +08:00
if sameNameQuery . Result != nil && sameNameQuery . Result . Id != current . Id {
2016-07-22 22:45:17 +08:00
return fmt . Errorf ( "Alert notification name %s already exists" , cmd . Name )
}
2016-06-14 14:33:50 +08:00
2016-07-22 22:45:17 +08:00
current . Updated = time . Now ( )
current . Settings = cmd . Settings
current . Name = cmd . Name
current . Type = cmd . Type
2016-09-06 03:33:05 +08:00
current . IsDefault = cmd . IsDefault
2018-06-05 16:27:29 +08:00
current . SendReminder = cmd . SendReminder
2018-05-21 00:12:10 +08:00
2018-06-05 16:27:29 +08:00
if current . SendReminder {
2018-06-05 04:19:27 +08:00
if cmd . Frequency == "" {
return m . ErrNotificationFrequencyNotFound
}
2018-05-21 04:08:42 +08:00
2018-06-05 04:19:27 +08:00
frequency , err := time . ParseDuration ( cmd . Frequency )
if err != nil {
return err
}
current . Frequency = frequency
2018-05-21 00:12:10 +08:00
}
2016-09-06 03:33:05 +08:00
2018-06-05 16:27:29 +08:00
sess . UseBool ( "is_default" , "send_reminder" )
2016-06-14 14:33:50 +08:00
2018-01-24 05:30:45 +08:00
if affected , err := sess . ID ( cmd . Id ) . Update ( current ) ; err != nil {
2016-06-14 14:33:50 +08:00
return err
2016-07-22 22:45:17 +08:00
} else if affected == 0 {
2018-06-05 04:19:27 +08:00
return fmt . Errorf ( "Could not update alert notification" )
2016-06-14 22:56:14 +08:00
}
2016-07-22 22:45:17 +08:00
cmd . Result = & current
2016-06-14 14:33:50 +08:00
return nil
} )
}
2018-05-20 04:21:00 +08:00
2018-06-15 21:30:17 +08:00
func RecordNotificationJournal ( ctx context . Context , cmd * m . RecordNotificationJournalCommand ) error {
return inTransactionCtx ( ctx , func ( sess * DBSession ) error {
2018-06-05 20:29:48 +08:00
journalEntry := & m . AlertNotificationJournal {
2018-05-20 04:21:00 +08:00
OrgId : cmd . OrgId ,
AlertId : cmd . AlertId ,
NotifierId : cmd . NotifierId ,
SentAt : cmd . SentAt ,
Success : cmd . Success ,
}
2018-09-19 05:18:39 +08:00
_ , err := sess . Insert ( journalEntry )
return err
2018-05-20 04:21:00 +08:00
} )
}
2018-06-15 21:30:17 +08:00
func GetLatestNotification ( ctx context . Context , cmd * m . GetLatestNotificationQuery ) error {
return inTransactionCtx ( ctx , func ( sess * DBSession ) error {
2018-06-16 17:27:04 +08:00
nj := & m . AlertNotificationJournal { }
2018-06-29 21:15:31 +08:00
2018-06-16 17:27:04 +08:00
_ , err := sess . Desc ( "alert_notification_journal.sent_at" ) .
Limit ( 1 ) .
Where ( "alert_notification_journal.org_id = ? AND alert_notification_journal.alert_id = ? AND alert_notification_journal.notifier_id = ?" , cmd . OrgId , cmd . AlertId , cmd . NotifierId ) . Get ( nj )
2018-05-20 04:21:00 +08:00
if err != nil {
return err
}
2018-06-16 17:27:04 +08:00
if nj . AlertId == 0 && nj . Id == 0 && nj . NotifierId == 0 && nj . OrgId == 0 {
return m . ErrJournalingNotFound
}
cmd . Result = nj
2018-05-20 04:21:00 +08:00
return nil
} )
}
2018-06-15 21:30:17 +08:00
func CleanNotificationJournal ( ctx context . Context , cmd * m . CleanNotificationJournalCommand ) error {
return inTransactionCtx ( ctx , func ( sess * DBSession ) error {
2018-06-15 22:27:20 +08:00
sql := "DELETE FROM alert_notification_journal WHERE alert_notification_journal.org_id = ? AND alert_notification_journal.alert_id = ? AND alert_notification_journal.notifier_id = ?"
2018-05-20 04:21:00 +08:00
_ , err := sess . Exec ( sql , cmd . OrgId , cmd . AlertId , cmd . NotifierId )
return err
} )
}