package query import ( "context" "fmt" "queryorchestration/internal/database/repository" resultprocessor "queryorchestration/internal/query/result/processor" contextfull "queryorchestration/internal/query/types/contextFull" jsonextractor "queryorchestration/internal/query/types/jsonExtractor" "github.com/google/uuid" ) func (s *Service) Create(ctx context.Context, entity *resultprocessor.Create) (uuid.UUID, error) { err := s.normalizeCreate(ctx, entity) if err != nil { return uuid.Nil, err } id, err := s.submitCreate(ctx, entity) if err != nil { return uuid.Nil, err } return id, err } func (s *Service) normalizeCreate(ctx context.Context, entity *resultprocessor.Create) error { err := s.NormalizeQueryIDs(ctx, entity) if err != nil { return err } err = s.NormalizeConfig(entity) if err != nil { return err } validator, err := s.getCreator(entity.Type) if err != nil { return err } err = validator.Validate(ctx, entity) if err != nil { return err } return nil } func (s *Service) submitCreate(ctx context.Context, entity *resultprocessor.Create) (uuid.UUID, error) { query, err := parseCreateQuery(entity) if err != nil { return uuid.Nil, err } var id uuid.UUID err = s.cfg.ExecuteDBTransaction(ctx, func(ctx context.Context, qtx *repository.Queries) error { id, err = qtx.CreateQuery(ctx, query.Type) if err != nil { return err } version, err := qtx.AddLatestQueryVersion(ctx, id) if err != nil { return err } err = qtx.AddActiveQueryVersion(ctx, &repository.AddActiveQueryVersionParams{ Queryid: id, Versionid: version, }) if err != nil { return err } if query.RequiredQueryIDs != nil { for _, reqQuery := range *query.RequiredQueryIDs { err = qtx.AddRequiredQuery(ctx, &repository.AddRequiredQueryParams{ Queryid: id, Requiredqueryid: reqQuery, Addedversion: version, }) if err != nil { return err } } } if query.Config != nil { err = qtx.SetQueryConfig(ctx, &repository.SetQueryConfigParams{ Queryid: id, Config: *query.Config, Addedversion: version, }) if err != nil { return err } } return nil }) if err != nil { return uuid.Nil, err } return id, nil } func (s *Service) getCreator(qType resultprocessor.Type) (resultprocessor.Creator, error) { switch qType { case resultprocessor.TypeJsonExtractor: return jsonextractor.NewCreator(), nil case resultprocessor.TypeContextFull: return contextfull.NewCreator(), nil default: return nil, fmt.Errorf("attempting to process invalid query type") } } type createQuery struct { Type repository.Querytype RequiredQueryIDs *[]uuid.UUID Config *[]byte } func parseCreateQuery(q *resultprocessor.Create) (*createQuery, error) { t, err := resultprocessor.ToDBQueryType(q.Type) if err != nil { return nil, err } var reqIDs *[]uuid.UUID if q.RequiredQueryIDs != nil { tIDs := *q.RequiredQueryIDs reqIDs = &tIDs } var cfg *[]byte if q.Config != nil { tC := []byte(*q.Config) cfg = &tC } return &createQuery{ Type: t, RequiredQueryIDs: reqIDs, Config: cfg, }, nil }