refactor: tables for image and processing_image

This allows a single table to be used to process images, meaning if
anything happens to the system we can always return to polling the
database and process these images individually.

Because of this we also want an `image` table to contain the actual
binary data for the image, so we aren't selecting and writing it each
time, as it is potentially a bottleneck.
This commit is contained in:
2025-02-26 20:01:56 +00:00
parent 410270e217
commit d8095b0c67
10 changed files with 362 additions and 41 deletions

View File

@@ -11,24 +11,113 @@ import (
"github.com/google/uuid"
)
func SaveImage(userId string, imageName string, imageData []byte) (model.UserImages, error) {
stmt := UserImages.INSERT(UserImages.UserID, UserImages.ImageName, UserImages.Image).VALUES(userId, imageName, imageData).RETURNING(UserImages.ID, UserImages.UserID, UserImages.ImageName)
func SaveImageToProcess(userId string, imageName string, imageData []byte) (model.UserImagesToProcess, error) {
insertImageStmt := Image.INSERT(Image.ImageName, Image.Image).VALUES(imageName, imageData).RETURNING(Image.ID)
userImage := model.UserImages{}
err := stmt.Query(db, &userImage)
// 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)
userImage := model.UserImagesToProcess{}
err = stmt.Query(db, &userImage)
return userImage, err
}
func GetImage(imageId string) (model.UserImages, error) {
func removeImageToProcess(imageId string) error {
id := uuid.MustParse(imageId)
stmt := UserImages.SELECT(UserImages.AllColumns).WHERE(UserImages.ID.EQ(UUID(id)))
images := []model.UserImages{}
stmt := UserImagesToProcess.DELETE().WHERE(UserImagesToProcess.ID.EQ(UUID(id)))
fmt.Println(stmt.DebugSql())
_, err := stmt.Exec(db)
return err
}
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 model.UserImages{}, errors.New(fmt.Sprintf("Expected 1, got %d\n", len(images)))
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)))
fmt.Println(stmt.DebugSql())
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
@@ -37,6 +126,9 @@ func GetImage(imageId string) (model.UserImages, error) {
type UserImagesWithInfo struct {
model.UserImages
// TODO: this shit
Image model.Image
Tags []model.ImageTags
Links []model.ImageLinks
Text []model.ImageText
@@ -44,7 +136,7 @@ type UserImagesWithInfo struct {
func GetUserImages(userId string) ([]UserImagesWithInfo, error) {
id := uuid.MustParse(userId)
stmt := SELECT(UserImages.ID, UserImages.ImageName, ImageTags.AllColumns, ImageText.AllColumns, ImageLinks.AllColumns).FROM(UserImages.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)))
stmt := SELECT(UserImages.AllColumns, ImageTags.AllColumns, ImageText.AllColumns, ImageLinks.AllColumns).FROM(UserImages.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)
@@ -63,6 +155,8 @@ func SaveImageTags(imageId string, tags []string) ([]model.ImageTags, error) {
stmt.RETURNING(ImageTags.AllColumns)
fmt.Println(stmt.DebugSql())
imageTags := []model.ImageTags{}
err := stmt.Query(db, &imageTags)