@@ -5,9 +5,18 @@ package ck
55
66import (
77 "context"
8+ "fmt"
9+ "strings"
810
911 "github.com/coze-dev/coze-loop/backend/infra/ck"
12+ "github.com/coze-dev/coze-loop/backend/modules/observability/infra/repo/ck/convertor"
13+ "github.com/coze-dev/coze-loop/backend/modules/observability/infra/repo/ck/gorm_gen/model"
1014 "github.com/coze-dev/coze-loop/backend/modules/observability/infra/repo/dao"
15+ obErrorx "github.com/coze-dev/coze-loop/backend/modules/observability/pkg/errno"
16+ "github.com/coze-dev/coze-loop/backend/pkg/errorx"
17+ "github.com/coze-dev/coze-loop/backend/pkg/logs"
18+ "gorm.io/gorm"
19+ "gorm.io/gorm/clause"
1120)
1221
1322func NewAnnotationCkDaoImpl (db ck.Provider ) (dao.IAnnotationDao , error ) {
@@ -21,13 +30,149 @@ type AnnotationCkDaoImpl struct {
2130}
2231
2332func (a * AnnotationCkDaoImpl ) Insert (ctx context.Context , params * dao.InsertAnnotationParam ) error {
24- return nil
33+ if params == nil || len (params .Annotations ) == 0 {
34+ return errorx .NewByCode (obErrorx .CommercialCommonInvalidParamCodeCode )
35+ }
36+ db := a .db .NewSession (ctx )
37+ retryTimes := 3
38+ var lastErr error
39+ for i := 0 ; i < retryTimes ; i ++ {
40+ if err := db .Table (params .Table ).Create (params .Annotations ).Error ; err != nil {
41+ lastErr = err
42+ } else {
43+ logs .CtxInfo (ctx , "insert annotations successfully" )
44+ return nil
45+ }
46+ }
47+ logs .CtxError (ctx , "fail to insert annotations: %v" , lastErr )
48+ return errorx .WrapByCode (lastErr , obErrorx .CommercialCommonInternalErrorCodeCode )
2549}
2650
2751func (a * AnnotationCkDaoImpl ) Get (ctx context.Context , params * dao.GetAnnotationParam ) (* dao.Annotation , error ) {
28- return nil , nil
52+ if params == nil || params .ID == "" {
53+ return nil , errorx .NewByCode (obErrorx .CommercialCommonInvalidParamCodeCode )
54+ }
55+ db , err := a .buildSql (ctx , & annoSqlParam {
56+ Tables : params .Tables ,
57+ StartTime : params .StartTime ,
58+ EndTime : params .EndTime ,
59+ ID : params .ID ,
60+ Limit : 1 ,
61+ })
62+ if err != nil {
63+ return nil , err
64+ }
65+ logs .CtxInfo (ctx , "Get Annotation SQL: %s" , db .ToSQL (func (tx * gorm.DB ) * gorm.DB {
66+ return tx .Find (nil )
67+ }))
68+ var annotations []* model.ObservabilityAnnotation
69+ if err := db .Find (& annotations ).Error ; err != nil {
70+ return nil , err
71+ }
72+ if len (annotations ) == 0 {
73+ return nil , nil
74+ } else if len (annotations ) > 1 {
75+ logs .CtxWarn (ctx , "multiple annotations found" )
76+ }
77+ return convertor .AnnotationCKModel2PO (annotations [0 ]), nil
2978}
3079
3180func (a * AnnotationCkDaoImpl ) List (ctx context.Context , params * dao.ListAnnotationsParam ) ([]* dao.Annotation , error ) {
32- return nil , nil
81+ if params == nil || len (params .SpanIDs ) == 0 {
82+ return nil , nil
83+ }
84+ db , err := a .buildSql (ctx , & annoSqlParam {
85+ Tables : params .Tables ,
86+ StartTime : params .StartTime ,
87+ EndTime : params .EndTime ,
88+ SpanIDs : params .SpanIDs ,
89+ DescByUpdatedAt : params .DescByUpdatedAt ,
90+ Limit : params .Limit ,
91+ })
92+ if err != nil {
93+ return nil , err
94+ }
95+ logs .CtxInfo (ctx , "List Annotations SQL: %s" , db .ToSQL (func (tx * gorm.DB ) * gorm.DB {
96+ return tx .Find (nil )
97+ }))
98+ var annotations []* model.ObservabilityAnnotation
99+ if err := db .Find (& annotations ).Error ; err != nil {
100+ return nil , err
101+ }
102+ return convertor .AnnotationListCKModels2PO (annotations ), nil
103+ }
104+
105+ type annoSqlParam struct {
106+ Tables []string
107+ StartTime int64
108+ EndTime int64
109+ ID string
110+ SpanIDs []string
111+ DescByUpdatedAt bool
112+ Limit int32
113+ }
114+
115+ func (a * AnnotationCkDaoImpl ) buildSql (ctx context.Context , param * annoSqlParam ) (* gorm.DB , error ) {
116+ db := a .db .NewSession (ctx )
117+ var tableQueries []* gorm.DB
118+ for _ , table := range param .Tables {
119+ query , err := a .buildSingleSql (ctx , db , table , param )
120+ if err != nil {
121+ return nil , err
122+ }
123+ tableQueries = append (tableQueries , query )
124+ }
125+ if len (tableQueries ) == 0 {
126+ return nil , fmt .Errorf ("no table configured" )
127+ } else if len (tableQueries ) == 1 {
128+ query := tableQueries [0 ].ToSQL (func (tx * gorm.DB ) * gorm.DB {
129+ return tx .Find (nil )
130+ })
131+ query += " SETTINGS final = 1"
132+ return db .Raw (query ), nil
133+ } else {
134+ queries := make ([]string , 0 )
135+ for i := 0 ; i < len (tableQueries ); i ++ {
136+ query := tableQueries [i ].ToSQL (func (tx * gorm.DB ) * gorm.DB {
137+ return tx .Find (nil )
138+ })
139+ queries = append (queries , "(" + query + ")" )
140+ }
141+ sql := fmt .Sprintf ("SELECT * FROM (%s)" , strings .Join (queries , " UNION ALL " ))
142+ if param .DescByUpdatedAt {
143+ sql += " ORDER BY updated_at DESC"
144+ } else {
145+ sql += " ORDER BY created_at ASC"
146+ }
147+ sql += fmt .Sprintf (" LIMIT %d SETTINGS final = 1" , param .Limit )
148+ return db .Raw (sql ), nil
149+ }
150+ }
151+
152+ // buildSingleSql 构建单表查询SQL
153+ func (a * AnnotationCkDaoImpl ) buildSingleSql (ctx context.Context , db * gorm.DB , tableName string , param * annoSqlParam ) (* gorm.DB , error ) {
154+ sqlQuery := db .
155+ Table (tableName ).
156+ Where ("deleted_at = 0" )
157+
158+ if param .ID != "" {
159+ sqlQuery = sqlQuery .Where ("id = ?" , param .ID )
160+ }
161+ if len (param .SpanIDs ) > 0 {
162+ sqlQuery = sqlQuery .Where ("span_id IN (?)" , param .SpanIDs )
163+ }
164+ sqlQuery = sqlQuery .
165+ Where ("start_time >= ?" , param .StartTime ).
166+ Where ("start_time <= ?" , param .EndTime )
167+ if param .DescByUpdatedAt {
168+ sqlQuery = sqlQuery .Order (clause.OrderBy {Columns : []clause.OrderByColumn {
169+ {Column : clause.Column {Name : "updated_at" }, Desc : true },
170+ }})
171+ } else {
172+ sqlQuery = sqlQuery .Order (clause.OrderBy {Columns : []clause.OrderByColumn {
173+ {Column : clause.Column {Name : "created_at" }, Desc : false },
174+ }})
175+ }
176+ sqlQuery = sqlQuery .Limit (int (param .Limit ))
177+ return sqlQuery , nil
33178}
0 commit comments