github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/strategy/strategy.go (about) 1 package strategy 2 3 import ( 4 "context" 5 "fmt" 6 7 confid "github.com/machinefi/w3bstream/pkg/depends/conf/id" 8 "github.com/machinefi/w3bstream/pkg/depends/kit/logr" 9 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx" 10 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder" 11 "github.com/machinefi/w3bstream/pkg/enums" 12 "github.com/machinefi/w3bstream/pkg/errors/status" 13 "github.com/machinefi/w3bstream/pkg/models" 14 "github.com/machinefi/w3bstream/pkg/types" 15 ) 16 17 func Update(ctx context.Context, id types.SFID, r *UpdateReq) (err error) { 18 var m *models.Strategy 19 20 return sqlx.NewTasks(types.MustMgrDBExecutorFromContext(ctx)).With( 21 func(d sqlx.DBExecutor) error { 22 ctx := types.WithMgrDBExecutor(ctx, d) 23 m, _ = types.StrategyFromContext(ctx) 24 if m == nil || m.StrategyID != id { 25 m, err = GetBySFID(ctx, id) 26 } 27 return err 28 }, 29 func(d sqlx.DBExecutor) error { 30 m.RelApplet = r.RelApplet 31 m.StrategyInfo = r.StrategyInfo 32 if err = m.UpdateByStrategyID(d); err != nil { 33 if sqlx.DBErr(err).IsConflict() { 34 return status.StrategyConflict.StatusErr().WithDesc( 35 fmt.Sprintf( 36 "[prj: %s] [app: %s] [type: %s] [hdl: %s]", 37 m.ProjectID, m.AppletID, m.EventType, m.Handler, 38 ), 39 ) 40 } 41 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 42 } 43 return nil 44 }, 45 ).Do() 46 } 47 48 func GetBySFID(ctx context.Context, id types.SFID) (*models.Strategy, error) { 49 d := types.MustMgrDBExecutorFromContext(ctx) 50 m := &models.Strategy{RelStrategy: models.RelStrategy{StrategyID: id}} 51 52 if err := m.FetchByStrategyID(d); err != nil { 53 if sqlx.DBErr(err).IsNotFound() { 54 return nil, status.StrategyNotFound 55 } 56 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 57 } 58 return m, nil 59 } 60 61 func List(ctx context.Context, r *ListReq) (*ListRsp, error) { 62 var ( 63 d = types.MustMgrDBExecutorFromContext(ctx) 64 m = &models.Strategy{} 65 66 err error 67 ret = &ListRsp{} 68 cond = r.Condition() 69 adds = r.Additions() 70 ) 71 72 ret.Data, err = m.List(d, cond, adds...) 73 if err != nil { 74 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 75 } 76 ret.Total, err = m.Count(d, cond) 77 if err != nil { 78 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 79 } 80 return ret, nil 81 } 82 83 func ListByCond(ctx context.Context, r *CondArgs, adds ...builder.Addition) ([]models.Strategy, error) { 84 data, err := (&models.Strategy{}).List( 85 types.MustMgrDBExecutorFromContext(ctx), 86 r.Condition(), 87 adds..., 88 ) 89 if err != nil { 90 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 91 } 92 return data, nil 93 } 94 95 func ListDetailByCond(ctx context.Context, r *CondArgs, adds ...builder.Addition) (data []*Detail, err error) { 96 var ( 97 d = types.MustMgrDBExecutorFromContext(ctx) 98 sty = &models.Strategy{} 99 app = &models.Applet{} 100 ins = &models.Instance{} 101 prj = &models.Project{} 102 cond = r.Condition() 103 ) 104 105 expr := builder.Select(builder.MultiWith(",", 106 builder.Alias(prj.ColName(), "f_prj_name"), 107 builder.Alias(sty.ColAppletID(), "f_app_id"), 108 builder.Alias(app.ColName(), "f_app_name"), 109 builder.Alias(ins.ColInstanceID(), "f_ins_id"), 110 builder.Alias(sty.ColHandler(), "f_hdl"), 111 builder.Alias(sty.ColEventType(), "f_evt"), 112 builder.Alias(sty.ColAutoCollectMetric(), "f_auto_collect"), 113 builder.Alias(sty.ColUpdatedAt(), "f_updated_at"), 114 builder.Alias(sty.ColCreatedAt(), "f_created_at"), 115 )).From( 116 d.T(sty), 117 append([]builder.Addition{ 118 builder.LeftJoin(d.T(app)).On(sty.ColAppletID().Eq(app.ColAppletID())), 119 builder.LeftJoin(d.T(prj)).On(sty.ColProjectID().Eq(prj.ColProjectID())), 120 builder.LeftJoin(d.T(ins)).On(sty.ColAppletID().Eq(ins.ColAppletID())), 121 builder.Where(cond), 122 }, adds...)..., 123 ) 124 err = d.QueryAndScan(expr, &data) 125 if err != nil { 126 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 127 } 128 return 129 } 130 131 func ListDetail(ctx context.Context, r *ListReq) (*ListDetailRsp, error) { 132 var ( 133 d = types.MustMgrDBExecutorFromContext(ctx) 134 m = &models.Strategy{} 135 136 err error 137 ret = &ListDetailRsp{} 138 ) 139 ret.Data, err = ListDetailByCond(ctx, &r.CondArgs, r.Addition()) 140 if ret.Total, err = m.Count(d, r.Condition()); err != nil { 141 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 142 } 143 return ret, nil 144 } 145 146 func RemoveBySFID(ctx context.Context, id types.SFID) error { 147 m := &models.Strategy{RelStrategy: models.RelStrategy{StrategyID: id}} 148 149 if err := m.DeleteByStrategyID(types.MustMgrDBExecutorFromContext(ctx)); err != nil { 150 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 151 } 152 return nil 153 } 154 155 func Remove(ctx context.Context, r *CondArgs) error { 156 var ( 157 d = types.MustMgrDBExecutorFromContext(ctx) 158 m = &models.Strategy{} 159 ) 160 161 _, err := d.Exec(builder.Delete().From( 162 d.T(m), 163 builder.Where(r.Condition()), 164 )) 165 if err != nil { 166 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 167 } 168 return nil 169 } 170 171 func Create(ctx context.Context, r *CreateReq) (*models.Strategy, error) { 172 var ( 173 idg = confid.MustNewSFIDGenerator() 174 app *models.Applet 175 sty = &models.Strategy{ 176 RelApplet: r.RelApplet, 177 StrategyInfo: r.StrategyInfo, 178 } 179 ) 180 181 err := sqlx.NewTasks(types.MustMgrDBExecutorFromContext(ctx)).With( 182 func(d sqlx.DBExecutor) error { 183 app, _ = types.AppletFromContext(ctx) 184 if app == nil || app.AppletID != sty.AppletID { 185 app = &models.Applet{ 186 RelApplet: models.RelApplet{AppletID: sty.AppletID}, 187 } 188 if err := app.FetchByAppletID(d); err != nil { 189 if sqlx.DBErr(err).IsNotFound() { 190 return status.AppletNotFound 191 } 192 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 193 } 194 } 195 return nil 196 }, 197 func(d sqlx.DBExecutor) error { 198 sty.ProjectID = app.ProjectID 199 sty.StrategyID = idg.MustGenSFID() 200 if err := sty.Create(d); err != nil { 201 if sqlx.DBErr(err).IsConflict() { 202 return status.StrategyConflict.StatusErr().WithDesc( 203 fmt.Sprintf( 204 "[prj: %s] [app: %s] [type: %s] [hdl: %s]", 205 sty.ProjectID, sty.AppletID, sty.EventType, sty.Handler, 206 ), 207 ) 208 } 209 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 210 } 211 return nil 212 }, 213 ).Do() 214 if err != nil { 215 return nil, err 216 } 217 return sty, nil 218 } 219 220 func BatchCreate(ctx context.Context, sty []models.Strategy) error { 221 if len(sty) == 0 { 222 return nil 223 } 224 225 return sqlx.NewTasks(types.MustMgrDBExecutorFromContext(ctx)).With( 226 func(d sqlx.DBExecutor) error { 227 for i := range sty { 228 s := &sty[i] 229 if err := s.Create(d); err != nil { 230 if sqlx.DBErr(err).IsConflict() { 231 return status.StrategyConflict.StatusErr().WithDesc( 232 fmt.Sprintf( 233 "[prj: %s] [app: %s] [type: %s] [hdl: %s]", 234 s.ProjectID, s.AppletID, s.EventType, s.Handler, 235 ), 236 ) 237 } 238 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 239 } 240 } 241 return nil 242 }, 243 ).Do() 244 } 245 246 func FilterByProjectAndEvent(ctx context.Context, id types.SFID, tpe string) ([]*types.StrategyResult, error) { 247 _, l := logr.Start(ctx, "strategy.FilterByProjectAndEventType") 248 defer l.End() 249 250 if tpe == "" { 251 tpe = enums.EVENTTYPEDEFAULT 252 } 253 254 data, err := ListDetailByCond(ctx, &CondArgs{ 255 ProjectID: id, EventTypes: []string{tpe}}, 256 ) 257 if err != nil { 258 return nil, err 259 } 260 261 results := make([]*types.StrategyResult, 0, len(data)) 262 for i := range data { 263 results = append(results, &data[i].StrategyResult) 264 } 265 266 return results, nil 267 }