github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/service/annotation.go (about) 1 package service 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/pyroscope-io/pyroscope/pkg/model" 8 "gorm.io/gorm" 9 "gorm.io/gorm/clause" 10 ) 11 12 type AnnotationsService struct{ db *gorm.DB } 13 14 func NewAnnotationsService(db *gorm.DB) AnnotationsService { 15 return AnnotationsService{db: db} 16 } 17 18 // CreateAnnotation creates a single annotation for a given application 19 // It does not check if the application has consumed any data 20 func (svc AnnotationsService) CreateAnnotation(ctx context.Context, params model.CreateAnnotation) (*model.Annotation, error) { 21 var u model.Annotation 22 23 if err := params.Parse(); err != nil { 24 return nil, err 25 } 26 27 u.AppName = params.AppName 28 u.Content = params.Content 29 u.Timestamp = params.Timestamp 30 31 tx := svc.db.WithContext(ctx) 32 33 // Upsert 34 if err := tx.Clauses(clause.OnConflict{ 35 Columns: []clause.Column{ 36 {Name: "app_name"}, 37 {Name: "timestamp"}, 38 }, 39 // Update fields we care about 40 DoUpdates: clause.AssignmentColumns([]string{"app_name", "timestamp", "content"}), 41 // Update updateAt fields 42 UpdateAll: true, 43 }).Create(&u).Error; err != nil { 44 return nil, err 45 } 46 47 return &u, nil 48 } 49 50 // FindAnnotationsByTimeRange finds all annotations for an app in a time range 51 func (svc AnnotationsService) FindAnnotationsByTimeRange(ctx context.Context, appName string, startTime time.Time, endTime time.Time) ([]model.Annotation, error) { 52 tx := svc.db.WithContext(ctx) 53 var u []model.Annotation 54 55 if err := tx.Where("app_name = ?", appName).Where("timestamp between ? and ?", startTime, endTime).Find(&u).Error; err != nil { 56 return u, err 57 } 58 59 return u, nil 60 }