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  }