package models import ( "errors" "fmt" "screenmark/screenmark/.gen/haystack/haystack/model" . "screenmark/screenmark/.gen/haystack/haystack/table" . "github.com/go-jet/jet/v2/postgres" "github.com/google/uuid" ) func SaveImageToProcess(userId string, imageName string, imageData []byte) (model.UserImagesToProcess, error) { insertImageStmt := Image.INSERT(Image.ImageName, Image.Image).VALUES(imageName, imageData).RETURNING(Image.ID) // TODO: should be a transaction image := model.Image{} err := insertImageStmt.Query(db, &image) if err != nil { return model.UserImagesToProcess{}, err } stmt := UserImagesToProcess.INSERT(UserImagesToProcess.UserID, UserImagesToProcess.ImageID).VALUES(userId, image.ID).RETURNING(UserImagesToProcess.AllColumns) fmt.Println(stmt.DebugSql()) userImage := model.UserImagesToProcess{} err = stmt.Query(db, &userImage) return userImage, err } func removeImageToProcess(imageId string) error { id := uuid.MustParse(imageId) stmt := UserImagesToProcess.DELETE().WHERE(UserImagesToProcess.ID.EQ(UUID(id))) _, err := stmt.Exec(db) return err } func getUserId(imageId uuid.UUID) (uuid.UUID, error) { stmt := UserImages.SELECT(UserImages.UserID).WHERE(UserImages.ID.EQ(UUID(imageId))) fmt.Println(stmt.DebugSql()) userIds := make([]string, 0) err := stmt.Query(db, &userIds) if err != nil { return uuid.Nil, err } if len(userIds) != 1 { return uuid.Nil, errors.New("expect only one user id per image id") } return uuid.Parse(userIds[0]) } func SaveImage(imageId uuid.UUID) (model.UserImages, error) { imageToProcess, err := GetImageToProcess(imageId.String()) if err != nil { return model.UserImages{}, err } stmt := UserImages.INSERT(UserImages.UserID, UserImages.ImageID).VALUES(imageToProcess.UserID, imageToProcess.ImageID).RETURNING(UserImages.ID, UserImages.UserID, UserImages.ImageID) userImage := model.UserImages{} err = stmt.Query(db, &userImage) if err != nil { return model.UserImages{}, err } err = removeImageToProcess(imageId.String()) if err != nil { return model.UserImages{}, err } return userImage, err } type ImageData struct { model.UserImages Image model.Image } func GetImage(imageId string) (ImageData, error) { id := uuid.MustParse(imageId) stmt := SELECT(UserImages.AllColumns, Image.AllColumns).FROM(UserImages.INNER_JOIN(Image, Image.ID.EQ(UserImages.ImageID))).WHERE(UserImages.ID.EQ(UUID(id))) images := []ImageData{} err := stmt.Query(db, &images) if len(images) != 1 { return ImageData{}, errors.New(fmt.Sprintf("Expected 1, got %d\n", len(images))) } return images[0], err } type ImageToProcessData struct { model.UserImagesToProcess Image model.Image } func GetImageToProcessWithData(imageId string) (ImageToProcessData, error) { id := uuid.MustParse(imageId) // stmt := UserImagesToProcess.SELECT(UserImages.AllColumns).WHERE(UserImages.ID.EQ(UUID(id))) // TODO: Image should be `Images` stmt := SELECT(UserImagesToProcess.AllColumns, Image.AllColumns).FROM(UserImagesToProcess.INNER_JOIN(Image, Image.ID.EQ(UserImagesToProcess.ImageID))).WHERE(UserImagesToProcess.ID.EQ(UUID(id))) images := []ImageToProcessData{} err := stmt.Query(db, &images) if len(images) != 1 { return ImageToProcessData{}, errors.New(fmt.Sprintf("Expected 1, got %d\n", len(images))) } return images[0], err } func GetImageToProcess(imageId string) (model.UserImagesToProcess, error) { id := uuid.MustParse(imageId) stmt := UserImagesToProcess.SELECT(UserImagesToProcess.AllColumns).WHERE(UserImagesToProcess.ID.EQ(UUID(id))) images := []model.UserImagesToProcess{} err := stmt.Query(db, &images) if len(images) != 1 { return model.UserImagesToProcess{}, errors.New(fmt.Sprintf("Expected 1, got %d\n", len(images))) } return images[0], err } type UserImagesWithInfo struct { ID uuid.UUID // TODO: this shit Image model.Image Tags []model.ImageTags Links []model.ImageLinks Text []model.ImageText } func GetUserImages(userId string) ([]UserImagesWithInfo, error) { id := uuid.MustParse(userId) stmt := SELECT(UserImages.ID.AS("UserImagesWithInfo.ID"), Image.ID, Image.ImageName, ImageTags.AllColumns, ImageText.AllColumns, ImageLinks.AllColumns).FROM(UserImages.INNER_JOIN(Image, Image.ID.EQ(UserImages.ImageID)).LEFT_JOIN(ImageTags, ImageTags.ImageID.EQ(UserImages.ID)).LEFT_JOIN(ImageText, ImageText.ImageID.EQ(UserImages.ID)).LEFT_JOIN(ImageLinks, ImageLinks.ImageID.EQ(UserImages.ID))).WHERE(UserImages.UserID.EQ(UUID(id))) images := []UserImagesWithInfo{} err := stmt.Query(db, &images) return images, err } func SaveImageTags(imageId string, tags []string) ([]model.ImageTags, error) { id := uuid.MustParse(imageId) userId, err := getUserId(id) if err != nil { return []model.ImageTags{}, err } err = CreateTags(userId, tags) if err != nil { return []model.ImageTags{}, err } userTagsExpression := make([]Expression, 0) for _, tag := range tags { userTagsExpression = append(userTagsExpression, String(tag)) } userTags := make([]model.UserTags, 0) getTagsStmt := UserTags.SELECT(UserTags.ID, UserTags.Tag).WHERE(UserTags.Tag.IN(userTagsExpression...)) err = getTagsStmt.Query(db, &userTags) if err != nil { return []model.ImageTags{}, err } stmt := ImageTags.INSERT(ImageTags.ImageID, ImageTags.TagID) for _, t := range userTags { stmt = stmt.VALUES(id, t.ID) } stmt.RETURNING(ImageTags.AllColumns) imageTags := make([]model.ImageTags, 0) err = stmt.Query(db, &imageTags) return imageTags, err } func SaveImageLinks(imageId string, links []string) ([]model.ImageLinks, error) { id := uuid.MustParse(imageId) stmt := ImageLinks.INSERT(ImageLinks.ImageID, ImageLinks.Link) for _, t := range links { stmt = stmt.VALUES(id, t) } stmt.RETURNING(ImageLinks.AllColumns) imageLinks := []model.ImageLinks{} err := stmt.Query(db, &imageLinks) return imageLinks, err } func SaveImageTexts(imageId string, texts []string) ([]model.ImageText, error) { id := uuid.MustParse(imageId) stmt := ImageText.INSERT(ImageText.ImageID, ImageText.ImageText) for _, t := range texts { stmt = stmt.VALUES(id, t) } stmt.RETURNING(ImageText.AllColumns) imageTags := []model.ImageText{} err := stmt.Query(db, &imageTags) return imageTags, err }