package models import ( "context" "database/sql" "fmt" "screenmark/screenmark/.gen/haystack/haystack/model" . "screenmark/screenmark/.gen/haystack/haystack/table" . "github.com/go-jet/jet/v2/postgres" "github.com/google/uuid" ) type StackModel struct { dbPool *sql.DB } type StackWithItems struct { model.Stacks SchemaItems []model.SchemaItems } type ImageWithSchema struct { model.ImageStacks Items []model.ImageSchemaItems } type IDValue struct { ID string `json:"id"` Value string `json:"value"` } // ======================================== // SELECT for lists // ======================================== func (m StackModel) List(ctx context.Context, userId uuid.UUID) ([]StackWithItems, error) { getStacksWithItems := SELECT( Stacks.AllColumns, SchemaItems.AllColumns, ). FROM( Stacks. INNER_JOIN(SchemaItems, SchemaItems.StackID.EQ(Stacks.ID)), ). WHERE(Stacks.UserID.EQ(UUID(userId))) lists := []StackWithItems{} err := getStacksWithItems.QueryContext(ctx, m.dbPool, &lists) return lists, err } func (m StackModel) ListItems(ctx context.Context, listID uuid.UUID) ([]ImageWithSchema, error) { getListItems := SELECT( ImageStacks.AllColumns, ImageSchemaItems.AllColumns, ). FROM( ImageStacks. INNER_JOIN(ImageSchemaItems, ImageSchemaItems.ImageID.EQ(ImageStacks.ImageID)), ). WHERE(ImageStacks.StackID.EQ(UUID(listID))) listItems := make([]ImageWithSchema, 0) err := getListItems.QueryContext(ctx, m.dbPool, &listItems) return listItems, err } func (m StackModel) Get(ctx context.Context, listID uuid.UUID) (model.Stacks, error) { getStackStmt := Stacks.SELECT(Stacks.AllColumns).WHERE(Stacks.ID.EQ(UUID(listID))) stack := model.Stacks{} err := getStackStmt.QueryContext(ctx, m.dbPool, &stack) return stack, err } // ======================================== // INSERT methods // ======================================== func (m StackModel) Save(ctx context.Context, userID uuid.UUID, name string, description string, status model.Progress) (model.Stacks, error) { saveListStmt := Stacks. INSERT(Stacks.UserID, Stacks.Name, Stacks.Description, Stacks.Status). VALUES(userID, name, description, status). RETURNING(Stacks.ID, Stacks.UserID, Stacks.Name, Stacks.Description, Stacks.Status, Stacks.CreatedAt) list := model.Stacks{} err := saveListStmt.QueryContext(ctx, m.dbPool, &list) return list, err } func (m StackModel) SaveItems(ctx context.Context, items []model.SchemaItems) error { saveItemsStmt := SchemaItems.INSERT(SchemaItems.MutableColumns).MODELS(items) _, err := saveItemsStmt.ExecContext(ctx, m.dbPool) return err } func (m StackModel) SaveImage(ctx context.Context, imageID uuid.UUID, stackID uuid.UUID) (model.ImageStacks, error) { saveImageStmt := ImageStacks. INSERT(ImageStacks.ImageID, ImageStacks.StackID). VALUES(imageID, stackID). RETURNING(ImageStacks.AllColumns) imageStack := model.ImageStacks{} err := saveImageStmt.QueryContext(ctx, m.dbPool, &imageStack) return imageStack, err } func (m StackModel) SaveSchemaItems(ctx context.Context, imageID uuid.UUID, items []IDValue) error { if len(items) == 0 { return fmt.Errorf("items cannot be empty") } saveSchemaItemStmt := ImageSchemaItems. INSERT( ImageSchemaItems.ImageID, ImageSchemaItems.SchemaItemID, ImageSchemaItems.Value, ) for _, item := range items { saveSchemaItemStmt = saveSchemaItemStmt.VALUES( imageID, item.ID, item.Value, ) } _, err := saveSchemaItemStmt.ExecContext(ctx, m.dbPool) return err } // ======================================== // DELETE methods // ======================================== func (m StackModel) DeleteImage(ctx context.Context, listID uuid.UUID, imageID uuid.UUID) error { deleteImageListStmt := ImageStacks.DELETE(). WHERE( ImageStacks.StackID.EQ(UUID(listID)). AND(ImageStacks.ImageID.EQ(UUID(imageID))), ) _, err := deleteImageListStmt.ExecContext(ctx, m.dbPool) return err } func (m StackModel) Delete(ctx context.Context, listID uuid.UUID, userID uuid.UUID) error { deleteStackStmt := Stacks.DELETE().WHERE(Stacks.ID.EQ(UUID(listID)).AND(Stacks.UserID.EQ(UUID(userID)))) _, err := deleteStackStmt.ExecContext(ctx, m.dbPool) return err } func NewStackModel(db *sql.DB) StackModel { return StackModel{dbPool: db} }